1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2022 Free Software Foundation, Inc.
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 Make sure all relevant comments, and all relevant code from all
26 actions, brought over from old parser. Verify exact correspondence
29 Add testcases covering every input symbol in every state in old and
32 Include full syntax for GNU C, including erroneous cases accepted
33 with error messages, in syntax productions in comments.
35 Make more diagnostics in the front end generally take an explicit
36 location rather than implicitly using input_location. */
39 #define INCLUDE_MEMORY
41 #include "coretypes.h"
46 #include "stringpool.h"
49 #include "stor-layout.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
54 #include "c-family/c-objc.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
63 #include "gcc-rich-location.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
71 #include "tree-pretty-print.h"
73 #include "c-family/known-headers.h"
75 /* We need to walk over decls with incomplete struct/union/enum types
76 after parsing the whole translation unit.
77 In finish_decl(), if the decl is static, has incomplete
78 struct/union/enum type, it is appended to incomplete_record_decls.
79 In c_parser_translation_unit(), we iterate over incomplete_record_decls
80 and report error if any of the decls are still incomplete. */
82 vec<tree> incomplete_record_decls;
85 set_c_expr_source_range (c_expr *expr,
86 location_t start, location_t finish)
88 expr->src_range.m_start = start;
89 expr->src_range.m_finish = finish;
91 set_source_range (expr->value, start, finish);
95 set_c_expr_source_range (c_expr *expr,
96 source_range src_range)
98 expr->src_range = src_range;
100 set_source_range (expr->value, src_range);
104 /* Initialization routine for this file. */
109 /* The only initialization required is of the reserved word
115 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
116 the c_token structure. */
117 gcc_assert (RID_MAX <= 255);
124 mask |= D_ASM | D_EXT;
128 if (!c_dialect_objc ())
129 mask |= D_OBJC | D_CXX_OBJC;
131 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
132 for (i = 0; i < num_c_common_reswords; i++)
134 /* If a keyword is disabled, do not enter it into the table
135 and so create a canonical spelling that isn't a keyword. */
136 if (c_common_reswords[i].disable & mask)
139 && (c_common_reswords[i].disable & D_CXXWARN))
141 id = get_identifier (c_common_reswords[i].word);
142 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
143 C_IS_RESERVED_WORD (id) = 1;
148 id = get_identifier (c_common_reswords[i].word);
149 C_SET_RID_CODE (id, c_common_reswords[i].rid);
150 C_IS_RESERVED_WORD (id) = 1;
151 ridpointers [(int) c_common_reswords[i].rid] = id;
154 for (i = 0; i < NUM_INT_N_ENTS; i++)
156 /* We always create the symbols but they aren't always supported. */
158 sprintf (name, "__int%d", int_n_data[i].bitsize);
159 id = get_identifier (name);
160 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
161 C_IS_RESERVED_WORD (id) = 1;
163 sprintf (name, "__int%d__", int_n_data[i].bitsize);
164 id = get_identifier (name);
165 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
166 C_IS_RESERVED_WORD (id) = 1;
171 id = get_identifier ("omp_all_memory");
172 C_SET_RID_CODE (id, RID_OMP_ALL_MEMORY);
173 C_IS_RESERVED_WORD (id) = 1;
174 ridpointers [RID_OMP_ALL_MEMORY] = id;
178 /* A parser structure recording information about the state and
179 context of parsing. Includes lexer information with up to two
180 tokens of look-ahead; more are not needed for C. */
181 struct GTY(()) c_parser {
182 /* The look-ahead tokens. */
183 c_token * GTY((skip)) tokens;
184 /* Buffer for look-ahead tokens. */
185 c_token tokens_buf[4];
186 /* How many look-ahead tokens are available (0 - 4, or
187 more if parsing from pre-lexed tokens). */
188 unsigned int tokens_avail;
189 /* Raw look-ahead tokens, used only for checking in Objective-C
190 whether '[[' starts attributes. */
191 vec<c_token, va_gc> *raw_tokens;
192 /* The number of raw look-ahead tokens that have since been fully
194 unsigned int raw_tokens_used;
195 /* True if a syntax error is being recovered from; false otherwise.
196 c_parser_error sets this flag. It should clear this flag when
197 enough tokens have been consumed to recover from the error. */
198 BOOL_BITFIELD error : 1;
199 /* True if we're processing a pragma, and shouldn't automatically
200 consume CPP_PRAGMA_EOL. */
201 BOOL_BITFIELD in_pragma : 1;
202 /* True if we're parsing the outermost block of an if statement. */
203 BOOL_BITFIELD in_if_block : 1;
204 /* True if we want to lex a translated, joined string (for an
205 initial #pragma pch_preprocess). Otherwise the parser is
206 responsible for concatenating strings and translating to the
207 execution character set as needed. */
208 BOOL_BITFIELD lex_joined_string : 1;
209 /* True if, when the parser is concatenating string literals, it
210 should translate them to the execution character set (false
211 inside attributes). */
212 BOOL_BITFIELD translate_strings_p : 1;
214 /* Objective-C specific parser/lexer information. */
216 /* True if we are in a context where the Objective-C "PQ" keywords
217 are considered keywords. */
218 BOOL_BITFIELD objc_pq_context : 1;
219 /* True if we are parsing a (potential) Objective-C foreach
220 statement. This is set to true after we parsed 'for (' and while
221 we wait for 'in' or ';' to decide if it's a standard C for loop or an
222 Objective-C foreach loop. */
223 BOOL_BITFIELD objc_could_be_foreach_context : 1;
224 /* The following flag is needed to contextualize Objective-C lexical
225 analysis. In some cases (e.g., 'int NSObject;'), it is
226 undesirable to bind an identifier to an Objective-C class, even
227 if a class with that name exists. */
228 BOOL_BITFIELD objc_need_raw_identifier : 1;
229 /* Nonzero if we're processing a __transaction statement. The value
230 is 1 | TM_STMT_ATTR_*. */
231 unsigned int in_transaction : 4;
232 /* True if we are in a context where the Objective-C "Property attribute"
233 keywords are valid. */
234 BOOL_BITFIELD objc_property_attr_context : 1;
236 /* Whether we have just seen/constructed a string-literal. Set when
237 returning a string-literal from c_parser_string_literal. Reset
238 in consume_token. Useful when we get a parse error and see an
239 unknown token, which could have been a string-literal constant
241 BOOL_BITFIELD seen_string_literal : 1;
243 /* Location of the last consumed token. */
244 location_t last_token_location;
247 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
250 c_parser_tokens_buf (c_parser *parser, unsigned n)
252 return &parser->tokens_buf[n];
255 /* Return the error state of PARSER. */
258 c_parser_error (c_parser *parser)
260 return parser->error;
263 /* Set the error state of PARSER to ERR. */
266 c_parser_set_error (c_parser *parser, bool err)
272 /* The actual parser and external interface. ??? Does this need to be
273 garbage-collected? */
275 static GTY (()) c_parser *the_parser;
277 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
278 context-sensitive postprocessing of the token is not done. */
281 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
283 timevar_push (TV_LEX);
285 if (raw || vec_safe_length (parser->raw_tokens) == 0)
287 token->type = c_lex_with_flags (&token->value, &token->location,
289 (parser->lex_joined_string
290 ? 0 : C_LEX_STRING_NO_JOIN));
291 token->id_kind = C_ID_NONE;
292 token->keyword = RID_MAX;
293 token->pragma_kind = PRAGMA_NONE;
297 /* Use a token previously lexed as a raw look-ahead token, and
298 complete the processing on it. */
299 *token = (*parser->raw_tokens)[parser->raw_tokens_used];
300 ++parser->raw_tokens_used;
301 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
303 vec_free (parser->raw_tokens);
304 parser->raw_tokens_used = 0;
317 bool objc_force_identifier = parser->objc_need_raw_identifier;
318 if (c_dialect_objc ())
319 parser->objc_need_raw_identifier = false;
321 if (C_IS_RESERVED_WORD (token->value))
323 enum rid rid_code = C_RID_CODE (token->value);
325 if (rid_code == RID_CXX_COMPAT_WARN)
327 warning_at (token->location,
329 "identifier %qE conflicts with C++ keyword",
332 else if (rid_code >= RID_FIRST_ADDR_SPACE
333 && rid_code <= RID_LAST_ADDR_SPACE)
336 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
337 targetm.addr_space.diagnose_usage (as, token->location);
338 token->id_kind = C_ID_ADDRSPACE;
339 token->keyword = rid_code;
342 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
344 /* We found an Objective-C "pq" keyword (in, out,
345 inout, bycopy, byref, oneway). They need special
346 care because the interpretation depends on the
348 if (parser->objc_pq_context)
350 token->type = CPP_KEYWORD;
351 token->keyword = rid_code;
354 else if (parser->objc_could_be_foreach_context
355 && rid_code == RID_IN)
357 /* We are in Objective-C, inside a (potential)
358 foreach context (which means after having
359 parsed 'for (', but before having parsed ';'),
360 and we found 'in'. We consider it the keyword
361 which terminates the declaration at the
362 beginning of a foreach-statement. Note that
363 this means you can't use 'in' for anything else
364 in that context; in particular, in Objective-C
365 you can't use 'in' as the name of the running
366 variable in a C for loop. We could potentially
367 try to add code here to disambiguate, but it
368 seems a reasonable limitation. */
369 token->type = CPP_KEYWORD;
370 token->keyword = rid_code;
373 /* Else, "pq" keywords outside of the "pq" context are
374 not keywords, and we fall through to the code for
377 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
379 /* We found an Objective-C "property attribute"
380 keyword (getter, setter, readonly, etc). These are
381 only valid in the property context. */
382 if (parser->objc_property_attr_context)
384 token->type = CPP_KEYWORD;
385 token->keyword = rid_code;
388 /* Else they are not special keywords.
391 else if (c_dialect_objc ()
392 && (OBJC_IS_AT_KEYWORD (rid_code)
393 || OBJC_IS_CXX_KEYWORD (rid_code)))
395 /* We found one of the Objective-C "@" keywords (defs,
396 selector, synchronized, etc) or one of the
397 Objective-C "cxx" keywords (class, private,
398 protected, public, try, catch, throw) without a
399 preceding '@' sign. Do nothing and fall through to
400 the code for normal tokens (in C++ we would still
401 consider the CXX ones keywords, but not in C). */
406 token->type = CPP_KEYWORD;
407 token->keyword = rid_code;
412 decl = lookup_name (token->value);
415 if (TREE_CODE (decl) == TYPE_DECL)
417 token->id_kind = C_ID_TYPENAME;
421 else if (c_dialect_objc ())
423 tree objc_interface_decl = objc_is_class_name (token->value);
424 /* Objective-C class names are in the same namespace as
425 variables and typedefs, and hence are shadowed by local
427 if (objc_interface_decl
428 && (!objc_force_identifier || global_bindings_p ()))
430 token->value = objc_interface_decl;
431 token->id_kind = C_ID_CLASSNAME;
435 token->id_kind = C_ID_ID;
439 /* This only happens in Objective-C; it must be a keyword. */
440 token->type = CPP_KEYWORD;
441 switch (C_RID_CODE (token->value))
443 /* Replace 'class' with '@class', 'private' with '@private',
444 etc. This prevents confusion with the C++ keyword
445 'class', and makes the tokens consistent with other
446 Objective-C 'AT' keywords. For example '@class' is
447 reported as RID_AT_CLASS which is consistent with
448 '@synchronized', which is reported as
451 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
452 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
453 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
454 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
455 case RID_THROW: token->keyword = RID_AT_THROW; break;
456 case RID_TRY: token->keyword = RID_AT_TRY; break;
457 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
458 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
459 default: token->keyword = C_RID_CODE (token->value);
464 case CPP_CLOSE_PAREN:
466 /* These tokens may affect the interpretation of any identifiers
467 following, if doing Objective-C. */
468 if (c_dialect_objc ())
469 parser->objc_need_raw_identifier = false;
472 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
473 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
480 timevar_pop (TV_LEX);
483 /* Return a pointer to the next token from PARSER, reading it in if
487 c_parser_peek_token (c_parser *parser)
489 if (parser->tokens_avail == 0)
491 c_lex_one_token (parser, &parser->tokens[0]);
492 parser->tokens_avail = 1;
494 return &parser->tokens[0];
497 /* Return a pointer to the next-but-one token from PARSER, reading it
498 in if necessary. The next token is already read in. */
501 c_parser_peek_2nd_token (c_parser *parser)
503 if (parser->tokens_avail >= 2)
504 return &parser->tokens[1];
505 gcc_assert (parser->tokens_avail == 1);
506 gcc_assert (parser->tokens[0].type != CPP_EOF);
507 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
508 c_lex_one_token (parser, &parser->tokens[1]);
509 parser->tokens_avail = 2;
510 return &parser->tokens[1];
513 /* Return a pointer to the Nth token from PARSER, reading it
514 in if necessary. The N-1th token is already read in. */
517 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
519 /* N is 1-based, not zero-based. */
522 if (parser->tokens_avail >= n)
523 return &parser->tokens[n - 1];
524 gcc_assert (parser->tokens_avail == n - 1);
525 c_lex_one_token (parser, &parser->tokens[n - 1]);
526 parser->tokens_avail = n;
527 return &parser->tokens[n - 1];
530 /* Return a pointer to the Nth token from PARSER, reading it in as a
531 raw look-ahead token if necessary. The N-1th token is already read
532 in. Raw look-ahead tokens remain available for when the non-raw
533 functions above are called. */
536 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
538 /* N is 1-based, not zero-based. */
541 if (parser->tokens_avail >= n)
542 return &parser->tokens[n - 1];
543 unsigned int raw_len = vec_safe_length (parser->raw_tokens);
544 unsigned int raw_avail
545 = parser->tokens_avail + raw_len - parser->raw_tokens_used;
546 gcc_assert (raw_avail >= n - 1);
548 return &(*parser->raw_tokens)[parser->raw_tokens_used
549 + n - 1 - parser->tokens_avail];
550 vec_safe_reserve (parser->raw_tokens, 1);
551 parser->raw_tokens->quick_grow (raw_len + 1);
552 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
553 return &(*parser->raw_tokens)[raw_len];
557 c_keyword_starts_typename (enum rid keyword)
592 if (keyword >= RID_FIRST_INT_N
593 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
594 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
600 /* Return true if TOKEN can start a type name,
603 c_token_starts_typename (c_token *token)
608 switch (token->id_kind)
617 gcc_assert (c_dialect_objc ());
623 return c_keyword_starts_typename (token->keyword);
625 if (c_dialect_objc ())
633 /* Return true if the next token from PARSER can start a type name,
634 false otherwise. LA specifies how to do lookahead in order to
635 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
638 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
640 c_token *token = c_parser_peek_token (parser);
641 if (c_token_starts_typename (token))
644 /* Try a bit harder to detect an unknown typename. */
645 if (la != cla_prefer_id
646 && token->type == CPP_NAME
647 && token->id_kind == C_ID_ID
649 /* Do not try too hard when we could have "object in array". */
650 && !parser->objc_could_be_foreach_context
652 && (la == cla_prefer_type
653 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
654 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
656 /* Only unknown identifiers. */
657 && !lookup_name (token->value))
663 /* Return true if TOKEN is a type qualifier, false otherwise. */
665 c_token_is_qualifier (c_token *token)
670 switch (token->id_kind)
678 switch (token->keyword)
696 /* Return true if the next token from PARSER is a type qualifier,
699 c_parser_next_token_is_qualifier (c_parser *parser)
701 c_token *token = c_parser_peek_token (parser);
702 return c_token_is_qualifier (token);
705 /* Return true if TOKEN can start declaration specifiers (not
706 including standard attributes), false otherwise. */
708 c_token_starts_declspecs (c_token *token)
713 switch (token->id_kind)
722 gcc_assert (c_dialect_objc ());
728 switch (token->keyword)
769 if (token->keyword >= RID_FIRST_INT_N
770 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
771 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
776 if (c_dialect_objc ())
785 /* Return true if TOKEN can start declaration specifiers (not
786 including standard attributes) or a static assertion, false
789 c_token_starts_declaration (c_token *token)
791 if (c_token_starts_declspecs (token)
792 || token->keyword == RID_STATIC_ASSERT)
798 /* Return true if the next token from PARSER can start declaration
799 specifiers (not including standard attributes), false
802 c_parser_next_token_starts_declspecs (c_parser *parser)
804 c_token *token = c_parser_peek_token (parser);
806 /* In Objective-C, a classname normally starts a declspecs unless it
807 is immediately followed by a dot. In that case, it is the
808 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
809 setter/getter on the class. c_token_starts_declspecs() can't
810 differentiate between the two cases because it only checks the
811 current token, so we have a special check here. */
812 if (c_dialect_objc ()
813 && token->type == CPP_NAME
814 && token->id_kind == C_ID_CLASSNAME
815 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
818 return c_token_starts_declspecs (token);
821 /* Return true if the next tokens from PARSER can start declaration
822 specifiers (not including standard attributes) or a static
823 assertion, false otherwise. */
825 c_parser_next_tokens_start_declaration (c_parser *parser)
827 c_token *token = c_parser_peek_token (parser);
830 if (c_dialect_objc ()
831 && token->type == CPP_NAME
832 && token->id_kind == C_ID_CLASSNAME
833 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
836 /* Labels do not start declarations. */
837 if (token->type == CPP_NAME
838 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
841 if (c_token_starts_declaration (token))
844 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
850 /* Consume the next token from PARSER. */
853 c_parser_consume_token (c_parser *parser)
855 gcc_assert (parser->tokens_avail >= 1);
856 gcc_assert (parser->tokens[0].type != CPP_EOF);
857 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
858 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
859 parser->last_token_location = parser->tokens[0].location;
860 if (parser->tokens != &parser->tokens_buf[0])
862 else if (parser->tokens_avail >= 2)
864 parser->tokens[0] = parser->tokens[1];
865 if (parser->tokens_avail >= 3)
867 parser->tokens[1] = parser->tokens[2];
868 if (parser->tokens_avail >= 4)
869 parser->tokens[2] = parser->tokens[3];
872 parser->tokens_avail--;
873 parser->seen_string_literal = false;
876 /* Expect the current token to be a #pragma. Consume it and remember
877 that we've begun parsing a pragma. */
880 c_parser_consume_pragma (c_parser *parser)
882 gcc_assert (!parser->in_pragma);
883 gcc_assert (parser->tokens_avail >= 1);
884 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
885 if (parser->tokens != &parser->tokens_buf[0])
887 else if (parser->tokens_avail >= 2)
889 parser->tokens[0] = parser->tokens[1];
890 if (parser->tokens_avail >= 3)
891 parser->tokens[1] = parser->tokens[2];
893 parser->tokens_avail--;
894 parser->in_pragma = true;
897 /* Update the global input_location from TOKEN. */
899 c_parser_set_source_position_from_token (c_token *token)
901 if (token->type != CPP_EOF)
903 input_location = token->location;
907 /* Helper function for c_parser_error.
908 Having peeked a token of kind TOK1_KIND that might signify
909 a conflict marker, peek successor tokens to determine
910 if we actually do have a conflict marker.
911 Specifically, we consider a run of 7 '<', '=' or '>' characters
912 at the start of a line as a conflict marker.
913 These come through the lexer as three pairs and a single,
914 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
915 If it returns true, *OUT_LOC is written to with the location/range
919 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
922 c_token *token2 = c_parser_peek_2nd_token (parser);
923 if (token2->type != tok1_kind)
925 c_token *token3 = c_parser_peek_nth_token (parser, 3);
926 if (token3->type != tok1_kind)
928 c_token *token4 = c_parser_peek_nth_token (parser, 4);
929 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
932 /* It must be at the start of the line. */
933 location_t start_loc = c_parser_peek_token (parser)->location;
934 if (LOCATION_COLUMN (start_loc) != 1)
937 /* We have a conflict marker. Construct a location of the form:
940 with start == caret, finishing at the end of the marker. */
941 location_t finish_loc = get_finish (token4->location);
942 *out_loc = make_location (start_loc, start_loc, finish_loc);
947 /* Issue a diagnostic of the form
948 FILE:LINE: MESSAGE before TOKEN
949 where TOKEN is the next token in the input stream of PARSER.
950 MESSAGE (specified by the caller) is usually of the form "expected
953 Use RICHLOC as the location of the diagnostic.
955 Do not issue a diagnostic if still recovering from an error.
957 Return true iff an error was actually emitted.
959 ??? This is taken from the C++ parser, but building up messages in
960 this way is not i18n-friendly and some other approach should be
964 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
965 rich_location *richloc)
967 c_token *token = c_parser_peek_token (parser);
970 parser->error = true;
974 /* If this is actually a conflict marker, report it as such. */
975 if (token->type == CPP_LSHIFT
976 || token->type == CPP_RSHIFT
977 || token->type == CPP_EQ_EQ)
980 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
982 error_at (loc, "version control conflict marker in file");
987 /* If we were parsing a string-literal and there is an unknown name
988 token right after, then check to see if that could also have been
989 a literal string by checking the name against a list of known
990 standard string literal constants defined in header files. If
991 there is one, then add that as an hint to the error message. */
992 auto_diagnostic_group d;
994 if (parser->seen_string_literal && token->type == CPP_NAME)
996 tree name = token->value;
997 const char *token_name = IDENTIFIER_POINTER (name);
998 const char *header_hint
999 = get_c_stdlib_header_for_string_macro_name (token_name);
1000 if (header_hint != NULL)
1001 h = name_hint (NULL, new suggest_missing_header (token->location,
1006 c_parse_error (gmsgid,
1007 /* Because c_parse_error does not understand
1008 CPP_KEYWORD, keywords are treated like
1010 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
1011 /* ??? The C parser does not save the cpp flags of a
1012 token, we need to pass 0 here and we will not get
1013 the source spelling of some tokens but rather the
1014 canonical spelling. */
1015 token->value, /*flags=*/0, richloc);
1019 /* As c_parser_error_richloc, but issue the message at the
1020 location of PARSER's next token, or at input_location
1021 if the next token is EOF. */
1024 c_parser_error (c_parser *parser, const char *gmsgid)
1026 c_token *token = c_parser_peek_token (parser);
1027 c_parser_set_source_position_from_token (token);
1028 rich_location richloc (line_table, input_location);
1029 return c_parser_error_richloc (parser, gmsgid, &richloc);
1032 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1033 This class is for tracking such a matching pair of symbols.
1034 In particular, it tracks the location of the first token,
1035 so that if the second token is missing, we can highlight the
1036 location of the first token when notifying the user about the
1039 template <typename traits_t>
1043 /* token_pair's ctor. */
1044 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1046 /* If the next token is the opening symbol for this pair, consume it and
1048 Otherwise, issue an error and return false.
1049 In either case, record the location of the opening token. */
1051 bool require_open (c_parser *parser)
1053 c_token *token = c_parser_peek_token (parser);
1055 m_open_loc = token->location;
1057 return c_parser_require (parser, traits_t::open_token_type,
1058 traits_t::open_gmsgid);
1061 /* Consume the next token from PARSER, recording its location as
1062 that of the opening token within the pair. */
1064 void consume_open (c_parser *parser)
1066 c_token *token = c_parser_peek_token (parser);
1067 gcc_assert (token->type == traits_t::open_token_type);
1068 m_open_loc = token->location;
1069 c_parser_consume_token (parser);
1072 /* If the next token is the closing symbol for this pair, consume it
1074 Otherwise, issue an error, highlighting the location of the
1075 corresponding opening token, and return false. */
1077 bool require_close (c_parser *parser) const
1079 return c_parser_require (parser, traits_t::close_token_type,
1080 traits_t::close_gmsgid, m_open_loc);
1083 /* Like token_pair::require_close, except that tokens will be skipped
1084 until the desired token is found. An error message is still produced
1085 if the next token is not as expected. */
1087 void skip_until_found_close (c_parser *parser) const
1089 c_parser_skip_until_found (parser, traits_t::close_token_type,
1090 traits_t::close_gmsgid, m_open_loc);
1094 location_t m_open_loc;
1097 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1099 struct matching_paren_traits
1101 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1102 static const char * const open_gmsgid;
1103 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1104 static const char * const close_gmsgid;
1107 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1108 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1110 /* "matching_parens" is a token_pair<T> class for tracking matching
1111 pairs of parentheses. */
1113 typedef token_pair<matching_paren_traits> matching_parens;
1115 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1117 struct matching_brace_traits
1119 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1120 static const char * const open_gmsgid;
1121 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1122 static const char * const close_gmsgid;
1125 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1126 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1128 /* "matching_braces" is a token_pair<T> class for tracking matching
1131 typedef token_pair<matching_brace_traits> matching_braces;
1133 /* Get a description of the matching symbol to TYPE e.g. "(" for
1137 get_matching_symbol (enum cpp_ttype type)
1143 case CPP_CLOSE_PAREN:
1145 case CPP_CLOSE_BRACE:
1150 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1151 issue the error MSGID. If MSGID is NULL then a message has already
1152 been produced and no message will be produced this time. Returns
1153 true if found, false otherwise.
1155 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1156 within any error as the location of an "opening" token matching
1157 the close token TYPE (e.g. the location of the '(' when TYPE is
1160 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1161 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1162 attempt to generate a fix-it hint for the problem.
1163 Otherwise msgid describes multiple token types (e.g.
1164 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1165 generate a fix-it hint. */
1168 c_parser_require (c_parser *parser,
1169 enum cpp_ttype type,
1171 location_t matching_location,
1172 bool type_is_unique)
1174 if (c_parser_next_token_is (parser, type))
1176 c_parser_consume_token (parser);
1181 location_t next_token_loc = c_parser_peek_token (parser)->location;
1182 gcc_rich_location richloc (next_token_loc);
1184 /* Potentially supply a fix-it hint, suggesting to add the
1185 missing token immediately after the *previous* token.
1186 This may move the primary location within richloc. */
1187 if (!parser->error && type_is_unique)
1188 maybe_suggest_missing_token_insertion (&richloc, type,
1189 parser->last_token_location);
1191 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1192 Attempt to consolidate diagnostics by printing it as a
1193 secondary range within the main diagnostic. */
1194 bool added_matching_location = false;
1195 if (matching_location != UNKNOWN_LOCATION)
1196 added_matching_location
1197 = richloc.add_location_if_nearby (matching_location);
1199 if (c_parser_error_richloc (parser, msgid, &richloc))
1200 /* If we weren't able to consolidate matching_location, then
1201 print it as a secondary diagnostic. */
1202 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1203 inform (matching_location, "to match this %qs",
1204 get_matching_symbol (type));
1210 /* If the next token is the indicated keyword, consume it. Otherwise,
1211 issue the error MSGID. Returns true if found, false otherwise. */
1214 c_parser_require_keyword (c_parser *parser,
1218 if (c_parser_next_token_is_keyword (parser, keyword))
1220 c_parser_consume_token (parser);
1225 c_parser_error (parser, msgid);
1230 /* Like c_parser_require, except that tokens will be skipped until the
1231 desired token is found. An error message is still produced if the
1232 next token is not as expected. If MSGID is NULL then a message has
1233 already been produced and no message will be produced this
1236 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1237 within any error as the location of an "opening" token matching
1238 the close token TYPE (e.g. the location of the '(' when TYPE is
1239 CPP_CLOSE_PAREN). */
1242 c_parser_skip_until_found (c_parser *parser,
1243 enum cpp_ttype type,
1245 location_t matching_location)
1247 unsigned nesting_depth = 0;
1249 if (c_parser_require (parser, type, msgid, matching_location))
1252 /* Skip tokens until the desired token is found. */
1255 /* Peek at the next token. */
1256 c_token *token = c_parser_peek_token (parser);
1257 /* If we've reached the token we want, consume it and stop. */
1258 if (token->type == type && !nesting_depth)
1260 c_parser_consume_token (parser);
1264 /* If we've run out of tokens, stop. */
1265 if (token->type == CPP_EOF)
1267 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1269 if (token->type == CPP_OPEN_BRACE
1270 || token->type == CPP_OPEN_PAREN
1271 || token->type == CPP_OPEN_SQUARE)
1273 else if (token->type == CPP_CLOSE_BRACE
1274 || token->type == CPP_CLOSE_PAREN
1275 || token->type == CPP_CLOSE_SQUARE)
1277 if (nesting_depth-- == 0)
1280 /* Consume this token. */
1281 c_parser_consume_token (parser);
1283 parser->error = false;
1286 /* Skip tokens until the end of a parameter is found, but do not
1287 consume the comma, semicolon or closing delimiter. */
1290 c_parser_skip_to_end_of_parameter (c_parser *parser)
1292 unsigned nesting_depth = 0;
1296 c_token *token = c_parser_peek_token (parser);
1297 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1300 /* If we've run out of tokens, stop. */
1301 if (token->type == CPP_EOF)
1303 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1305 if (token->type == CPP_OPEN_BRACE
1306 || token->type == CPP_OPEN_PAREN
1307 || token->type == CPP_OPEN_SQUARE)
1309 else if (token->type == CPP_CLOSE_BRACE
1310 || token->type == CPP_CLOSE_PAREN
1311 || token->type == CPP_CLOSE_SQUARE)
1313 if (nesting_depth-- == 0)
1316 /* Consume this token. */
1317 c_parser_consume_token (parser);
1319 parser->error = false;
1322 /* Expect to be at the end of the pragma directive and consume an
1323 end of line marker. */
1326 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1328 gcc_assert (parser->in_pragma);
1329 parser->in_pragma = false;
1331 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1332 c_parser_error (parser, "expected end of line");
1334 cpp_ttype token_type;
1337 c_token *token = c_parser_peek_token (parser);
1338 token_type = token->type;
1339 if (token_type == CPP_EOF)
1341 c_parser_consume_token (parser);
1343 while (token_type != CPP_PRAGMA_EOL);
1345 parser->error = false;
1348 /* Skip tokens until we have consumed an entire block, or until we
1349 have consumed a non-nested ';'. */
1352 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1354 unsigned nesting_depth = 0;
1355 bool save_error = parser->error;
1361 /* Peek at the next token. */
1362 token = c_parser_peek_token (parser);
1364 switch (token->type)
1369 case CPP_PRAGMA_EOL:
1370 if (parser->in_pragma)
1375 /* If the next token is a ';', we have reached the
1376 end of the statement. */
1379 /* Consume the ';'. */
1380 c_parser_consume_token (parser);
1385 case CPP_CLOSE_BRACE:
1386 /* If the next token is a non-nested '}', then we have
1387 reached the end of the current block. */
1388 if (nesting_depth == 0 || --nesting_depth == 0)
1390 c_parser_consume_token (parser);
1395 case CPP_OPEN_BRACE:
1396 /* If it the next token is a '{', then we are entering a new
1397 block. Consume the entire block. */
1402 /* If we see a pragma, consume the whole thing at once. We
1403 have some safeguards against consuming pragmas willy-nilly.
1404 Normally, we'd expect to be here with parser->error set,
1405 which disables these safeguards. But it's possible to get
1406 here for secondary error recovery, after parser->error has
1408 c_parser_consume_pragma (parser);
1409 c_parser_skip_to_pragma_eol (parser);
1410 parser->error = save_error;
1417 c_parser_consume_token (parser);
1421 parser->error = false;
1424 /* CPP's options (initialized by c-opts.cc). */
1425 extern cpp_options *cpp_opts;
1427 /* Save the warning flags which are controlled by __extension__. */
1430 disable_extension_diagnostics (void)
1433 | (warn_pointer_arith << 1)
1434 | (warn_traditional << 2)
1436 | (warn_long_long << 4)
1437 | (warn_cxx_compat << 5)
1438 | (warn_overlength_strings << 6)
1439 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1440 play tricks to properly restore it. */
1441 | ((warn_c90_c99_compat == 1) << 7)
1442 | ((warn_c90_c99_compat == -1) << 8)
1443 /* Similarly for warn_c99_c11_compat. */
1444 | ((warn_c99_c11_compat == 1) << 9)
1445 | ((warn_c99_c11_compat == -1) << 10)
1446 /* Similarly for warn_c11_c2x_compat. */
1447 | ((warn_c11_c2x_compat == 1) << 11)
1448 | ((warn_c11_c2x_compat == -1) << 12)
1450 cpp_opts->cpp_pedantic = pedantic = 0;
1451 warn_pointer_arith = 0;
1452 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1454 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1455 warn_cxx_compat = 0;
1456 warn_overlength_strings = 0;
1457 warn_c90_c99_compat = 0;
1458 warn_c99_c11_compat = 0;
1459 warn_c11_c2x_compat = 0;
1463 /* Restore the warning flags which are controlled by __extension__.
1464 FLAGS is the return value from disable_extension_diagnostics. */
1467 restore_extension_diagnostics (int flags)
1469 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1470 warn_pointer_arith = (flags >> 1) & 1;
1471 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1472 flag_iso = (flags >> 3) & 1;
1473 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1474 warn_cxx_compat = (flags >> 5) & 1;
1475 warn_overlength_strings = (flags >> 6) & 1;
1476 /* See above for why is this needed. */
1477 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1478 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1479 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1482 /* Helper data structure for parsing #pragma acc routine. */
1483 struct oacc_routine_data {
1484 bool error_seen; /* Set if error has been reported. */
1485 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1490 /* Used for parsing objc foreach statements. */
1491 static tree objc_foreach_break_label, objc_foreach_continue_label;
1493 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1495 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1496 static void c_parser_external_declaration (c_parser *);
1497 static void c_parser_asm_definition (c_parser *);
1498 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1499 bool, bool, tree * = NULL,
1500 vec<c_token> * = NULL,
1501 bool have_attrs = false,
1503 struct oacc_routine_data * = NULL,
1505 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1506 static void c_parser_static_assert_declaration (c_parser *);
1507 static struct c_typespec c_parser_enum_specifier (c_parser *);
1508 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1509 static tree c_parser_struct_declaration (c_parser *);
1510 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1511 static tree c_parser_alignas_specifier (c_parser *);
1512 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1514 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1516 struct c_declarator *);
1517 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1519 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1521 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1522 static tree c_parser_simple_asm_expr (c_parser *);
1523 static tree c_parser_gnu_attributes (c_parser *);
1524 static struct c_expr c_parser_initializer (c_parser *, tree);
1525 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1526 struct obstack *, tree);
1527 static void c_parser_initelt (c_parser *, struct obstack *);
1528 static void c_parser_initval (c_parser *, struct c_expr *,
1530 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1531 static location_t c_parser_compound_statement_nostart (c_parser *);
1532 static void c_parser_label (c_parser *, tree);
1533 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1534 static void c_parser_statement_after_labels (c_parser *, bool *,
1535 vec<tree> * = NULL);
1536 static tree c_parser_c99_block_statement (c_parser *, bool *,
1537 location_t * = NULL);
1538 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1539 static void c_parser_switch_statement (c_parser *, bool *);
1540 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1541 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1542 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1543 static tree c_parser_asm_statement (c_parser *);
1544 static tree c_parser_asm_operands (c_parser *);
1545 static tree c_parser_asm_goto_operands (c_parser *);
1546 static tree c_parser_asm_clobbers (c_parser *);
1547 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1549 static struct c_expr c_parser_conditional_expression (c_parser *,
1550 struct c_expr *, tree);
1551 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1553 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1554 static struct c_expr c_parser_unary_expression (c_parser *);
1555 static struct c_expr c_parser_sizeof_expression (c_parser *);
1556 static struct c_expr c_parser_alignof_expression (c_parser *);
1557 static struct c_expr c_parser_postfix_expression (c_parser *);
1558 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1559 struct c_type_name *,
1561 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1564 static tree c_parser_transaction (c_parser *, enum rid);
1565 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1566 static tree c_parser_transaction_cancel (c_parser *);
1567 static struct c_expr c_parser_expression (c_parser *);
1568 static struct c_expr c_parser_expression_conv (c_parser *);
1569 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1570 vec<tree, va_gc> **, location_t *,
1571 tree *, vec<location_t> *,
1572 unsigned int * = NULL);
1573 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1575 static void c_parser_oacc_declare (c_parser *);
1576 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1577 static void c_parser_oacc_update (c_parser *);
1578 static void c_parser_omp_construct (c_parser *, bool *);
1579 static void c_parser_omp_threadprivate (c_parser *);
1580 static void c_parser_omp_barrier (c_parser *);
1581 static void c_parser_omp_depobj (c_parser *);
1582 static void c_parser_omp_flush (c_parser *);
1583 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1584 tree, tree *, bool *);
1585 static void c_parser_omp_taskwait (c_parser *);
1586 static void c_parser_omp_taskyield (c_parser *);
1587 static void c_parser_omp_cancel (c_parser *);
1588 static void c_parser_omp_nothing (c_parser *);
1590 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1591 pragma_stmt, pragma_compound };
1592 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1593 static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1594 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1595 static void c_parser_omp_end_declare_target (c_parser *);
1596 static bool c_parser_omp_declare (c_parser *, enum pragma_context);
1597 static void c_parser_omp_requires (c_parser *);
1598 static bool c_parser_omp_error (c_parser *, enum pragma_context);
1599 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1600 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1602 /* These Objective-C parser functions are only ever called when
1603 compiling Objective-C. */
1604 static void c_parser_objc_class_definition (c_parser *, tree);
1605 static void c_parser_objc_class_instance_variables (c_parser *);
1606 static void c_parser_objc_class_declaration (c_parser *);
1607 static void c_parser_objc_alias_declaration (c_parser *);
1608 static void c_parser_objc_protocol_definition (c_parser *, tree);
1609 static bool c_parser_objc_method_type (c_parser *);
1610 static void c_parser_objc_method_definition (c_parser *);
1611 static void c_parser_objc_methodprotolist (c_parser *);
1612 static void c_parser_objc_methodproto (c_parser *);
1613 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1614 static tree c_parser_objc_type_name (c_parser *);
1615 static tree c_parser_objc_protocol_refs (c_parser *);
1616 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1617 static void c_parser_objc_synchronized_statement (c_parser *);
1618 static tree c_parser_objc_selector (c_parser *);
1619 static tree c_parser_objc_selector_arg (c_parser *);
1620 static tree c_parser_objc_receiver (c_parser *);
1621 static tree c_parser_objc_message_args (c_parser *);
1622 static tree c_parser_objc_keywordexpr (c_parser *);
1623 static void c_parser_objc_at_property_declaration (c_parser *);
1624 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1625 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1626 static bool c_parser_objc_diagnose_bad_element_prefix
1627 (c_parser *, struct c_declspecs *);
1628 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1630 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1633 external-declarations
1635 external-declarations:
1636 external-declaration
1637 external-declarations external-declaration
1646 c_parser_translation_unit (c_parser *parser)
1648 if (c_parser_next_token_is (parser, CPP_EOF))
1650 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1651 "ISO C forbids an empty translation unit");
1655 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1656 mark_valid_location_for_stdc_pragma (false);
1660 c_parser_external_declaration (parser);
1661 obstack_free (&parser_obstack, obstack_position);
1663 while (c_parser_next_token_is_not (parser, CPP_EOF));
1668 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1669 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1670 error ("storage size of %q+D isn%'t known", decl);
1672 if (current_omp_declare_target_attribute)
1675 error ("%<#pragma omp declare target%> without corresponding "
1676 "%<#pragma omp end declare target%>");
1677 current_omp_declare_target_attribute = 0;
1681 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1683 external-declaration:
1689 external-declaration:
1692 __extension__ external-declaration
1696 external-declaration:
1697 objc-class-definition
1698 objc-class-declaration
1699 objc-alias-declaration
1700 objc-protocol-definition
1701 objc-method-definition
1706 c_parser_external_declaration (c_parser *parser)
1709 switch (c_parser_peek_token (parser)->type)
1712 switch (c_parser_peek_token (parser)->keyword)
1715 ext = disable_extension_diagnostics ();
1716 c_parser_consume_token (parser);
1717 c_parser_external_declaration (parser);
1718 restore_extension_diagnostics (ext);
1721 c_parser_asm_definition (parser);
1723 case RID_AT_INTERFACE:
1724 case RID_AT_IMPLEMENTATION:
1725 gcc_assert (c_dialect_objc ());
1726 c_parser_objc_class_definition (parser, NULL_TREE);
1729 gcc_assert (c_dialect_objc ());
1730 c_parser_objc_class_declaration (parser);
1733 gcc_assert (c_dialect_objc ());
1734 c_parser_objc_alias_declaration (parser);
1736 case RID_AT_PROTOCOL:
1737 gcc_assert (c_dialect_objc ());
1738 c_parser_objc_protocol_definition (parser, NULL_TREE);
1740 case RID_AT_PROPERTY:
1741 gcc_assert (c_dialect_objc ());
1742 c_parser_objc_at_property_declaration (parser);
1744 case RID_AT_SYNTHESIZE:
1745 gcc_assert (c_dialect_objc ());
1746 c_parser_objc_at_synthesize_declaration (parser);
1748 case RID_AT_DYNAMIC:
1749 gcc_assert (c_dialect_objc ());
1750 c_parser_objc_at_dynamic_declaration (parser);
1753 gcc_assert (c_dialect_objc ());
1754 c_parser_consume_token (parser);
1755 objc_finish_implementation ();
1762 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1763 "ISO C does not allow extra %<;%> outside of a function");
1764 c_parser_consume_token (parser);
1767 mark_valid_location_for_stdc_pragma (true);
1768 c_parser_pragma (parser, pragma_external, NULL);
1769 mark_valid_location_for_stdc_pragma (false);
1773 if (c_dialect_objc ())
1775 c_parser_objc_method_definition (parser);
1778 /* Else fall through, and yield a syntax error trying to parse
1779 as a declaration or function definition. */
1783 /* A declaration or a function definition (or, in Objective-C,
1784 an @interface or @protocol with prefix attributes). We can
1785 only tell which after parsing the declaration specifiers, if
1786 any, and the first declarator. */
1787 c_parser_declaration_or_fndef (parser, true, true, true, false, true);
1792 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
1793 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1795 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1798 add_debug_begin_stmt (location_t loc)
1800 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1801 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1804 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1805 SET_EXPR_LOCATION (stmt, loc);
1809 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1810 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1811 is accepted; otherwise (old-style parameter declarations) only other
1812 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1813 assertion is accepted; otherwise (old-style parameter declarations)
1814 it is not. If NESTED is true, we are inside a function or parsing
1815 old-style parameter declarations; any functions encountered are
1816 nested functions and declaration specifiers are required; otherwise
1817 we are at top level and functions are normal functions and
1818 declaration specifiers may be optional. If EMPTY_OK is true, empty
1819 declarations are OK (subject to all other constraints); otherwise
1820 (old-style parameter declarations) they are diagnosed. If
1821 START_ATTR_OK is true, the declaration specifiers may start with
1822 attributes (GNU or standard); otherwise they may not.
1823 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1824 declaration when parsing an Objective-C foreach statement.
1825 FALLTHRU_ATTR_P is used to signal whether this function parsed
1826 "__attribute__((fallthrough));". ATTRS are any standard attributes
1827 parsed in the caller (in contexts where such attributes had to be
1828 parsed to determine whether what follows is a declaration or a
1829 statement); HAVE_ATTRS says whether there were any such attributes
1833 declaration-specifiers init-declarator-list[opt] ;
1834 static_assert-declaration
1836 function-definition:
1837 declaration-specifiers[opt] declarator declaration-list[opt]
1842 declaration-list declaration
1844 init-declarator-list:
1846 init-declarator-list , init-declarator
1849 declarator simple-asm-expr[opt] gnu-attributes[opt]
1850 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1854 nested-function-definition:
1855 declaration-specifiers declarator declaration-list[opt]
1861 gnu-attributes objc-class-definition
1862 gnu-attributes objc-category-definition
1863 gnu-attributes objc-protocol-definition
1865 The simple-asm-expr and gnu-attributes are GNU extensions.
1867 This function does not handle __extension__; that is handled in its
1868 callers. ??? Following the old parser, __extension__ may start
1869 external declarations, declarations in functions and declarations
1870 at the start of "for" loops, but not old-style parameter
1873 C99 requires declaration specifiers in a function definition; the
1874 absence is diagnosed through the diagnosis of implicit int. In GNU
1875 C we also allow but diagnose declarations without declaration
1876 specifiers, but only at top level (elsewhere they conflict with
1879 In Objective-C, declarations of the looping variable in a foreach
1880 statement are exceptionally terminated by 'in' (for example, 'for
1881 (NSObject *object in array) { ... }').
1886 threadprivate-directive
1890 gimple-function-definition:
1891 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1892 declaration-list[opt] compound-statement
1894 rtl-function-definition:
1895 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1896 declaration-list[opt] compound-statement */
1899 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1900 bool static_assert_ok, bool empty_ok,
1901 bool nested, bool start_attr_ok,
1902 tree *objc_foreach_object_declaration
1904 vec<c_token> *omp_declare_simd_clauses
1906 bool have_attrs /* = false */,
1907 tree attrs /* = NULL_TREE */,
1908 struct oacc_routine_data *oacc_routine_data
1910 bool *fallthru_attr_p /* = NULL */)
1912 struct c_declspecs *specs;
1914 tree all_prefix_attrs;
1915 bool diagnosed_no_specs = false;
1916 location_t here = c_parser_peek_token (parser)->location;
1918 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1920 if (static_assert_ok
1921 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1923 c_parser_static_assert_declaration (parser);
1926 specs = build_null_declspecs ();
1928 /* Handle any standard attributes parsed in the caller. */
1931 declspecs_add_attrs (here, specs, attrs);
1932 specs->non_std_attrs_seen_p = false;
1935 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1936 if (c_parser_peek_token (parser)->type == CPP_NAME
1937 && c_parser_peek_token (parser)->id_kind == C_ID_ID
1938 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1939 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1940 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1942 tree name = c_parser_peek_token (parser)->value;
1944 /* Issue a warning about NAME being an unknown type name, perhaps
1945 with some kind of hint.
1946 If the user forgot a "struct" etc, suggest inserting
1947 it. Otherwise, attempt to look for misspellings. */
1948 gcc_rich_location richloc (here);
1949 if (tag_exists_p (RECORD_TYPE, name))
1951 /* This is not C++ with its implicit typedef. */
1952 richloc.add_fixit_insert_before ("struct ");
1954 "unknown type name %qE;"
1955 " use %<struct%> keyword to refer to the type",
1958 else if (tag_exists_p (UNION_TYPE, name))
1960 richloc.add_fixit_insert_before ("union ");
1962 "unknown type name %qE;"
1963 " use %<union%> keyword to refer to the type",
1966 else if (tag_exists_p (ENUMERAL_TYPE, name))
1968 richloc.add_fixit_insert_before ("enum ");
1970 "unknown type name %qE;"
1971 " use %<enum%> keyword to refer to the type",
1976 auto_diagnostic_group d;
1977 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1979 if (const char *suggestion = hint.suggestion ())
1981 richloc.add_fixit_replace (suggestion);
1983 "unknown type name %qE; did you mean %qs?",
1987 error_at (here, "unknown type name %qE", name);
1990 /* Parse declspecs normally to get a correct pointer type, but avoid
1991 a further "fails to be a type name" error. Refuse nested functions
1992 since it is not how the user likely wants us to recover. */
1993 c_parser_peek_token (parser)->type = CPP_KEYWORD;
1994 c_parser_peek_token (parser)->keyword = RID_VOID;
1995 c_parser_peek_token (parser)->value = error_mark_node;
1999 /* When there are standard attributes at the start of the
2000 declaration (to apply to the entity being declared), an
2001 init-declarator-list or function definition must be present. */
2002 if (c_parser_nth_token_starts_std_attributes (parser, 1))
2005 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
2006 true, true, start_attr_ok, true, cla_nonabstract_decl);
2009 c_parser_skip_to_end_of_block_or_statement (parser);
2012 if (nested && !specs->declspecs_seen_p)
2014 c_parser_error (parser, "expected declaration specifiers");
2015 c_parser_skip_to_end_of_block_or_statement (parser);
2019 finish_declspecs (specs);
2020 bool auto_type_p = specs->typespec_word == cts_auto_type;
2021 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2024 error_at (here, "%<__auto_type%> in empty declaration");
2025 else if (specs->typespec_kind == ctsk_none
2026 && attribute_fallthrough_p (specs->attrs))
2028 if (fallthru_attr_p != NULL)
2029 *fallthru_attr_p = true;
2032 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2037 pedwarn (here, OPT_Wattributes,
2038 "%<fallthrough%> attribute at top level");
2040 else if (empty_ok && !(have_attrs
2041 && specs->non_std_attrs_seen_p))
2045 shadow_tag_warned (specs, 1);
2046 pedwarn (here, 0, "empty declaration");
2048 c_parser_consume_token (parser);
2049 if (oacc_routine_data)
2050 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2054 /* Provide better error recovery. Note that a type name here is usually
2055 better diagnosed as a redeclaration. */
2057 && specs->typespec_kind == ctsk_tagdef
2058 && c_parser_next_token_starts_declspecs (parser)
2059 && !c_parser_next_token_is (parser, CPP_NAME))
2061 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2062 parser->error = false;
2063 shadow_tag_warned (specs, 1);
2066 else if (c_dialect_objc () && !auto_type_p)
2068 /* Prefix attributes are an error on method decls. */
2069 switch (c_parser_peek_token (parser)->type)
2073 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2077 warning_at (c_parser_peek_token (parser)->location,
2079 "prefix attributes are ignored for methods");
2080 specs->attrs = NULL_TREE;
2083 c_parser_objc_method_definition (parser);
2085 c_parser_objc_methodproto (parser);
2091 /* This is where we parse 'attributes @interface ...',
2092 'attributes @implementation ...', 'attributes @protocol ...'
2093 (where attributes could be, for example, __attribute__
2096 switch (c_parser_peek_token (parser)->keyword)
2098 case RID_AT_INTERFACE:
2100 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2102 c_parser_objc_class_definition (parser, specs->attrs);
2106 case RID_AT_IMPLEMENTATION:
2108 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2112 warning_at (c_parser_peek_token (parser)->location,
2114 "prefix attributes are ignored for implementations");
2115 specs->attrs = NULL_TREE;
2117 c_parser_objc_class_definition (parser, NULL_TREE);
2121 case RID_AT_PROTOCOL:
2123 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2125 c_parser_objc_protocol_definition (parser, specs->attrs);
2132 case RID_AT_PROPERTY:
2135 c_parser_error (parser, "unexpected attribute");
2136 specs->attrs = NULL;
2143 else if (attribute_fallthrough_p (specs->attrs))
2144 warning_at (here, OPT_Wattributes,
2145 "%<fallthrough%> attribute not followed by %<;%>");
2147 pending_xref_error ();
2148 prefix_attrs = specs->attrs;
2149 all_prefix_attrs = prefix_attrs;
2150 specs->attrs = NULL_TREE;
2153 struct c_declarator *declarator;
2156 tree fnbody = NULL_TREE;
2157 /* Declaring either one or more declarators (in which case we
2158 should diagnose if there were no declaration specifiers) or a
2159 function definition (in which case the diagnostic for
2160 implicit int suffices). */
2161 declarator = c_parser_declarator (parser,
2162 specs->typespec_kind != ctsk_none,
2163 C_DTR_NORMAL, &dummy);
2164 if (declarator == NULL)
2166 if (omp_declare_simd_clauses)
2167 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2168 omp_declare_simd_clauses);
2169 if (oacc_routine_data)
2170 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2171 c_parser_skip_to_end_of_block_or_statement (parser);
2174 if (auto_type_p && declarator->kind != cdk_id)
2177 "%<__auto_type%> requires a plain identifier"
2179 c_parser_skip_to_end_of_block_or_statement (parser);
2182 if (c_parser_next_token_is (parser, CPP_EQ)
2183 || c_parser_next_token_is (parser, CPP_COMMA)
2184 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2185 || c_parser_next_token_is_keyword (parser, RID_ASM)
2186 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2187 || c_parser_next_token_is_keyword (parser, RID_IN))
2189 tree asm_name = NULL_TREE;
2190 tree postfix_attrs = NULL_TREE;
2191 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2193 diagnosed_no_specs = true;
2194 pedwarn (here, 0, "data definition has no type or storage class");
2196 /* Having seen a data definition, there cannot now be a
2197 function definition. */
2199 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2200 asm_name = c_parser_simple_asm_expr (parser);
2201 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2203 postfix_attrs = c_parser_gnu_attributes (parser);
2204 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2206 /* This means there is an attribute specifier after
2207 the declarator in a function definition. Provide
2208 some more information for the user. */
2209 error_at (here, "attributes should be specified before the "
2210 "declarator in a function definition");
2211 c_parser_skip_to_end_of_block_or_statement (parser);
2215 if (c_parser_next_token_is (parser, CPP_EQ))
2219 location_t init_loc;
2220 c_parser_consume_token (parser);
2223 init_loc = c_parser_peek_token (parser)->location;
2224 rich_location richloc (line_table, init_loc);
2225 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2226 /* A parameter is initialized, which is invalid. Don't
2227 attempt to instrument the initializer. */
2228 int flag_sanitize_save = flag_sanitize;
2229 if (nested && !empty_ok)
2231 init = c_parser_expr_no_commas (parser, NULL);
2232 flag_sanitize = flag_sanitize_save;
2233 if (TREE_CODE (init.value) == COMPONENT_REF
2234 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2236 "%<__auto_type%> used with a bit-field"
2238 init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2239 tree init_type = TREE_TYPE (init.value);
2240 bool vm_type = variably_modified_type_p (init_type,
2243 init.value = save_expr (init.value);
2245 specs->typespec_kind = ctsk_typeof;
2246 specs->locations[cdw_typedef] = init_loc;
2247 specs->typedef_p = true;
2248 specs->type = init_type;
2251 bool maybe_const = true;
2252 tree type_expr = c_fully_fold (init.value, false,
2254 specs->expr_const_operands &= maybe_const;
2256 specs->expr = build2 (COMPOUND_EXPR,
2257 TREE_TYPE (type_expr),
2258 specs->expr, type_expr);
2260 specs->expr = type_expr;
2262 d = start_decl (declarator, specs, true,
2263 chainon (postfix_attrs, all_prefix_attrs));
2265 d = error_mark_node;
2266 if (omp_declare_simd_clauses)
2267 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2268 omp_declare_simd_clauses);
2272 /* The declaration of the variable is in effect while
2273 its initializer is parsed. */
2274 d = start_decl (declarator, specs, true,
2275 chainon (postfix_attrs, all_prefix_attrs));
2277 d = error_mark_node;
2278 if (omp_declare_simd_clauses)
2279 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2280 omp_declare_simd_clauses);
2281 init_loc = c_parser_peek_token (parser)->location;
2282 rich_location richloc (line_table, init_loc);
2283 start_init (d, asm_name, global_bindings_p (), &richloc);
2284 /* A parameter is initialized, which is invalid. Don't
2285 attempt to instrument the initializer. */
2286 int flag_sanitize_save = flag_sanitize;
2287 if (TREE_CODE (d) == PARM_DECL)
2289 init = c_parser_initializer (parser, d);
2290 flag_sanitize = flag_sanitize_save;
2293 if (oacc_routine_data)
2294 c_finish_oacc_routine (oacc_routine_data, d, false);
2295 if (d != error_mark_node)
2297 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2298 finish_decl (d, init_loc, init.value,
2299 init.original_type, asm_name);
2307 "%<__auto_type%> requires an initialized "
2308 "data declaration");
2309 c_parser_skip_to_end_of_block_or_statement (parser);
2313 location_t lastloc = UNKNOWN_LOCATION;
2314 tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2315 tree d = start_decl (declarator, specs, false, attrs, &lastloc);
2316 if (d && TREE_CODE (d) == FUNCTION_DECL)
2318 /* Find the innermost declarator that is neither cdk_id
2320 const struct c_declarator *decl = declarator;
2321 const struct c_declarator *last_non_id_attrs = NULL;
2329 last_non_id_attrs = decl;
2330 decl = decl->declarator;
2334 decl = decl->declarator;
2345 /* If it exists and is cdk_function declaration whose
2346 arguments have not been set yet, use its arguments. */
2347 if (last_non_id_attrs
2348 && last_non_id_attrs->kind == cdk_function)
2350 tree parms = last_non_id_attrs->u.arg_info->parms;
2351 if (DECL_ARGUMENTS (d) == NULL_TREE
2352 && DECL_INITIAL (d) == NULL_TREE)
2353 DECL_ARGUMENTS (d) = parms;
2355 warn_parm_array_mismatch (lastloc, d, parms);
2358 if (omp_declare_simd_clauses)
2360 tree parms = NULL_TREE;
2361 if (d && TREE_CODE (d) == FUNCTION_DECL)
2363 struct c_declarator *ce = declarator;
2365 if (ce->kind == cdk_function)
2367 parms = ce->u.arg_info->parms;
2371 ce = ce->declarator;
2374 temp_store_parm_decls (d, parms);
2375 c_finish_omp_declare_simd (parser, d, parms,
2376 omp_declare_simd_clauses);
2378 temp_pop_parm_decls ();
2380 if (oacc_routine_data)
2381 c_finish_oacc_routine (oacc_routine_data, d, false);
2383 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2384 NULL_TREE, asm_name);
2386 if (c_parser_next_token_is_keyword (parser, RID_IN))
2389 *objc_foreach_object_declaration = d;
2391 *objc_foreach_object_declaration = error_mark_node;
2394 if (c_parser_next_token_is (parser, CPP_COMMA))
2399 "%<__auto_type%> may only be used with"
2400 " a single declarator");
2401 c_parser_skip_to_end_of_block_or_statement (parser);
2404 c_parser_consume_token (parser);
2405 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2406 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2409 all_prefix_attrs = prefix_attrs;
2412 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2414 c_parser_consume_token (parser);
2417 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2419 /* This can only happen in Objective-C: we found the
2420 'in' that terminates the declaration inside an
2421 Objective-C foreach statement. Do not consume the
2422 token, so that the caller can use it to determine
2423 that this indeed is a foreach context. */
2428 c_parser_error (parser, "expected %<,%> or %<;%>");
2429 c_parser_skip_to_end_of_block_or_statement (parser);
2433 else if (auto_type_p)
2436 "%<__auto_type%> requires an initialized data declaration");
2437 c_parser_skip_to_end_of_block_or_statement (parser);
2442 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2443 "%<asm%> or %<__attribute__%>");
2444 c_parser_skip_to_end_of_block_or_statement (parser);
2447 /* Function definition (nested or otherwise). */
2450 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2451 c_push_function_context ();
2453 if (!start_function (specs, declarator, all_prefix_attrs))
2455 /* At this point we've consumed:
2456 declaration-specifiers declarator
2457 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2458 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2460 declaration-specifiers declarator
2461 aren't grokkable as a function definition, so we have
2463 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2464 if (c_parser_next_token_starts_declspecs (parser))
2467 declaration-specifiers declarator decl-specs
2468 then assume we have a missing semicolon, which would
2470 declaration-specifiers declarator decl-specs
2473 <~~~~~~~~~ declaration ~~~~~~~~~~>
2474 Use c_parser_require to get an error with a fix-it hint. */
2475 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2476 parser->error = false;
2480 /* This can appear in many cases looking nothing like a
2481 function definition, so we don't give a more specific
2482 error suggesting there was one. */
2483 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2484 "or %<__attribute__%>");
2487 c_pop_function_context ();
2491 if (DECL_DECLARED_INLINE_P (current_function_decl))
2492 tv = TV_PARSE_INLINE;
2495 auto_timevar at (g_timer, tv);
2497 /* Parse old-style parameter declarations. ??? Attributes are
2498 not allowed to start declaration specifiers here because of a
2499 syntax conflict between a function declaration with attribute
2500 suffix and a function definition with an attribute prefix on
2501 first old-style parameter declaration. Following the old
2502 parser, they are not accepted on subsequent old-style
2503 parameter declarations either. However, there is no
2504 ambiguity after the first declaration, nor indeed on the
2505 first as long as we don't allow postfix attributes after a
2506 declarator with a nonempty identifier list in a definition;
2507 and postfix attributes have never been accepted here in
2508 function definitions either. */
2509 while (c_parser_next_token_is_not (parser, CPP_EOF)
2510 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2511 c_parser_declaration_or_fndef (parser, false, false, false,
2513 store_parm_decls ();
2514 if (omp_declare_simd_clauses)
2515 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2516 omp_declare_simd_clauses);
2517 if (oacc_routine_data)
2518 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2519 location_t startloc = c_parser_peek_token (parser)->location;
2520 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2522 location_t endloc = startloc;
2524 /* If the definition was marked with __RTL, use the RTL parser now,
2525 consuming the function body. */
2526 if (specs->declspec_il == cdil_rtl)
2528 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2530 /* Normally, store_parm_decls sets next_is_function_body,
2531 anticipating a function body. We need a push_scope/pop_scope
2532 pair to flush out this state, or subsequent function parsing
2537 finish_function (endloc);
2540 /* If the definition was marked with __GIMPLE then parse the
2541 function body as GIMPLE. */
2542 else if (specs->declspec_il != cdil_none)
2544 bool saved = in_late_binary_op;
2545 in_late_binary_op = true;
2546 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2548 specs->entry_bb_count);
2549 in_late_binary_op = saved;
2552 fnbody = c_parser_compound_statement (parser, &endloc);
2553 tree fndecl = current_function_decl;
2556 tree decl = current_function_decl;
2557 /* Mark nested functions as needing static-chain initially.
2558 lower_nested_functions will recompute it but the
2559 DECL_STATIC_CHAIN flag is also used before that happens,
2560 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2561 DECL_STATIC_CHAIN (decl) = 1;
2563 finish_function (endloc);
2564 c_pop_function_context ();
2565 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2571 finish_function (endloc);
2573 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2574 if (specs->declspec_il != cdil_none)
2575 DECL_SAVED_TREE (fndecl) = NULL_TREE;
2581 /* Parse an asm-definition (asm() outside a function body). This is a
2589 c_parser_asm_definition (c_parser *parser)
2591 tree asm_str = c_parser_simple_asm_expr (parser);
2593 symtab->finalize_toplevel_asm (asm_str);
2594 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2597 /* Parse a static assertion (C11 6.7.10).
2599 static_assert-declaration:
2600 static_assert-declaration-no-semi ;
2604 c_parser_static_assert_declaration (c_parser *parser)
2606 c_parser_static_assert_declaration_no_semi (parser);
2608 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2609 c_parser_skip_to_end_of_block_or_statement (parser);
2612 /* Parse a static assertion (C11 6.7.10), without the trailing
2615 static_assert-declaration-no-semi:
2616 _Static_assert ( constant-expression , string-literal )
2619 static_assert-declaration-no-semi:
2620 _Static_assert ( constant-expression )
2624 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2626 location_t assert_loc, value_loc;
2628 tree string = NULL_TREE;
2630 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2631 assert_loc = c_parser_peek_token (parser)->location;
2633 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2634 "ISO C99 does not support %<_Static_assert%>");
2636 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2637 "ISO C90 does not support %<_Static_assert%>");
2638 c_parser_consume_token (parser);
2639 matching_parens parens;
2640 if (!parens.require_open (parser))
2642 location_t value_tok_loc = c_parser_peek_token (parser)->location;
2643 value = c_parser_expr_no_commas (parser, NULL).value;
2644 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2645 if (c_parser_next_token_is (parser, CPP_COMMA))
2647 c_parser_consume_token (parser);
2648 switch (c_parser_peek_token (parser)->type)
2654 case CPP_UTF8STRING:
2655 string = c_parser_string_literal (parser, false, true).value;
2658 c_parser_error (parser, "expected string literal");
2662 else if (flag_isoc11)
2663 /* If pedantic for pre-C11, the use of _Static_assert itself will
2664 have been diagnosed, so do not also diagnose the use of this
2665 new C2X feature of _Static_assert. */
2666 pedwarn_c11 (assert_loc, OPT_Wpedantic,
2667 "ISO C11 does not support omitting the string in "
2668 "%<_Static_assert%>");
2669 parens.require_close (parser);
2671 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2673 error_at (value_loc, "expression in static assertion is not an integer");
2676 if (TREE_CODE (value) != INTEGER_CST)
2678 value = c_fully_fold (value, false, NULL);
2679 /* Strip no-op conversions. */
2680 STRIP_TYPE_NOPS (value);
2681 if (TREE_CODE (value) == INTEGER_CST)
2682 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2683 "is not an integer constant expression");
2685 if (TREE_CODE (value) != INTEGER_CST)
2687 error_at (value_loc, "expression in static assertion is not constant");
2690 constant_expression_warning (value);
2691 if (integer_zerop (value))
2694 error_at (assert_loc, "static assertion failed: %E", string);
2696 error_at (assert_loc, "static assertion failed");
2700 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2701 6.7, C11 6.7), adding them to SPECS (which may already include some).
2702 Storage class specifiers are accepted iff SCSPEC_OK; type
2703 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2704 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2705 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2706 addition to the syntax shown, standard attributes are accepted at
2707 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2708 unlike gnu-attributes, they are not accepted in the middle of the
2709 list. (This combines various different syntax productions in the C
2710 standard, and in some cases gnu-attributes and standard attributes
2711 at the start may already have been parsed before this function is
2714 declaration-specifiers:
2715 storage-class-specifier declaration-specifiers[opt]
2716 type-specifier declaration-specifiers[opt]
2717 type-qualifier declaration-specifiers[opt]
2718 function-specifier declaration-specifiers[opt]
2719 alignment-specifier declaration-specifiers[opt]
2721 Function specifiers (inline) are from C99, and are currently
2722 handled as storage class specifiers, as is __thread. Alignment
2723 specifiers are from C11.
2725 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2726 storage-class-specifier:
2734 (_Thread_local is new in C11.)
2736 C99 6.7.4, C11 6.7.4:
2741 (_Noreturn is new in C11.)
2743 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2756 [_Imaginary removed in C99 TC2]
2757 struct-or-union-specifier
2760 atomic-type-specifier
2762 (_Bool and _Complex are new in C99.)
2763 (atomic-type-specifier is new in C11.)
2765 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2771 address-space-qualifier
2774 (restrict is new in C99.)
2775 (_Atomic is new in C11.)
2779 declaration-specifiers:
2780 gnu-attributes declaration-specifiers[opt]
2786 identifier recognized by the target
2788 storage-class-specifier:
2802 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2803 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2805 atomic-type-specifier
2806 _Atomic ( type-name )
2811 class-name objc-protocol-refs[opt]
2812 typedef-name objc-protocol-refs
2817 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2818 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2819 bool alignspec_ok, bool auto_type_ok,
2820 bool start_std_attr_ok, bool end_std_attr_ok,
2821 enum c_lookahead_kind la)
2823 bool attrs_ok = start_attr_ok;
2824 bool seen_type = specs->typespec_kind != ctsk_none;
2827 gcc_assert (la == cla_prefer_id);
2829 if (start_std_attr_ok
2830 && c_parser_nth_token_starts_std_attributes (parser, 1))
2832 gcc_assert (!specs->non_std_attrs_seen_p);
2833 location_t loc = c_parser_peek_token (parser)->location;
2834 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2835 declspecs_add_attrs (loc, specs, attrs);
2836 specs->non_std_attrs_seen_p = false;
2839 while (c_parser_next_token_is (parser, CPP_NAME)
2840 || c_parser_next_token_is (parser, CPP_KEYWORD)
2841 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2843 struct c_typespec t;
2846 location_t loc = c_parser_peek_token (parser)->location;
2848 /* If we cannot accept a type, exit if the next token must start
2849 one. Also, if we already have seen a tagged definition,
2850 a typename would be an error anyway and likely the user
2851 has simply forgotten a semicolon, so we exit. */
2852 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2853 && c_parser_next_tokens_start_typename (parser, la)
2854 && !c_parser_next_token_is_qualifier (parser)
2855 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2858 if (c_parser_next_token_is (parser, CPP_NAME))
2860 c_token *name_token = c_parser_peek_token (parser);
2861 tree value = name_token->value;
2862 c_id_kind kind = name_token->id_kind;
2864 if (kind == C_ID_ADDRSPACE)
2867 = name_token->keyword - RID_FIRST_ADDR_SPACE;
2868 declspecs_add_addrspace (name_token->location, specs, as);
2869 c_parser_consume_token (parser);
2874 gcc_assert (!c_parser_next_token_is_qualifier (parser));
2876 /* If we cannot accept a type, and the next token must start one,
2877 exit. Do the same if we already have seen a tagged definition,
2878 since it would be an error anyway and likely the user has simply
2879 forgotten a semicolon. */
2880 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2883 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2884 a C_ID_CLASSNAME. */
2885 c_parser_consume_token (parser);
2888 if (kind == C_ID_ID)
2890 error_at (loc, "unknown type name %qE", value);
2891 t.kind = ctsk_typedef;
2892 t.spec = error_mark_node;
2894 else if (kind == C_ID_TYPENAME
2895 && (!c_dialect_objc ()
2896 || c_parser_next_token_is_not (parser, CPP_LESS)))
2898 t.kind = ctsk_typedef;
2899 /* For a typedef name, record the meaning, not the name.
2900 In case of 'foo foo, bar;'. */
2901 t.spec = lookup_name (value);
2905 tree proto = NULL_TREE;
2906 gcc_assert (c_dialect_objc ());
2908 if (c_parser_next_token_is (parser, CPP_LESS))
2909 proto = c_parser_objc_protocol_refs (parser);
2910 t.spec = objc_get_protocol_qualified_type (value, proto);
2913 t.expr_const_operands = true;
2914 declspecs_add_type (name_token->location, specs, t);
2917 if (c_parser_next_token_is (parser, CPP_LESS))
2919 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2920 nisse@lysator.liu.se. */
2922 gcc_assert (c_dialect_objc ());
2923 if (!typespec_ok || seen_type)
2925 proto = c_parser_objc_protocol_refs (parser);
2927 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2929 t.expr_const_operands = true;
2930 declspecs_add_type (loc, specs, t);
2933 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2934 switch (c_parser_peek_token (parser)->keyword)
2947 /* TODO: Distinguish between function specifiers (inline, noreturn)
2948 and storage class specifiers, either here or in
2949 declspecs_add_scspec. */
2950 declspecs_add_scspec (loc, specs,
2951 c_parser_peek_token (parser)->value);
2952 c_parser_consume_token (parser);
2984 if (c_dialect_objc ())
2985 parser->objc_need_raw_identifier = true;
2986 t.kind = ctsk_resword;
2987 t.spec = c_parser_peek_token (parser)->value;
2989 t.expr_const_operands = true;
2990 declspecs_add_type (loc, specs, t);
2991 c_parser_consume_token (parser);
2998 t = c_parser_enum_specifier (parser);
2999 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3000 declspecs_add_type (loc, specs, t);
3008 t = c_parser_struct_or_union_specifier (parser);
3009 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3010 declspecs_add_type (loc, specs, t);
3013 /* ??? The old parser rejected typeof after other type
3014 specifiers, but is a syntax error the best way of
3016 if (!typespec_ok || seen_type)
3020 t = c_parser_typeof_specifier (parser);
3021 declspecs_add_type (loc, specs, t);
3024 /* C parser handling of Objective-C constructs needs
3025 checking for correct lvalue-to-rvalue conversions, and
3026 the code in build_modify_expr handling various
3027 Objective-C cases, and that in build_unary_op handling
3028 Objective-C cases for increment / decrement, also needs
3029 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3030 and objc_types_are_equivalent may also need updates. */
3031 if (c_dialect_objc ())
3032 sorry ("%<_Atomic%> in Objective-C");
3034 pedwarn_c99 (loc, OPT_Wpedantic,
3035 "ISO C99 does not support the %<_Atomic%> qualifier");
3037 pedwarn_c99 (loc, OPT_Wpedantic,
3038 "ISO C90 does not support the %<_Atomic%> qualifier");
3041 value = c_parser_peek_token (parser)->value;
3042 c_parser_consume_token (parser);
3043 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3045 /* _Atomic ( type-name ). */
3047 c_parser_consume_token (parser);
3048 struct c_type_name *type = c_parser_type_name (parser);
3049 t.kind = ctsk_typeof;
3050 t.spec = error_mark_node;
3052 t.expr_const_operands = true;
3054 t.spec = groktypename (type, &t.expr,
3055 &t.expr_const_operands);
3056 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3058 if (t.spec != error_mark_node)
3060 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3061 error_at (loc, "%<_Atomic%>-qualified array type");
3062 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3063 error_at (loc, "%<_Atomic%>-qualified function type");
3064 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3065 error_at (loc, "%<_Atomic%> applied to a qualified type");
3067 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3069 declspecs_add_type (loc, specs, t);
3072 declspecs_add_qual (loc, specs, value);
3078 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3079 c_parser_consume_token (parser);
3084 attrs = c_parser_gnu_attributes (parser);
3085 declspecs_add_attrs (loc, specs, attrs);
3090 align = c_parser_alignas_specifier (parser);
3091 declspecs_add_alignas (loc, specs, align);
3095 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3096 c_parser_consume_token (parser);
3097 specs->declspec_il = cdil_gimple;
3098 specs->locations[cdw_gimple] = loc;
3099 c_parser_gimple_or_rtl_pass_list (parser, specs);
3102 c_parser_consume_token (parser);
3103 specs->declspec_il = cdil_rtl;
3104 specs->locations[cdw_rtl] = loc;
3105 c_parser_gimple_or_rtl_pass_list (parser, specs);
3113 && c_parser_nth_token_starts_std_attributes (parser, 1))
3114 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3117 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3120 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3122 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3124 enum gnu-attributes[opt] identifier
3126 The form with trailing comma is new in C99. The forms with
3127 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3128 without commas in the syntax (assignment expressions, not just
3129 conditional expressions); assignment expressions will be diagnosed
3134 enumerator-list , enumerator
3137 enumeration-constant attribute-specifier-sequence[opt]
3138 enumeration-constant attribute-specifier-sequence[opt]
3139 = constant-expression
3144 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3145 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3146 = constant-expression
3150 static struct c_typespec
3151 c_parser_enum_specifier (c_parser *parser)
3153 struct c_typespec ret;
3154 bool have_std_attrs;
3155 tree std_attrs = NULL_TREE;
3157 tree ident = NULL_TREE;
3158 location_t enum_loc;
3159 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3160 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3161 c_parser_consume_token (parser);
3162 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3164 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3165 attrs = c_parser_gnu_attributes (parser);
3166 enum_loc = c_parser_peek_token (parser)->location;
3167 /* Set the location in case we create a decl now. */
3168 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3169 if (c_parser_next_token_is (parser, CPP_NAME))
3171 ident = c_parser_peek_token (parser)->value;
3172 ident_loc = c_parser_peek_token (parser)->location;
3173 enum_loc = ident_loc;
3174 c_parser_consume_token (parser);
3176 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3178 /* Parse an enum definition. */
3179 struct c_enum_contents the_enum;
3182 /* We chain the enumerators in reverse order, then put them in
3183 forward order at the end. */
3185 timevar_push (TV_PARSE_ENUM);
3186 type = start_enum (enum_loc, &the_enum, ident);
3188 c_parser_consume_token (parser);
3196 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3197 location_t decl_loc, value_loc;
3198 if (c_parser_next_token_is_not (parser, CPP_NAME))
3200 /* Give a nicer error for "enum {}". */
3201 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3204 error_at (c_parser_peek_token (parser)->location,
3205 "empty enum is invalid");
3206 parser->error = true;
3209 c_parser_error (parser, "expected identifier");
3210 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3211 values = error_mark_node;
3214 token = c_parser_peek_token (parser);
3215 enum_id = token->value;
3216 /* Set the location in case we create a decl now. */
3217 c_parser_set_source_position_from_token (token);
3218 decl_loc = value_loc = token->location;
3219 c_parser_consume_token (parser);
3220 /* Parse any specified attributes. */
3221 tree std_attrs = NULL_TREE;
3222 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3223 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3224 tree enum_attrs = chainon (std_attrs,
3225 c_parser_gnu_attributes (parser));
3226 if (c_parser_next_token_is (parser, CPP_EQ))
3228 c_parser_consume_token (parser);
3229 value_loc = c_parser_peek_token (parser)->location;
3230 enum_value = c_parser_expr_no_commas (parser, NULL).value;
3233 enum_value = NULL_TREE;
3234 enum_decl = build_enumerator (decl_loc, value_loc,
3235 &the_enum, enum_id, enum_value);
3237 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3238 TREE_CHAIN (enum_decl) = values;
3241 if (c_parser_next_token_is (parser, CPP_COMMA))
3243 comma_loc = c_parser_peek_token (parser)->location;
3245 c_parser_consume_token (parser);
3247 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3250 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3251 "comma at end of enumerator list");
3252 c_parser_consume_token (parser);
3257 c_parser_error (parser, "expected %<,%> or %<}%>");
3258 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3259 values = error_mark_node;
3263 postfix_attrs = c_parser_gnu_attributes (parser);
3264 ret.spec = finish_enum (type, nreverse (values),
3266 chainon (attrs, postfix_attrs)));
3267 ret.kind = ctsk_tagdef;
3268 ret.expr = NULL_TREE;
3269 ret.expr_const_operands = true;
3270 timevar_pop (TV_PARSE_ENUM);
3275 c_parser_error (parser, "expected %<{%>");
3276 ret.spec = error_mark_node;
3277 ret.kind = ctsk_tagref;
3278 ret.expr = NULL_TREE;
3279 ret.expr_const_operands = true;
3282 /* Attributes may only appear when the members are defined or in
3283 certain forward declarations (treat enum forward declarations in
3284 GNU C analogously to struct and union forward declarations in
3286 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3287 c_parser_error (parser, "expected %<;%>");
3288 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3290 /* In ISO C, enumerated types can be referred to only if already
3292 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3295 pedwarn (enum_loc, OPT_Wpedantic,
3296 "ISO C forbids forward references to %<enum%> types");
3301 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3303 struct-or-union-specifier:
3304 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3305 identifier[opt] { struct-contents } gnu-attributes[opt]
3306 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3310 struct-declaration-list
3312 struct-declaration-list:
3313 struct-declaration ;
3314 struct-declaration-list struct-declaration ;
3321 struct-declaration-list struct-declaration
3323 struct-declaration-list:
3324 struct-declaration-list ;
3327 (Note that in the syntax here, unlike that in ISO C, the semicolons
3328 are included here rather than in struct-declaration, in order to
3329 describe the syntax with extra semicolons and missing semicolon at
3334 struct-declaration-list:
3335 @defs ( class-name )
3337 (Note this does not include a trailing semicolon, but can be
3338 followed by further declarations, and gets a pedwarn-if-pedantic
3339 when followed by a semicolon.) */
3341 static struct c_typespec
3342 c_parser_struct_or_union_specifier (c_parser *parser)
3344 struct c_typespec ret;
3345 bool have_std_attrs;
3346 tree std_attrs = NULL_TREE;
3348 tree ident = NULL_TREE;
3349 location_t struct_loc;
3350 location_t ident_loc = UNKNOWN_LOCATION;
3351 enum tree_code code;
3352 switch (c_parser_peek_token (parser)->keyword)
3363 struct_loc = c_parser_peek_token (parser)->location;
3364 c_parser_consume_token (parser);
3365 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3367 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3368 attrs = c_parser_gnu_attributes (parser);
3370 /* Set the location in case we create a decl now. */
3371 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3373 if (c_parser_next_token_is (parser, CPP_NAME))
3375 ident = c_parser_peek_token (parser)->value;
3376 ident_loc = c_parser_peek_token (parser)->location;
3377 struct_loc = ident_loc;
3378 c_parser_consume_token (parser);
3380 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3382 /* Parse a struct or union definition. Start the scope of the
3383 tag before parsing components. */
3384 class c_struct_parse_info *struct_info;
3385 tree type = start_struct (struct_loc, code, ident, &struct_info);
3387 /* We chain the components in reverse order, then put them in
3388 forward order at the end. Each struct-declaration may
3389 declare multiple components (comma-separated), so we must use
3390 chainon to join them, although when parsing each
3391 struct-declaration we can use TREE_CHAIN directly.
3393 The theory behind all this is that there will be more
3394 semicolon separated fields than comma separated fields, and
3395 so we'll be minimizing the number of node traversals required
3398 timevar_push (TV_PARSE_STRUCT);
3399 contents = NULL_TREE;
3400 c_parser_consume_token (parser);
3401 /* Handle the Objective-C @defs construct,
3402 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3403 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3406 gcc_assert (c_dialect_objc ());
3407 c_parser_consume_token (parser);
3408 matching_parens parens;
3409 if (!parens.require_open (parser))
3411 if (c_parser_next_token_is (parser, CPP_NAME)
3412 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3414 name = c_parser_peek_token (parser)->value;
3415 c_parser_consume_token (parser);
3419 c_parser_error (parser, "expected class name");
3420 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3423 parens.skip_until_found_close (parser);
3424 contents = nreverse (objc_get_class_ivars (name));
3427 /* Parse the struct-declarations and semicolons. Problems with
3428 semicolons are diagnosed here; empty structures are diagnosed
3433 /* Parse any stray semicolon. */
3434 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3436 location_t semicolon_loc
3437 = c_parser_peek_token (parser)->location;
3438 gcc_rich_location richloc (semicolon_loc);
3439 richloc.add_fixit_remove ();
3440 pedwarn (&richloc, OPT_Wpedantic,
3441 "extra semicolon in struct or union specified");
3442 c_parser_consume_token (parser);
3445 /* Stop if at the end of the struct or union contents. */
3446 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3448 c_parser_consume_token (parser);
3451 /* Accept #pragmas at struct scope. */
3452 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3454 c_parser_pragma (parser, pragma_struct, NULL);
3457 /* Parse some comma-separated declarations, but not the
3458 trailing semicolon if any. */
3459 decls = c_parser_struct_declaration (parser);
3460 contents = chainon (decls, contents);
3461 /* If no semicolon follows, either we have a parse error or
3462 are at the end of the struct or union and should
3464 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3465 c_parser_consume_token (parser);
3468 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3469 pedwarn (c_parser_peek_token (parser)->location, 0,
3470 "no semicolon at end of struct or union");
3471 else if (parser->error
3472 || !c_parser_next_token_starts_declspecs (parser))
3474 c_parser_error (parser, "expected %<;%>");
3475 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3479 /* If we come here, we have already emitted an error
3480 for an expected `;', identifier or `(', and we also
3481 recovered already. Go on with the next field. */
3484 postfix_attrs = c_parser_gnu_attributes (parser);
3485 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3487 chainon (attrs, postfix_attrs)),
3489 ret.kind = ctsk_tagdef;
3490 ret.expr = NULL_TREE;
3491 ret.expr_const_operands = true;
3492 timevar_pop (TV_PARSE_STRUCT);
3497 c_parser_error (parser, "expected %<{%>");
3498 ret.spec = error_mark_node;
3499 ret.kind = ctsk_tagref;
3500 ret.expr = NULL_TREE;
3501 ret.expr_const_operands = true;
3504 /* Attributes may only appear when the members are defined or in
3505 certain forward declarations. */
3506 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3507 c_parser_error (parser, "expected %<;%>");
3508 /* ??? Existing practice is that GNU attributes are ignored after
3509 the struct or union keyword when not defining the members. */
3510 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
3514 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3515 *without* the trailing semicolon.
3518 attribute-specifier-sequence[opt] specifier-qualifier-list
3519 attribute-specifier-sequence[opt] struct-declarator-list
3520 static_assert-declaration-no-semi
3522 specifier-qualifier-list:
3523 type-specifier specifier-qualifier-list[opt]
3524 type-qualifier specifier-qualifier-list[opt]
3525 alignment-specifier specifier-qualifier-list[opt]
3526 gnu-attributes specifier-qualifier-list[opt]
3528 struct-declarator-list:
3530 struct-declarator-list , gnu-attributes[opt] struct-declarator
3533 declarator gnu-attributes[opt]
3534 declarator[opt] : constant-expression gnu-attributes[opt]
3539 __extension__ struct-declaration
3540 specifier-qualifier-list
3542 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3543 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3544 any expression without commas in the syntax (assignment
3545 expressions, not just conditional expressions); assignment
3546 expressions will be diagnosed as non-constant. */
3549 c_parser_struct_declaration (c_parser *parser)
3551 struct c_declspecs *specs;
3553 tree all_prefix_attrs;
3555 location_t decl_loc;
3556 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3560 ext = disable_extension_diagnostics ();
3561 c_parser_consume_token (parser);
3562 decl = c_parser_struct_declaration (parser);
3563 restore_extension_diagnostics (ext);
3566 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3568 c_parser_static_assert_declaration_no_semi (parser);
3571 specs = build_null_declspecs ();
3572 decl_loc = c_parser_peek_token (parser)->location;
3573 /* Strictly by the standard, we shouldn't allow _Alignas here,
3574 but it appears to have been intended to allow it there, so
3575 we're keeping it as it is until WG14 reaches a conclusion
3577 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3578 c_parser_declspecs (parser, specs, false, true, true,
3579 true, false, true, true, cla_nonabstract_decl);
3582 if (!specs->declspecs_seen_p)
3584 c_parser_error (parser, "expected specifier-qualifier-list");
3587 finish_declspecs (specs);
3588 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3589 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3592 if (specs->typespec_kind == ctsk_none)
3594 pedwarn (decl_loc, OPT_Wpedantic,
3595 "ISO C forbids member declarations with no members");
3596 shadow_tag_warned (specs, pedantic);
3601 /* Support for unnamed structs or unions as members of
3602 structs or unions (which is [a] useful and [b] supports
3606 ret = grokfield (c_parser_peek_token (parser)->location,
3607 build_id_declarator (NULL_TREE), specs,
3610 decl_attributes (&ret, attrs, 0);
3615 /* Provide better error recovery. Note that a type name here is valid,
3616 and will be treated as a field name. */
3617 if (specs->typespec_kind == ctsk_tagdef
3618 && TREE_CODE (specs->type) != ENUMERAL_TYPE
3619 && c_parser_next_token_starts_declspecs (parser)
3620 && !c_parser_next_token_is (parser, CPP_NAME))
3622 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3623 parser->error = false;
3627 pending_xref_error ();
3628 prefix_attrs = specs->attrs;
3629 all_prefix_attrs = prefix_attrs;
3630 specs->attrs = NULL_TREE;
3634 /* Declaring one or more declarators or un-named bit-fields. */
3635 struct c_declarator *declarator;
3637 if (c_parser_next_token_is (parser, CPP_COLON))
3638 declarator = build_id_declarator (NULL_TREE);
3640 declarator = c_parser_declarator (parser,
3641 specs->typespec_kind != ctsk_none,
3642 C_DTR_NORMAL, &dummy);
3643 if (declarator == NULL)
3645 c_parser_skip_to_end_of_block_or_statement (parser);
3648 if (c_parser_next_token_is (parser, CPP_COLON)
3649 || c_parser_next_token_is (parser, CPP_COMMA)
3650 || c_parser_next_token_is (parser, CPP_SEMICOLON)
3651 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3652 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3654 tree postfix_attrs = NULL_TREE;
3655 tree width = NULL_TREE;
3657 if (c_parser_next_token_is (parser, CPP_COLON))
3659 c_parser_consume_token (parser);
3660 width = c_parser_expr_no_commas (parser, NULL).value;
3662 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3663 postfix_attrs = c_parser_gnu_attributes (parser);
3664 d = grokfield (c_parser_peek_token (parser)->location,
3665 declarator, specs, width, &all_prefix_attrs);
3666 decl_attributes (&d, chainon (postfix_attrs,
3667 all_prefix_attrs), 0);
3668 DECL_CHAIN (d) = decls;
3670 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3671 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3674 all_prefix_attrs = prefix_attrs;
3675 if (c_parser_next_token_is (parser, CPP_COMMA))
3676 c_parser_consume_token (parser);
3677 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3678 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3680 /* Semicolon consumed in caller. */
3685 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3691 c_parser_error (parser,
3692 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3693 "%<__attribute__%>");
3700 /* Parse a typeof specifier (a GNU extension).
3703 typeof ( expression )
3704 typeof ( type-name )
3707 static struct c_typespec
3708 c_parser_typeof_specifier (c_parser *parser)
3710 struct c_typespec ret;
3711 ret.kind = ctsk_typeof;
3712 ret.spec = error_mark_node;
3713 ret.expr = NULL_TREE;
3714 ret.expr_const_operands = true;
3715 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3716 c_parser_consume_token (parser);
3717 c_inhibit_evaluation_warnings++;
3719 matching_parens parens;
3720 if (!parens.require_open (parser))
3722 c_inhibit_evaluation_warnings--;
3726 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3728 struct c_type_name *type = c_parser_type_name (parser);
3729 c_inhibit_evaluation_warnings--;
3733 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3734 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3740 location_t here = c_parser_peek_token (parser)->location;
3741 struct c_expr expr = c_parser_expression (parser);
3742 c_inhibit_evaluation_warnings--;
3744 if (TREE_CODE (expr.value) == COMPONENT_REF
3745 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3746 error_at (here, "%<typeof%> applied to a bit-field");
3747 mark_exp_read (expr.value);
3748 ret.spec = TREE_TYPE (expr.value);
3749 was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3750 /* This is returned with the type so that when the type is
3751 evaluated, this can be evaluated. */
3753 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3754 pop_maybe_used (was_vm);
3756 parens.skip_until_found_close (parser);
3760 /* Parse an alignment-specifier.
3764 alignment-specifier:
3765 _Alignas ( type-name )
3766 _Alignas ( constant-expression )
3770 c_parser_alignas_specifier (c_parser * parser)
3772 tree ret = error_mark_node;
3773 location_t loc = c_parser_peek_token (parser)->location;
3774 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3775 c_parser_consume_token (parser);
3777 pedwarn_c99 (loc, OPT_Wpedantic,
3778 "ISO C99 does not support %<_Alignas%>");
3780 pedwarn_c99 (loc, OPT_Wpedantic,
3781 "ISO C90 does not support %<_Alignas%>");
3782 matching_parens parens;
3783 if (!parens.require_open (parser))
3785 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3787 struct c_type_name *type = c_parser_type_name (parser);
3789 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3793 ret = c_parser_expr_no_commas (parser, NULL).value;
3794 parens.skip_until_found_close (parser);
3798 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3799 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3800 a typedef name may be redeclared; otherwise it may not. KIND
3801 indicates which kind of declarator is wanted. Returns a valid
3802 declarator except in the case of a syntax error in which case NULL is
3803 returned. *SEEN_ID is set to true if an identifier being declared is
3804 seen; this is used to diagnose bad forms of abstract array declarators
3805 and to determine whether an identifier list is syntactically permitted.
3808 pointer[opt] direct-declarator
3812 ( gnu-attributes[opt] declarator )
3813 direct-declarator array-declarator
3814 direct-declarator ( parameter-type-list )
3815 direct-declarator ( identifier-list[opt] )
3818 * type-qualifier-list[opt]
3819 * type-qualifier-list[opt] pointer
3821 type-qualifier-list:
3824 type-qualifier-list type-qualifier
3825 type-qualifier-list gnu-attributes
3828 [ type-qualifier-list[opt] assignment-expression[opt] ]
3829 [ static type-qualifier-list[opt] assignment-expression ]
3830 [ type-qualifier-list static assignment-expression ]
3831 [ type-qualifier-list[opt] * ]
3833 parameter-type-list:
3835 parameter-list , ...
3838 parameter-declaration
3839 parameter-list , parameter-declaration
3841 parameter-declaration:
3842 declaration-specifiers declarator gnu-attributes[opt]
3843 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3847 identifier-list , identifier
3849 abstract-declarator:
3851 pointer[opt] direct-abstract-declarator
3853 direct-abstract-declarator:
3854 ( gnu-attributes[opt] abstract-declarator )
3855 direct-abstract-declarator[opt] array-declarator
3856 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3861 direct-declarator ( parameter-forward-declarations
3862 parameter-type-list[opt] )
3864 direct-abstract-declarator:
3865 direct-abstract-declarator[opt] ( parameter-forward-declarations
3866 parameter-type-list[opt] )
3868 parameter-forward-declarations:
3870 parameter-forward-declarations parameter-list ;
3872 The uses of gnu-attributes shown above are GNU extensions.
3874 Some forms of array declarator are not included in C99 in the
3875 syntax for abstract declarators; these are disallowed elsewhere.
3876 This may be a defect (DR#289).
3878 This function also accepts an omitted abstract declarator as being
3879 an abstract declarator, although not part of the formal syntax. */
3881 struct c_declarator *
3882 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3885 /* Parse any initial pointer part. */
3886 if (c_parser_next_token_is (parser, CPP_MULT))
3888 struct c_declspecs *quals_attrs = build_null_declspecs ();
3889 struct c_declarator *inner;
3890 c_parser_consume_token (parser);
3891 c_parser_declspecs (parser, quals_attrs, false, false, true,
3892 false, false, true, false, cla_prefer_id);
3893 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3897 return make_pointer_declarator (quals_attrs, inner);
3899 /* Now we have a direct declarator, direct abstract declarator or
3900 nothing (which counts as a direct abstract declarator here). */
3901 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3904 /* Parse a direct declarator or direct abstract declarator; arguments
3905 as c_parser_declarator. */
3907 static struct c_declarator *
3908 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3911 /* The direct declarator must start with an identifier (possibly
3912 omitted) or a parenthesized declarator (possibly abstract). In
3913 an ordinary declarator, initial parentheses must start a
3914 parenthesized declarator. In an abstract declarator or parameter
3915 declarator, they could start a parenthesized declarator or a
3916 parameter list. To tell which, the open parenthesis and any
3917 following gnu-attributes must be read. If a declaration
3918 specifier or standard attributes follow, then it is a parameter
3919 list; if the specifier is a typedef name, there might be an
3920 ambiguity about redeclaring it, which is resolved in the
3921 direction of treating it as a typedef name. If a close
3922 parenthesis follows, it is also an empty parameter list, as the
3923 syntax does not permit empty abstract declarators. Otherwise, it
3924 is a parenthesized declarator (in which case the analysis may be
3925 repeated inside it, recursively).
3927 ??? There is an ambiguity in a parameter declaration "int
3928 (__attribute__((foo)) x)", where x is not a typedef name: it
3929 could be an abstract declarator for a function, or declare x with
3930 parentheses. The proper resolution of this ambiguity needs
3931 documenting. At present we follow an accident of the old
3932 parser's implementation, whereby the first parameter must have
3933 some declaration specifiers other than just gnu-attributes. Thus as
3934 a parameter declaration it is treated as a parenthesized
3935 parameter named x, and as an abstract declarator it is
3938 ??? Also following the old parser, gnu-attributes inside an empty
3939 parameter list are ignored, making it a list not yielding a
3940 prototype, rather than giving an error or making it have one
3941 parameter with implicit type int.
3943 ??? Also following the old parser, typedef names may be
3944 redeclared in declarators, but not Objective-C class names. */
3946 if (kind != C_DTR_ABSTRACT
3947 && c_parser_next_token_is (parser, CPP_NAME)
3949 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3950 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3951 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3953 struct c_declarator *inner
3954 = build_id_declarator (c_parser_peek_token (parser)->value);
3956 inner->id_loc = c_parser_peek_token (parser)->location;
3957 c_parser_consume_token (parser);
3958 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3959 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
3960 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3963 if (kind != C_DTR_NORMAL
3964 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3965 && !c_parser_nth_token_starts_std_attributes (parser, 1))
3967 struct c_declarator *inner = build_id_declarator (NULL_TREE);
3968 inner->id_loc = c_parser_peek_token (parser)->location;
3969 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3972 /* Either we are at the end of an abstract declarator, or we have
3975 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3978 struct c_declarator *inner;
3979 c_parser_consume_token (parser);
3980 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
3982 attrs = c_parser_gnu_attributes (parser);
3983 if (kind != C_DTR_NORMAL
3984 && (c_parser_next_token_starts_declspecs (parser)
3986 && c_parser_nth_token_starts_std_attributes (parser, 1))
3987 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3989 struct c_arg_info *args
3990 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3991 attrs, have_gnu_attrs);
3996 inner = build_id_declarator (NULL_TREE);
3998 && args->types != error_mark_node
3999 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4000 && c_parser_nth_token_starts_std_attributes (parser, 1))
4003 = c_parser_std_attribute_specifier_sequence (parser);
4005 inner = build_attrs_declarator (std_attrs, inner);
4007 inner = build_function_declarator (args, inner);
4008 return c_parser_direct_declarator_inner (parser, *seen_id,
4012 /* A parenthesized declarator. */
4013 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4014 if (inner != NULL && attrs != NULL)
4015 inner = build_attrs_declarator (attrs, inner);
4016 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4018 c_parser_consume_token (parser);
4022 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4026 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4033 if (kind == C_DTR_NORMAL)
4035 c_parser_error (parser, "expected identifier or %<(%>");
4039 return build_id_declarator (NULL_TREE);
4043 /* Parse part of a direct declarator or direct abstract declarator,
4044 given that some (in INNER) has already been parsed; ID_PRESENT is
4045 true if an identifier is present, false for an abstract
4048 static struct c_declarator *
4049 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4050 struct c_declarator *inner)
4052 /* Parse a sequence of array declarators and parameter lists. */
4053 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4054 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4056 location_t brace_loc = c_parser_peek_token (parser)->location;
4057 struct c_declarator *declarator;
4058 struct c_declspecs *quals_attrs = build_null_declspecs ();
4061 struct c_expr dimen;
4062 dimen.value = NULL_TREE;
4063 dimen.original_code = ERROR_MARK;
4064 dimen.original_type = NULL_TREE;
4065 c_parser_consume_token (parser);
4066 c_parser_declspecs (parser, quals_attrs, false, false, true,
4067 false, false, false, false, cla_prefer_id);
4068 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4070 c_parser_consume_token (parser);
4071 if (static_seen && !quals_attrs->declspecs_seen_p)
4072 c_parser_declspecs (parser, quals_attrs, false, false, true,
4073 false, false, false, false, cla_prefer_id);
4074 if (!quals_attrs->declspecs_seen_p)
4076 /* If "static" is present, there must be an array dimension.
4077 Otherwise, there may be a dimension, "*", or no
4082 dimen = c_parser_expr_no_commas (parser, NULL);
4086 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4088 dimen.value = NULL_TREE;
4091 else if (c_parser_next_token_is (parser, CPP_MULT))
4093 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4095 dimen.value = NULL_TREE;
4097 c_parser_consume_token (parser);
4102 dimen = c_parser_expr_no_commas (parser, NULL);
4108 dimen = c_parser_expr_no_commas (parser, NULL);
4111 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4112 c_parser_consume_token (parser);
4115 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4120 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4121 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4122 static_seen, star_seen);
4123 if (declarator == NULL)
4125 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4128 = c_parser_std_attribute_specifier_sequence (parser);
4130 inner = build_attrs_declarator (std_attrs, inner);
4132 inner = set_array_declarator_inner (declarator, inner);
4133 return c_parser_direct_declarator_inner (parser, id_present, inner);
4135 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4138 struct c_arg_info *args;
4139 c_parser_consume_token (parser);
4140 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4142 attrs = c_parser_gnu_attributes (parser);
4143 args = c_parser_parms_declarator (parser, id_present, attrs,
4150 && args->types != error_mark_node
4151 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4152 && c_parser_nth_token_starts_std_attributes (parser, 1))
4155 = c_parser_std_attribute_specifier_sequence (parser);
4157 inner = build_attrs_declarator (std_attrs, inner);
4159 inner = build_function_declarator (args, inner);
4160 return c_parser_direct_declarator_inner (parser, id_present, inner);
4166 /* Parse a parameter list or identifier list, including the closing
4167 parenthesis but not the opening one. ATTRS are the gnu-attributes
4168 at the start of the list. ID_LIST_OK is true if an identifier list
4169 is acceptable; such a list must not have attributes at the start.
4170 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4171 attributes) were present (in which case standard attributes cannot
4174 static struct c_arg_info *
4175 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4176 bool have_gnu_attrs)
4179 declare_parm_level ();
4180 /* If the list starts with an identifier, it is an identifier list.
4181 Otherwise, it is either a prototype list or an empty list. */
4184 && c_parser_next_token_is (parser, CPP_NAME)
4185 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4187 /* Look ahead to detect typos in type names. */
4188 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4189 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4190 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4191 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4192 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4194 tree list = NULL_TREE, *nextp = &list;
4195 while (c_parser_next_token_is (parser, CPP_NAME)
4196 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4198 *nextp = build_tree_list (NULL_TREE,
4199 c_parser_peek_token (parser)->value);
4200 nextp = & TREE_CHAIN (*nextp);
4201 c_parser_consume_token (parser);
4202 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4204 c_parser_consume_token (parser);
4205 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4207 c_parser_error (parser, "expected identifier");
4211 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4213 struct c_arg_info *ret = build_arg_info ();
4215 c_parser_consume_token (parser);
4221 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4229 struct c_arg_info *ret
4230 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4236 /* Parse a parameter list (possibly empty), including the closing
4237 parenthesis but not the opening one. ATTRS are the gnu-attributes
4238 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4239 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4240 which means standard attributes cannot start the list. EXPR is
4241 NULL or an expression that needs to be evaluated for the side
4242 effects of array size expressions in the parameters. */
4244 static struct c_arg_info *
4245 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4246 bool have_gnu_attrs)
4248 bool bad_parm = false;
4250 /* ??? Following the old parser, forward parameter declarations may
4251 use abstract declarators, and if no real parameter declarations
4252 follow the forward declarations then this is not diagnosed. Also
4253 note as above that gnu-attributes are ignored as the only contents of
4254 the parentheses, or as the only contents after forward
4256 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4258 struct c_arg_info *ret = build_arg_info ();
4259 c_parser_consume_token (parser);
4262 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4264 struct c_arg_info *ret = build_arg_info ();
4266 if (flag_allow_parameterless_variadic_functions)
4268 /* F (...) is allowed. */
4269 ret->types = NULL_TREE;
4273 /* Suppress -Wold-style-definition for this case. */
4274 ret->types = error_mark_node;
4275 error_at (c_parser_peek_token (parser)->location,
4276 "ISO C requires a named argument before %<...%>");
4278 c_parser_consume_token (parser);
4279 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4281 c_parser_consume_token (parser);
4286 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4291 /* Nonempty list of parameters, either terminated with semicolon
4292 (forward declarations; recurse) or with close parenthesis (normal
4293 function) or with ", ... )" (variadic function). */
4296 /* Parse a parameter. */
4297 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4300 have_gnu_attrs = false;
4304 push_parm_decl (parm, &expr);
4305 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4308 c_parser_consume_token (parser);
4309 mark_forward_parm_decls ();
4310 bool new_have_gnu_attrs
4311 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4312 new_attrs = c_parser_gnu_attributes (parser);
4313 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4314 new_have_gnu_attrs);
4316 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4318 c_parser_consume_token (parser);
4322 return get_parm_info (false, expr);
4324 if (!c_parser_require (parser, CPP_COMMA,
4325 "expected %<;%>, %<,%> or %<)%>",
4326 UNKNOWN_LOCATION, false))
4328 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4331 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4333 c_parser_consume_token (parser);
4334 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4336 c_parser_consume_token (parser);
4340 return get_parm_info (true, expr);
4344 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4352 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4353 start of the declaration if it is the first parameter;
4354 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4357 static struct c_parm *
4358 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4359 bool have_gnu_attrs)
4361 struct c_declspecs *specs;
4362 struct c_declarator *declarator;
4364 tree postfix_attrs = NULL_TREE;
4367 /* Accept #pragmas between parameter declarations. */
4368 while (c_parser_next_token_is (parser, CPP_PRAGMA))
4369 c_parser_pragma (parser, pragma_param, NULL);
4371 if (!c_parser_next_token_starts_declspecs (parser)
4372 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4374 c_token *token = c_parser_peek_token (parser);
4377 c_parser_set_source_position_from_token (token);
4378 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4380 auto_diagnostic_group d;
4381 name_hint hint = lookup_name_fuzzy (token->value,
4382 FUZZY_LOOKUP_TYPENAME,
4384 if (const char *suggestion = hint.suggestion ())
4386 gcc_rich_location richloc (token->location);
4387 richloc.add_fixit_replace (suggestion);
4389 "unknown type name %qE; did you mean %qs?",
4390 token->value, suggestion);
4393 error_at (token->location, "unknown type name %qE", token->value);
4394 parser->error = true;
4396 /* ??? In some Objective-C cases '...' isn't applicable so there
4397 should be a different message. */
4399 c_parser_error (parser,
4400 "expected declaration specifiers or %<...%>");
4401 c_parser_skip_to_end_of_parameter (parser);
4405 location_t start_loc = c_parser_peek_token (parser)->location;
4407 specs = build_null_declspecs ();
4410 declspecs_add_attrs (input_location, specs, attrs);
4413 c_parser_declspecs (parser, specs, true, true, true, true, false,
4414 !have_gnu_attrs, true, cla_nonabstract_decl);
4415 finish_declspecs (specs);
4416 pending_xref_error ();
4417 prefix_attrs = specs->attrs;
4418 specs->attrs = NULL_TREE;
4419 declarator = c_parser_declarator (parser,
4420 specs->typespec_kind != ctsk_none,
4421 C_DTR_PARM, &dummy);
4422 if (declarator == NULL)
4424 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4427 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4428 postfix_attrs = c_parser_gnu_attributes (parser);
4430 /* Generate a location for the parameter, ranging from the start of the
4431 initial token to the end of the final token.
4433 If we have a identifier, then use it for the caret location, e.g.
4435 extern int callee (int one, int (*two)(int, int), float three);
4436 ~~~~~~^~~~~~~~~~~~~~
4438 otherwise, reuse the start location for the caret location e.g.:
4440 extern int callee (int one, int (*)(int, int), float three);
4443 location_t end_loc = parser->last_token_location;
4445 /* Find any cdk_id declarator; determine if we have an identifier. */
4446 c_declarator *id_declarator = declarator;
4447 while (id_declarator && id_declarator->kind != cdk_id)
4448 id_declarator = id_declarator->declarator;
4449 location_t caret_loc = (id_declarator->u.id.id
4450 ? id_declarator->id_loc
4452 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4454 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4455 declarator, param_loc);
4458 /* Parse a string literal in an asm expression. It should not be
4459 translated, and wide string literals are an error although
4460 permitted by the syntax. This is a GNU extension.
4467 c_parser_asm_string_literal (c_parser *parser)
4470 int save_flag = warn_overlength_strings;
4471 warn_overlength_strings = 0;
4472 str = c_parser_string_literal (parser, false, false).value;
4473 warn_overlength_strings = save_flag;
4477 /* Parse a simple asm expression. This is used in restricted
4478 contexts, where a full expression with inputs and outputs does not
4479 make sense. This is a GNU extension.
4482 asm ( asm-string-literal )
4486 c_parser_simple_asm_expr (c_parser *parser)
4489 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4490 c_parser_consume_token (parser);
4491 matching_parens parens;
4492 if (!parens.require_open (parser))
4494 str = c_parser_asm_string_literal (parser);
4495 if (!parens.require_close (parser))
4497 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4504 c_parser_gnu_attribute_any_word (c_parser *parser)
4506 tree attr_name = NULL_TREE;
4508 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4510 /* ??? See comment above about what keywords are accepted here. */
4512 switch (c_parser_peek_token (parser)->keyword)
4543 case RID_TRANSACTION_ATOMIC:
4544 case RID_TRANSACTION_CANCEL:
4560 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4561 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4563 else if (c_parser_next_token_is (parser, CPP_NAME))
4564 attr_name = c_parser_peek_token (parser)->value;
4569 /* Parse attribute arguments. This is a common form of syntax
4570 covering all currently valid GNU and standard attributes.
4572 gnu-attribute-arguments:
4574 identifier , nonempty-expr-list
4577 where the "identifier" must not be declared as a type. ??? Why not
4578 allow identifiers declared as types to start the arguments? */
4581 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4582 bool require_string, bool allow_empty_args)
4584 vec<tree, va_gc> *expr_list;
4586 /* Parse the attribute contents. If they start with an
4587 identifier which is followed by a comma or close
4588 parenthesis, then the arguments start with that
4589 identifier; otherwise they are an expression list.
4590 In objective-c the identifier may be a classname. */
4591 if (c_parser_next_token_is (parser, CPP_NAME)
4592 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4593 || (c_dialect_objc ()
4594 && c_parser_peek_token (parser)->id_kind
4596 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4597 || (c_parser_peek_2nd_token (parser)->type
4598 == CPP_CLOSE_PAREN))
4599 && (takes_identifier
4600 || (c_dialect_objc ()
4601 && c_parser_peek_token (parser)->id_kind
4602 == C_ID_CLASSNAME)))
4604 tree arg1 = c_parser_peek_token (parser)->value;
4605 c_parser_consume_token (parser);
4606 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4607 attr_args = build_tree_list (NULL_TREE, arg1);
4611 c_parser_consume_token (parser);
4612 expr_list = c_parser_expr_list (parser, false, true,
4613 NULL, NULL, NULL, NULL);
4614 tree_list = build_tree_list_vec (expr_list);
4615 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4616 release_tree_vector (expr_list);
4621 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4623 if (!allow_empty_args)
4624 error_at (c_parser_peek_token (parser)->location,
4625 "parentheses must be omitted if "
4626 "attribute argument list is empty");
4627 attr_args = NULL_TREE;
4629 else if (require_string)
4631 /* The only valid argument for this attribute is a string
4632 literal. Handle this specially here to avoid accepting
4633 string literals with excess parentheses. */
4634 tree string = c_parser_string_literal (parser, false, true).value;
4635 attr_args = build_tree_list (NULL_TREE, string);
4639 expr_list = c_parser_expr_list (parser, false, true,
4640 NULL, NULL, NULL, NULL);
4641 attr_args = build_tree_list_vec (expr_list);
4642 release_tree_vector (expr_list);
4648 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4652 gnu-attributes gnu-attribute
4655 __attribute__ ( ( gnu-attribute-list ) )
4659 gnu-attribute_list , gnu-attrib
4664 any-word ( gnu-attribute-arguments )
4666 where "any-word" may be any identifier (including one declared as a
4667 type), a reserved word storage class specifier, type specifier or
4668 type qualifier. ??? This still leaves out most reserved keywords
4669 (following the old parser), shouldn't we include them?
4670 When EXPECT_COMMA is true, expect the attribute to be preceded
4671 by a comma and fail if it isn't.
4672 When EMPTY_OK is true, allow and consume any number of consecutive
4673 commas with no attributes in between. */
4676 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4677 bool expect_comma = false, bool empty_ok = true)
4679 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4681 && !c_parser_next_token_is (parser, CPP_NAME)
4682 && !c_parser_next_token_is (parser, CPP_KEYWORD))
4685 while (c_parser_next_token_is (parser, CPP_COMMA))
4687 c_parser_consume_token (parser);
4692 tree attr_name = c_parser_gnu_attribute_any_word (parser);
4693 if (attr_name == NULL_TREE)
4696 attr_name = canonicalize_attr_name (attr_name);
4697 c_parser_consume_token (parser);
4700 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4702 if (expect_comma && !comma_first)
4704 /* A comma is missing between the last attribute on the chain
4706 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4708 return error_mark_node;
4710 attr = build_tree_list (attr_name, NULL_TREE);
4711 /* Add this attribute to the list. */
4712 attrs = chainon (attrs, attr);
4715 c_parser_consume_token (parser);
4718 = c_parser_attribute_arguments (parser,
4719 attribute_takes_identifier_p (attr_name),
4722 attr = build_tree_list (attr_name, attr_args);
4723 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4724 c_parser_consume_token (parser);
4727 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4729 return error_mark_node;
4732 if (expect_comma && !comma_first)
4734 /* A comma is missing between the last attribute on the chain
4736 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4738 return error_mark_node;
4741 /* Add this attribute to the list. */
4742 attrs = chainon (attrs, attr);
4747 c_parser_gnu_attributes (c_parser *parser)
4749 tree attrs = NULL_TREE;
4750 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4752 bool save_translate_strings_p = parser->translate_strings_p;
4753 parser->translate_strings_p = false;
4754 /* Consume the `__attribute__' keyword. */
4755 c_parser_consume_token (parser);
4756 /* Look for the two `(' tokens. */
4757 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4759 parser->translate_strings_p = save_translate_strings_p;
4762 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4764 parser->translate_strings_p = save_translate_strings_p;
4765 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4768 /* Parse the attribute list. Require a comma between successive
4769 (possibly empty) attributes. */
4770 for (bool expect_comma = false; ; expect_comma = true)
4772 /* Parse a single attribute. */
4773 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4774 if (attr == error_mark_node)
4781 /* Look for the two `)' tokens. */
4782 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4783 c_parser_consume_token (parser);
4786 parser->translate_strings_p = save_translate_strings_p;
4787 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4791 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4792 c_parser_consume_token (parser);
4795 parser->translate_strings_p = save_translate_strings_p;
4796 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4800 parser->translate_strings_p = save_translate_strings_p;
4806 /* Parse an optional balanced token sequence.
4808 balanced-token-sequence:
4810 balanced-token-sequence balanced-token
4813 ( balanced-token-sequence[opt] )
4814 [ balanced-token-sequence[opt] ]
4815 { balanced-token-sequence[opt] }
4816 any token other than ()[]{}
4820 c_parser_balanced_token_sequence (c_parser *parser)
4824 c_token *token = c_parser_peek_token (parser);
4825 switch (token->type)
4827 case CPP_OPEN_BRACE:
4829 matching_braces braces;
4830 braces.consume_open (parser);
4831 c_parser_balanced_token_sequence (parser);
4832 braces.require_close (parser);
4836 case CPP_OPEN_PAREN:
4838 matching_parens parens;
4839 parens.consume_open (parser);
4840 c_parser_balanced_token_sequence (parser);
4841 parens.require_close (parser);
4845 case CPP_OPEN_SQUARE:
4846 c_parser_consume_token (parser);
4847 c_parser_balanced_token_sequence (parser);
4848 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4851 case CPP_CLOSE_BRACE:
4852 case CPP_CLOSE_PAREN:
4853 case CPP_CLOSE_SQUARE:
4858 c_parser_consume_pragma (parser);
4859 c_parser_skip_to_pragma_eol (parser, false);
4863 c_parser_consume_token (parser);
4869 /* Parse standard (C2X) attributes (including GNU attributes in the
4872 attribute-specifier-sequence:
4873 attribute-specifier-sequence[opt] attribute-specifier
4875 attribute-specifier:
4876 [ [ attribute-list ] ]
4880 attribute-list, attribute[opt]
4883 attribute-token attribute-argument-clause[opt]
4887 attribute-prefixed-token
4892 attribute-prefixed-token:
4893 attribute-prefix :: identifier
4898 attribute-argument-clause:
4899 ( balanced-token-sequence[opt] )
4901 Keywords are accepted as identifiers for this purpose.
4905 c_parser_std_attribute (c_parser *parser, bool for_tm)
4907 c_token *token = c_parser_peek_token (parser);
4908 tree ns, name, attribute;
4910 /* Parse the attribute-token. */
4911 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4913 c_parser_error (parser, "expected identifier");
4914 return error_mark_node;
4916 name = canonicalize_attr_name (token->value);
4917 c_parser_consume_token (parser);
4918 if (c_parser_next_token_is (parser, CPP_SCOPE))
4921 c_parser_consume_token (parser);
4922 token = c_parser_peek_token (parser);
4923 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4925 c_parser_error (parser, "expected identifier");
4926 return error_mark_node;
4928 name = canonicalize_attr_name (token->value);
4929 c_parser_consume_token (parser);
4933 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
4935 /* Parse the arguments, if any. */
4936 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
4937 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4940 location_t open_loc = c_parser_peek_token (parser)->location;
4941 matching_parens parens;
4942 parens.consume_open (parser);
4943 if ((as && as->max_length == 0)
4944 /* Special-case the transactional-memory attribute "outer",
4945 which is specially handled but not registered as an
4946 attribute, to avoid allowing arbitrary balanced token
4947 sequences as arguments. */
4948 || is_attribute_p ("outer", name))
4950 error_at (open_loc, "%qE attribute does not take any arguments", name);
4951 parens.skip_until_found_close (parser);
4952 return error_mark_node;
4954 /* If this is a fake attribute created to handle -Wno-attributes,
4955 we must skip parsing the arguments. */
4956 if (as && !attribute_ignored_p (as))
4958 bool takes_identifier
4960 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
4961 && attribute_takes_identifier_p (name));
4964 && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
4965 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
4966 TREE_VALUE (attribute)
4967 = c_parser_attribute_arguments (parser, takes_identifier,
4968 require_string, false);
4971 c_parser_balanced_token_sequence (parser);
4972 parens.require_close (parser);
4975 if (ns == NULL_TREE && !for_tm && !as)
4977 /* An attribute with standard syntax and no namespace specified
4978 is a constraint violation if it is not one of the known
4979 standard attributes. Diagnose it here with a pedwarn and
4980 then discard it to prevent a duplicate warning later. */
4981 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4983 return error_mark_node;
4989 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
4991 location_t loc = c_parser_peek_token (parser)->location;
4992 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4994 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4996 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5000 pedwarn_c11 (loc, OPT_Wpedantic,
5001 "ISO C does not support %<[[]]%> attributes before C2X");
5002 tree attributes = NULL_TREE;
5005 c_token *token = c_parser_peek_token (parser);
5006 if (token->type == CPP_CLOSE_SQUARE)
5008 if (token->type == CPP_COMMA)
5010 c_parser_consume_token (parser);
5013 tree attribute = c_parser_std_attribute (parser, for_tm);
5014 if (attribute != error_mark_node)
5016 TREE_CHAIN (attribute) = attributes;
5017 attributes = attribute;
5019 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5022 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5023 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5024 return nreverse (attributes);
5027 /* Look past an optional balanced token sequence of raw look-ahead
5028 tokens starting with the *Nth token. *N is updated to point to the
5029 following token. Return true if such a sequence was found, false
5030 if the tokens parsed were not balanced. */
5033 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5037 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5038 switch (token->type)
5040 case CPP_OPEN_BRACE:
5043 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5045 token = c_parser_peek_nth_token_raw (parser, *n);
5046 if (token->type == CPP_CLOSE_BRACE)
5056 case CPP_OPEN_PAREN:
5059 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5061 token = c_parser_peek_nth_token_raw (parser, *n);
5062 if (token->type == CPP_CLOSE_PAREN)
5072 case CPP_OPEN_SQUARE:
5075 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5077 token = c_parser_peek_nth_token_raw (parser, *n);
5078 if (token->type == CPP_CLOSE_SQUARE)
5088 case CPP_CLOSE_BRACE:
5089 case CPP_CLOSE_PAREN:
5090 case CPP_CLOSE_SQUARE:
5101 /* Return whether standard attributes start with the Nth token. */
5104 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5106 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5107 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5109 /* In C, '[[' must start attributes. In Objective-C, we need to
5110 check whether '[[' is matched by ']]'. */
5111 if (!c_dialect_objc ())
5114 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5116 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5117 if (token->type != CPP_CLOSE_SQUARE)
5119 token = c_parser_peek_nth_token_raw (parser, n + 1);
5120 return token->type == CPP_CLOSE_SQUARE;
5124 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5126 tree attributes = NULL_TREE;
5129 tree attrs = c_parser_std_attribute_specifier (parser, false);
5130 attributes = chainon (attributes, attrs);
5132 while (c_parser_nth_token_starts_std_attributes (parser, 1));
5136 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5137 says whether alignment specifiers are OK (only in cases that might
5138 be the type name of a compound literal).
5141 specifier-qualifier-list abstract-declarator[opt]
5144 struct c_type_name *
5145 c_parser_type_name (c_parser *parser, bool alignas_ok)
5147 struct c_declspecs *specs = build_null_declspecs ();
5148 struct c_declarator *declarator;
5149 struct c_type_name *ret;
5151 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5152 false, true, cla_prefer_type);
5153 if (!specs->declspecs_seen_p)
5155 c_parser_error (parser, "expected specifier-qualifier-list");
5158 if (specs->type != error_mark_node)
5160 pending_xref_error ();
5161 finish_declspecs (specs);
5163 declarator = c_parser_declarator (parser,
5164 specs->typespec_kind != ctsk_none,
5165 C_DTR_ABSTRACT, &dummy);
5166 if (declarator == NULL)
5168 ret = XOBNEW (&parser_obstack, struct c_type_name);
5170 ret->declarator = declarator;
5174 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5177 assignment-expression
5178 { initializer-list }
5179 { initializer-list , }
5182 designation[opt] initializer
5183 initializer-list , designation[opt] initializer
5190 designator-list designator
5197 [ constant-expression ]
5209 [ constant-expression ... constant-expression ]
5211 Any expression without commas is accepted in the syntax for the
5212 constant-expressions, with non-constant expressions rejected later.
5214 DECL is the declaration we're parsing this initializer for.
5216 This function is only used for top-level initializers; for nested
5217 ones, see c_parser_initval. */
5219 static struct c_expr
5220 c_parser_initializer (c_parser *parser, tree decl)
5222 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5223 return c_parser_braced_init (parser, NULL_TREE, false, NULL, decl);
5227 location_t loc = c_parser_peek_token (parser)->location;
5228 if (decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
5230 "variable-sized object may not be initialized except "
5231 "with an empty initializer");
5232 ret = c_parser_expr_no_commas (parser, NULL);
5233 /* This is handled mostly by gimplify.cc, but we have to deal with
5234 not warning about int x = x; as it is a GCC extension to turn off
5235 this warning but only if warn_init_self is zero. */
5237 && !DECL_EXTERNAL (decl)
5238 && !TREE_STATIC (decl)
5239 && ret.value == decl
5241 suppress_warning (decl, OPT_Winit_self);
5242 if (TREE_CODE (ret.value) != STRING_CST
5243 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
5244 ret = convert_lvalue_to_rvalue (loc, ret, true, true);
5249 /* The location of the last comma within the current initializer list,
5250 or UNKNOWN_LOCATION if not within one. */
5252 location_t last_init_list_comma;
5254 /* Parse a braced initializer list. TYPE is the type specified for a
5255 compound literal, and NULL_TREE for other initializers and for
5256 nested braced lists. NESTED_P is true for nested braced lists,
5257 false for the list of a compound literal or the list that is the
5258 top-level initializer in a declaration. DECL is the declaration for
5259 the top-level initializer for a declaration, otherwise NULL_TREE. */
5261 static struct c_expr
5262 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5263 struct obstack *outer_obstack, tree decl)
5266 struct obstack braced_init_obstack;
5267 location_t brace_loc = c_parser_peek_token (parser)->location;
5268 gcc_obstack_init (&braced_init_obstack);
5269 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5270 matching_braces braces;
5271 braces.consume_open (parser);
5274 finish_implicit_inits (brace_loc, outer_obstack);
5275 push_init_level (brace_loc, 0, &braced_init_obstack);
5278 really_start_incremental_init (type);
5279 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5281 pedwarn_c11 (brace_loc, OPT_Wpedantic,
5282 "ISO C forbids empty initializer braces before C2X");
5286 if (decl && decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
5287 error_at (brace_loc,
5288 "variable-sized object may not be initialized except "
5289 "with an empty initializer");
5290 /* Parse a non-empty initializer list, possibly with a trailing
5294 c_parser_initelt (parser, &braced_init_obstack);
5297 if (c_parser_next_token_is (parser, CPP_COMMA))
5299 last_init_list_comma = c_parser_peek_token (parser)->location;
5300 c_parser_consume_token (parser);
5304 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5308 c_token *next_tok = c_parser_peek_token (parser);
5309 if (next_tok->type != CPP_CLOSE_BRACE)
5312 ret.original_code = ERROR_MARK;
5313 ret.original_type = NULL;
5314 braces.skip_until_found_close (parser);
5315 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5316 obstack_free (&braced_init_obstack, NULL);
5319 location_t close_loc = next_tok->location;
5320 c_parser_consume_token (parser);
5321 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5322 obstack_free (&braced_init_obstack, NULL);
5323 set_c_expr_source_range (&ret, brace_loc, close_loc);
5327 /* Parse a nested initializer, including designators. */
5330 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5332 /* Parse any designator or designator list. A single array
5333 designator may have the subsequent "=" omitted in GNU C, but a
5334 longer list or a structure member designator may not. */
5335 if (c_parser_next_token_is (parser, CPP_NAME)
5336 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5338 /* Old-style structure member designator. */
5339 set_init_label (c_parser_peek_token (parser)->location,
5340 c_parser_peek_token (parser)->value,
5341 c_parser_peek_token (parser)->location,
5342 braced_init_obstack);
5343 /* Use the colon as the error location. */
5344 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5345 "obsolete use of designated initializer with %<:%>");
5346 c_parser_consume_token (parser);
5347 c_parser_consume_token (parser);
5351 /* des_seen is 0 if there have been no designators, 1 if there
5352 has been a single array designator and 2 otherwise. */
5354 /* Location of a designator. */
5355 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5356 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5357 || c_parser_next_token_is (parser, CPP_DOT))
5359 int des_prev = des_seen;
5361 des_loc = c_parser_peek_token (parser)->location;
5364 if (c_parser_next_token_is (parser, CPP_DOT))
5367 c_parser_consume_token (parser);
5368 if (c_parser_next_token_is (parser, CPP_NAME))
5370 set_init_label (des_loc, c_parser_peek_token (parser)->value,
5371 c_parser_peek_token (parser)->location,
5372 braced_init_obstack);
5373 c_parser_consume_token (parser);
5379 init.original_code = ERROR_MARK;
5380 init.original_type = NULL;
5381 c_parser_error (parser, "expected identifier");
5382 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5383 process_init_element (input_location, init, false,
5384 braced_init_obstack);
5391 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5392 location_t array_index_loc = UNKNOWN_LOCATION;
5393 /* ??? Following the old parser, [ objc-receiver
5394 objc-message-args ] is accepted as an initializer,
5395 being distinguished from a designator by what follows
5396 the first assignment expression inside the square
5397 brackets, but after a first array designator a
5398 subsequent square bracket is for Objective-C taken to
5399 start an expression, using the obsolete form of
5400 designated initializer without '=', rather than
5401 possibly being a second level of designation: in LALR
5402 terms, the '[' is shifted rather than reducing
5403 designator to designator-list. */
5404 if (des_prev == 1 && c_dialect_objc ())
5406 des_seen = des_prev;
5409 if (des_prev == 0 && c_dialect_objc ())
5411 /* This might be an array designator or an
5412 Objective-C message expression. If the former,
5413 continue parsing here; if the latter, parse the
5414 remainder of the initializer given the starting
5415 primary-expression. ??? It might make sense to
5416 distinguish when des_prev == 1 as well; see
5417 previous comment. */
5419 struct c_expr mexpr;
5420 c_parser_consume_token (parser);
5421 if (c_parser_peek_token (parser)->type == CPP_NAME
5422 && ((c_parser_peek_token (parser)->id_kind
5424 || (c_parser_peek_token (parser)->id_kind
5425 == C_ID_CLASSNAME)))
5427 /* Type name receiver. */
5428 tree id = c_parser_peek_token (parser)->value;
5429 c_parser_consume_token (parser);
5430 rec = objc_get_class_reference (id);
5431 goto parse_message_args;
5433 first = c_parser_expr_no_commas (parser, NULL).value;
5434 mark_exp_read (first);
5435 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5436 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5437 goto array_desig_after_first;
5438 /* Expression receiver. So far only one part
5439 without commas has been parsed; there might be
5440 more of the expression. */
5442 while (c_parser_next_token_is (parser, CPP_COMMA))
5445 location_t comma_loc, exp_loc;
5446 comma_loc = c_parser_peek_token (parser)->location;
5447 c_parser_consume_token (parser);
5448 exp_loc = c_parser_peek_token (parser)->location;
5449 next = c_parser_expr_no_commas (parser, NULL);
5450 next = convert_lvalue_to_rvalue (exp_loc, next,
5452 rec = build_compound_expr (comma_loc, rec, next.value);
5455 /* Now parse the objc-message-args. */
5456 args = c_parser_objc_message_args (parser);
5457 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5460 = objc_build_message_expr (rec, args);
5461 mexpr.original_code = ERROR_MARK;
5462 mexpr.original_type = NULL;
5463 /* Now parse and process the remainder of the
5464 initializer, starting with this message
5465 expression as a primary-expression. */
5466 c_parser_initval (parser, &mexpr, braced_init_obstack);
5469 c_parser_consume_token (parser);
5470 array_index_loc = c_parser_peek_token (parser)->location;
5471 first = c_parser_expr_no_commas (parser, NULL).value;
5472 mark_exp_read (first);
5473 array_desig_after_first:
5474 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5476 ellipsis_loc = c_parser_peek_token (parser)->location;
5477 c_parser_consume_token (parser);
5478 second = c_parser_expr_no_commas (parser, NULL).value;
5479 mark_exp_read (second);
5483 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5485 c_parser_consume_token (parser);
5486 set_init_index (array_index_loc, first, second,
5487 braced_init_obstack);
5489 pedwarn (ellipsis_loc, OPT_Wpedantic,
5490 "ISO C forbids specifying range of elements to initialize");
5493 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5499 if (c_parser_next_token_is (parser, CPP_EQ))
5501 pedwarn_c90 (des_loc, OPT_Wpedantic,
5502 "ISO C90 forbids specifying subobject "
5504 c_parser_consume_token (parser);
5509 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5510 "obsolete use of designated initializer without %<=%>");
5515 init.original_code = ERROR_MARK;
5516 init.original_type = NULL;
5517 c_parser_error (parser, "expected %<=%>");
5518 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5519 process_init_element (input_location, init, false,
5520 braced_init_obstack);
5526 c_parser_initval (parser, NULL, braced_init_obstack);
5529 /* Parse a nested initializer; as c_parser_initializer but parses
5530 initializers within braced lists, after any designators have been
5531 applied. If AFTER is not NULL then it is an Objective-C message
5532 expression which is the primary-expression starting the
5536 c_parser_initval (c_parser *parser, struct c_expr *after,
5537 struct obstack * braced_init_obstack)
5540 gcc_assert (!after || c_dialect_objc ());
5541 location_t loc = c_parser_peek_token (parser)->location;
5543 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
5544 init = c_parser_braced_init (parser, NULL_TREE, true,
5545 braced_init_obstack, NULL_TREE);
5548 init = c_parser_expr_no_commas (parser, after);
5549 if (init.value != NULL_TREE
5550 && TREE_CODE (init.value) != STRING_CST
5551 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
5552 init = convert_lvalue_to_rvalue (loc, init, true, true);
5554 process_init_element (loc, init, false, braced_init_obstack);
5557 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5558 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5561 { block-item-list[opt] }
5562 { label-declarations block-item-list }
5566 block-item-list block-item
5579 { label-declarations block-item-list }
5582 __extension__ nested-declaration
5583 nested-function-definition
5587 label-declarations label-declaration
5590 __label__ identifier-list ;
5592 Allowing the mixing of declarations and code is new in C99. The
5593 GNU syntax also permits (not shown above) labels at the end of
5594 compound statements, which yield an error. We don't allow labels
5595 on declarations; this might seem like a natural extension, but
5596 there would be a conflict between gnu-attributes on the label and
5597 prefix gnu-attributes on the declaration. ??? The syntax follows the
5598 old parser in requiring something after label declarations.
5599 Although they are erroneous if the labels declared aren't defined,
5600 is it useful for the syntax to be this way?
5621 cancellation-point-directive */
5624 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
5627 location_t brace_loc;
5628 brace_loc = c_parser_peek_token (parser)->location;
5629 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5631 /* Ensure a scope is entered and left anyway to avoid confusion
5632 if we have just prepared to enter a function body. */
5633 stmt = c_begin_compound_stmt (true);
5634 c_end_compound_stmt (brace_loc, stmt, true);
5635 return error_mark_node;
5637 stmt = c_begin_compound_stmt (true);
5638 location_t end_loc = c_parser_compound_statement_nostart (parser);
5642 return c_end_compound_stmt (brace_loc, stmt, true);
5645 /* Parse a compound statement except for the opening brace. This is
5646 used for parsing both compound statements and statement expressions
5647 (which follow different paths to handling the opening). */
5650 c_parser_compound_statement_nostart (c_parser *parser)
5652 bool last_stmt = false;
5653 bool last_label = false;
5654 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5655 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5656 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5658 location_t endloc = c_parser_peek_token (parser)->location;
5659 add_debug_begin_stmt (endloc);
5660 c_parser_consume_token (parser);
5663 mark_valid_location_for_stdc_pragma (true);
5664 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5666 /* Read zero or more forward-declarations for labels that nested
5667 functions can jump to. */
5668 mark_valid_location_for_stdc_pragma (false);
5669 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5671 label_loc = c_parser_peek_token (parser)->location;
5672 c_parser_consume_token (parser);
5673 /* Any identifiers, including those declared as type names,
5678 if (c_parser_next_token_is_not (parser, CPP_NAME))
5680 c_parser_error (parser, "expected identifier");
5684 = declare_label (c_parser_peek_token (parser)->value);
5685 C_DECLARED_LABEL_FLAG (label) = 1;
5686 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5687 c_parser_consume_token (parser);
5688 if (c_parser_next_token_is (parser, CPP_COMMA))
5689 c_parser_consume_token (parser);
5693 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5695 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5697 /* We must now have at least one statement, label or declaration. */
5698 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5700 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5701 c_parser_error (parser, "expected declaration or statement");
5702 location_t endloc = c_parser_peek_token (parser)->location;
5703 c_parser_consume_token (parser);
5706 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5708 location_t loc = c_parser_peek_token (parser)->location;
5709 loc = expansion_point_location_if_in_system_header (loc);
5710 /* Standard attributes may start a label, statement or declaration. */
5712 = c_parser_nth_token_starts_std_attributes (parser, 1);
5713 tree std_attrs = NULL_TREE;
5715 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5716 if (c_parser_next_token_is_keyword (parser, RID_CASE)
5717 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5718 || (c_parser_next_token_is (parser, CPP_NAME)
5719 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5721 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5722 label_loc = c_parser_peek_2nd_token (parser)->location;
5724 label_loc = c_parser_peek_token (parser)->location;
5727 mark_valid_location_for_stdc_pragma (false);
5728 c_parser_label (parser, std_attrs);
5730 else if (c_parser_next_tokens_start_declaration (parser)
5732 && c_parser_next_token_is (parser, CPP_SEMICOLON)))
5735 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5736 "a label can only be part of a statement and "
5737 "a declaration is not a statement");
5739 mark_valid_location_for_stdc_pragma (false);
5740 bool fallthru_attr_p = false;
5741 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5742 true, true, true, NULL,
5743 NULL, have_std_attrs, std_attrs,
5744 NULL, &fallthru_attr_p);
5746 if (last_stmt && !fallthru_attr_p)
5747 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5748 "ISO C90 forbids mixed declarations and code");
5749 last_stmt = fallthru_attr_p;
5752 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5754 /* __extension__ can start a declaration, but is also an
5755 unary operator that can start an expression. Consume all
5756 but the last of a possible series of __extension__ to
5757 determine which. If standard attributes have already
5758 been seen, it must start a statement, not a declaration,
5759 but standard attributes starting a declaration may appear
5760 after __extension__. */
5761 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5762 && (c_parser_peek_2nd_token (parser)->keyword
5764 c_parser_consume_token (parser);
5766 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5767 || c_parser_nth_token_starts_std_attributes (parser, 2)))
5770 ext = disable_extension_diagnostics ();
5771 c_parser_consume_token (parser);
5773 mark_valid_location_for_stdc_pragma (false);
5774 c_parser_declaration_or_fndef (parser, true, true, true, true,
5776 /* Following the old parser, __extension__ does not
5777 disable this diagnostic. */
5778 restore_extension_diagnostics (ext);
5780 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5781 "ISO C90 forbids mixed declarations and code");
5787 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5790 c_parser_error (parser, "expected declaration or statement");
5791 /* External pragmas, and some omp pragmas, are not associated
5792 with regular c code, and so are not to be considered statements
5793 syntactically. This ensures that the user doesn't put them
5794 places that would turn into syntax errors if the directive
5796 if (c_parser_pragma (parser,
5797 last_label ? pragma_stmt : pragma_compound,
5799 last_label = false, last_stmt = true;
5801 else if (c_parser_next_token_is (parser, CPP_EOF))
5803 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5804 c_parser_error (parser, "expected declaration or statement");
5805 return c_parser_peek_token (parser)->location;
5807 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5809 if (parser->in_if_block)
5811 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5812 error_at (loc, "expected %<}%> before %<else%>");
5813 return c_parser_peek_token (parser)->location;
5817 error_at (loc, "%<else%> without a previous %<if%>");
5818 c_parser_consume_token (parser);
5825 c_warn_unused_attributes (std_attrs);
5828 mark_valid_location_for_stdc_pragma (false);
5829 c_parser_statement_after_labels (parser, NULL);
5832 parser->error = false;
5835 pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
5836 location_t endloc = c_parser_peek_token (parser)->location;
5837 c_parser_consume_token (parser);
5838 /* Restore the value we started with. */
5839 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5843 /* Parse all consecutive labels, possibly preceded by standard
5844 attributes. In this context, a statement is required, not a
5845 declaration, so attributes must be followed by a statement that is
5846 not just a semicolon. */
5849 c_parser_all_labels (c_parser *parser)
5851 tree std_attrs = NULL;
5852 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5854 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5855 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5856 c_parser_error (parser, "expected statement");
5858 while (c_parser_next_token_is_keyword (parser, RID_CASE)
5859 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5860 || (c_parser_next_token_is (parser, CPP_NAME)
5861 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5863 c_parser_label (parser, std_attrs);
5865 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5867 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5868 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5869 c_parser_error (parser, "expected statement");
5873 c_warn_unused_attributes (std_attrs);
5876 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5879 identifier : gnu-attributes[opt]
5880 case constant-expression :
5886 case constant-expression ... constant-expression :
5888 The use of gnu-attributes on labels is a GNU extension. The syntax in
5889 GNU C accepts any expressions without commas, non-constant
5890 expressions being rejected later. Any standard
5891 attribute-specifier-sequence before the first label has been parsed
5892 in the caller, to distinguish statements from declarations. Any
5893 attribute-specifier-sequence after the label is parsed in this
5896 c_parser_label (c_parser *parser, tree std_attrs)
5898 location_t loc1 = c_parser_peek_token (parser)->location;
5899 tree label = NULL_TREE;
5901 /* Remember whether this case or a user-defined label is allowed to fall
5903 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5905 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5908 c_parser_consume_token (parser);
5909 exp1 = c_parser_expr_no_commas (parser, NULL).value;
5910 if (c_parser_next_token_is (parser, CPP_COLON))
5912 c_parser_consume_token (parser);
5913 label = do_case (loc1, exp1, NULL_TREE);
5915 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5917 c_parser_consume_token (parser);
5918 exp2 = c_parser_expr_no_commas (parser, NULL).value;
5919 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5920 label = do_case (loc1, exp1, exp2);
5923 c_parser_error (parser, "expected %<:%> or %<...%>");
5925 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5927 c_parser_consume_token (parser);
5928 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5929 label = do_case (loc1, NULL_TREE, NULL_TREE);
5933 tree name = c_parser_peek_token (parser)->value;
5936 location_t loc2 = c_parser_peek_token (parser)->location;
5937 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5938 c_parser_consume_token (parser);
5939 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5940 c_parser_consume_token (parser);
5941 attrs = c_parser_gnu_attributes (parser);
5942 tlab = define_label (loc2, name);
5945 decl_attributes (&tlab, attrs, 0);
5946 decl_attributes (&tlab, std_attrs, 0);
5947 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5950 && c_parser_next_tokens_start_declaration (parser))
5951 warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
5952 " label and declaration appertains to the label");
5956 if (TREE_CODE (label) == LABEL_EXPR)
5957 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5959 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5963 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5967 attribute-specifier-sequence[opt] compound-statement
5968 expression-statement
5969 attribute-specifier-sequence[opt] selection-statement
5970 attribute-specifier-sequence[opt] iteration-statement
5971 attribute-specifier-sequence[opt] jump-statement
5974 attribute-specifier-sequence[opt] label statement
5976 expression-statement:
5978 attribute-specifier-sequence expression ;
5980 selection-statement:
5984 iteration-statement:
5993 return expression[opt] ;
5998 attribute-specifier-sequence[opt] asm-statement
6003 expression-statement:
6009 attribute-specifier-sequence[opt] objc-throw-statement
6010 attribute-specifier-sequence[opt] objc-try-catch-statement
6011 attribute-specifier-sequence[opt] objc-synchronized-statement
6013 objc-throw-statement:
6020 attribute-specifier-sequence[opt] openacc-construct
6029 parallel-directive structured-block
6032 kernels-directive structured-block
6035 data-directive structured-block
6038 loop-directive structured-block
6043 attribute-specifier-sequence[opt] openmp-construct
6052 parallel-for-construct
6053 parallel-for-simd-construct
6054 parallel-sections-construct
6061 parallel-directive structured-block
6064 for-directive iteration-statement
6067 simd-directive iteration-statements
6070 for-simd-directive iteration-statements
6073 sections-directive section-scope
6076 single-directive structured-block
6078 parallel-for-construct:
6079 parallel-for-directive iteration-statement
6081 parallel-for-simd-construct:
6082 parallel-for-simd-directive iteration-statement
6084 parallel-sections-construct:
6085 parallel-sections-directive section-scope
6088 master-directive structured-block
6091 critical-directive structured-block
6094 atomic-directive expression-statement
6097 ordered-directive structured-block
6099 Transactional Memory:
6102 attribute-specifier-sequence[opt] transaction-statement
6103 attribute-specifier-sequence[opt] transaction-cancel-statement
6105 IF_P is used to track whether there's a (possibly labeled) if statement
6106 which is not enclosed in braces and has an else clause. This is used to
6107 implement -Wparentheses. */
6110 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6112 c_parser_all_labels (parser);
6113 if (loc_after_labels)
6114 *loc_after_labels = c_parser_peek_token (parser)->location;
6115 c_parser_statement_after_labels (parser, if_p, NULL);
6118 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6119 of if-else-if conditions. All labels and standard attributes have
6120 been parsed in the caller.
6122 IF_P is used to track whether there's a (possibly labeled) if statement
6123 which is not enclosed in braces and has an else clause. This is used to
6124 implement -Wparentheses. */
6127 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6130 location_t loc = c_parser_peek_token (parser)->location;
6131 tree stmt = NULL_TREE;
6132 bool in_if_block = parser->in_if_block;
6133 parser->in_if_block = false;
6137 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6138 add_debug_begin_stmt (loc);
6141 switch (c_parser_peek_token (parser)->type)
6143 case CPP_OPEN_BRACE:
6144 add_stmt (c_parser_compound_statement (parser));
6147 switch (c_parser_peek_token (parser)->keyword)
6150 c_parser_if_statement (parser, if_p, chain);
6153 c_parser_switch_statement (parser, if_p);
6156 c_parser_while_statement (parser, false, 0, if_p);
6159 c_parser_do_statement (parser, false, 0);
6162 c_parser_for_statement (parser, false, 0, if_p);
6165 c_parser_consume_token (parser);
6166 if (c_parser_next_token_is (parser, CPP_NAME))
6168 stmt = c_finish_goto_label (loc,
6169 c_parser_peek_token (parser)->value);
6170 c_parser_consume_token (parser);
6172 else if (c_parser_next_token_is (parser, CPP_MULT))
6176 c_parser_consume_token (parser);
6177 val = c_parser_expression (parser);
6178 val = convert_lvalue_to_rvalue (loc, val, false, true);
6179 stmt = c_finish_goto_ptr (loc, val);
6182 c_parser_error (parser, "expected identifier or %<*%>");
6183 goto expect_semicolon;
6185 c_parser_consume_token (parser);
6186 stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
6187 goto expect_semicolon;
6189 c_parser_consume_token (parser);
6190 stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
6191 goto expect_semicolon;
6193 c_parser_consume_token (parser);
6194 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6196 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6197 c_parser_consume_token (parser);
6201 location_t xloc = c_parser_peek_token (parser)->location;
6202 struct c_expr expr = c_parser_expression_conv (parser);
6203 mark_exp_read (expr.value);
6204 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6205 expr.value, expr.original_type);
6206 goto expect_semicolon;
6210 stmt = c_parser_asm_statement (parser);
6212 case RID_TRANSACTION_ATOMIC:
6213 case RID_TRANSACTION_RELAXED:
6214 stmt = c_parser_transaction (parser,
6215 c_parser_peek_token (parser)->keyword);
6217 case RID_TRANSACTION_CANCEL:
6218 stmt = c_parser_transaction_cancel (parser);
6219 goto expect_semicolon;
6221 gcc_assert (c_dialect_objc ());
6222 c_parser_consume_token (parser);
6223 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6225 stmt = objc_build_throw_stmt (loc, NULL_TREE);
6226 c_parser_consume_token (parser);
6230 struct c_expr expr = c_parser_expression (parser);
6231 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6232 expr.value = c_fully_fold (expr.value, false, NULL);
6233 stmt = objc_build_throw_stmt (loc, expr.value);
6234 goto expect_semicolon;
6238 gcc_assert (c_dialect_objc ());
6239 c_parser_objc_try_catch_finally_statement (parser);
6241 case RID_AT_SYNCHRONIZED:
6242 gcc_assert (c_dialect_objc ());
6243 c_parser_objc_synchronized_statement (parser);
6247 /* Allow '__attribute__((fallthrough));'. */
6248 tree attrs = c_parser_gnu_attributes (parser);
6249 if (attribute_fallthrough_p (attrs))
6251 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6253 tree fn = build_call_expr_internal_loc (loc,
6258 c_parser_consume_token (parser);
6261 warning_at (loc, OPT_Wattributes,
6262 "%<fallthrough%> attribute not followed "
6265 else if (attrs != NULL_TREE)
6266 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
6267 " can be applied to a null statement");
6275 c_parser_consume_token (parser);
6277 case CPP_CLOSE_PAREN:
6278 case CPP_CLOSE_SQUARE:
6279 /* Avoid infinite loop in error recovery:
6280 c_parser_skip_until_found stops at a closing nesting
6281 delimiter without consuming it, but here we need to consume
6282 it to proceed further. */
6283 c_parser_error (parser, "expected statement");
6284 c_parser_consume_token (parser);
6287 if (!c_parser_pragma (parser, pragma_stmt, if_p))
6292 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6294 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6297 /* Two cases cannot and do not have line numbers associated: If stmt
6298 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6299 cannot hold line numbers. But that's OK because the statement
6300 will either be changed to a MODIFY_EXPR during gimplification of
6301 the statement expr, or discarded. If stmt was compound, but
6302 without new variables, we will have skipped the creation of a
6303 BIND and will have a bare STATEMENT_LIST. But that's OK because
6304 (recursively) all of the component statements should already have
6305 line numbers assigned. ??? Can we discard no-op statements
6307 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6308 protected_set_expr_location (stmt, loc);
6310 parser->in_if_block = in_if_block;
6313 /* Parse the condition from an if, do, while or for statements. */
6316 c_parser_condition (c_parser *parser)
6318 location_t loc = c_parser_peek_token (parser)->location;
6320 cond = c_parser_expression_conv (parser).value;
6321 cond = c_objc_common_truthvalue_conversion (loc, cond);
6322 cond = c_fully_fold (cond, false, NULL);
6323 if (warn_sequence_point)
6324 verify_sequence_points (cond);
6328 /* Parse a parenthesized condition from an if, do or while statement.
6334 c_parser_paren_condition (c_parser *parser)
6337 matching_parens parens;
6338 if (!parens.require_open (parser))
6339 return error_mark_node;
6340 cond = c_parser_condition (parser);
6341 parens.skip_until_found_close (parser);
6345 /* Parse a statement which is a block in C99.
6347 IF_P is used to track whether there's a (possibly labeled) if statement
6348 which is not enclosed in braces and has an else clause. This is used to
6349 implement -Wparentheses. */
6352 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6353 location_t *loc_after_labels)
6355 tree block = c_begin_compound_stmt (flag_isoc99);
6356 location_t loc = c_parser_peek_token (parser)->location;
6357 c_parser_statement (parser, if_p, loc_after_labels);
6358 return c_end_compound_stmt (loc, block, flag_isoc99);
6361 /* Parse the body of an if statement. This is just parsing a
6362 statement but (a) it is a block in C99, (b) we track whether the
6363 body is an if statement for the sake of -Wparentheses warnings, (c)
6364 we handle an empty body specially for the sake of -Wempty-body
6365 warnings, and (d) we call parser_compound_statement directly
6366 because c_parser_statement_after_labels resets
6367 parser->in_if_block.
6369 IF_P is used to track whether there's a (possibly labeled) if statement
6370 which is not enclosed in braces and has an else clause. This is used to
6371 implement -Wparentheses. */
6374 c_parser_if_body (c_parser *parser, bool *if_p,
6375 const token_indent_info &if_tinfo)
6377 tree block = c_begin_compound_stmt (flag_isoc99);
6378 location_t body_loc = c_parser_peek_token (parser)->location;
6379 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6380 token_indent_info body_tinfo
6381 = get_token_indent_info (c_parser_peek_token (parser));
6383 c_parser_all_labels (parser);
6384 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6386 location_t loc = c_parser_peek_token (parser)->location;
6387 add_stmt (build_empty_stmt (loc));
6388 c_parser_consume_token (parser);
6389 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6390 warning_at (loc, OPT_Wempty_body,
6391 "suggest braces around empty body in an %<if%> statement");
6393 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6394 add_stmt (c_parser_compound_statement (parser));
6397 body_loc_after_labels = c_parser_peek_token (parser)->location;
6398 c_parser_statement_after_labels (parser, if_p);
6401 token_indent_info next_tinfo
6402 = get_token_indent_info (c_parser_peek_token (parser));
6403 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6404 if (body_loc_after_labels != UNKNOWN_LOCATION
6405 && next_tinfo.type != CPP_SEMICOLON)
6406 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6407 if_tinfo.location, RID_IF);
6409 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6412 /* Parse the else body of an if statement. This is just parsing a
6413 statement but (a) it is a block in C99, (b) we handle an empty body
6414 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6415 of if-else-if conditions. */
6418 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6421 location_t body_loc = c_parser_peek_token (parser)->location;
6422 tree block = c_begin_compound_stmt (flag_isoc99);
6423 token_indent_info body_tinfo
6424 = get_token_indent_info (c_parser_peek_token (parser));
6425 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6427 c_parser_all_labels (parser);
6428 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6430 location_t loc = c_parser_peek_token (parser)->location;
6433 "suggest braces around empty body in an %<else%> statement");
6434 add_stmt (build_empty_stmt (loc));
6435 c_parser_consume_token (parser);
6439 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6440 body_loc_after_labels = c_parser_peek_token (parser)->location;
6441 c_parser_statement_after_labels (parser, NULL, chain);
6444 token_indent_info next_tinfo
6445 = get_token_indent_info (c_parser_peek_token (parser));
6446 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6447 if (body_loc_after_labels != UNKNOWN_LOCATION
6448 && next_tinfo.type != CPP_SEMICOLON)
6449 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6450 else_tinfo.location, RID_ELSE);
6452 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6455 /* We might need to reclassify any previously-lexed identifier, e.g.
6456 when we've left a for loop with an if-statement without else in the
6457 body - we might have used a wrong scope for the token. See PR67784. */
6460 c_parser_maybe_reclassify_token (c_parser *parser)
6462 if (c_parser_next_token_is (parser, CPP_NAME))
6464 c_token *token = c_parser_peek_token (parser);
6466 if (token->id_kind != C_ID_CLASSNAME)
6468 tree decl = lookup_name (token->value);
6470 token->id_kind = C_ID_ID;
6473 if (TREE_CODE (decl) == TYPE_DECL)
6474 token->id_kind = C_ID_TYPENAME;
6476 else if (c_dialect_objc ())
6478 tree objc_interface_decl = objc_is_class_name (token->value);
6479 /* Objective-C class names are in the same namespace as
6480 variables and typedefs, and hence are shadowed by local
6482 if (objc_interface_decl)
6484 token->value = objc_interface_decl;
6485 token->id_kind = C_ID_CLASSNAME;
6492 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6495 if ( expression ) statement
6496 if ( expression ) statement else statement
6498 CHAIN is a vector of if-else-if conditions.
6499 IF_P is used to track whether there's a (possibly labeled) if statement
6500 which is not enclosed in braces and has an else clause. This is used to
6501 implement -Wparentheses. */
6504 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6509 bool nested_if = false;
6510 tree first_body, second_body;
6513 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
6514 token_indent_info if_tinfo
6515 = get_token_indent_info (c_parser_peek_token (parser));
6516 c_parser_consume_token (parser);
6517 block = c_begin_compound_stmt (flag_isoc99);
6518 loc = c_parser_peek_token (parser)->location;
6519 cond = c_parser_paren_condition (parser);
6520 in_if_block = parser->in_if_block;
6521 parser->in_if_block = true;
6522 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
6523 parser->in_if_block = in_if_block;
6525 if (warn_duplicated_cond)
6526 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6528 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6530 token_indent_info else_tinfo
6531 = get_token_indent_info (c_parser_peek_token (parser));
6532 c_parser_consume_token (parser);
6533 if (warn_duplicated_cond)
6535 if (c_parser_next_token_is_keyword (parser, RID_IF)
6538 /* We've got "if (COND) else if (COND2)". Start the
6539 condition chain and add COND as the first element. */
6540 chain = new vec<tree> ();
6541 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6542 chain->safe_push (cond);
6544 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6545 /* This is if-else without subsequent if. Zap the condition
6546 chain; we would have already warned at this point. */
6549 second_body = c_parser_else_body (parser, else_tinfo, chain);
6550 /* Set IF_P to true to indicate that this if statement has an
6551 else clause. This may trigger the Wparentheses warning
6552 below when we get back up to the parent if statement. */
6558 second_body = NULL_TREE;
6560 /* Diagnose an ambiguous else if if-then-else is nested inside
6563 warning_at (loc, OPT_Wdangling_else,
6564 "suggest explicit braces to avoid ambiguous %<else%>");
6566 if (warn_duplicated_cond)
6567 /* This if statement does not have an else clause. We don't
6568 need the condition chain anymore. */
6571 c_finish_if_stmt (loc, cond, first_body, second_body);
6572 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6574 c_parser_maybe_reclassify_token (parser);
6577 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6580 switch (expression) statement
6584 c_parser_switch_statement (c_parser *parser, bool *if_p)
6587 tree block, expr, body;
6588 unsigned char save_in_statement;
6589 location_t switch_loc = c_parser_peek_token (parser)->location;
6590 location_t switch_cond_loc;
6591 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6592 c_parser_consume_token (parser);
6593 block = c_begin_compound_stmt (flag_isoc99);
6594 bool explicit_cast_p = false;
6595 matching_parens parens;
6596 if (parens.require_open (parser))
6598 switch_cond_loc = c_parser_peek_token (parser)->location;
6599 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6600 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6601 explicit_cast_p = true;
6602 ce = c_parser_expression (parser);
6603 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
6605 /* ??? expr has no valid location? */
6606 parens.skip_until_found_close (parser);
6610 switch_cond_loc = UNKNOWN_LOCATION;
6611 expr = error_mark_node;
6612 ce.original_type = error_mark_node;
6614 c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6615 save_in_statement = in_statement;
6616 in_statement |= IN_SWITCH_STMT;
6617 location_t loc_after_labels;
6618 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6619 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6620 location_t next_loc = c_parser_peek_token (parser)->location;
6621 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6622 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6624 c_finish_switch (body, ce.original_type);
6625 in_statement = save_in_statement;
6626 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6627 c_parser_maybe_reclassify_token (parser);
6630 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6633 while (expression) statement
6635 IF_P is used to track whether there's a (possibly labeled) if statement
6636 which is not enclosed in braces and has an else clause. This is used to
6637 implement -Wparentheses. */
6640 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6643 tree block, cond, body;
6644 unsigned char save_in_statement;
6646 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6647 token_indent_info while_tinfo
6648 = get_token_indent_info (c_parser_peek_token (parser));
6649 c_parser_consume_token (parser);
6650 block = c_begin_compound_stmt (flag_isoc99);
6651 loc = c_parser_peek_token (parser)->location;
6652 cond = c_parser_paren_condition (parser);
6653 if (ivdep && cond != error_mark_node)
6654 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6655 build_int_cst (integer_type_node,
6656 annot_expr_ivdep_kind),
6658 if (unroll && cond != error_mark_node)
6659 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6660 build_int_cst (integer_type_node,
6661 annot_expr_unroll_kind),
6662 build_int_cst (integer_type_node, unroll));
6663 save_in_statement = in_statement;
6664 in_statement = IN_ITERATION_STMT;
6666 token_indent_info body_tinfo
6667 = get_token_indent_info (c_parser_peek_token (parser));
6669 location_t loc_after_labels;
6670 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6671 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6672 add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
6673 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6674 c_parser_maybe_reclassify_token (parser);
6676 token_indent_info next_tinfo
6677 = get_token_indent_info (c_parser_peek_token (parser));
6678 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6680 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6681 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6682 while_tinfo.location, RID_WHILE);
6684 in_statement = save_in_statement;
6687 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6690 do statement while ( expression ) ;
6694 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6696 tree block, cond, body;
6697 unsigned char save_in_statement;
6699 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6700 c_parser_consume_token (parser);
6701 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6702 warning_at (c_parser_peek_token (parser)->location,
6704 "suggest braces around empty body in %<do%> statement");
6705 block = c_begin_compound_stmt (flag_isoc99);
6706 loc = c_parser_peek_token (parser)->location;
6707 save_in_statement = in_statement;
6708 in_statement = IN_ITERATION_STMT;
6709 body = c_parser_c99_block_statement (parser, NULL);
6710 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6711 in_statement = save_in_statement;
6712 cond = c_parser_paren_condition (parser);
6713 if (ivdep && cond != error_mark_node)
6714 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6715 build_int_cst (integer_type_node,
6716 annot_expr_ivdep_kind),
6718 if (unroll && cond != error_mark_node)
6719 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6720 build_int_cst (integer_type_node,
6721 annot_expr_unroll_kind),
6722 build_int_cst (integer_type_node, unroll));
6723 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6724 c_parser_skip_to_end_of_block_or_statement (parser);
6726 add_stmt (build_stmt (loc, DO_STMT, cond, body));
6727 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6730 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6733 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6734 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6736 The form with a declaration is new in C99.
6738 ??? In accordance with the old parser, the declaration may be a
6739 nested function, which is then rejected in check_for_loop_decls,
6740 but does it make any sense for this to be included in the grammar?
6741 Note in particular that the nested function does not include a
6742 trailing ';', whereas the "declaration" production includes one.
6743 Also, can we reject bad declarations earlier and cheaper than
6744 check_for_loop_decls?
6746 In Objective-C, there are two additional variants:
6749 for ( expression in expresssion ) statement
6750 for ( declaration in expression ) statement
6752 This is inconsistent with C, because the second variant is allowed
6753 even if c99 is not enabled.
6755 The rest of the comment documents these Objective-C foreach-statement.
6757 Here is the canonical example of the first variant:
6758 for (object in array) { do something with object }
6759 we call the first expression ("object") the "object_expression" and
6760 the second expression ("array") the "collection_expression".
6761 object_expression must be an lvalue of type "id" (a generic Objective-C
6762 object) because the loop works by assigning to object_expression the
6763 various objects from the collection_expression. collection_expression
6764 must evaluate to something of type "id" which responds to the method
6765 countByEnumeratingWithState:objects:count:.
6767 The canonical example of the second variant is:
6768 for (id object in array) { do something with object }
6769 which is completely equivalent to
6772 for (object in array) { do something with object }
6774 Note that initizializing 'object' in some way (eg, "for ((object =
6775 xxx) in array) { do something with object }") is possibly
6776 technically valid, but completely pointless as 'object' will be
6777 assigned to something else as soon as the loop starts. We should
6778 most likely reject it (TODO).
6780 The beginning of the Objective-C foreach-statement looks exactly
6781 like the beginning of the for-statement, and we can tell it is a
6782 foreach-statement only because the initial declaration or
6783 expression is terminated by 'in' instead of ';'.
6785 IF_P is used to track whether there's a (possibly labeled) if statement
6786 which is not enclosed in braces and has an else clause. This is used to
6787 implement -Wparentheses. */
6790 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6793 tree block, cond, incr, body;
6794 unsigned char save_in_statement;
6795 tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
6796 /* The following are only used when parsing an ObjC foreach statement. */
6797 tree object_expression;
6798 /* Silence the bogus uninitialized warning. */
6799 tree collection_expression = NULL;
6800 location_t loc = c_parser_peek_token (parser)->location;
6801 location_t for_loc = loc;
6802 bool is_foreach_statement = false;
6803 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6804 token_indent_info for_tinfo
6805 = get_token_indent_info (c_parser_peek_token (parser));
6806 c_parser_consume_token (parser);
6807 /* Open a compound statement in Objective-C as well, just in case this is
6808 as foreach expression. */
6809 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6810 cond = error_mark_node;
6811 incr = error_mark_node;
6812 matching_parens parens;
6813 if (parens.require_open (parser))
6815 /* Parse the initialization declaration or expression. */
6816 object_expression = error_mark_node;
6817 parser->objc_could_be_foreach_context = c_dialect_objc ();
6818 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6820 parser->objc_could_be_foreach_context = false;
6821 c_parser_consume_token (parser);
6822 c_finish_expr_stmt (loc, NULL_TREE);
6824 else if (c_parser_next_tokens_start_declaration (parser)
6825 || c_parser_nth_token_starts_std_attributes (parser, 1))
6827 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6828 &object_expression);
6829 parser->objc_could_be_foreach_context = false;
6831 if (c_parser_next_token_is_keyword (parser, RID_IN))
6833 c_parser_consume_token (parser);
6834 is_foreach_statement = true;
6835 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6836 c_parser_error (parser, "multiple iterating variables in "
6837 "fast enumeration");
6840 check_for_loop_decls (for_loc, flag_isoc99);
6842 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6844 /* __extension__ can start a declaration, but is also an
6845 unary operator that can start an expression. Consume all
6846 but the last of a possible series of __extension__ to
6848 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6849 && (c_parser_peek_2nd_token (parser)->keyword
6851 c_parser_consume_token (parser);
6852 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6853 || c_parser_nth_token_starts_std_attributes (parser, 2))
6856 ext = disable_extension_diagnostics ();
6857 c_parser_consume_token (parser);
6858 c_parser_declaration_or_fndef (parser, true, true, true, true,
6859 true, &object_expression);
6860 parser->objc_could_be_foreach_context = false;
6862 restore_extension_diagnostics (ext);
6863 if (c_parser_next_token_is_keyword (parser, RID_IN))
6865 c_parser_consume_token (parser);
6866 is_foreach_statement = true;
6867 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6868 c_parser_error (parser, "multiple iterating variables in "
6869 "fast enumeration");
6872 check_for_loop_decls (for_loc, flag_isoc99);
6882 tree init_expression;
6883 ce = c_parser_expression (parser);
6884 init_expression = ce.value;
6885 parser->objc_could_be_foreach_context = false;
6886 if (c_parser_next_token_is_keyword (parser, RID_IN))
6888 c_parser_consume_token (parser);
6889 is_foreach_statement = true;
6890 if (! lvalue_p (init_expression))
6891 c_parser_error (parser, "invalid iterating variable in "
6892 "fast enumeration");
6894 = c_fully_fold (init_expression, false, NULL);
6898 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6899 init_expression = ce.value;
6900 c_finish_expr_stmt (loc, init_expression);
6901 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6906 /* Parse the loop condition. In the case of a foreach
6907 statement, there is no loop condition. */
6908 gcc_assert (!parser->objc_could_be_foreach_context);
6909 if (!is_foreach_statement)
6911 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6915 c_parser_error (parser, "missing loop condition in loop "
6916 "with %<GCC ivdep%> pragma");
6917 cond = error_mark_node;
6921 c_parser_error (parser, "missing loop condition in loop "
6922 "with %<GCC unroll%> pragma");
6923 cond = error_mark_node;
6927 c_parser_consume_token (parser);
6933 cond = c_parser_condition (parser);
6934 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6937 if (ivdep && cond != error_mark_node)
6938 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6939 build_int_cst (integer_type_node,
6940 annot_expr_ivdep_kind),
6942 if (unroll && cond != error_mark_node)
6943 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6944 build_int_cst (integer_type_node,
6945 annot_expr_unroll_kind),
6946 build_int_cst (integer_type_node, unroll));
6948 /* Parse the increment expression (the third expression in a
6949 for-statement). In the case of a foreach-statement, this is
6950 the expression that follows the 'in'. */
6951 loc = c_parser_peek_token (parser)->location;
6952 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6954 if (is_foreach_statement)
6956 c_parser_error (parser,
6957 "missing collection in fast enumeration");
6958 collection_expression = error_mark_node;
6961 incr = c_process_expr_stmt (loc, NULL_TREE);
6965 if (is_foreach_statement)
6966 collection_expression
6967 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
6970 struct c_expr ce = c_parser_expression (parser);
6971 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6972 incr = c_process_expr_stmt (loc, ce.value);
6975 parens.skip_until_found_close (parser);
6977 save_in_statement = in_statement;
6978 if (is_foreach_statement)
6980 in_statement = IN_OBJC_FOREACH;
6981 save_objc_foreach_break_label = objc_foreach_break_label;
6982 save_objc_foreach_continue_label = objc_foreach_continue_label;
6983 objc_foreach_break_label = create_artificial_label (loc);
6984 objc_foreach_continue_label = create_artificial_label (loc);
6987 in_statement = IN_ITERATION_STMT;
6989 token_indent_info body_tinfo
6990 = get_token_indent_info (c_parser_peek_token (parser));
6992 location_t loc_after_labels;
6993 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6994 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6996 if (is_foreach_statement)
6997 objc_finish_foreach_loop (for_loc, object_expression,
6998 collection_expression, body,
6999 objc_foreach_break_label,
7000 objc_foreach_continue_label);
7002 add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
7004 add_stmt (c_end_compound_stmt (for_loc, block,
7005 flag_isoc99 || c_dialect_objc ()));
7006 c_parser_maybe_reclassify_token (parser);
7008 token_indent_info next_tinfo
7009 = get_token_indent_info (c_parser_peek_token (parser));
7010 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
7012 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
7013 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
7014 for_tinfo.location, RID_FOR);
7016 in_statement = save_in_statement;
7017 if (is_foreach_statement)
7019 objc_foreach_break_label = save_objc_foreach_break_label;
7020 objc_foreach_continue_label = save_objc_foreach_continue_label;
7024 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7025 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7034 asm-qualifier-list asm-qualifier
7038 asm asm-qualifier-list[opt] ( asm-argument ) ;
7042 asm-string-literal : asm-operands[opt]
7043 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7044 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7046 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7049 The form with asm-goto-operands is valid if and only if the
7050 asm-qualifier-list contains goto, and is the only allowed form in that case.
7051 Duplicate asm-qualifiers are not allowed.
7053 The :: token is considered equivalent to two consecutive : tokens. */
7056 c_parser_asm_statement (c_parser *parser)
7058 tree str, outputs, inputs, clobbers, labels, ret;
7060 location_t asm_loc = c_parser_peek_token (parser)->location;
7061 int section, nsections;
7063 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7064 c_parser_consume_token (parser);
7066 /* Handle the asm-qualifier-list. */
7067 location_t volatile_loc = UNKNOWN_LOCATION;
7068 location_t inline_loc = UNKNOWN_LOCATION;
7069 location_t goto_loc = UNKNOWN_LOCATION;
7072 c_token *token = c_parser_peek_token (parser);
7073 location_t loc = token->location;
7074 switch (token->keyword)
7079 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7080 inform (volatile_loc, "first seen here");
7084 c_parser_consume_token (parser);
7090 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7091 inform (inline_loc, "first seen here");
7095 c_parser_consume_token (parser);
7101 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7102 inform (goto_loc, "first seen here");
7106 c_parser_consume_token (parser);
7111 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7112 c_parser_consume_token (parser);
7121 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7122 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7123 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7127 matching_parens parens;
7128 if (!parens.require_open (parser))
7131 str = c_parser_asm_string_literal (parser);
7132 if (str == NULL_TREE)
7133 goto error_close_paren;
7136 outputs = NULL_TREE;
7138 clobbers = NULL_TREE;
7141 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7144 /* Parse each colon-delimited section of operands. */
7145 nsections = 3 + is_goto;
7146 for (section = 0; section < nsections; ++section)
7148 if (c_parser_next_token_is (parser, CPP_SCOPE))
7151 if (section == nsections)
7153 c_parser_error (parser, "expected %<)%>");
7154 goto error_close_paren;
7156 c_parser_consume_token (parser);
7158 else if (!c_parser_require (parser, CPP_COLON,
7160 ? G_("expected %<:%>")
7161 : G_("expected %<:%> or %<)%>"),
7162 UNKNOWN_LOCATION, is_goto))
7163 goto error_close_paren;
7165 /* Once past any colon, we're no longer a simple asm. */
7168 if ((!c_parser_next_token_is (parser, CPP_COLON)
7169 && !c_parser_next_token_is (parser, CPP_SCOPE)
7170 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7175 outputs = c_parser_asm_operands (parser);
7178 inputs = c_parser_asm_operands (parser);
7181 clobbers = c_parser_asm_clobbers (parser);
7184 labels = c_parser_asm_goto_operands (parser);
7190 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7195 if (!parens.require_close (parser))
7197 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7201 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7202 c_parser_skip_to_end_of_block_or_statement (parser);
7204 ret = build_asm_stmt (is_volatile,
7205 build_asm_expr (asm_loc, str, outputs, inputs,
7206 clobbers, labels, simple, is_inline));
7212 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7216 /* Parse asm operands, a GNU extension.
7220 asm-operands , asm-operand
7223 asm-string-literal ( expression )
7224 [ identifier ] asm-string-literal ( expression )
7228 c_parser_asm_operands (c_parser *parser)
7230 tree list = NULL_TREE;
7235 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7237 c_parser_consume_token (parser);
7238 if (c_parser_next_token_is (parser, CPP_NAME))
7240 tree id = c_parser_peek_token (parser)->value;
7241 c_parser_consume_token (parser);
7242 name = build_string (IDENTIFIER_LENGTH (id),
7243 IDENTIFIER_POINTER (id));
7247 c_parser_error (parser, "expected identifier");
7248 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7251 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7256 str = c_parser_asm_string_literal (parser);
7257 if (str == NULL_TREE)
7259 matching_parens parens;
7260 if (!parens.require_open (parser))
7262 expr = c_parser_expression (parser);
7263 mark_exp_read (expr.value);
7264 if (!parens.require_close (parser))
7266 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7269 list = chainon (list, build_tree_list (build_tree_list (name, str),
7271 if (c_parser_next_token_is (parser, CPP_COMMA))
7272 c_parser_consume_token (parser);
7279 /* Parse asm clobbers, a GNU extension.
7283 asm-clobbers , asm-string-literal
7287 c_parser_asm_clobbers (c_parser *parser)
7289 tree list = NULL_TREE;
7292 tree str = c_parser_asm_string_literal (parser);
7294 list = tree_cons (NULL_TREE, str, list);
7297 if (c_parser_next_token_is (parser, CPP_COMMA))
7298 c_parser_consume_token (parser);
7305 /* Parse asm goto labels, a GNU extension.
7309 asm-goto-operands , identifier
7313 c_parser_asm_goto_operands (c_parser *parser)
7315 tree list = NULL_TREE;
7320 if (c_parser_next_token_is (parser, CPP_NAME))
7322 c_token *tok = c_parser_peek_token (parser);
7324 label = lookup_label_for_goto (tok->location, name);
7325 c_parser_consume_token (parser);
7326 TREE_USED (label) = 1;
7330 c_parser_error (parser, "expected identifier");
7334 name = build_string (IDENTIFIER_LENGTH (name),
7335 IDENTIFIER_POINTER (name));
7336 list = tree_cons (name, label, list);
7337 if (c_parser_next_token_is (parser, CPP_COMMA))
7338 c_parser_consume_token (parser);
7340 return nreverse (list);
7344 /* Parse a possibly concatenated sequence of string literals.
7345 TRANSLATE says whether to translate them to the execution character
7346 set; WIDE_OK says whether any kind of prefixed string literal is
7347 permitted in this context. This code is based on that in
7351 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7355 struct obstack str_ob;
7356 struct obstack loc_ob;
7357 cpp_string str, istr, *strs;
7359 location_t loc, last_tok_loc;
7360 enum cpp_ttype type;
7361 tree value, string_tree;
7363 tok = c_parser_peek_token (parser);
7364 loc = tok->location;
7365 last_tok_loc = linemap_resolve_location (line_table, loc,
7366 LRK_MACRO_DEFINITION_LOCATION,
7375 case CPP_UTF8STRING:
7376 string_tree = tok->value;
7380 c_parser_error (parser, "expected string literal");
7382 ret.value = NULL_TREE;
7383 ret.original_code = ERROR_MARK;
7384 ret.original_type = NULL_TREE;
7388 /* Try to avoid the overhead of creating and destroying an obstack
7389 for the common case of just one string. */
7390 switch (c_parser_peek_2nd_token (parser)->type)
7393 c_parser_consume_token (parser);
7394 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7395 str.len = TREE_STRING_LENGTH (string_tree);
7404 case CPP_UTF8STRING:
7405 gcc_obstack_init (&str_ob);
7406 gcc_obstack_init (&loc_ob);
7410 c_parser_consume_token (parser);
7412 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7413 str.len = TREE_STRING_LENGTH (string_tree);
7414 if (type != tok->type)
7416 if (type == CPP_STRING)
7418 else if (tok->type != CPP_STRING)
7419 error ("unsupported non-standard concatenation "
7420 "of string literals");
7422 obstack_grow (&str_ob, &str, sizeof (cpp_string));
7423 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7424 tok = c_parser_peek_token (parser);
7425 string_tree = tok->value;
7427 = linemap_resolve_location (line_table, tok->location,
7428 LRK_MACRO_DEFINITION_LOCATION, NULL);
7430 while (tok->type == CPP_STRING
7431 || tok->type == CPP_WSTRING
7432 || tok->type == CPP_STRING16
7433 || tok->type == CPP_STRING32
7434 || tok->type == CPP_UTF8STRING);
7435 strs = (cpp_string *) obstack_finish (&str_ob);
7438 if (count > 1 && !in_system_header_at (input_location))
7439 warning (OPT_Wtraditional,
7440 "traditional C rejects string constant concatenation");
7442 if ((type == CPP_STRING || wide_ok)
7444 ? cpp_interpret_string : cpp_interpret_string_notranslate)
7445 (parse_in, strs, count, &istr, type)))
7447 value = build_string (istr.len, (const char *) istr.text);
7448 free (CONST_CAST (unsigned char *, istr.text));
7451 location_t *locs = (location_t *) obstack_finish (&loc_ob);
7452 gcc_assert (g_string_concat_db);
7453 g_string_concat_db->record_string_concatenation (count, locs);
7458 if (type != CPP_STRING && !wide_ok)
7460 error_at (loc, "a wide string is invalid in this context");
7463 /* Callers cannot generally handle error_mark_node in this
7464 context, so return the empty string instead. An error has
7465 been issued, either above or from cpp_interpret_string. */
7470 case CPP_UTF8STRING:
7471 if (type == CPP_UTF8STRING && flag_char8_t)
7473 value = build_string (TYPE_PRECISION (char8_type_node)
7474 / TYPE_PRECISION (char_type_node),
7475 ""); /* char8_t is 8 bits */
7478 value = build_string (1, "");
7481 value = build_string (TYPE_PRECISION (char16_type_node)
7482 / TYPE_PRECISION (char_type_node),
7483 "\0"); /* char16_t is 16 bits */
7486 value = build_string (TYPE_PRECISION (char32_type_node)
7487 / TYPE_PRECISION (char_type_node),
7488 "\0\0\0"); /* char32_t is 32 bits */
7491 value = build_string (TYPE_PRECISION (wchar_type_node)
7492 / TYPE_PRECISION (char_type_node),
7493 "\0\0\0"); /* widest supported wchar_t
7503 TREE_TYPE (value) = char_array_type_node;
7505 case CPP_UTF8STRING:
7507 TREE_TYPE (value) = char8_array_type_node;
7509 TREE_TYPE (value) = char_array_type_node;
7512 TREE_TYPE (value) = char16_array_type_node;
7515 TREE_TYPE (value) = char32_array_type_node;
7518 TREE_TYPE (value) = wchar_array_type_node;
7520 value = fix_string_type (value);
7524 obstack_free (&str_ob, 0);
7525 obstack_free (&loc_ob, 0);
7529 ret.original_code = STRING_CST;
7530 ret.original_type = NULL_TREE;
7531 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7532 parser->seen_string_literal = true;
7536 /* Parse an expression other than a compound expression; that is, an
7537 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7538 AFTER is not NULL then it is an Objective-C message expression which
7539 is the primary-expression starting the expression as an initializer.
7541 assignment-expression:
7542 conditional-expression
7543 unary-expression assignment-operator assignment-expression
7545 assignment-operator: one of
7546 = *= /= %= += -= <<= >>= &= ^= |=
7548 In GNU C we accept any conditional expression on the LHS and
7549 diagnose the invalid lvalue rather than producing a syntax
7552 static struct c_expr
7553 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7554 tree omp_atomic_lhs)
7556 struct c_expr lhs, rhs, ret;
7557 enum tree_code code;
7558 location_t op_location, exp_location;
7559 bool save_in_omp_for = c_in_omp_for;
7560 c_in_omp_for = false;
7561 gcc_assert (!after || c_dialect_objc ());
7562 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
7563 op_location = c_parser_peek_token (parser)->location;
7564 switch (c_parser_peek_token (parser)->type)
7573 code = TRUNC_DIV_EXPR;
7576 code = TRUNC_MOD_EXPR;
7591 code = BIT_AND_EXPR;
7594 code = BIT_XOR_EXPR;
7597 code = BIT_IOR_EXPR;
7600 c_in_omp_for = save_in_omp_for;
7603 c_parser_consume_token (parser);
7604 exp_location = c_parser_peek_token (parser)->location;
7605 rhs = c_parser_expr_no_commas (parser, NULL);
7606 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
7608 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7609 code, exp_location, rhs.value,
7611 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
7612 if (code == NOP_EXPR)
7613 ret.original_code = MODIFY_EXPR;
7616 suppress_warning (ret.value, OPT_Wparentheses);
7617 ret.original_code = ERROR_MARK;
7619 ret.original_type = NULL;
7620 c_in_omp_for = save_in_omp_for;
7624 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7625 AFTER is not NULL then it is an Objective-C message expression which is
7626 the primary-expression starting the expression as an initializer.
7628 conditional-expression:
7629 logical-OR-expression
7630 logical-OR-expression ? expression : conditional-expression
7634 conditional-expression:
7635 logical-OR-expression ? : conditional-expression
7638 static struct c_expr
7639 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7640 tree omp_atomic_lhs)
7642 struct c_expr cond, exp1, exp2, ret;
7643 location_t start, cond_loc, colon_loc;
7645 gcc_assert (!after || c_dialect_objc ());
7647 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
7649 if (c_parser_next_token_is_not (parser, CPP_QUERY))
7651 if (cond.value != error_mark_node)
7652 start = cond.get_start ();
7654 start = UNKNOWN_LOCATION;
7655 cond_loc = c_parser_peek_token (parser)->location;
7656 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
7657 c_parser_consume_token (parser);
7658 if (c_parser_next_token_is (parser, CPP_COLON))
7660 tree eptype = NULL_TREE;
7662 location_t middle_loc = c_parser_peek_token (parser)->location;
7663 pedwarn (middle_loc, OPT_Wpedantic,
7664 "ISO C forbids omitting the middle term of a %<?:%> expression");
7665 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7667 eptype = TREE_TYPE (cond.value);
7668 cond.value = TREE_OPERAND (cond.value, 0);
7670 tree e = cond.value;
7671 while (TREE_CODE (e) == COMPOUND_EXPR)
7672 e = TREE_OPERAND (e, 1);
7673 warn_for_omitted_condop (middle_loc, e);
7674 /* Make sure first operand is calculated only once. */
7675 exp1.value = save_expr (default_conversion (cond.value));
7677 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7678 exp1.original_type = NULL;
7679 exp1.src_range = cond.src_range;
7680 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7681 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7686 = c_objc_common_truthvalue_conversion
7687 (cond_loc, default_conversion (cond.value));
7688 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7689 exp1 = c_parser_expression_conv (parser);
7690 mark_exp_read (exp1.value);
7691 c_inhibit_evaluation_warnings +=
7692 ((cond.value == truthvalue_true_node)
7693 - (cond.value == truthvalue_false_node));
7696 colon_loc = c_parser_peek_token (parser)->location;
7697 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7699 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7701 ret.original_code = ERROR_MARK;
7702 ret.original_type = NULL;
7706 location_t exp2_loc = c_parser_peek_token (parser)->location;
7707 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7708 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7710 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7711 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7712 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7713 if (UNLIKELY (omp_atomic_lhs != NULL)
7714 && (TREE_CODE (cond.value) == GT_EXPR
7715 || TREE_CODE (cond.value) == LT_EXPR
7716 || TREE_CODE (cond.value) == EQ_EXPR)
7717 && c_tree_equal (exp2.value, omp_atomic_lhs)
7718 && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
7719 || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
7720 ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
7721 cond.value, exp1.value, exp2.value);
7724 = build_conditional_expr (colon_loc, cond.value,
7725 cond.original_code == C_MAYBE_CONST_EXPR,
7726 exp1.value, exp1.original_type, loc1,
7727 exp2.value, exp2.original_type, loc2);
7728 ret.original_code = ERROR_MARK;
7729 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7730 ret.original_type = NULL;
7735 /* If both sides are enum type, the default conversion will have
7736 made the type of the result be an integer type. We want to
7737 remember the enum types we started with. */
7738 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7739 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7740 ret.original_type = ((t1 != error_mark_node
7741 && t2 != error_mark_node
7742 && (TYPE_MAIN_VARIANT (t1)
7743 == TYPE_MAIN_VARIANT (t2)))
7747 set_c_expr_source_range (&ret, start, exp2.get_finish ());
7751 /* Parse a binary expression; that is, a logical-OR-expression (C90
7752 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7753 NULL then it is an Objective-C message expression which is the
7754 primary-expression starting the expression as an initializer.
7756 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7757 when it should be the unfolded lhs. In a valid OpenMP source,
7758 one of the operands of the toplevel binary expression must be equal
7759 to it. In that case, just return a build2 created binary operation
7760 rather than result of parser_build_binary_op.
7762 multiplicative-expression:
7764 multiplicative-expression * cast-expression
7765 multiplicative-expression / cast-expression
7766 multiplicative-expression % cast-expression
7768 additive-expression:
7769 multiplicative-expression
7770 additive-expression + multiplicative-expression
7771 additive-expression - multiplicative-expression
7775 shift-expression << additive-expression
7776 shift-expression >> additive-expression
7778 relational-expression:
7780 relational-expression < shift-expression
7781 relational-expression > shift-expression
7782 relational-expression <= shift-expression
7783 relational-expression >= shift-expression
7785 equality-expression:
7786 relational-expression
7787 equality-expression == relational-expression
7788 equality-expression != relational-expression
7792 AND-expression & equality-expression
7794 exclusive-OR-expression:
7796 exclusive-OR-expression ^ AND-expression
7798 inclusive-OR-expression:
7799 exclusive-OR-expression
7800 inclusive-OR-expression | exclusive-OR-expression
7802 logical-AND-expression:
7803 inclusive-OR-expression
7804 logical-AND-expression && inclusive-OR-expression
7806 logical-OR-expression:
7807 logical-AND-expression
7808 logical-OR-expression || logical-AND-expression
7811 static struct c_expr
7812 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7813 tree omp_atomic_lhs)
7815 /* A binary expression is parsed using operator-precedence parsing,
7816 with the operands being cast expressions. All the binary
7817 operators are left-associative. Thus a binary expression is of
7820 E0 op1 E1 op2 E2 ...
7822 which we represent on a stack. On the stack, the precedence
7823 levels are strictly increasing. When a new operator is
7824 encountered of higher precedence than that at the top of the
7825 stack, it is pushed; its LHS is the top expression, and its RHS
7826 is everything parsed until it is popped. When a new operator is
7827 encountered with precedence less than or equal to that at the top
7828 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7829 by the result of the operation until the operator at the top of
7830 the stack has lower precedence than the new operator or there is
7831 only one element on the stack; then the top expression is the LHS
7832 of the new operator. In the case of logical AND and OR
7833 expressions, we also need to adjust c_inhibit_evaluation_warnings
7834 as appropriate when the operators are pushed and popped. */
7837 /* The expression at this stack level. */
7839 /* The precedence of the operator on its left, PREC_NONE at the
7840 bottom of the stack. */
7841 enum c_parser_prec prec;
7842 /* The operation on its left. */
7844 /* The source location of this operation. */
7846 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
7850 /* Location of the binary operator. */
7851 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
7854 switch (stack[sp].op) \
7856 case TRUTH_ANDIF_EXPR: \
7857 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7858 == truthvalue_false_node); \
7860 case TRUTH_ORIF_EXPR: \
7861 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7862 == truthvalue_true_node); \
7864 case TRUNC_DIV_EXPR: \
7865 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7866 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
7867 && (stack[sp].expr.original_code == SIZEOF_EXPR \
7868 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
7870 tree type0 = stack[sp - 1].sizeof_arg; \
7871 tree type1 = stack[sp].sizeof_arg; \
7872 tree first_arg = type0; \
7873 if (!TYPE_P (type0)) \
7874 type0 = TREE_TYPE (type0); \
7875 if (!TYPE_P (type1)) \
7876 type1 = TREE_TYPE (type1); \
7877 if (POINTER_TYPE_P (type0) \
7878 && comptypes (TREE_TYPE (type0), type1) \
7879 && !(TREE_CODE (first_arg) == PARM_DECL \
7880 && C_ARRAY_PARAMETER (first_arg) \
7881 && warn_sizeof_array_argument)) \
7883 auto_diagnostic_group d; \
7884 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7885 "division %<sizeof (%T) / sizeof (%T)%> " \
7886 "does not compute the number of array " \
7889 if (DECL_P (first_arg)) \
7890 inform (DECL_SOURCE_LOCATION (first_arg), \
7891 "first %<sizeof%> operand was declared here"); \
7893 else if (TREE_CODE (type0) == ARRAY_TYPE \
7894 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
7895 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
7896 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
7897 stack[sp].sizeof_arg, type1); \
7903 stack[sp - 1].expr \
7904 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7905 stack[sp - 1].expr, true, true); \
7907 = convert_lvalue_to_rvalue (stack[sp].loc, \
7908 stack[sp].expr, true, true); \
7909 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
7910 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
7911 && ((1 << stack[sp].prec) \
7912 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
7913 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
7914 | (1 << PREC_ADD) | (1 << PREC_MULT) \
7915 | (1 << PREC_EQ)))) \
7916 || ((c_parser_next_token_is (parser, CPP_QUERY) \
7917 || (omp_atomic_lhs == void_list_node \
7918 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
7919 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
7920 && stack[sp].op != TRUNC_MOD_EXPR \
7921 && stack[sp].op != GE_EXPR \
7922 && stack[sp].op != LE_EXPR \
7923 && stack[sp].op != NE_EXPR \
7924 && stack[0].expr.value != error_mark_node \
7925 && stack[1].expr.value != error_mark_node \
7926 && (omp_atomic_lhs == void_list_node \
7927 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7928 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
7929 || (stack[sp].op == EQ_EXPR \
7930 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
7932 tree t = make_node (stack[1].op); \
7933 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
7934 TREE_OPERAND (t, 0) = stack[0].expr.value; \
7935 TREE_OPERAND (t, 1) = stack[1].expr.value; \
7936 stack[0].expr.value = t; \
7939 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7941 stack[sp - 1].expr, \
7945 gcc_assert (!after || c_dialect_objc ());
7946 stack[0].loc = c_parser_peek_token (parser)->location;
7947 stack[0].expr = c_parser_cast_expression (parser, after);
7948 stack[0].prec = PREC_NONE;
7949 stack[0].sizeof_arg = c_last_sizeof_arg;
7953 enum c_parser_prec oprec;
7954 enum tree_code ocode;
7955 source_range src_range;
7958 switch (c_parser_peek_token (parser)->type)
7966 ocode = TRUNC_DIV_EXPR;
7970 ocode = TRUNC_MOD_EXPR;
7982 ocode = LSHIFT_EXPR;
7986 ocode = RSHIFT_EXPR;
8000 case CPP_GREATER_EQ:
8013 oprec = PREC_BITAND;
8014 ocode = BIT_AND_EXPR;
8017 oprec = PREC_BITXOR;
8018 ocode = BIT_XOR_EXPR;
8022 ocode = BIT_IOR_EXPR;
8025 oprec = PREC_LOGAND;
8026 ocode = TRUTH_ANDIF_EXPR;
8030 ocode = TRUTH_ORIF_EXPR;
8033 /* Not a binary operator, so end of the binary
8037 binary_loc = c_parser_peek_token (parser)->location;
8038 while (oprec <= stack[sp].prec)
8040 c_parser_consume_token (parser);
8043 case TRUTH_ANDIF_EXPR:
8044 src_range = stack[sp].expr.src_range;
8046 = convert_lvalue_to_rvalue (stack[sp].loc,
8047 stack[sp].expr, true, true);
8048 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8049 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8050 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8051 == truthvalue_false_node);
8052 set_c_expr_source_range (&stack[sp].expr, src_range);
8054 case TRUTH_ORIF_EXPR:
8055 src_range = stack[sp].expr.src_range;
8057 = convert_lvalue_to_rvalue (stack[sp].loc,
8058 stack[sp].expr, true, true);
8059 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8060 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8061 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8062 == truthvalue_true_node);
8063 set_c_expr_source_range (&stack[sp].expr, src_range);
8069 stack[sp].loc = binary_loc;
8070 stack[sp].expr = c_parser_cast_expression (parser, NULL);
8071 stack[sp].prec = oprec;
8072 stack[sp].op = ocode;
8073 stack[sp].sizeof_arg = c_last_sizeof_arg;
8078 return stack[0].expr;
8082 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8083 is not NULL then it is an Objective-C message expression which is the
8084 primary-expression starting the expression as an initializer.
8088 ( type-name ) unary-expression
8091 static struct c_expr
8092 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8094 location_t cast_loc = c_parser_peek_token (parser)->location;
8095 gcc_assert (!after || c_dialect_objc ());
8097 return c_parser_postfix_expression_after_primary (parser,
8099 /* If the expression begins with a parenthesized type name, it may
8100 be either a cast or a compound literal; we need to see whether
8101 the next character is '{' to tell the difference. If not, it is
8102 an unary expression. Full detection of unknown typenames here
8103 would require a 3-token lookahead. */
8104 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8105 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8107 struct c_type_name *type_name;
8110 matching_parens parens;
8111 parens.consume_open (parser);
8112 type_name = c_parser_type_name (parser, true);
8113 parens.skip_until_found_close (parser);
8114 if (type_name == NULL)
8117 ret.original_code = ERROR_MARK;
8118 ret.original_type = NULL;
8122 /* Save casted types in the function's used types hash table. */
8123 used_types_insert (type_name->specs->type);
8125 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8126 return c_parser_postfix_expression_after_paren_type (parser, type_name,
8128 if (type_name->specs->alignas_p)
8129 error_at (type_name->specs->locations[cdw_alignas],
8130 "alignment specified for type name in cast");
8132 location_t expr_loc = c_parser_peek_token (parser)->location;
8133 expr = c_parser_cast_expression (parser, NULL);
8134 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8136 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8137 if (ret.value && expr.value)
8138 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8139 ret.original_code = ERROR_MARK;
8140 ret.original_type = NULL;
8144 return c_parser_unary_expression (parser);
8147 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8153 unary-operator cast-expression
8154 sizeof unary-expression
8155 sizeof ( type-name )
8157 unary-operator: one of
8163 __alignof__ unary-expression
8164 __alignof__ ( type-name )
8167 (C11 permits _Alignof with type names only.)
8169 unary-operator: one of
8170 __extension__ __real__ __imag__
8172 Transactional Memory:
8175 transaction-expression
8177 In addition, the GNU syntax treats ++ and -- as unary operators, so
8178 they may be applied to cast expressions with errors for non-lvalues
8181 static struct c_expr
8182 c_parser_unary_expression (c_parser *parser)
8185 struct c_expr ret, op;
8186 location_t op_loc = c_parser_peek_token (parser)->location;
8189 ret.original_code = ERROR_MARK;
8190 ret.original_type = NULL;
8191 switch (c_parser_peek_token (parser)->type)
8194 c_parser_consume_token (parser);
8195 exp_loc = c_parser_peek_token (parser)->location;
8196 op = c_parser_cast_expression (parser, NULL);
8198 op = default_function_array_read_conversion (exp_loc, op);
8199 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8200 case CPP_MINUS_MINUS:
8201 c_parser_consume_token (parser);
8202 exp_loc = c_parser_peek_token (parser)->location;
8203 op = c_parser_cast_expression (parser, NULL);
8205 op = default_function_array_read_conversion (exp_loc, op);
8206 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8208 c_parser_consume_token (parser);
8209 op = c_parser_cast_expression (parser, NULL);
8210 mark_exp_read (op.value);
8211 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8214 c_parser_consume_token (parser);
8215 exp_loc = c_parser_peek_token (parser)->location;
8216 op = c_parser_cast_expression (parser, NULL);
8217 finish = op.get_finish ();
8218 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8219 location_t combined_loc = make_location (op_loc, op_loc, finish);
8220 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8221 ret.src_range.m_start = op_loc;
8222 ret.src_range.m_finish = finish;
8226 if (!c_dialect_objc () && !in_system_header_at (input_location))
8229 "traditional C rejects the unary plus operator");
8230 c_parser_consume_token (parser);
8231 exp_loc = c_parser_peek_token (parser)->location;
8232 op = c_parser_cast_expression (parser, NULL);
8233 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8234 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8236 c_parser_consume_token (parser);
8237 exp_loc = c_parser_peek_token (parser)->location;
8238 op = c_parser_cast_expression (parser, NULL);
8239 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8240 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8242 c_parser_consume_token (parser);
8243 exp_loc = c_parser_peek_token (parser)->location;
8244 op = c_parser_cast_expression (parser, NULL);
8245 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8246 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8248 c_parser_consume_token (parser);
8249 exp_loc = c_parser_peek_token (parser)->location;
8250 op = c_parser_cast_expression (parser, NULL);
8251 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8252 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8254 /* Refer to the address of a label as a pointer. */
8255 c_parser_consume_token (parser);
8256 if (c_parser_next_token_is (parser, CPP_NAME))
8258 ret.value = finish_label_address_expr
8259 (c_parser_peek_token (parser)->value, op_loc);
8260 set_c_expr_source_range (&ret, op_loc,
8261 c_parser_peek_token (parser)->get_finish ());
8262 c_parser_consume_token (parser);
8266 c_parser_error (parser, "expected identifier");
8271 switch (c_parser_peek_token (parser)->keyword)
8274 return c_parser_sizeof_expression (parser);
8276 return c_parser_alignof_expression (parser);
8277 case RID_BUILTIN_HAS_ATTRIBUTE:
8278 return c_parser_has_attribute_expression (parser);
8280 c_parser_consume_token (parser);
8281 ext = disable_extension_diagnostics ();
8282 ret = c_parser_cast_expression (parser, NULL);
8283 restore_extension_diagnostics (ext);
8286 c_parser_consume_token (parser);
8287 exp_loc = c_parser_peek_token (parser)->location;
8288 op = c_parser_cast_expression (parser, NULL);
8289 op = default_function_array_conversion (exp_loc, op);
8290 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8292 c_parser_consume_token (parser);
8293 exp_loc = c_parser_peek_token (parser)->location;
8294 op = c_parser_cast_expression (parser, NULL);
8295 op = default_function_array_conversion (exp_loc, op);
8296 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8297 case RID_TRANSACTION_ATOMIC:
8298 case RID_TRANSACTION_RELAXED:
8299 return c_parser_transaction_expression (parser,
8300 c_parser_peek_token (parser)->keyword);
8302 return c_parser_postfix_expression (parser);
8305 return c_parser_postfix_expression (parser);
8309 /* Parse a sizeof expression. */
8311 static struct c_expr
8312 c_parser_sizeof_expression (c_parser *parser)
8315 struct c_expr result;
8316 location_t expr_loc;
8317 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8320 location_t finish = UNKNOWN_LOCATION;
8322 start = c_parser_peek_token (parser)->location;
8324 c_parser_consume_token (parser);
8325 c_inhibit_evaluation_warnings++;
8327 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8328 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8330 /* Either sizeof ( type-name ) or sizeof unary-expression
8331 starting with a compound literal. */
8332 struct c_type_name *type_name;
8333 matching_parens parens;
8334 parens.consume_open (parser);
8335 expr_loc = c_parser_peek_token (parser)->location;
8336 type_name = c_parser_type_name (parser, true);
8337 parens.skip_until_found_close (parser);
8338 finish = parser->tokens_buf[0].location;
8339 if (type_name == NULL)
8342 c_inhibit_evaluation_warnings--;
8345 ret.original_code = ERROR_MARK;
8346 ret.original_type = NULL;
8349 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8351 expr = c_parser_postfix_expression_after_paren_type (parser,
8354 finish = expr.get_finish ();
8357 /* sizeof ( type-name ). */
8358 if (type_name->specs->alignas_p)
8359 error_at (type_name->specs->locations[cdw_alignas],
8360 "alignment specified for type name in %<sizeof%>");
8361 c_inhibit_evaluation_warnings--;
8363 result = c_expr_sizeof_type (expr_loc, type_name);
8367 expr_loc = c_parser_peek_token (parser)->location;
8368 expr = c_parser_unary_expression (parser);
8369 finish = expr.get_finish ();
8371 c_inhibit_evaluation_warnings--;
8373 mark_exp_read (expr.value);
8374 if (TREE_CODE (expr.value) == COMPONENT_REF
8375 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8376 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8377 result = c_expr_sizeof_expr (expr_loc, expr);
8379 if (finish == UNKNOWN_LOCATION)
8381 set_c_expr_source_range (&result, start, finish);
8385 /* Parse an alignof expression. */
8387 static struct c_expr
8388 c_parser_alignof_expression (c_parser *parser)
8391 location_t start_loc = c_parser_peek_token (parser)->location;
8393 tree alignof_spelling = c_parser_peek_token (parser)->value;
8394 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8395 bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
8397 /* A diagnostic is not required for the use of this identifier in
8398 the implementation namespace; only diagnose it for the C11
8399 spelling because of existing code using the other spellings. */
8403 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8406 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8409 c_parser_consume_token (parser);
8410 c_inhibit_evaluation_warnings++;
8412 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8413 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8415 /* Either __alignof__ ( type-name ) or __alignof__
8416 unary-expression starting with a compound literal. */
8418 struct c_type_name *type_name;
8420 matching_parens parens;
8421 parens.consume_open (parser);
8422 loc = c_parser_peek_token (parser)->location;
8423 type_name = c_parser_type_name (parser, true);
8424 end_loc = c_parser_peek_token (parser)->location;
8425 parens.skip_until_found_close (parser);
8426 if (type_name == NULL)
8429 c_inhibit_evaluation_warnings--;
8432 ret.original_code = ERROR_MARK;
8433 ret.original_type = NULL;
8436 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8438 expr = c_parser_postfix_expression_after_paren_type (parser,
8443 /* alignof ( type-name ). */
8444 if (type_name->specs->alignas_p)
8445 error_at (type_name->specs->locations[cdw_alignas],
8446 "alignment specified for type name in %qE",
8448 c_inhibit_evaluation_warnings--;
8450 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8452 false, is_c11_alignof, 1);
8453 ret.original_code = ERROR_MARK;
8454 ret.original_type = NULL;
8455 set_c_expr_source_range (&ret, start_loc, end_loc);
8461 expr = c_parser_unary_expression (parser);
8462 end_loc = expr.src_range.m_finish;
8464 mark_exp_read (expr.value);
8465 c_inhibit_evaluation_warnings--;
8469 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8471 ret.value = c_alignof_expr (start_loc, expr.value);
8472 ret.original_code = ERROR_MARK;
8473 ret.original_type = NULL;
8474 set_c_expr_source_range (&ret, start_loc, end_loc);
8479 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8482 static struct c_expr
8483 c_parser_has_attribute_expression (c_parser *parser)
8485 gcc_assert (c_parser_next_token_is_keyword (parser,
8486 RID_BUILTIN_HAS_ATTRIBUTE));
8487 location_t start = c_parser_peek_token (parser)->location;
8488 c_parser_consume_token (parser);
8490 c_inhibit_evaluation_warnings++;
8492 matching_parens parens;
8493 if (!parens.require_open (parser))
8495 c_inhibit_evaluation_warnings--;
8498 struct c_expr result;
8499 result.set_error ();
8500 result.original_code = ERROR_MARK;
8501 result.original_type = NULL;
8505 /* Treat the type argument the same way as in typeof for the purposes
8506 of warnings. FIXME: Generalize this so the warning refers to
8507 __builtin_has_attribute rather than typeof. */
8510 /* The first operand: one of DECL, EXPR, or TYPE. */
8511 tree oper = NULL_TREE;
8512 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8514 struct c_type_name *tname = c_parser_type_name (parser);
8518 oper = groktypename (tname, NULL, NULL);
8519 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8524 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8525 c_inhibit_evaluation_warnings--;
8527 if (cexpr.value != error_mark_node)
8529 mark_exp_read (cexpr.value);
8531 tree etype = TREE_TYPE (oper);
8532 bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8533 /* This is returned with the type so that when the type is
8534 evaluated, this can be evaluated. */
8536 oper = c_fully_fold (oper, false, NULL);
8537 pop_maybe_used (was_vm);
8541 struct c_expr result;
8542 result.original_code = ERROR_MARK;
8543 result.original_type = NULL;
8545 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8547 /* Consume the closing parenthesis if that's the next token
8548 in the likely case the built-in was invoked with fewer
8549 than two arguments. */
8550 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8551 c_parser_consume_token (parser);
8552 c_inhibit_evaluation_warnings--;
8553 result.set_error ();
8557 bool save_translate_strings_p = parser->translate_strings_p;
8559 location_t atloc = c_parser_peek_token (parser)->location;
8560 /* Parse a single attribute. Require no leading comma and do not
8561 allow empty attributes. */
8562 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
8564 parser->translate_strings_p = save_translate_strings_p;
8566 location_t finish = c_parser_peek_token (parser)->location;
8567 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8568 c_parser_consume_token (parser);
8571 c_parser_error (parser, "expected identifier");
8572 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8574 result.set_error ();
8580 error_at (atloc, "expected identifier");
8581 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8583 result.set_error ();
8587 result.original_code = INTEGER_CST;
8588 result.original_type = boolean_type_node;
8590 if (has_attribute (atloc, oper, attr, default_conversion))
8591 result.value = boolean_true_node;
8593 result.value = boolean_false_node;
8595 set_c_expr_source_range (&result, start, finish);
8599 /* Helper function to read arguments of builtins which are interfaces
8600 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8601 others. The name of the builtin is passed using BNAME parameter.
8602 Function returns true if there were no errors while parsing and
8603 stores the arguments in CEXPR_LIST. If it returns true,
8604 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8607 c_parser_get_builtin_args (c_parser *parser, const char *bname,
8608 vec<c_expr_t, va_gc> **ret_cexpr_list,
8610 location_t *out_close_paren_loc)
8612 location_t loc = c_parser_peek_token (parser)->location;
8613 vec<c_expr_t, va_gc> *cexpr_list;
8615 bool saved_force_folding_builtin_constant_p;
8617 *ret_cexpr_list = NULL;
8618 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8620 error_at (loc, "cannot take address of %qs", bname);
8624 c_parser_consume_token (parser);
8626 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8628 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8629 c_parser_consume_token (parser);
8633 saved_force_folding_builtin_constant_p
8634 = force_folding_builtin_constant_p;
8635 force_folding_builtin_constant_p |= choose_expr_p;
8636 expr = c_parser_expr_no_commas (parser, NULL);
8637 force_folding_builtin_constant_p
8638 = saved_force_folding_builtin_constant_p;
8639 vec_alloc (cexpr_list, 1);
8640 vec_safe_push (cexpr_list, expr);
8641 while (c_parser_next_token_is (parser, CPP_COMMA))
8643 c_parser_consume_token (parser);
8644 expr = c_parser_expr_no_commas (parser, NULL);
8645 vec_safe_push (cexpr_list, expr);
8648 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8649 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8652 *ret_cexpr_list = cexpr_list;
8656 /* This represents a single generic-association. */
8658 struct c_generic_association
8660 /* The location of the starting token of the type. */
8661 location_t type_location;
8662 /* The association's type, or NULL_TREE for 'default'. */
8664 /* The association's expression. */
8665 struct c_expr expression;
8668 /* Parse a generic-selection. (C11 6.5.1.1).
8671 _Generic ( assignment-expression , generic-assoc-list )
8675 generic-assoc-list , generic-association
8677 generic-association:
8678 type-name : assignment-expression
8679 default : assignment-expression
8682 static struct c_expr
8683 c_parser_generic_selection (c_parser *parser)
8685 struct c_expr selector, error_expr;
8687 struct c_generic_association matched_assoc;
8688 int match_found = -1;
8689 location_t generic_loc, selector_loc;
8691 error_expr.original_code = ERROR_MARK;
8692 error_expr.original_type = NULL;
8693 error_expr.set_error ();
8694 matched_assoc.type_location = UNKNOWN_LOCATION;
8695 matched_assoc.type = NULL_TREE;
8696 matched_assoc.expression = error_expr;
8698 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8699 generic_loc = c_parser_peek_token (parser)->location;
8700 c_parser_consume_token (parser);
8702 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8703 "ISO C99 does not support %<_Generic%>");
8705 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8706 "ISO C90 does not support %<_Generic%>");
8708 matching_parens parens;
8709 if (!parens.require_open (parser))
8712 c_inhibit_evaluation_warnings++;
8713 selector_loc = c_parser_peek_token (parser)->location;
8714 selector = c_parser_expr_no_commas (parser, NULL);
8715 selector = default_function_array_conversion (selector_loc, selector);
8716 c_inhibit_evaluation_warnings--;
8718 if (selector.value == error_mark_node)
8720 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8723 mark_exp_read (selector.value);
8724 selector_type = TREE_TYPE (selector.value);
8725 /* In ISO C terms, rvalues (including the controlling expression of
8726 _Generic) do not have qualified types. */
8727 if (TREE_CODE (selector_type) != ARRAY_TYPE)
8728 selector_type = TYPE_MAIN_VARIANT (selector_type);
8729 /* In ISO C terms, _Noreturn is not part of the type of expressions
8730 such as &abort, but in GCC it is represented internally as a type
8732 if (FUNCTION_POINTER_TYPE_P (selector_type)
8733 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8735 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8737 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8739 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8743 auto_vec<c_generic_association> associations;
8746 struct c_generic_association assoc, *iter;
8748 c_token *token = c_parser_peek_token (parser);
8750 assoc.type_location = token->location;
8751 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8753 c_parser_consume_token (parser);
8754 assoc.type = NULL_TREE;
8758 struct c_type_name *type_name;
8760 type_name = c_parser_type_name (parser);
8761 if (type_name == NULL)
8763 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8766 assoc.type = groktypename (type_name, NULL, NULL);
8767 if (assoc.type == error_mark_node)
8769 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8773 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8774 error_at (assoc.type_location,
8775 "%<_Generic%> association has function type");
8776 else if (!COMPLETE_TYPE_P (assoc.type))
8777 error_at (assoc.type_location,
8778 "%<_Generic%> association has incomplete type");
8780 if (variably_modified_type_p (assoc.type, NULL_TREE))
8781 error_at (assoc.type_location,
8782 "%<_Generic%> association has "
8783 "variable length type");
8786 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8788 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8792 assoc.expression = c_parser_expr_no_commas (parser, NULL);
8793 if (assoc.expression.value == error_mark_node)
8795 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8799 for (ix = 0; associations.iterate (ix, &iter); ++ix)
8801 if (assoc.type == NULL_TREE)
8803 if (iter->type == NULL_TREE)
8805 error_at (assoc.type_location,
8806 "duplicate %<default%> case in %<_Generic%>");
8807 inform (iter->type_location, "original %<default%> is here");
8810 else if (iter->type != NULL_TREE)
8812 if (comptypes (assoc.type, iter->type))
8814 error_at (assoc.type_location,
8815 "%<_Generic%> specifies two compatible types");
8816 inform (iter->type_location, "compatible type is here");
8821 if (assoc.type == NULL_TREE)
8823 if (match_found < 0)
8825 matched_assoc = assoc;
8826 match_found = associations.length ();
8829 else if (comptypes (assoc.type, selector_type))
8831 if (match_found < 0 || matched_assoc.type == NULL_TREE)
8833 matched_assoc = assoc;
8834 match_found = associations.length ();
8838 error_at (assoc.type_location,
8839 "%<_Generic%> selector matches multiple associations");
8840 inform (matched_assoc.type_location,
8841 "other match is here");
8845 associations.safe_push (assoc);
8847 if (c_parser_peek_token (parser)->type != CPP_COMMA)
8849 c_parser_consume_token (parser);
8853 struct c_generic_association *iter;
8854 FOR_EACH_VEC_ELT (associations, ix, iter)
8855 if (ix != (unsigned) match_found)
8856 mark_exp_read (iter->expression.value);
8858 if (!parens.require_close (parser))
8860 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8864 if (match_found < 0)
8866 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8867 "compatible with any association",
8872 return matched_assoc.expression;
8875 /* Check the validity of a function pointer argument *EXPR (argument
8876 position POS) to __builtin_tgmath. Return the number of function
8877 arguments if possibly valid; return 0 having reported an error if
8881 check_tgmath_function (c_expr *expr, unsigned int pos)
8883 tree type = TREE_TYPE (expr->value);
8884 if (!FUNCTION_POINTER_TYPE_P (type))
8886 error_at (expr->get_location (),
8887 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8891 type = TREE_TYPE (type);
8892 if (!prototype_p (type))
8894 error_at (expr->get_location (),
8895 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8898 if (stdarg_p (type))
8900 error_at (expr->get_location (),
8901 "argument %u of %<__builtin_tgmath%> has variable arguments",
8905 unsigned int nargs = 0;
8906 function_args_iterator iter;
8908 FOREACH_FUNCTION_ARGS (type, t, iter)
8910 if (t == void_type_node)
8916 error_at (expr->get_location (),
8917 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
8923 /* Ways in which a parameter or return value of a type-generic macro
8924 may vary between the different functions the macro may call. */
8925 enum tgmath_parm_kind
8927 tgmath_fixed, tgmath_real, tgmath_complex
8930 /* Helper function for c_parser_postfix_expression. Parse predefined
8933 static struct c_expr
8934 c_parser_predefined_identifier (c_parser *parser)
8936 location_t loc = c_parser_peek_token (parser)->location;
8937 switch (c_parser_peek_token (parser)->keyword)
8939 case RID_FUNCTION_NAME:
8940 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8941 "identifier", "__FUNCTION__");
8943 case RID_PRETTY_FUNCTION_NAME:
8944 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8945 "identifier", "__PRETTY_FUNCTION__");
8947 case RID_C99_FUNCTION_NAME:
8948 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8949 "%<__func__%> predefined identifier");
8956 expr.original_code = ERROR_MARK;
8957 expr.original_type = NULL;
8958 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8959 c_parser_peek_token (parser)->value);
8960 set_c_expr_source_range (&expr, loc, loc);
8961 c_parser_consume_token (parser);
8965 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8966 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8967 call c_parser_postfix_expression_after_paren_type on encountering them.
8971 postfix-expression [ expression ]
8972 postfix-expression ( argument-expression-list[opt] )
8973 postfix-expression . identifier
8974 postfix-expression -> identifier
8975 postfix-expression ++
8976 postfix-expression --
8977 ( type-name ) { initializer-list }
8978 ( type-name ) { initializer-list , }
8980 argument-expression-list:
8982 argument-expression-list , argument-expression
8995 (treated as a keyword in GNU C)
8998 ( compound-statement )
8999 __builtin_va_arg ( assignment-expression , type-name )
9000 __builtin_offsetof ( type-name , offsetof-member-designator )
9001 __builtin_choose_expr ( assignment-expression ,
9002 assignment-expression ,
9003 assignment-expression )
9004 __builtin_types_compatible_p ( type-name , type-name )
9005 __builtin_tgmath ( expr-list )
9006 __builtin_complex ( assignment-expression , assignment-expression )
9007 __builtin_shuffle ( assignment-expression , assignment-expression )
9008 __builtin_shuffle ( assignment-expression ,
9009 assignment-expression ,
9010 assignment-expression, )
9011 __builtin_convertvector ( assignment-expression , type-name )
9012 __builtin_assoc_barrier ( assignment-expression )
9014 offsetof-member-designator:
9016 offsetof-member-designator . identifier
9017 offsetof-member-designator [ expression ]
9022 [ objc-receiver objc-message-args ]
9023 @selector ( objc-selector-arg )
9024 @protocol ( identifier )
9025 @encode ( type-name )
9027 Classname . identifier
9030 static struct c_expr
9031 c_parser_postfix_expression (c_parser *parser)
9033 struct c_expr expr, e1;
9034 struct c_type_name *t1, *t2;
9035 location_t loc = c_parser_peek_token (parser)->location;
9036 source_range tok_range = c_parser_peek_token (parser)->get_range ();
9037 expr.original_code = ERROR_MARK;
9038 expr.original_type = NULL;
9039 switch (c_parser_peek_token (parser)->type)
9042 expr.value = c_parser_peek_token (parser)->value;
9043 set_c_expr_source_range (&expr, tok_range);
9044 loc = c_parser_peek_token (parser)->location;
9045 c_parser_consume_token (parser);
9046 if (TREE_CODE (expr.value) == FIXED_CST
9047 && !targetm.fixed_point_supported_p ())
9049 error_at (loc, "fixed-point types not supported for this target");
9058 expr.value = c_parser_peek_token (parser)->value;
9059 /* For the purpose of warning when a pointer is compared with
9060 a zero character constant. */
9061 expr.original_type = char_type_node;
9062 set_c_expr_source_range (&expr, tok_range);
9063 c_parser_consume_token (parser);
9069 case CPP_UTF8STRING:
9070 expr = c_parser_string_literal (parser, parser->translate_strings_p,
9073 case CPP_OBJC_STRING:
9074 gcc_assert (c_dialect_objc ());
9076 = objc_build_string_object (c_parser_peek_token (parser)->value);
9077 set_c_expr_source_range (&expr, tok_range);
9078 c_parser_consume_token (parser);
9081 switch (c_parser_peek_token (parser)->id_kind)
9085 tree id = c_parser_peek_token (parser)->value;
9086 c_parser_consume_token (parser);
9087 expr.value = build_external_ref (loc, id,
9088 (c_parser_peek_token (parser)->type
9090 &expr.original_type);
9091 set_c_expr_source_range (&expr, tok_range);
9094 case C_ID_CLASSNAME:
9096 /* Here we parse the Objective-C 2.0 Class.name dot
9098 tree class_name = c_parser_peek_token (parser)->value;
9100 c_parser_consume_token (parser);
9101 gcc_assert (c_dialect_objc ());
9102 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9107 if (c_parser_next_token_is_not (parser, CPP_NAME))
9109 c_parser_error (parser, "expected identifier");
9113 c_token *component_tok = c_parser_peek_token (parser);
9114 component = component_tok->value;
9115 location_t end_loc = component_tok->get_finish ();
9116 c_parser_consume_token (parser);
9117 expr.value = objc_build_class_component_ref (class_name,
9119 set_c_expr_source_range (&expr, loc, end_loc);
9123 c_parser_error (parser, "expected expression");
9128 case CPP_OPEN_PAREN:
9129 /* A parenthesized expression, statement expression or compound
9131 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9133 /* A statement expression. */
9135 location_t brace_loc;
9136 c_parser_consume_token (parser);
9137 brace_loc = c_parser_peek_token (parser)->location;
9138 c_parser_consume_token (parser);
9139 /* If we've not yet started the current function's statement list,
9140 or we're in the parameter scope of an old-style function
9141 declaration, statement expressions are not allowed. */
9142 if (!building_stmt_list_p () || old_style_parameter_scope ())
9144 error_at (loc, "braced-group within expression allowed "
9145 "only inside a function");
9146 parser->error = true;
9147 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9148 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9152 stmt = c_begin_stmt_expr ();
9153 c_parser_compound_statement_nostart (parser);
9154 location_t close_loc = c_parser_peek_token (parser)->location;
9155 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9157 pedwarn (loc, OPT_Wpedantic,
9158 "ISO C forbids braced-groups within expressions");
9159 expr.value = c_finish_stmt_expr (brace_loc, stmt);
9160 set_c_expr_source_range (&expr, loc, close_loc);
9161 mark_exp_read (expr.value);
9165 /* A parenthesized expression. */
9166 location_t loc_open_paren = c_parser_peek_token (parser)->location;
9167 c_parser_consume_token (parser);
9168 expr = c_parser_expression (parser);
9169 if (TREE_CODE (expr.value) == MODIFY_EXPR)
9170 suppress_warning (expr.value, OPT_Wparentheses);
9171 if (expr.original_code != C_MAYBE_CONST_EXPR
9172 && expr.original_code != SIZEOF_EXPR)
9173 expr.original_code = ERROR_MARK;
9174 /* Remember that we saw ( ) around the sizeof. */
9175 if (expr.original_code == SIZEOF_EXPR)
9176 expr.original_code = PAREN_SIZEOF_EXPR;
9177 /* Don't change EXPR.ORIGINAL_TYPE. */
9178 location_t loc_close_paren = c_parser_peek_token (parser)->location;
9179 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9180 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9181 "expected %<)%>", loc_open_paren);
9185 switch (c_parser_peek_token (parser)->keyword)
9187 case RID_FUNCTION_NAME:
9188 case RID_PRETTY_FUNCTION_NAME:
9189 case RID_C99_FUNCTION_NAME:
9190 expr = c_parser_predefined_identifier (parser);
9194 location_t start_loc = loc;
9195 c_parser_consume_token (parser);
9196 matching_parens parens;
9197 if (!parens.require_open (parser))
9202 e1 = c_parser_expr_no_commas (parser, NULL);
9203 mark_exp_read (e1.value);
9204 e1.value = c_fully_fold (e1.value, false, NULL);
9205 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9207 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9211 loc = c_parser_peek_token (parser)->location;
9212 t1 = c_parser_type_name (parser);
9213 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9214 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9222 tree type_expr = NULL_TREE;
9223 expr.value = c_build_va_arg (start_loc, e1.value, loc,
9224 groktypename (t1, &type_expr, NULL));
9227 expr.value = build2 (C_MAYBE_CONST_EXPR,
9228 TREE_TYPE (expr.value), type_expr,
9230 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9232 set_c_expr_source_range (&expr, start_loc, end_loc);
9238 c_parser_consume_token (parser);
9239 matching_parens parens;
9240 if (!parens.require_open (parser))
9245 t1 = c_parser_type_name (parser);
9247 parser->error = true;
9248 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9249 gcc_assert (parser->error);
9252 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9256 tree type = groktypename (t1, NULL, NULL);
9258 if (type == error_mark_node)
9259 offsetof_ref = error_mark_node;
9262 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9263 SET_EXPR_LOCATION (offsetof_ref, loc);
9265 /* Parse the second argument to __builtin_offsetof. We
9266 must have one identifier, and beyond that we want to
9267 accept sub structure and sub array references. */
9268 if (c_parser_next_token_is (parser, CPP_NAME))
9270 c_token *comp_tok = c_parser_peek_token (parser);
9272 = build_component_ref (loc, offsetof_ref, comp_tok->value,
9273 comp_tok->location, UNKNOWN_LOCATION);
9274 c_parser_consume_token (parser);
9275 while (c_parser_next_token_is (parser, CPP_DOT)
9276 || c_parser_next_token_is (parser,
9278 || c_parser_next_token_is (parser,
9281 if (c_parser_next_token_is (parser, CPP_DEREF))
9283 loc = c_parser_peek_token (parser)->location;
9284 offsetof_ref = build_array_ref (loc,
9289 else if (c_parser_next_token_is (parser, CPP_DOT))
9292 c_parser_consume_token (parser);
9293 if (c_parser_next_token_is_not (parser,
9296 c_parser_error (parser, "expected identifier");
9299 c_token *comp_tok = c_parser_peek_token (parser);
9301 = build_component_ref (loc, offsetof_ref,
9305 c_parser_consume_token (parser);
9311 loc = c_parser_peek_token (parser)->location;
9312 c_parser_consume_token (parser);
9313 ce = c_parser_expression (parser);
9314 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9316 idx = c_fully_fold (idx, false, NULL);
9317 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9319 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9324 c_parser_error (parser, "expected identifier");
9325 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9326 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9328 expr.value = fold_offsetof (offsetof_ref);
9329 set_c_expr_source_range (&expr, loc, end_loc);
9332 case RID_CHOOSE_EXPR:
9334 vec<c_expr_t, va_gc> *cexpr_list;
9335 c_expr_t *e1_p, *e2_p, *e3_p;
9337 location_t close_paren_loc;
9339 c_parser_consume_token (parser);
9340 if (!c_parser_get_builtin_args (parser,
9341 "__builtin_choose_expr",
9349 if (vec_safe_length (cexpr_list) != 3)
9351 error_at (loc, "wrong number of arguments to "
9352 "%<__builtin_choose_expr%>");
9357 e1_p = &(*cexpr_list)[0];
9358 e2_p = &(*cexpr_list)[1];
9359 e3_p = &(*cexpr_list)[2];
9362 mark_exp_read (e2_p->value);
9363 mark_exp_read (e3_p->value);
9364 if (TREE_CODE (c) != INTEGER_CST
9365 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9367 "first argument to %<__builtin_choose_expr%> not"
9369 constant_expression_warning (c);
9370 expr = integer_zerop (c) ? *e3_p : *e2_p;
9371 set_c_expr_source_range (&expr, loc, close_paren_loc);
9374 case RID_TYPES_COMPATIBLE_P:
9376 c_parser_consume_token (parser);
9377 matching_parens parens;
9378 if (!parens.require_open (parser))
9383 t1 = c_parser_type_name (parser);
9389 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9391 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9395 t2 = c_parser_type_name (parser);
9401 location_t close_paren_loc = c_parser_peek_token (parser)->location;
9402 parens.skip_until_found_close (parser);
9404 e1 = groktypename (t1, NULL, NULL);
9405 e2 = groktypename (t2, NULL, NULL);
9406 if (e1 == error_mark_node || e2 == error_mark_node)
9412 e1 = TYPE_MAIN_VARIANT (e1);
9413 e2 = TYPE_MAIN_VARIANT (e2);
9416 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9417 set_c_expr_source_range (&expr, loc, close_paren_loc);
9420 case RID_BUILTIN_TGMATH:
9422 vec<c_expr_t, va_gc> *cexpr_list;
9423 location_t close_paren_loc;
9425 c_parser_consume_token (parser);
9426 if (!c_parser_get_builtin_args (parser,
9435 if (vec_safe_length (cexpr_list) < 3)
9437 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9444 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9445 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9446 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9452 if (vec_safe_length (cexpr_list) < nargs)
9454 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9458 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9459 if (num_functions < 2)
9461 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9466 /* The first NUM_FUNCTIONS expressions are the function
9467 pointers. The remaining NARGS expressions are the
9468 arguments that are to be passed to one of those
9469 functions, chosen following <tgmath.h> rules. */
9470 for (unsigned int j = 1; j < num_functions; j++)
9472 unsigned int this_nargs
9473 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9474 if (this_nargs == 0)
9479 if (this_nargs != nargs)
9481 error_at ((*cexpr_list)[j].get_location (),
9482 "argument %u of %<__builtin_tgmath%> has "
9483 "wrong number of arguments", j + 1);
9489 /* The functions all have the same number of arguments.
9490 Determine whether arguments and return types vary in
9491 ways permitted for <tgmath.h> functions. */
9492 /* The first entry in each of these vectors is for the
9493 return type, subsequent entries for parameter
9495 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9496 auto_vec<tree> parm_first (nargs + 1);
9497 auto_vec<bool> parm_complex (nargs + 1);
9498 auto_vec<bool> parm_varies (nargs + 1);
9499 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9500 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9501 parm_first.quick_push (first_ret);
9502 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9503 parm_varies.quick_push (false);
9504 function_args_iterator iter;
9506 unsigned int argpos;
9507 FOREACH_FUNCTION_ARGS (first_type, t, iter)
9509 if (t == void_type_node)
9511 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9512 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9513 parm_varies.quick_push (false);
9515 for (unsigned int j = 1; j < num_functions; j++)
9517 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9518 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9519 if (ret != parm_first[0])
9521 parm_varies[0] = true;
9522 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9523 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9525 error_at ((*cexpr_list)[0].get_location (),
9526 "invalid type-generic return type for "
9527 "argument %u of %<__builtin_tgmath%>",
9532 if (!SCALAR_FLOAT_TYPE_P (ret)
9533 && !COMPLEX_FLOAT_TYPE_P (ret))
9535 error_at ((*cexpr_list)[j].get_location (),
9536 "invalid type-generic return type for "
9537 "argument %u of %<__builtin_tgmath%>",
9543 if (TREE_CODE (ret) == COMPLEX_TYPE)
9544 parm_complex[0] = true;
9546 FOREACH_FUNCTION_ARGS (type, t, iter)
9548 if (t == void_type_node)
9550 t = TYPE_MAIN_VARIANT (t);
9551 if (t != parm_first[argpos])
9553 parm_varies[argpos] = true;
9554 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9555 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9557 error_at ((*cexpr_list)[0].get_location (),
9558 "invalid type-generic type for "
9559 "argument %u of argument %u of "
9560 "%<__builtin_tgmath%>", argpos, 1);
9564 if (!SCALAR_FLOAT_TYPE_P (t)
9565 && !COMPLEX_FLOAT_TYPE_P (t))
9567 error_at ((*cexpr_list)[j].get_location (),
9568 "invalid type-generic type for "
9569 "argument %u of argument %u of "
9570 "%<__builtin_tgmath%>", argpos, j + 1);
9575 if (TREE_CODE (t) == COMPLEX_TYPE)
9576 parm_complex[argpos] = true;
9580 enum tgmath_parm_kind max_variation = tgmath_fixed;
9581 for (unsigned int j = 0; j <= nargs; j++)
9583 enum tgmath_parm_kind this_kind;
9586 if (parm_complex[j])
9587 max_variation = this_kind = tgmath_complex;
9590 this_kind = tgmath_real;
9591 if (max_variation != tgmath_complex)
9592 max_variation = tgmath_real;
9596 this_kind = tgmath_fixed;
9597 parm_kind.quick_push (this_kind);
9599 if (max_variation == tgmath_fixed)
9601 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9602 "all have the same type");
9607 /* Identify a parameter (not the return type) that varies,
9608 including with complex types if any variation includes
9609 complex types; there must be at least one such
9611 unsigned int tgarg = 0;
9612 for (unsigned int j = 1; j <= nargs; j++)
9613 if (parm_kind[j] == max_variation)
9620 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9621 "lack type-generic parameter");
9626 /* Determine the type of the relevant parameter for each
9628 auto_vec<tree> tg_type (num_functions);
9629 for (unsigned int j = 0; j < num_functions; j++)
9631 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9633 FOREACH_FUNCTION_ARGS (type, t, iter)
9635 if (argpos == tgarg)
9637 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9644 /* Verify that the corresponding types are different for
9645 all the listed functions. Also determine whether all
9646 the types are complex, whether all the types are
9647 standard or binary, and whether all the types are
9649 bool all_complex = true;
9650 bool all_binary = true;
9651 bool all_decimal = true;
9652 hash_set<tree> tg_types;
9653 FOR_EACH_VEC_ELT (tg_type, i, t)
9655 if (TREE_CODE (t) == COMPLEX_TYPE)
9656 all_decimal = false;
9659 all_complex = false;
9660 if (DECIMAL_FLOAT_TYPE_P (t))
9663 all_decimal = false;
9665 if (tg_types.add (t))
9667 error_at ((*cexpr_list)[i].get_location (),
9668 "duplicate type-generic parameter type for "
9669 "function argument %u of %<__builtin_tgmath%>",
9676 /* Verify that other parameters and the return type whose
9677 types vary have their types varying in the correct
9679 for (unsigned int j = 0; j < num_functions; j++)
9681 tree exp_type = tg_type[j];
9682 tree exp_real_type = exp_type;
9683 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9684 exp_real_type = TREE_TYPE (exp_type);
9685 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9686 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9687 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9688 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9690 error_at ((*cexpr_list)[j].get_location (),
9691 "bad return type for function argument %u "
9692 "of %<__builtin_tgmath%>", j + 1);
9697 FOREACH_FUNCTION_ARGS (type, t, iter)
9699 if (t == void_type_node)
9701 t = TYPE_MAIN_VARIANT (t);
9702 if ((parm_kind[argpos] == tgmath_complex
9704 || (parm_kind[argpos] == tgmath_real
9705 && t != exp_real_type))
9707 error_at ((*cexpr_list)[j].get_location (),
9708 "bad type for argument %u of "
9709 "function argument %u of "
9710 "%<__builtin_tgmath%>", argpos, j + 1);
9718 /* The functions listed are a valid set of functions for a
9719 <tgmath.h> macro to select between. Identify the
9720 matching function, if any. First, the argument types
9721 must be combined following <tgmath.h> rules. Integer
9722 types are treated as _Decimal64 if any type-generic
9723 argument is decimal, or if the only alternatives for
9724 type-generic arguments are of decimal types, and are
9725 otherwise treated as double (or _Complex double for
9726 complex integer types, or _Float64 or _Complex _Float64
9727 if all the return types are the same _FloatN or
9728 _FloatNx type). After that adjustment, types are
9729 combined following the usual arithmetic conversions.
9730 If the function only accepts complex arguments, a
9731 complex type is produced. */
9732 bool arg_complex = all_complex;
9733 bool arg_binary = all_binary;
9734 bool arg_int_decimal = all_decimal;
9735 for (unsigned int j = 1; j <= nargs; j++)
9737 if (parm_kind[j] == tgmath_fixed)
9739 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9740 tree type = TREE_TYPE (ce->value);
9741 if (!INTEGRAL_TYPE_P (type)
9742 && !SCALAR_FLOAT_TYPE_P (type)
9743 && TREE_CODE (type) != COMPLEX_TYPE)
9745 error_at (ce->get_location (),
9746 "invalid type of argument %u of type-generic "
9751 if (DECIMAL_FLOAT_TYPE_P (type))
9753 arg_int_decimal = true;
9756 error_at (ce->get_location (),
9757 "decimal floating-point argument %u to "
9758 "complex-only type-generic function", j);
9762 else if (all_binary)
9764 error_at (ce->get_location (),
9765 "decimal floating-point argument %u to "
9766 "binary-only type-generic function", j);
9770 else if (arg_complex)
9772 error_at (ce->get_location (),
9773 "both complex and decimal floating-point "
9774 "arguments to type-generic function");
9778 else if (arg_binary)
9780 error_at (ce->get_location (),
9781 "both binary and decimal floating-point "
9782 "arguments to type-generic function");
9787 else if (TREE_CODE (type) == COMPLEX_TYPE)
9790 if (COMPLEX_FLOAT_TYPE_P (type))
9794 error_at (ce->get_location (),
9795 "complex argument %u to "
9796 "decimal-only type-generic function", j);
9800 else if (arg_int_decimal)
9802 error_at (ce->get_location (),
9803 "both complex and decimal floating-point "
9804 "arguments to type-generic function");
9809 else if (SCALAR_FLOAT_TYPE_P (type))
9814 error_at (ce->get_location (),
9815 "binary argument %u to "
9816 "decimal-only type-generic function", j);
9820 else if (arg_int_decimal)
9822 error_at (ce->get_location (),
9823 "both binary and decimal floating-point "
9824 "arguments to type-generic function");
9830 /* For a macro rounding its result to a narrower type, map
9831 integer types to _Float64 not double if the return type
9832 is a _FloatN or _FloatNx type. */
9833 bool arg_int_float64 = false;
9834 if (parm_kind[0] == tgmath_fixed
9835 && SCALAR_FLOAT_TYPE_P (parm_first[0])
9836 && float64_type_node != NULL_TREE)
9837 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9838 if (parm_first[0] == FLOATN_TYPE_NODE (j))
9840 arg_int_float64 = true;
9843 tree arg_real = NULL_TREE;
9844 for (unsigned int j = 1; j <= nargs; j++)
9846 if (parm_kind[j] == tgmath_fixed)
9848 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9849 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9850 if (TREE_CODE (type) == COMPLEX_TYPE)
9851 type = TREE_TYPE (type);
9852 if (INTEGRAL_TYPE_P (type))
9853 type = (arg_int_decimal
9854 ? dfloat64_type_node
9857 : double_type_node);
9858 if (arg_real == NULL_TREE)
9861 arg_real = common_type (arg_real, type);
9862 if (arg_real == error_mark_node)
9868 tree arg_type = (arg_complex
9869 ? build_complex_type (arg_real)
9872 /* Look for a function to call with type-generic parameter
9874 c_expr_t *fn = NULL;
9875 for (unsigned int j = 0; j < num_functions; j++)
9877 if (tg_type[j] == arg_type)
9879 fn = &(*cexpr_list)[j];
9884 && parm_kind[0] == tgmath_fixed
9885 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
9887 /* Presume this is a macro that rounds its result to a
9888 narrower type, and look for the first function with
9889 at least the range and precision of the argument
9891 for (unsigned int j = 0; j < num_functions; j++)
9894 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9896 tree real_tg_type = (arg_complex
9897 ? TREE_TYPE (tg_type[j])
9899 if (DECIMAL_FLOAT_TYPE_P (arg_real)
9900 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
9902 scalar_float_mode arg_mode
9903 = SCALAR_FLOAT_TYPE_MODE (arg_real);
9904 scalar_float_mode tg_mode
9905 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9906 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9907 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9908 if (arg_fmt->b == tg_fmt->b
9909 && arg_fmt->p <= tg_fmt->p
9910 && arg_fmt->emax <= tg_fmt->emax
9911 && (arg_fmt->emin - arg_fmt->p
9912 >= tg_fmt->emin - tg_fmt->p))
9914 fn = &(*cexpr_list)[j];
9921 error_at (loc, "no matching function for type-generic call");
9926 /* Construct a call to FN. */
9927 vec<tree, va_gc> *args;
9928 vec_alloc (args, nargs);
9929 vec<tree, va_gc> *origtypes;
9930 vec_alloc (origtypes, nargs);
9931 auto_vec<location_t> arg_loc (nargs);
9932 for (unsigned int j = 0; j < nargs; j++)
9934 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9935 args->quick_push (ce->value);
9936 arg_loc.quick_push (ce->get_location ());
9937 origtypes->quick_push (ce->original_type);
9939 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9941 set_c_expr_source_range (&expr, loc, close_paren_loc);
9944 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9946 vec<c_expr_t, va_gc> *cexpr_list;
9949 location_t close_paren_loc;
9951 c_parser_consume_token (parser);
9952 if (!c_parser_get_builtin_args (parser,
9953 "__builtin_call_with_static_chain",
9960 if (vec_safe_length (cexpr_list) != 2)
9962 error_at (loc, "wrong number of arguments to "
9963 "%<__builtin_call_with_static_chain%>");
9968 expr = (*cexpr_list)[0];
9969 e2_p = &(*cexpr_list)[1];
9970 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9971 chain_value = e2_p->value;
9972 mark_exp_read (chain_value);
9974 if (TREE_CODE (expr.value) != CALL_EXPR)
9975 error_at (loc, "first argument to "
9976 "%<__builtin_call_with_static_chain%> "
9977 "must be a call expression");
9978 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9979 error_at (loc, "second argument to "
9980 "%<__builtin_call_with_static_chain%> "
9981 "must be a pointer type");
9983 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
9984 set_c_expr_source_range (&expr, loc, close_paren_loc);
9987 case RID_BUILTIN_COMPLEX:
9989 vec<c_expr_t, va_gc> *cexpr_list;
9990 c_expr_t *e1_p, *e2_p;
9991 location_t close_paren_loc;
9993 c_parser_consume_token (parser);
9994 if (!c_parser_get_builtin_args (parser,
9995 "__builtin_complex",
10003 if (vec_safe_length (cexpr_list) != 2)
10005 error_at (loc, "wrong number of arguments to "
10006 "%<__builtin_complex%>");
10011 e1_p = &(*cexpr_list)[0];
10012 e2_p = &(*cexpr_list)[1];
10014 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
10015 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
10016 e1_p->value = convert (TREE_TYPE (e1_p->value),
10017 TREE_OPERAND (e1_p->value, 0));
10018 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
10019 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
10020 e2_p->value = convert (TREE_TYPE (e2_p->value),
10021 TREE_OPERAND (e2_p->value, 0));
10022 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
10023 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
10024 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
10025 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
10027 error_at (loc, "%<__builtin_complex%> operand "
10028 "not of real binary floating-point type");
10032 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
10033 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
10036 "%<__builtin_complex%> operands of different types");
10040 pedwarn_c90 (loc, OPT_Wpedantic,
10041 "ISO C90 does not support complex types");
10042 expr.value = build2_loc (loc, COMPLEX_EXPR,
10045 (TREE_TYPE (e1_p->value))),
10046 e1_p->value, e2_p->value);
10047 set_c_expr_source_range (&expr, loc, close_paren_loc);
10050 case RID_BUILTIN_SHUFFLE:
10052 vec<c_expr_t, va_gc> *cexpr_list;
10055 location_t close_paren_loc;
10057 c_parser_consume_token (parser);
10058 if (!c_parser_get_builtin_args (parser,
10059 "__builtin_shuffle",
10060 &cexpr_list, false,
10067 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10068 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10070 if (vec_safe_length (cexpr_list) == 2)
10071 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10073 (*cexpr_list)[1].value);
10075 else if (vec_safe_length (cexpr_list) == 3)
10076 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10077 (*cexpr_list)[1].value,
10078 (*cexpr_list)[2].value);
10081 error_at (loc, "wrong number of arguments to "
10082 "%<__builtin_shuffle%>");
10085 set_c_expr_source_range (&expr, loc, close_paren_loc);
10088 case RID_BUILTIN_SHUFFLEVECTOR:
10090 vec<c_expr_t, va_gc> *cexpr_list;
10093 location_t close_paren_loc;
10095 c_parser_consume_token (parser);
10096 if (!c_parser_get_builtin_args (parser,
10097 "__builtin_shufflevector",
10098 &cexpr_list, false,
10105 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10106 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10108 if (vec_safe_length (cexpr_list) < 3)
10110 error_at (loc, "wrong number of arguments to "
10111 "%<__builtin_shuffle%>");
10116 auto_vec<tree, 16> mask;
10117 for (i = 2; i < cexpr_list->length (); ++i)
10118 mask.safe_push ((*cexpr_list)[i].value);
10119 expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
10120 (*cexpr_list)[1].value,
10123 set_c_expr_source_range (&expr, loc, close_paren_loc);
10126 case RID_BUILTIN_CONVERTVECTOR:
10128 location_t start_loc = loc;
10129 c_parser_consume_token (parser);
10130 matching_parens parens;
10131 if (!parens.require_open (parser))
10136 e1 = c_parser_expr_no_commas (parser, NULL);
10137 mark_exp_read (e1.value);
10138 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10140 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10144 loc = c_parser_peek_token (parser)->location;
10145 t1 = c_parser_type_name (parser);
10146 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10147 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10153 tree type_expr = NULL_TREE;
10154 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10155 groktypename (t1, &type_expr,
10157 set_c_expr_source_range (&expr, start_loc, end_loc);
10161 case RID_BUILTIN_ASSOC_BARRIER:
10163 location_t start_loc = loc;
10164 c_parser_consume_token (parser);
10165 matching_parens parens;
10166 if (!parens.require_open (parser))
10171 e1 = c_parser_expr_no_commas (parser, NULL);
10172 mark_exp_read (e1.value);
10173 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10174 parens.skip_until_found_close (parser);
10175 expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
10176 set_c_expr_source_range (&expr, start_loc, end_loc);
10179 case RID_AT_SELECTOR:
10181 gcc_assert (c_dialect_objc ());
10182 c_parser_consume_token (parser);
10183 matching_parens parens;
10184 if (!parens.require_open (parser))
10189 tree sel = c_parser_objc_selector_arg (parser);
10190 location_t close_loc = c_parser_peek_token (parser)->location;
10191 parens.skip_until_found_close (parser);
10192 expr.value = objc_build_selector_expr (loc, sel);
10193 set_c_expr_source_range (&expr, loc, close_loc);
10196 case RID_AT_PROTOCOL:
10198 gcc_assert (c_dialect_objc ());
10199 c_parser_consume_token (parser);
10200 matching_parens parens;
10201 if (!parens.require_open (parser))
10206 if (c_parser_next_token_is_not (parser, CPP_NAME))
10208 c_parser_error (parser, "expected identifier");
10209 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10213 tree id = c_parser_peek_token (parser)->value;
10214 c_parser_consume_token (parser);
10215 location_t close_loc = c_parser_peek_token (parser)->location;
10216 parens.skip_until_found_close (parser);
10217 expr.value = objc_build_protocol_expr (id);
10218 set_c_expr_source_range (&expr, loc, close_loc);
10221 case RID_AT_ENCODE:
10223 /* Extension to support C-structures in the archiver. */
10224 gcc_assert (c_dialect_objc ());
10225 c_parser_consume_token (parser);
10226 matching_parens parens;
10227 if (!parens.require_open (parser))
10232 t1 = c_parser_type_name (parser);
10236 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10239 location_t close_loc = c_parser_peek_token (parser)->location;
10240 parens.skip_until_found_close (parser);
10241 tree type = groktypename (t1, NULL, NULL);
10242 expr.value = objc_build_encode_expr (type);
10243 set_c_expr_source_range (&expr, loc, close_loc);
10247 expr = c_parser_generic_selection (parser);
10249 case RID_OMP_ALL_MEMORY:
10250 gcc_assert (flag_openmp);
10251 c_parser_consume_token (parser);
10252 error_at (loc, "%<omp_all_memory%> may only be used in OpenMP "
10253 "%<depend%> clause");
10257 c_parser_error (parser, "expected expression");
10262 case CPP_OPEN_SQUARE:
10263 if (c_dialect_objc ())
10265 tree receiver, args;
10266 c_parser_consume_token (parser);
10267 receiver = c_parser_objc_receiver (parser);
10268 args = c_parser_objc_message_args (parser);
10269 location_t close_loc = c_parser_peek_token (parser)->location;
10270 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10272 expr.value = objc_build_message_expr (receiver, args);
10273 set_c_expr_source_range (&expr, loc, close_loc);
10276 /* Else fall through to report error. */
10279 c_parser_error (parser, "expected expression");
10284 return c_parser_postfix_expression_after_primary
10285 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10288 /* Parse a postfix expression after a parenthesized type name: the
10289 brace-enclosed initializer of a compound literal, possibly followed
10290 by some postfix operators. This is separate because it is not
10291 possible to tell until after the type name whether a cast
10292 expression has a cast or a compound literal, or whether the operand
10293 of sizeof is a parenthesized type name or starts with a compound
10294 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10295 location of the first token after the parentheses around the type
10298 static struct c_expr
10299 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10300 struct c_type_name *type_name,
10301 location_t type_loc)
10304 struct c_expr init;
10306 struct c_expr expr;
10307 location_t start_loc;
10308 tree type_expr = NULL_TREE;
10309 bool type_expr_const = true;
10310 check_compound_literal_type (type_loc, type_name);
10311 rich_location richloc (line_table, type_loc);
10312 start_init (NULL_TREE, NULL, 0, &richloc);
10313 type = groktypename (type_name, &type_expr, &type_expr_const);
10314 start_loc = c_parser_peek_token (parser)->location;
10315 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10317 error_at (type_loc, "compound literal has variable size");
10318 type = error_mark_node;
10320 init = c_parser_braced_init (parser, type, false, NULL, NULL_TREE);
10322 maybe_warn_string_init (type_loc, type, init);
10324 if (type != error_mark_node
10325 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10326 && current_function_decl)
10328 error ("compound literal qualified by address-space qualifier");
10329 type = error_mark_node;
10332 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
10333 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10334 ? CONSTRUCTOR_NON_CONST (init.value)
10335 : init.original_code == C_MAYBE_CONST_EXPR);
10336 non_const |= !type_expr_const;
10337 unsigned int alignas_align = 0;
10338 if (type != error_mark_node
10339 && type_name->specs->align_log != -1)
10341 alignas_align = 1U << type_name->specs->align_log;
10342 if (alignas_align < min_align_of_type (type))
10344 error_at (type_name->specs->locations[cdw_alignas],
10345 "%<_Alignas%> specifiers cannot reduce "
10346 "alignment of compound literal");
10350 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10352 set_c_expr_source_range (&expr, init.src_range);
10353 expr.original_code = ERROR_MARK;
10354 expr.original_type = NULL;
10355 if (type != error_mark_node
10356 && expr.value != error_mark_node
10359 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10361 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10362 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10366 gcc_assert (!non_const);
10367 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10368 type_expr, expr.value);
10371 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
10374 /* Callback function for sizeof_pointer_memaccess_warning to compare
10378 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10380 return comptypes (type1, type2) == 1;
10383 /* Warn for patterns where abs-like function appears to be used incorrectly,
10384 gracefully ignore any non-abs-like function. The warning location should
10385 be LOC. FNDECL is the declaration of called function, it must be a
10386 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10390 warn_for_abs (location_t loc, tree fndecl, tree arg)
10392 /* Avoid warning in unreachable subexpressions. */
10393 if (c_inhibit_evaluation_warnings)
10396 tree atype = TREE_TYPE (arg);
10398 /* Casts from pointers (and thus arrays and fndecls) will generate
10399 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10400 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10401 types and possibly other exotic types. */
10402 if (!INTEGRAL_TYPE_P (atype)
10403 && !SCALAR_FLOAT_TYPE_P (atype)
10404 && TREE_CODE (atype) != COMPLEX_TYPE)
10407 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10412 case BUILT_IN_LABS:
10413 case BUILT_IN_LLABS:
10414 case BUILT_IN_IMAXABS:
10415 if (!INTEGRAL_TYPE_P (atype))
10417 if (SCALAR_FLOAT_TYPE_P (atype))
10418 warning_at (loc, OPT_Wabsolute_value,
10419 "using integer absolute value function %qD when "
10420 "argument is of floating-point type %qT",
10422 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10423 warning_at (loc, OPT_Wabsolute_value,
10424 "using integer absolute value function %qD when "
10425 "argument is of complex type %qT", fndecl, atype);
10427 gcc_unreachable ();
10430 if (TYPE_UNSIGNED (atype))
10431 warning_at (loc, OPT_Wabsolute_value,
10432 "taking the absolute value of unsigned type %qT "
10433 "has no effect", atype);
10436 CASE_FLT_FN (BUILT_IN_FABS):
10437 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10438 if (!SCALAR_FLOAT_TYPE_P (atype)
10439 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10441 if (INTEGRAL_TYPE_P (atype))
10442 warning_at (loc, OPT_Wabsolute_value,
10443 "using floating-point absolute value function %qD "
10444 "when argument is of integer type %qT", fndecl, atype);
10445 else if (DECIMAL_FLOAT_TYPE_P (atype))
10446 warning_at (loc, OPT_Wabsolute_value,
10447 "using floating-point absolute value function %qD "
10448 "when argument is of decimal floating-point type %qT",
10450 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10451 warning_at (loc, OPT_Wabsolute_value,
10452 "using floating-point absolute value function %qD when "
10453 "argument is of complex type %qT", fndecl, atype);
10455 gcc_unreachable ();
10460 CASE_FLT_FN (BUILT_IN_CABS):
10461 if (TREE_CODE (atype) != COMPLEX_TYPE)
10463 if (INTEGRAL_TYPE_P (atype))
10464 warning_at (loc, OPT_Wabsolute_value,
10465 "using complex absolute value function %qD when "
10466 "argument is of integer type %qT", fndecl, atype);
10467 else if (SCALAR_FLOAT_TYPE_P (atype))
10468 warning_at (loc, OPT_Wabsolute_value,
10469 "using complex absolute value function %qD when "
10470 "argument is of floating-point type %qT",
10473 gcc_unreachable ();
10479 case BUILT_IN_FABSD32:
10480 case BUILT_IN_FABSD64:
10481 case BUILT_IN_FABSD128:
10482 if (!DECIMAL_FLOAT_TYPE_P (atype))
10484 if (INTEGRAL_TYPE_P (atype))
10485 warning_at (loc, OPT_Wabsolute_value,
10486 "using decimal floating-point absolute value "
10487 "function %qD when argument is of integer type %qT",
10489 else if (SCALAR_FLOAT_TYPE_P (atype))
10490 warning_at (loc, OPT_Wabsolute_value,
10491 "using decimal floating-point absolute value "
10492 "function %qD when argument is of floating-point "
10493 "type %qT", fndecl, atype);
10494 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10495 warning_at (loc, OPT_Wabsolute_value,
10496 "using decimal floating-point absolute value "
10497 "function %qD when argument is of complex type %qT",
10500 gcc_unreachable ();
10509 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10512 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10513 if (TREE_CODE (atype) == COMPLEX_TYPE)
10515 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10516 atype = TREE_TYPE (atype);
10517 ftype = TREE_TYPE (ftype);
10520 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10521 warning_at (loc, OPT_Wabsolute_value,
10522 "absolute value function %qD given an argument of type %qT "
10523 "but has parameter of type %qT which may cause truncation "
10524 "of value", fndecl, atype, ftype);
10528 /* Parse a postfix expression after the initial primary or compound
10529 literal; that is, parse a series of postfix operators.
10531 EXPR_LOC is the location of the primary expression. */
10533 static struct c_expr
10534 c_parser_postfix_expression_after_primary (c_parser *parser,
10535 location_t expr_loc,
10536 struct c_expr expr)
10538 struct c_expr orig_expr;
10540 location_t sizeof_arg_loc[3], comp_loc;
10541 tree sizeof_arg[3];
10542 unsigned int literal_zero_mask;
10544 vec<tree, va_gc> *exprlist;
10545 vec<tree, va_gc> *origtypes = NULL;
10546 vec<location_t> arg_loc = vNULL;
10552 location_t op_loc = c_parser_peek_token (parser)->location;
10553 switch (c_parser_peek_token (parser)->type)
10555 case CPP_OPEN_SQUARE:
10556 /* Array reference. */
10557 c_parser_consume_token (parser);
10558 idx = c_parser_expression (parser).value;
10559 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10561 start = expr.get_start ();
10562 finish = parser->tokens_buf[0].location;
10563 expr.value = build_array_ref (op_loc, expr.value, idx);
10564 set_c_expr_source_range (&expr, start, finish);
10565 expr.original_code = ERROR_MARK;
10566 expr.original_type = NULL;
10568 case CPP_OPEN_PAREN:
10569 /* Function call. */
10571 matching_parens parens;
10572 parens.consume_open (parser);
10573 for (i = 0; i < 3; i++)
10575 sizeof_arg[i] = NULL_TREE;
10576 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10578 literal_zero_mask = 0;
10579 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10582 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
10583 sizeof_arg_loc, sizeof_arg,
10584 &arg_loc, &literal_zero_mask);
10585 parens.skip_until_found_close (parser);
10588 mark_exp_read (expr.value);
10589 if (warn_sizeof_pointer_memaccess)
10590 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
10591 expr.value, exprlist,
10593 sizeof_ptr_memacc_comptypes);
10594 if (TREE_CODE (expr.value) == FUNCTION_DECL)
10596 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10597 && vec_safe_length (exprlist) == 3)
10599 tree arg0 = (*exprlist)[0];
10600 tree arg2 = (*exprlist)[2];
10601 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10603 if (warn_absolute_value
10604 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10605 && vec_safe_length (exprlist) == 1)
10606 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
10609 start = expr.get_start ();
10610 finish = parser->tokens_buf[0].get_finish ();
10612 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10613 exprlist, origtypes);
10614 set_c_expr_source_range (&expr, start, finish);
10616 expr.original_code = ERROR_MARK;
10617 if (TREE_CODE (expr.value) == INTEGER_CST
10618 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
10619 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
10620 expr.original_code = C_MAYBE_CONST_EXPR;
10621 expr.original_type = NULL;
10624 release_tree_vector (exprlist);
10625 release_tree_vector (origtypes);
10627 arg_loc.release ();
10630 /* Structure element reference. */
10631 c_parser_consume_token (parser);
10632 expr = default_function_array_conversion (expr_loc, expr);
10633 if (c_parser_next_token_is (parser, CPP_NAME))
10635 c_token *comp_tok = c_parser_peek_token (parser);
10636 ident = comp_tok->value;
10637 comp_loc = comp_tok->location;
10641 c_parser_error (parser, "expected identifier");
10643 expr.original_code = ERROR_MARK;
10644 expr.original_type = NULL;
10647 start = expr.get_start ();
10648 finish = c_parser_peek_token (parser)->get_finish ();
10649 c_parser_consume_token (parser);
10650 expr.value = build_component_ref (op_loc, expr.value, ident,
10651 comp_loc, UNKNOWN_LOCATION);
10652 set_c_expr_source_range (&expr, start, finish);
10653 expr.original_code = ERROR_MARK;
10654 if (TREE_CODE (expr.value) != COMPONENT_REF)
10655 expr.original_type = NULL;
10658 /* Remember the original type of a bitfield. */
10659 tree field = TREE_OPERAND (expr.value, 1);
10660 if (TREE_CODE (field) != FIELD_DECL)
10661 expr.original_type = NULL;
10663 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10667 /* Structure element reference. */
10668 c_parser_consume_token (parser);
10669 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
10670 if (c_parser_next_token_is (parser, CPP_NAME))
10672 c_token *comp_tok = c_parser_peek_token (parser);
10673 ident = comp_tok->value;
10674 comp_loc = comp_tok->location;
10678 c_parser_error (parser, "expected identifier");
10680 expr.original_code = ERROR_MARK;
10681 expr.original_type = NULL;
10684 start = expr.get_start ();
10685 finish = c_parser_peek_token (parser)->get_finish ();
10686 c_parser_consume_token (parser);
10687 expr.value = build_component_ref (op_loc,
10688 build_indirect_ref (op_loc,
10692 expr.get_location ());
10693 set_c_expr_source_range (&expr, start, finish);
10694 expr.original_code = ERROR_MARK;
10695 if (TREE_CODE (expr.value) != COMPONENT_REF)
10696 expr.original_type = NULL;
10699 /* Remember the original type of a bitfield. */
10700 tree field = TREE_OPERAND (expr.value, 1);
10701 if (TREE_CODE (field) != FIELD_DECL)
10702 expr.original_type = NULL;
10704 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10707 case CPP_PLUS_PLUS:
10708 /* Postincrement. */
10709 start = expr.get_start ();
10710 finish = c_parser_peek_token (parser)->get_finish ();
10711 c_parser_consume_token (parser);
10712 expr = default_function_array_read_conversion (expr_loc, expr);
10713 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10714 expr.value, false);
10715 set_c_expr_source_range (&expr, start, finish);
10716 expr.original_code = ERROR_MARK;
10717 expr.original_type = NULL;
10719 case CPP_MINUS_MINUS:
10720 /* Postdecrement. */
10721 start = expr.get_start ();
10722 finish = c_parser_peek_token (parser)->get_finish ();
10723 c_parser_consume_token (parser);
10724 expr = default_function_array_read_conversion (expr_loc, expr);
10725 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10726 expr.value, false);
10727 set_c_expr_source_range (&expr, start, finish);
10728 expr.original_code = ERROR_MARK;
10729 expr.original_type = NULL;
10737 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10740 assignment-expression
10741 expression , assignment-expression
10744 static struct c_expr
10745 c_parser_expression (c_parser *parser)
10747 location_t tloc = c_parser_peek_token (parser)->location;
10748 struct c_expr expr;
10749 expr = c_parser_expr_no_commas (parser, NULL);
10750 if (c_parser_next_token_is (parser, CPP_COMMA))
10751 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
10752 while (c_parser_next_token_is (parser, CPP_COMMA))
10754 struct c_expr next;
10756 location_t loc = c_parser_peek_token (parser)->location;
10757 location_t expr_loc;
10758 c_parser_consume_token (parser);
10759 expr_loc = c_parser_peek_token (parser)->location;
10760 lhsval = expr.value;
10761 while (TREE_CODE (lhsval) == COMPOUND_EXPR
10762 || TREE_CODE (lhsval) == NOP_EXPR)
10764 if (TREE_CODE (lhsval) == COMPOUND_EXPR)
10765 lhsval = TREE_OPERAND (lhsval, 1);
10767 lhsval = TREE_OPERAND (lhsval, 0);
10769 if (DECL_P (lhsval) || handled_component_p (lhsval))
10770 mark_exp_read (lhsval);
10771 next = c_parser_expr_no_commas (parser, NULL);
10772 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
10773 expr.value = build_compound_expr (loc, expr.value, next.value);
10774 expr.original_code = COMPOUND_EXPR;
10775 expr.original_type = next.original_type;
10780 /* Parse an expression and convert functions or arrays to pointers and
10781 lvalues to rvalues. */
10783 static struct c_expr
10784 c_parser_expression_conv (c_parser *parser)
10786 struct c_expr expr;
10787 location_t loc = c_parser_peek_token (parser)->location;
10788 expr = c_parser_expression (parser);
10789 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
10793 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10794 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10797 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10800 if (idx >= HOST_BITS_PER_INT)
10803 c_token *tok = c_parser_peek_token (parser);
10812 /* If a parameter is literal zero alone, remember it
10813 for -Wmemset-transposed-args warning. */
10814 if (integer_zerop (tok->value)
10815 && !TREE_OVERFLOW (tok->value)
10816 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10817 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10818 *literal_zero_mask |= 1U << idx;
10824 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10825 functions and arrays to pointers and lvalues to rvalues. If
10826 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10827 locations of function arguments into this vector.
10829 nonempty-expr-list:
10830 assignment-expression
10831 nonempty-expr-list , assignment-expression
10834 static vec<tree, va_gc> *
10835 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
10836 vec<tree, va_gc> **p_orig_types,
10837 location_t *sizeof_arg_loc, tree *sizeof_arg,
10838 vec<location_t> *locations,
10839 unsigned int *literal_zero_mask)
10841 vec<tree, va_gc> *ret;
10842 vec<tree, va_gc> *orig_types;
10843 struct c_expr expr;
10844 unsigned int idx = 0;
10846 ret = make_tree_vector ();
10847 if (p_orig_types == NULL)
10850 orig_types = make_tree_vector ();
10852 if (literal_zero_mask)
10853 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
10854 expr = c_parser_expr_no_commas (parser, NULL);
10856 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
10858 expr.value = c_fully_fold (expr.value, false, NULL);
10859 ret->quick_push (expr.value);
10861 orig_types->quick_push (expr.original_type);
10863 locations->safe_push (expr.get_location ());
10864 if (sizeof_arg != NULL
10865 && (expr.original_code == SIZEOF_EXPR
10866 || expr.original_code == PAREN_SIZEOF_EXPR))
10868 sizeof_arg[0] = c_last_sizeof_arg;
10869 sizeof_arg_loc[0] = c_last_sizeof_loc;
10871 while (c_parser_next_token_is (parser, CPP_COMMA))
10873 c_parser_consume_token (parser);
10874 if (literal_zero_mask)
10875 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
10876 expr = c_parser_expr_no_commas (parser, NULL);
10878 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10881 expr.value = c_fully_fold (expr.value, false, NULL);
10882 vec_safe_push (ret, expr.value);
10884 vec_safe_push (orig_types, expr.original_type);
10886 locations->safe_push (expr.get_location ());
10888 && sizeof_arg != NULL
10889 && (expr.original_code == SIZEOF_EXPR
10890 || expr.original_code == PAREN_SIZEOF_EXPR))
10892 sizeof_arg[idx] = c_last_sizeof_arg;
10893 sizeof_arg_loc[idx] = c_last_sizeof_loc;
10897 *p_orig_types = orig_types;
10901 /* Parse Objective-C-specific constructs. */
10903 /* Parse an objc-class-definition.
10905 objc-class-definition:
10906 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10907 objc-class-instance-variables[opt] objc-methodprotolist @end
10908 @implementation identifier objc-superclass[opt]
10909 objc-class-instance-variables[opt]
10910 @interface identifier ( identifier ) objc-protocol-refs[opt]
10911 objc-methodprotolist @end
10912 @interface identifier ( ) objc-protocol-refs[opt]
10913 objc-methodprotolist @end
10914 @implementation identifier ( identifier )
10919 "@interface identifier (" must start "@interface identifier (
10920 identifier ) ...": objc-methodprotolist in the first production may
10921 not start with a parenthesized identifier as a declarator of a data
10922 definition with no declaration specifiers if the objc-superclass,
10923 objc-protocol-refs and objc-class-instance-variables are omitted. */
10926 c_parser_objc_class_definition (c_parser *parser, tree attributes)
10931 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10933 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10936 gcc_unreachable ();
10938 c_parser_consume_token (parser);
10939 if (c_parser_next_token_is_not (parser, CPP_NAME))
10941 c_parser_error (parser, "expected identifier");
10944 id1 = c_parser_peek_token (parser)->value;
10945 location_t loc1 = c_parser_peek_token (parser)->location;
10946 c_parser_consume_token (parser);
10947 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10949 /* We have a category or class extension. */
10951 tree proto = NULL_TREE;
10952 matching_parens parens;
10953 parens.consume_open (parser);
10954 if (c_parser_next_token_is_not (parser, CPP_NAME))
10956 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10958 /* We have a class extension. */
10963 c_parser_error (parser, "expected identifier or %<)%>");
10964 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10970 id2 = c_parser_peek_token (parser)->value;
10971 c_parser_consume_token (parser);
10973 parens.skip_until_found_close (parser);
10976 objc_start_category_implementation (id1, id2);
10979 if (c_parser_next_token_is (parser, CPP_LESS))
10980 proto = c_parser_objc_protocol_refs (parser);
10981 objc_start_category_interface (id1, id2, proto, attributes);
10982 c_parser_objc_methodprotolist (parser);
10983 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10984 objc_finish_interface ();
10987 if (c_parser_next_token_is (parser, CPP_COLON))
10989 c_parser_consume_token (parser);
10990 if (c_parser_next_token_is_not (parser, CPP_NAME))
10992 c_parser_error (parser, "expected identifier");
10995 superclass = c_parser_peek_token (parser)->value;
10996 c_parser_consume_token (parser);
10999 superclass = NULL_TREE;
11002 tree proto = NULL_TREE;
11003 if (c_parser_next_token_is (parser, CPP_LESS))
11004 proto = c_parser_objc_protocol_refs (parser);
11005 objc_start_class_interface (id1, loc1, superclass, proto, attributes);
11008 objc_start_class_implementation (id1, superclass);
11009 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11010 c_parser_objc_class_instance_variables (parser);
11013 objc_continue_interface ();
11014 c_parser_objc_methodprotolist (parser);
11015 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11016 objc_finish_interface ();
11020 objc_continue_implementation ();
11025 /* Parse objc-class-instance-variables.
11027 objc-class-instance-variables:
11028 { objc-instance-variable-decl-list[opt] }
11030 objc-instance-variable-decl-list:
11031 objc-visibility-spec
11032 objc-instance-variable-decl ;
11034 objc-instance-variable-decl-list objc-visibility-spec
11035 objc-instance-variable-decl-list objc-instance-variable-decl ;
11036 objc-instance-variable-decl-list ;
11038 objc-visibility-spec:
11043 objc-instance-variable-decl:
11048 c_parser_objc_class_instance_variables (c_parser *parser)
11050 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
11051 c_parser_consume_token (parser);
11052 while (c_parser_next_token_is_not (parser, CPP_EOF))
11055 /* Parse any stray semicolon. */
11056 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11058 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11059 "extra semicolon");
11060 c_parser_consume_token (parser);
11063 /* Stop if at the end of the instance variables. */
11064 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
11066 c_parser_consume_token (parser);
11069 /* Parse any objc-visibility-spec. */
11070 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
11072 c_parser_consume_token (parser);
11073 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
11076 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
11078 c_parser_consume_token (parser);
11079 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
11082 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
11084 c_parser_consume_token (parser);
11085 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
11088 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
11090 c_parser_consume_token (parser);
11091 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
11094 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
11096 c_parser_pragma (parser, pragma_external, NULL);
11100 /* Parse some comma-separated declarations. */
11101 decls = c_parser_struct_declaration (parser);
11104 /* There is a syntax error. We want to skip the offending
11105 tokens up to the next ';' (included) or '}'
11108 /* First, skip manually a ')' or ']'. This is because they
11109 reduce the nesting level, so c_parser_skip_until_found()
11110 wouldn't be able to skip past them. */
11111 c_token *token = c_parser_peek_token (parser);
11112 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
11113 c_parser_consume_token (parser);
11115 /* Then, do the standard skipping. */
11116 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11118 /* We hopefully recovered. Start normal parsing again. */
11119 parser->error = false;
11124 /* Comma-separated instance variables are chained together
11125 in reverse order; add them one by one. */
11126 tree ivar = nreverse (decls);
11127 for (; ivar; ivar = DECL_CHAIN (ivar))
11128 objc_add_instance_variable (copy_node (ivar));
11130 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11134 /* Parse an objc-class-declaration.
11136 objc-class-declaration:
11137 @class identifier-list ;
11141 c_parser_objc_class_declaration (c_parser *parser)
11143 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
11144 c_parser_consume_token (parser);
11145 /* Any identifiers, including those declared as type names, are OK
11150 if (c_parser_next_token_is_not (parser, CPP_NAME))
11152 c_parser_error (parser, "expected identifier");
11153 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11154 parser->error = false;
11157 id = c_parser_peek_token (parser)->value;
11158 objc_declare_class (id);
11159 c_parser_consume_token (parser);
11160 if (c_parser_next_token_is (parser, CPP_COMMA))
11161 c_parser_consume_token (parser);
11165 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11168 /* Parse an objc-alias-declaration.
11170 objc-alias-declaration:
11171 @compatibility_alias identifier identifier ;
11175 c_parser_objc_alias_declaration (c_parser *parser)
11178 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11179 c_parser_consume_token (parser);
11180 if (c_parser_next_token_is_not (parser, CPP_NAME))
11182 c_parser_error (parser, "expected identifier");
11183 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11186 id1 = c_parser_peek_token (parser)->value;
11187 c_parser_consume_token (parser);
11188 if (c_parser_next_token_is_not (parser, CPP_NAME))
11190 c_parser_error (parser, "expected identifier");
11191 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11194 id2 = c_parser_peek_token (parser)->value;
11195 c_parser_consume_token (parser);
11196 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11197 objc_declare_alias (id1, id2);
11200 /* Parse an objc-protocol-definition.
11202 objc-protocol-definition:
11203 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11204 @protocol identifier-list ;
11206 "@protocol identifier ;" should be resolved as "@protocol
11207 identifier-list ;": objc-methodprotolist may not start with a
11208 semicolon in the first alternative if objc-protocol-refs are
11212 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11214 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11216 c_parser_consume_token (parser);
11217 if (c_parser_next_token_is_not (parser, CPP_NAME))
11219 c_parser_error (parser, "expected identifier");
11222 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11223 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11225 /* Any identifiers, including those declared as type names, are
11230 if (c_parser_next_token_is_not (parser, CPP_NAME))
11232 c_parser_error (parser, "expected identifier");
11235 id = c_parser_peek_token (parser)->value;
11236 objc_declare_protocol (id, attributes);
11237 c_parser_consume_token (parser);
11238 if (c_parser_next_token_is (parser, CPP_COMMA))
11239 c_parser_consume_token (parser);
11243 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11247 tree id = c_parser_peek_token (parser)->value;
11248 tree proto = NULL_TREE;
11249 c_parser_consume_token (parser);
11250 if (c_parser_next_token_is (parser, CPP_LESS))
11251 proto = c_parser_objc_protocol_refs (parser);
11252 parser->objc_pq_context = true;
11253 objc_start_protocol (id, proto, attributes);
11254 c_parser_objc_methodprotolist (parser);
11255 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11256 parser->objc_pq_context = false;
11257 objc_finish_interface ();
11261 /* Parse an objc-method-type.
11267 Return true if it is a class method (+) and false if it is
11268 an instance method (-).
11271 c_parser_objc_method_type (c_parser *parser)
11273 switch (c_parser_peek_token (parser)->type)
11276 c_parser_consume_token (parser);
11279 c_parser_consume_token (parser);
11282 gcc_unreachable ();
11286 /* Parse an objc-method-definition.
11288 objc-method-definition:
11289 objc-method-type objc-method-decl ;[opt] compound-statement
11293 c_parser_objc_method_definition (c_parser *parser)
11295 bool is_class_method = c_parser_objc_method_type (parser);
11296 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11297 parser->objc_pq_context = true;
11298 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11300 if (decl == error_mark_node)
11301 return; /* Bail here. */
11303 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11305 c_parser_consume_token (parser);
11306 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11307 "extra semicolon in method definition specified");
11310 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11312 c_parser_error (parser, "expected %<{%>");
11316 parser->objc_pq_context = false;
11317 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11319 add_stmt (c_parser_compound_statement (parser));
11320 objc_finish_method_definition (current_function_decl);
11324 /* This code is executed when we find a method definition
11325 outside of an @implementation context (or invalid for other
11326 reasons). Parse the method (to keep going) but do not emit
11329 c_parser_compound_statement (parser);
11333 /* Parse an objc-methodprotolist.
11335 objc-methodprotolist:
11337 objc-methodprotolist objc-methodproto
11338 objc-methodprotolist declaration
11339 objc-methodprotolist ;
11343 The declaration is a data definition, which may be missing
11344 declaration specifiers under the same rules and diagnostics as
11345 other data definitions outside functions, and the stray semicolon
11346 is diagnosed the same way as a stray semicolon outside a
11350 c_parser_objc_methodprotolist (c_parser *parser)
11354 /* The list is terminated by @end. */
11355 switch (c_parser_peek_token (parser)->type)
11357 case CPP_SEMICOLON:
11358 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11359 "ISO C does not allow extra %<;%> outside of a function");
11360 c_parser_consume_token (parser);
11364 c_parser_objc_methodproto (parser);
11367 c_parser_pragma (parser, pragma_external, NULL);
11372 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11374 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
11375 c_parser_objc_at_property_declaration (parser);
11376 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11378 objc_set_method_opt (true);
11379 c_parser_consume_token (parser);
11381 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11383 objc_set_method_opt (false);
11384 c_parser_consume_token (parser);
11387 c_parser_declaration_or_fndef (parser, false, false, true,
11394 /* Parse an objc-methodproto.
11397 objc-method-type objc-method-decl ;
11401 c_parser_objc_methodproto (c_parser *parser)
11403 bool is_class_method = c_parser_objc_method_type (parser);
11404 tree decl, attributes = NULL_TREE;
11406 /* Remember protocol qualifiers in prototypes. */
11407 parser->objc_pq_context = true;
11408 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11410 /* Forget protocol qualifiers now. */
11411 parser->objc_pq_context = false;
11413 /* Do not allow the presence of attributes to hide an erroneous
11414 method implementation in the interface section. */
11415 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11417 c_parser_error (parser, "expected %<;%>");
11421 if (decl != error_mark_node)
11422 objc_add_method_declaration (is_class_method, decl, attributes);
11424 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11427 /* If we are at a position that method attributes may be present, check that
11428 there are not any parsed already (a syntax error) and then collect any
11429 specified at the current location. Finally, if new attributes were present,
11430 check that the next token is legal ( ';' for decls and '{' for defs). */
11433 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11438 c_parser_error (parser,
11439 "method attributes must be specified at the end only");
11440 *attributes = NULL_TREE;
11444 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11445 *attributes = c_parser_gnu_attributes (parser);
11447 /* If there were no attributes here, just report any earlier error. */
11448 if (*attributes == NULL_TREE || bad)
11451 /* If the attributes are followed by a ; or {, then just report any earlier
11453 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11454 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11457 /* We've got attributes, but not at the end. */
11458 c_parser_error (parser,
11459 "expected %<;%> or %<{%> after method attribute definition");
11463 /* Parse an objc-method-decl.
11466 ( objc-type-name ) objc-selector
11468 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11469 objc-keyword-selector objc-optparmlist
11472 objc-keyword-selector:
11474 objc-keyword-selector objc-keyword-decl
11477 objc-selector : ( objc-type-name ) identifier
11478 objc-selector : identifier
11479 : ( objc-type-name ) identifier
11483 objc-optparms objc-optellipsis
11487 objc-opt-parms , parameter-declaration
11495 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11496 tree *attributes, tree *expr)
11498 tree type = NULL_TREE;
11500 tree parms = NULL_TREE;
11501 bool ellipsis = false;
11502 bool attr_err = false;
11504 *attributes = NULL_TREE;
11505 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11507 matching_parens parens;
11508 parens.consume_open (parser);
11509 type = c_parser_objc_type_name (parser);
11510 parens.skip_until_found_close (parser);
11512 sel = c_parser_objc_selector (parser);
11513 /* If there is no selector, or a colon follows, we have an
11514 objc-keyword-selector. If there is a selector, and a colon does
11515 not follow, that selector ends the objc-method-decl. */
11516 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11519 tree list = NULL_TREE;
11522 tree atype = NULL_TREE, id, keyworddecl;
11523 tree param_attr = NULL_TREE;
11524 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11526 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11528 c_parser_consume_token (parser);
11529 atype = c_parser_objc_type_name (parser);
11530 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11533 /* New ObjC allows attributes on method parameters. */
11534 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11535 param_attr = c_parser_gnu_attributes (parser);
11536 if (c_parser_next_token_is_not (parser, CPP_NAME))
11538 c_parser_error (parser, "expected identifier");
11539 return error_mark_node;
11541 id = c_parser_peek_token (parser)->value;
11542 c_parser_consume_token (parser);
11543 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
11544 list = chainon (list, keyworddecl);
11545 tsel = c_parser_objc_selector (parser);
11546 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11550 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11552 /* Parse the optional parameter list. Optional Objective-C
11553 method parameters follow the C syntax, and may include '...'
11554 to denote a variable number of arguments. */
11555 parms = make_node (TREE_LIST);
11556 while (c_parser_next_token_is (parser, CPP_COMMA))
11558 struct c_parm *parm;
11559 c_parser_consume_token (parser);
11560 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11563 c_parser_consume_token (parser);
11564 attr_err |= c_parser_objc_maybe_method_attributes
11565 (parser, attributes) ;
11568 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11571 parms = chainon (parms,
11572 build_tree_list (NULL_TREE, grokparm (parm, expr)));
11577 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11581 c_parser_error (parser, "objective-c method declaration is expected");
11582 return error_mark_node;
11586 return error_mark_node;
11588 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
11591 /* Parse an objc-type-name.
11594 objc-type-qualifiers[opt] type-name
11595 objc-type-qualifiers[opt]
11597 objc-type-qualifiers:
11598 objc-type-qualifier
11599 objc-type-qualifiers objc-type-qualifier
11601 objc-type-qualifier: one of
11602 in out inout bycopy byref oneway
11606 c_parser_objc_type_name (c_parser *parser)
11608 tree quals = NULL_TREE;
11609 struct c_type_name *type_name = NULL;
11610 tree type = NULL_TREE;
11613 c_token *token = c_parser_peek_token (parser);
11614 if (token->type == CPP_KEYWORD
11615 && (token->keyword == RID_IN
11616 || token->keyword == RID_OUT
11617 || token->keyword == RID_INOUT
11618 || token->keyword == RID_BYCOPY
11619 || token->keyword == RID_BYREF
11620 || token->keyword == RID_ONEWAY))
11622 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
11623 c_parser_consume_token (parser);
11628 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
11629 type_name = c_parser_type_name (parser);
11631 type = groktypename (type_name, NULL, NULL);
11633 /* If the type is unknown, and error has already been produced and
11634 we need to recover from the error. In that case, use NULL_TREE
11635 for the type, as if no type had been specified; this will use the
11636 default type ('id') which is good for error recovery. */
11637 if (type == error_mark_node)
11640 return build_tree_list (quals, type);
11643 /* Parse objc-protocol-refs.
11645 objc-protocol-refs:
11646 < identifier-list >
11650 c_parser_objc_protocol_refs (c_parser *parser)
11652 tree list = NULL_TREE;
11653 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11654 c_parser_consume_token (parser);
11655 /* Any identifiers, including those declared as type names, are OK
11660 if (c_parser_next_token_is_not (parser, CPP_NAME))
11662 c_parser_error (parser, "expected identifier");
11665 id = c_parser_peek_token (parser)->value;
11666 list = chainon (list, build_tree_list (NULL_TREE, id));
11667 c_parser_consume_token (parser);
11668 if (c_parser_next_token_is (parser, CPP_COMMA))
11669 c_parser_consume_token (parser);
11673 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11677 /* Parse an objc-try-catch-finally-statement.
11679 objc-try-catch-finally-statement:
11680 @try compound-statement objc-catch-list[opt]
11681 @try compound-statement objc-catch-list[opt] @finally compound-statement
11684 @catch ( objc-catch-parameter-declaration ) compound-statement
11685 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11687 objc-catch-parameter-declaration:
11688 parameter-declaration
11691 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11693 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11694 for C++. Keep them in sync. */
11697 c_parser_objc_try_catch_finally_statement (c_parser *parser)
11699 location_t location;
11702 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
11703 c_parser_consume_token (parser);
11704 location = c_parser_peek_token (parser)->location;
11705 objc_maybe_warn_exceptions (location);
11706 stmt = c_parser_compound_statement (parser);
11707 objc_begin_try_stmt (location, stmt);
11709 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
11711 struct c_parm *parm;
11712 tree parameter_declaration = error_mark_node;
11713 bool seen_open_paren = false;
11715 c_parser_consume_token (parser);
11716 matching_parens parens;
11717 if (!parens.require_open (parser))
11718 seen_open_paren = true;
11719 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11721 /* We have "@catch (...)" (where the '...' are literally
11722 what is in the code). Skip the '...'.
11723 parameter_declaration is set to NULL_TREE, and
11724 objc_being_catch_clauses() knows that that means
11726 c_parser_consume_token (parser);
11727 parameter_declaration = NULL_TREE;
11731 /* We have "@catch (NSException *exception)" or something
11732 like that. Parse the parameter declaration. */
11733 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11735 parameter_declaration = error_mark_node;
11737 parameter_declaration = grokparm (parm, NULL);
11739 if (seen_open_paren)
11740 parens.require_close (parser);
11743 /* If there was no open parenthesis, we are recovering from
11744 an error, and we are trying to figure out what mistake
11745 the user has made. */
11747 /* If there is an immediate closing parenthesis, the user
11748 probably forgot the opening one (ie, they typed "@catch
11749 NSException *e)". Parse the closing parenthesis and keep
11751 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11752 c_parser_consume_token (parser);
11754 /* If these is no immediate closing parenthesis, the user
11755 probably doesn't know that parenthesis are required at
11756 all (ie, they typed "@catch NSException *e"). So, just
11757 forget about the closing parenthesis and keep going. */
11759 objc_begin_catch_clause (parameter_declaration);
11760 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
11761 c_parser_compound_statement_nostart (parser);
11762 objc_finish_catch_clause ();
11764 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
11766 c_parser_consume_token (parser);
11767 location = c_parser_peek_token (parser)->location;
11768 stmt = c_parser_compound_statement (parser);
11769 objc_build_finally_clause (location, stmt);
11771 objc_finish_try_stmt ();
11774 /* Parse an objc-synchronized-statement.
11776 objc-synchronized-statement:
11777 @synchronized ( expression ) compound-statement
11781 c_parser_objc_synchronized_statement (c_parser *parser)
11785 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
11786 c_parser_consume_token (parser);
11787 loc = c_parser_peek_token (parser)->location;
11788 objc_maybe_warn_exceptions (loc);
11789 matching_parens parens;
11790 if (parens.require_open (parser))
11792 struct c_expr ce = c_parser_expression (parser);
11793 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11795 expr = c_fully_fold (expr, false, NULL);
11796 parens.skip_until_found_close (parser);
11799 expr = error_mark_node;
11800 stmt = c_parser_compound_statement (parser);
11801 objc_build_synchronized (loc, expr, stmt);
11804 /* Parse an objc-selector; return NULL_TREE without an error if the
11805 next token is not an objc-selector.
11810 enum struct union if else while do for switch case default
11811 break continue return goto asm sizeof typeof __alignof
11812 unsigned long const short volatile signed restrict _Complex
11813 in out inout bycopy byref oneway int char float double void _Bool
11816 ??? Why this selection of keywords but not, for example, storage
11817 class specifiers? */
11820 c_parser_objc_selector (c_parser *parser)
11822 c_token *token = c_parser_peek_token (parser);
11823 tree value = token->value;
11824 if (token->type == CPP_NAME)
11826 c_parser_consume_token (parser);
11829 if (token->type != CPP_KEYWORD)
11831 switch (token->keyword)
11870 CASE_RID_FLOATN_NX:
11874 case RID_AUTO_TYPE:
11879 c_parser_consume_token (parser);
11886 /* Parse an objc-selector-arg.
11890 objc-keywordname-list
11892 objc-keywordname-list:
11894 objc-keywordname-list objc-keywordname
11902 c_parser_objc_selector_arg (c_parser *parser)
11904 tree sel = c_parser_objc_selector (parser);
11905 tree list = NULL_TREE;
11907 && c_parser_next_token_is_not (parser, CPP_COLON)
11908 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11912 if (c_parser_next_token_is (parser, CPP_SCOPE))
11914 c_parser_consume_token (parser);
11915 list = chainon (list, build_tree_list (sel, NULL_TREE));
11916 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
11920 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11922 list = chainon (list, build_tree_list (sel, NULL_TREE));
11924 sel = c_parser_objc_selector (parser);
11926 && c_parser_next_token_is_not (parser, CPP_COLON)
11927 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11933 /* Parse an objc-receiver.
11942 c_parser_objc_receiver (c_parser *parser)
11944 location_t loc = c_parser_peek_token (parser)->location;
11946 if (c_parser_peek_token (parser)->type == CPP_NAME
11947 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11948 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11950 tree id = c_parser_peek_token (parser)->value;
11951 c_parser_consume_token (parser);
11952 return objc_get_class_reference (id);
11954 struct c_expr ce = c_parser_expression (parser);
11955 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11956 return c_fully_fold (ce.value, false, NULL);
11959 /* Parse objc-message-args.
11963 objc-keywordarg-list
11965 objc-keywordarg-list:
11967 objc-keywordarg-list objc-keywordarg
11970 objc-selector : objc-keywordexpr
11975 c_parser_objc_message_args (c_parser *parser)
11977 tree sel = c_parser_objc_selector (parser);
11978 tree list = NULL_TREE;
11979 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11984 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11985 return error_mark_node;
11986 keywordexpr = c_parser_objc_keywordexpr (parser);
11987 list = chainon (list, build_tree_list (sel, keywordexpr));
11988 sel = c_parser_objc_selector (parser);
11989 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11995 /* Parse an objc-keywordexpr.
12002 c_parser_objc_keywordexpr (c_parser *parser)
12005 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
12006 NULL, NULL, NULL, NULL);
12007 if (vec_safe_length (expr_list) == 1)
12009 /* Just return the expression, remove a level of
12011 ret = (*expr_list)[0];
12015 /* We have a comma expression, we will collapse later. */
12016 ret = build_tree_list_vec (expr_list);
12018 release_tree_vector (expr_list);
12022 /* A check, needed in several places, that ObjC interface, implementation or
12023 method definitions are not prefixed by incorrect items. */
12025 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
12026 struct c_declspecs *specs)
12028 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
12029 || specs->typespec_kind != ctsk_none)
12031 c_parser_error (parser,
12032 "no type or storage class may be specified here,");
12033 c_parser_skip_to_end_of_block_or_statement (parser);
12039 /* Parse an Objective-C @property declaration. The syntax is:
12041 objc-property-declaration:
12042 '@property' objc-property-attributes[opt] struct-declaration ;
12044 objc-property-attributes:
12045 '(' objc-property-attribute-list ')'
12047 objc-property-attribute-list:
12048 objc-property-attribute
12049 objc-property-attribute-list, objc-property-attribute
12051 objc-property-attribute
12052 'getter' = identifier
12053 'setter' = identifier
12062 @property NSString *name;
12063 @property (readonly) id object;
12064 @property (retain, nonatomic, getter=getTheName) id name;
12065 @property int a, b, c;
12067 PS: This function is identical to cp_parser_objc_at_propery_declaration
12068 for C++. Keep them in sync. */
12070 c_parser_objc_at_property_declaration (c_parser *parser)
12072 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
12073 location_t loc = c_parser_peek_token (parser)->location;
12074 c_parser_consume_token (parser); /* Eat '@property'. */
12076 /* Parse the optional attribute list.
12078 A list of parsed, but not verified, attributes. */
12079 vec<property_attribute_info *> prop_attr_list = vNULL;
12081 bool syntax_error = false;
12082 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12084 matching_parens parens;
12086 location_t attr_start = c_parser_peek_token (parser)->location;
12088 parens.consume_open (parser);
12090 /* Property attribute keywords are valid now. */
12091 parser->objc_property_attr_context = true;
12093 /* Allow @property (), with a warning. */
12094 location_t attr_end = c_parser_peek_token (parser)->location;
12096 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12098 location_t attr_comb = make_location (attr_end, attr_start, attr_end);
12099 warning_at (attr_comb, OPT_Wattributes,
12100 "empty property attribute list");
12105 c_token *token = c_parser_peek_token (parser);
12106 attr_start = token->location;
12107 attr_end = get_finish (token->location);
12108 location_t attr_comb = make_location (attr_start, attr_start,
12111 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
12113 warning_at (attr_comb, OPT_Wattributes,
12114 "missing property attribute");
12115 if (token->type == CPP_CLOSE_PAREN)
12117 c_parser_consume_token (parser);
12121 tree attr_name = NULL_TREE;
12122 enum rid keyword = RID_MAX; /* Not a valid property attribute. */
12123 bool add_at = false;
12124 if (token->type == CPP_KEYWORD)
12126 keyword = token->keyword;
12127 if (OBJC_IS_AT_KEYWORD (keyword))
12129 /* For '@' keywords the token value has the keyword,
12130 prepend the '@' for diagnostics. */
12131 attr_name = token->value;
12135 attr_name = ridpointers[(int)keyword];
12137 else if (token->type == CPP_NAME)
12138 attr_name = token->value;
12139 c_parser_consume_token (parser);
12141 enum objc_property_attribute_kind prop_kind
12142 = objc_prop_attr_kind_for_rid (keyword);
12143 property_attribute_info *prop
12144 = new property_attribute_info (attr_name, attr_comb, prop_kind);
12145 prop_attr_list.safe_push (prop);
12148 switch (prop->prop_kind)
12151 case OBJC_PROPERTY_ATTR_UNKNOWN:
12153 error_at (attr_comb, "unknown property attribute %<%s%s%>",
12154 add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
12156 error_at (attr_comb, "unknown property attribute");
12157 prop->parse_error = syntax_error = true;
12160 case OBJC_PROPERTY_ATTR_GETTER:
12161 case OBJC_PROPERTY_ATTR_SETTER:
12162 if (c_parser_next_token_is_not (parser, CPP_EQ))
12164 attr_comb = make_location (attr_end, attr_start, attr_end);
12165 error_at (attr_comb, "expected %<=%> after Objective-C %qE",
12167 prop->parse_error = syntax_error = true;
12170 token = c_parser_peek_token (parser);
12171 attr_end = token->location;
12172 c_parser_consume_token (parser); /* eat the = */
12173 if (c_parser_next_token_is_not (parser, CPP_NAME))
12175 attr_comb = make_location (attr_end, attr_start, attr_end);
12176 error_at (attr_comb, "expected %qE selector name",
12178 prop->parse_error = syntax_error = true;
12181 /* Get the end of the method name, and consume the name. */
12182 token = c_parser_peek_token (parser);
12183 attr_end = get_finish (token->location);
12184 meth_name = token->value;
12185 c_parser_consume_token (parser);
12186 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
12188 if (c_parser_next_token_is_not (parser, CPP_COLON))
12190 attr_comb = make_location (attr_end, attr_start,
12192 error_at (attr_comb, "setter method names must"
12193 " terminate with %<:%>");
12194 prop->parse_error = syntax_error = true;
12198 attr_end = get_finish (c_parser_peek_token
12199 (parser)->location);
12200 c_parser_consume_token (parser);
12202 attr_comb = make_location (attr_start, attr_start,
12206 attr_comb = make_location (attr_start, attr_start,
12208 prop->ident = meth_name;
12209 /* Updated location including all that was successfully
12211 prop->prop_loc = attr_comb;
12215 /* If we see a comma here, then keep going - even if we already
12216 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12217 this makes a more useful output and avoid spurious warnings about
12218 missing attributes that are, in fact, specified after the one with
12219 the syntax error. */
12220 if (c_parser_next_token_is (parser, CPP_COMMA))
12221 c_parser_consume_token (parser);
12225 parser->objc_property_attr_context = false;
12227 if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
12228 /* We don't really want to chew the whole of the file looking for a
12229 matching closing parenthesis, so we will try to read the decl and
12230 let the error handling for that close out the statement. */
12233 syntax_error = false, parens.skip_until_found_close (parser);
12236 /* 'properties' is the list of properties that we read. Usually a
12237 single one, but maybe more (eg, in "@property int a, b, c;" there
12239 tree properties = c_parser_struct_declaration (parser);
12241 if (properties == error_mark_node)
12242 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12245 if (properties == NULL_TREE)
12246 c_parser_error (parser, "expected identifier");
12249 /* Comma-separated properties are chained together in reverse order;
12250 add them one by one. */
12251 properties = nreverse (properties);
12252 for (; properties; properties = TREE_CHAIN (properties))
12253 objc_add_property_declaration (loc, copy_node (properties),
12256 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12259 while (!prop_attr_list.is_empty())
12260 delete prop_attr_list.pop ();
12261 prop_attr_list.release ();
12262 parser->error = false;
12265 /* Parse an Objective-C @synthesize declaration. The syntax is:
12267 objc-synthesize-declaration:
12268 @synthesize objc-synthesize-identifier-list ;
12270 objc-synthesize-identifier-list:
12271 objc-synthesize-identifier
12272 objc-synthesize-identifier-list, objc-synthesize-identifier
12274 objc-synthesize-identifier
12276 identifier = identifier
12279 @synthesize MyProperty;
12280 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12282 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12283 for C++. Keep them in sync.
12286 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12288 tree list = NULL_TREE;
12290 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12291 loc = c_parser_peek_token (parser)->location;
12293 c_parser_consume_token (parser);
12296 tree property, ivar;
12297 if (c_parser_next_token_is_not (parser, CPP_NAME))
12299 c_parser_error (parser, "expected identifier");
12300 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12301 /* Once we find the semicolon, we can resume normal parsing.
12302 We have to reset parser->error manually because
12303 c_parser_skip_until_found() won't reset it for us if the
12304 next token is precisely a semicolon. */
12305 parser->error = false;
12308 property = c_parser_peek_token (parser)->value;
12309 c_parser_consume_token (parser);
12310 if (c_parser_next_token_is (parser, CPP_EQ))
12312 c_parser_consume_token (parser);
12313 if (c_parser_next_token_is_not (parser, CPP_NAME))
12315 c_parser_error (parser, "expected identifier");
12316 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12317 parser->error = false;
12320 ivar = c_parser_peek_token (parser)->value;
12321 c_parser_consume_token (parser);
12325 list = chainon (list, build_tree_list (ivar, property));
12326 if (c_parser_next_token_is (parser, CPP_COMMA))
12327 c_parser_consume_token (parser);
12331 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12332 objc_add_synthesize_declaration (loc, list);
12335 /* Parse an Objective-C @dynamic declaration. The syntax is:
12337 objc-dynamic-declaration:
12338 @dynamic identifier-list ;
12341 @dynamic MyProperty;
12342 @dynamic MyProperty, AnotherProperty;
12344 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12345 for C++. Keep them in sync.
12348 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12350 tree list = NULL_TREE;
12352 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12353 loc = c_parser_peek_token (parser)->location;
12355 c_parser_consume_token (parser);
12359 if (c_parser_next_token_is_not (parser, CPP_NAME))
12361 c_parser_error (parser, "expected identifier");
12362 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12363 parser->error = false;
12366 property = c_parser_peek_token (parser)->value;
12367 list = chainon (list, build_tree_list (NULL_TREE, property));
12368 c_parser_consume_token (parser);
12369 if (c_parser_next_token_is (parser, CPP_COMMA))
12370 c_parser_consume_token (parser);
12374 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12375 objc_add_dynamic_declaration (loc, list);
12379 /* Parse a pragma GCC ivdep. */
12382 c_parse_pragma_ivdep (c_parser *parser)
12384 c_parser_consume_pragma (parser);
12385 c_parser_skip_to_pragma_eol (parser);
12389 /* Parse a pragma GCC unroll. */
12391 static unsigned short
12392 c_parser_pragma_unroll (c_parser *parser)
12394 unsigned short unroll;
12395 c_parser_consume_pragma (parser);
12396 location_t location = c_parser_peek_token (parser)->location;
12397 tree expr = c_parser_expr_no_commas (parser, NULL).value;
12398 mark_exp_read (expr);
12399 expr = c_fully_fold (expr, false, NULL);
12400 HOST_WIDE_INT lunroll = 0;
12401 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12402 || TREE_CODE (expr) != INTEGER_CST
12403 || (lunroll = tree_to_shwi (expr)) < 0
12404 || lunroll >= USHRT_MAX)
12406 error_at (location, "%<#pragma GCC unroll%> requires an"
12407 " assignment-expression that evaluates to a non-negative"
12408 " integral constant less than %u", USHRT_MAX);
12413 unroll = (unsigned short)lunroll;
12418 c_parser_skip_to_pragma_eol (parser);
12422 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12423 should be considered, statements. ALLOW_STMT is true if we're within
12424 the context of a function and such pragmas are to be allowed. Returns
12425 true if we actually parsed such a pragma. */
12428 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
12431 const char *construct = NULL;
12433 input_location = c_parser_peek_token (parser)->location;
12434 id = c_parser_peek_token (parser)->pragma_kind;
12435 gcc_assert (id != PRAGMA_NONE);
12439 case PRAGMA_OACC_DECLARE:
12440 c_parser_oacc_declare (parser);
12443 case PRAGMA_OACC_ENTER_DATA:
12444 if (context != pragma_compound)
12446 construct = "acc enter data";
12448 if (context == pragma_stmt)
12450 error_at (c_parser_peek_token (parser)->location,
12451 "%<#pragma %s%> may only be used in compound "
12452 "statements", construct);
12453 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12458 c_parser_oacc_enter_exit_data (parser, true);
12461 case PRAGMA_OACC_EXIT_DATA:
12462 if (context != pragma_compound)
12464 construct = "acc exit data";
12467 c_parser_oacc_enter_exit_data (parser, false);
12470 case PRAGMA_OACC_ROUTINE:
12471 if (context != pragma_external)
12473 error_at (c_parser_peek_token (parser)->location,
12474 "%<#pragma acc routine%> must be at file scope");
12475 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12478 c_parser_oacc_routine (parser, context);
12481 case PRAGMA_OACC_UPDATE:
12482 if (context != pragma_compound)
12484 construct = "acc update";
12487 c_parser_oacc_update (parser);
12490 case PRAGMA_OMP_BARRIER:
12491 if (context != pragma_compound)
12493 construct = "omp barrier";
12496 c_parser_omp_barrier (parser);
12499 case PRAGMA_OMP_DEPOBJ:
12500 if (context != pragma_compound)
12502 construct = "omp depobj";
12505 c_parser_omp_depobj (parser);
12508 case PRAGMA_OMP_FLUSH:
12509 if (context != pragma_compound)
12511 construct = "omp flush";
12514 c_parser_omp_flush (parser);
12517 case PRAGMA_OMP_TASKWAIT:
12518 if (context != pragma_compound)
12520 construct = "omp taskwait";
12523 c_parser_omp_taskwait (parser);
12526 case PRAGMA_OMP_TASKYIELD:
12527 if (context != pragma_compound)
12529 construct = "omp taskyield";
12532 c_parser_omp_taskyield (parser);
12535 case PRAGMA_OMP_CANCEL:
12536 if (context != pragma_compound)
12538 construct = "omp cancel";
12541 c_parser_omp_cancel (parser);
12544 case PRAGMA_OMP_CANCELLATION_POINT:
12545 return c_parser_omp_cancellation_point (parser, context);
12547 case PRAGMA_OMP_THREADPRIVATE:
12548 c_parser_omp_threadprivate (parser);
12551 case PRAGMA_OMP_TARGET:
12552 return c_parser_omp_target (parser, context, if_p);
12554 case PRAGMA_OMP_END_DECLARE_TARGET:
12555 c_parser_omp_end_declare_target (parser);
12558 case PRAGMA_OMP_SCAN:
12559 error_at (c_parser_peek_token (parser)->location,
12560 "%<#pragma omp scan%> may only be used in "
12561 "a loop construct with %<inscan%> %<reduction%> clause");
12562 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12565 case PRAGMA_OMP_SECTION:
12566 error_at (c_parser_peek_token (parser)->location,
12567 "%<#pragma omp section%> may only be used in "
12568 "%<#pragma omp sections%> construct");
12569 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12572 case PRAGMA_OMP_DECLARE:
12573 return c_parser_omp_declare (parser, context);
12575 case PRAGMA_OMP_REQUIRES:
12576 if (context != pragma_external)
12578 error_at (c_parser_peek_token (parser)->location,
12579 "%<#pragma omp requires%> may only be used at file scope");
12580 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12583 c_parser_omp_requires (parser);
12586 case PRAGMA_OMP_NOTHING:
12587 c_parser_omp_nothing (parser);
12590 case PRAGMA_OMP_ERROR:
12591 return c_parser_omp_error (parser, context);
12593 case PRAGMA_OMP_ORDERED:
12594 return c_parser_omp_ordered (parser, context, if_p);
12598 const bool ivdep = c_parse_pragma_ivdep (parser);
12599 unsigned short unroll;
12600 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12601 unroll = c_parser_pragma_unroll (parser);
12604 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12605 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12606 && !c_parser_next_token_is_keyword (parser, RID_DO))
12608 c_parser_error (parser, "for, while or do statement expected");
12611 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12612 c_parser_for_statement (parser, ivdep, unroll, if_p);
12613 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12614 c_parser_while_statement (parser, ivdep, unroll, if_p);
12616 c_parser_do_statement (parser, ivdep, unroll);
12620 case PRAGMA_UNROLL:
12622 unsigned short unroll = c_parser_pragma_unroll (parser);
12624 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12625 ivdep = c_parse_pragma_ivdep (parser);
12628 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12629 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12630 && !c_parser_next_token_is_keyword (parser, RID_DO))
12632 c_parser_error (parser, "for, while or do statement expected");
12635 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12636 c_parser_for_statement (parser, ivdep, unroll, if_p);
12637 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12638 c_parser_while_statement (parser, ivdep, unroll, if_p);
12640 c_parser_do_statement (parser, ivdep, unroll);
12644 case PRAGMA_GCC_PCH_PREPROCESS:
12645 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12646 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12649 case PRAGMA_OACC_WAIT:
12650 if (context != pragma_compound)
12652 construct = "acc wait";
12655 /* FALL THROUGH. */
12658 if (id < PRAGMA_FIRST_EXTERNAL)
12660 if (context != pragma_stmt && context != pragma_compound)
12663 c_parser_error (parser, "expected declaration specifiers");
12664 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12667 c_parser_omp_construct (parser, if_p);
12673 c_parser_consume_pragma (parser);
12674 c_invoke_pragma_handler (id);
12676 /* Skip to EOL, but suppress any error message. Those will have been
12677 generated by the handler routine through calling error, as opposed
12678 to calling c_parser_error. */
12679 parser->error = true;
12680 c_parser_skip_to_pragma_eol (parser);
12685 /* The interface the pragma parsers have to the lexer. */
12688 pragma_lex (tree *value, location_t *loc)
12690 c_token *tok = c_parser_peek_token (the_parser);
12691 enum cpp_ttype ret = tok->type;
12693 *value = tok->value;
12695 *loc = tok->location;
12697 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12699 else if (ret == CPP_STRING)
12700 *value = c_parser_string_literal (the_parser, false, false).value;
12703 if (ret == CPP_KEYWORD)
12705 c_parser_consume_token (the_parser);
12712 c_parser_pragma_pch_preprocess (c_parser *parser)
12716 parser->lex_joined_string = true;
12717 c_parser_consume_pragma (parser);
12718 if (c_parser_next_token_is (parser, CPP_STRING))
12720 name = c_parser_peek_token (parser)->value;
12721 c_parser_consume_token (parser);
12724 c_parser_error (parser, "expected string literal");
12725 c_parser_skip_to_pragma_eol (parser);
12726 parser->lex_joined_string = false;
12729 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
12732 /* OpenACC and OpenMP parsing routines. */
12734 /* Returns name of the next clause.
12735 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12736 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12737 returned and the token is consumed. */
12739 static pragma_omp_clause
12740 c_parser_omp_clause_name (c_parser *parser)
12742 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
12744 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
12745 result = PRAGMA_OACC_CLAUSE_AUTO;
12746 else if (c_parser_next_token_is_keyword (parser, RID_IF))
12747 result = PRAGMA_OMP_CLAUSE_IF;
12748 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
12749 result = PRAGMA_OMP_CLAUSE_DEFAULT;
12750 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
12751 result = PRAGMA_OMP_CLAUSE_FOR;
12752 else if (c_parser_next_token_is (parser, CPP_NAME))
12754 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12759 if (!strcmp ("affinity", p))
12760 result = PRAGMA_OMP_CLAUSE_AFFINITY;
12761 else if (!strcmp ("aligned", p))
12762 result = PRAGMA_OMP_CLAUSE_ALIGNED;
12763 else if (!strcmp ("allocate", p))
12764 result = PRAGMA_OMP_CLAUSE_ALLOCATE;
12765 else if (!strcmp ("async", p))
12766 result = PRAGMA_OACC_CLAUSE_ASYNC;
12767 else if (!strcmp ("attach", p))
12768 result = PRAGMA_OACC_CLAUSE_ATTACH;
12771 if (!strcmp ("bind", p))
12772 result = PRAGMA_OMP_CLAUSE_BIND;
12775 if (!strcmp ("collapse", p))
12776 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
12777 else if (!strcmp ("copy", p))
12778 result = PRAGMA_OACC_CLAUSE_COPY;
12779 else if (!strcmp ("copyin", p))
12780 result = PRAGMA_OMP_CLAUSE_COPYIN;
12781 else if (!strcmp ("copyout", p))
12782 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12783 else if (!strcmp ("copyprivate", p))
12784 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
12785 else if (!strcmp ("create", p))
12786 result = PRAGMA_OACC_CLAUSE_CREATE;
12789 if (!strcmp ("defaultmap", p))
12790 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
12791 else if (!strcmp ("delete", p))
12792 result = PRAGMA_OACC_CLAUSE_DELETE;
12793 else if (!strcmp ("depend", p))
12794 result = PRAGMA_OMP_CLAUSE_DEPEND;
12795 else if (!strcmp ("detach", p))
12796 result = PRAGMA_OACC_CLAUSE_DETACH;
12797 else if (!strcmp ("device", p))
12798 result = PRAGMA_OMP_CLAUSE_DEVICE;
12799 else if (!strcmp ("deviceptr", p))
12800 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
12801 else if (!strcmp ("device_resident", p))
12802 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
12803 else if (!strcmp ("device_type", p))
12804 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
12805 else if (!strcmp ("dist_schedule", p))
12806 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
12809 if (!strcmp ("enter", p))
12810 result = PRAGMA_OMP_CLAUSE_ENTER;
12813 if (!strcmp ("filter", p))
12814 result = PRAGMA_OMP_CLAUSE_FILTER;
12815 else if (!strcmp ("final", p))
12816 result = PRAGMA_OMP_CLAUSE_FINAL;
12817 else if (!strcmp ("finalize", p))
12818 result = PRAGMA_OACC_CLAUSE_FINALIZE;
12819 else if (!strcmp ("firstprivate", p))
12820 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
12821 else if (!strcmp ("from", p))
12822 result = PRAGMA_OMP_CLAUSE_FROM;
12825 if (!strcmp ("gang", p))
12826 result = PRAGMA_OACC_CLAUSE_GANG;
12827 else if (!strcmp ("grainsize", p))
12828 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
12831 if (!strcmp ("has_device_addr", p))
12832 result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
12833 else if (!strcmp ("hint", p))
12834 result = PRAGMA_OMP_CLAUSE_HINT;
12835 else if (!strcmp ("host", p))
12836 result = PRAGMA_OACC_CLAUSE_HOST;
12839 if (!strcmp ("if_present", p))
12840 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
12841 else if (!strcmp ("in_reduction", p))
12842 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
12843 else if (!strcmp ("inbranch", p))
12844 result = PRAGMA_OMP_CLAUSE_INBRANCH;
12845 else if (!strcmp ("independent", p))
12846 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
12847 else if (!strcmp ("is_device_ptr", p))
12848 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
12851 if (!strcmp ("lastprivate", p))
12852 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
12853 else if (!strcmp ("linear", p))
12854 result = PRAGMA_OMP_CLAUSE_LINEAR;
12855 else if (!strcmp ("link", p))
12856 result = PRAGMA_OMP_CLAUSE_LINK;
12859 if (!strcmp ("map", p))
12860 result = PRAGMA_OMP_CLAUSE_MAP;
12861 else if (!strcmp ("mergeable", p))
12862 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
12865 if (!strcmp ("no_create", p))
12866 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
12867 else if (!strcmp ("nogroup", p))
12868 result = PRAGMA_OMP_CLAUSE_NOGROUP;
12869 else if (!strcmp ("nohost", p))
12870 result = PRAGMA_OACC_CLAUSE_NOHOST;
12871 else if (!strcmp ("nontemporal", p))
12872 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
12873 else if (!strcmp ("notinbranch", p))
12874 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
12875 else if (!strcmp ("nowait", p))
12876 result = PRAGMA_OMP_CLAUSE_NOWAIT;
12877 else if (!strcmp ("num_gangs", p))
12878 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
12879 else if (!strcmp ("num_tasks", p))
12880 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
12881 else if (!strcmp ("num_teams", p))
12882 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
12883 else if (!strcmp ("num_threads", p))
12884 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
12885 else if (!strcmp ("num_workers", p))
12886 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
12889 if (!strcmp ("ordered", p))
12890 result = PRAGMA_OMP_CLAUSE_ORDERED;
12891 else if (!strcmp ("order", p))
12892 result = PRAGMA_OMP_CLAUSE_ORDER;
12895 if (!strcmp ("parallel", p))
12896 result = PRAGMA_OMP_CLAUSE_PARALLEL;
12897 else if (!strcmp ("present", p))
12898 result = PRAGMA_OACC_CLAUSE_PRESENT;
12899 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12901 else if (!strcmp ("present_or_copy", p)
12902 || !strcmp ("pcopy", p))
12903 result = PRAGMA_OACC_CLAUSE_COPY;
12904 else if (!strcmp ("present_or_copyin", p)
12905 || !strcmp ("pcopyin", p))
12906 result = PRAGMA_OACC_CLAUSE_COPYIN;
12907 else if (!strcmp ("present_or_copyout", p)
12908 || !strcmp ("pcopyout", p))
12909 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12910 else if (!strcmp ("present_or_create", p)
12911 || !strcmp ("pcreate", p))
12912 result = PRAGMA_OACC_CLAUSE_CREATE;
12913 else if (!strcmp ("priority", p))
12914 result = PRAGMA_OMP_CLAUSE_PRIORITY;
12915 else if (!strcmp ("private", p))
12916 result = PRAGMA_OMP_CLAUSE_PRIVATE;
12917 else if (!strcmp ("proc_bind", p))
12918 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
12921 if (!strcmp ("reduction", p))
12922 result = PRAGMA_OMP_CLAUSE_REDUCTION;
12925 if (!strcmp ("safelen", p))
12926 result = PRAGMA_OMP_CLAUSE_SAFELEN;
12927 else if (!strcmp ("schedule", p))
12928 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
12929 else if (!strcmp ("sections", p))
12930 result = PRAGMA_OMP_CLAUSE_SECTIONS;
12931 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
12932 result = PRAGMA_OACC_CLAUSE_HOST;
12933 else if (!strcmp ("seq", p))
12934 result = PRAGMA_OACC_CLAUSE_SEQ;
12935 else if (!strcmp ("shared", p))
12936 result = PRAGMA_OMP_CLAUSE_SHARED;
12937 else if (!strcmp ("simd", p))
12938 result = PRAGMA_OMP_CLAUSE_SIMD;
12939 else if (!strcmp ("simdlen", p))
12940 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12943 if (!strcmp ("task_reduction", p))
12944 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12945 else if (!strcmp ("taskgroup", p))
12946 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12947 else if (!strcmp ("thread_limit", p))
12948 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
12949 else if (!strcmp ("threads", p))
12950 result = PRAGMA_OMP_CLAUSE_THREADS;
12951 else if (!strcmp ("tile", p))
12952 result = PRAGMA_OACC_CLAUSE_TILE;
12953 else if (!strcmp ("to", p))
12954 result = PRAGMA_OMP_CLAUSE_TO;
12957 if (!strcmp ("uniform", p))
12958 result = PRAGMA_OMP_CLAUSE_UNIFORM;
12959 else if (!strcmp ("untied", p))
12960 result = PRAGMA_OMP_CLAUSE_UNTIED;
12961 else if (!strcmp ("use_device", p))
12962 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
12963 else if (!strcmp ("use_device_addr", p))
12964 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
12965 else if (!strcmp ("use_device_ptr", p))
12966 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
12969 if (!strcmp ("vector", p))
12970 result = PRAGMA_OACC_CLAUSE_VECTOR;
12971 else if (!strcmp ("vector_length", p))
12972 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
12975 if (!strcmp ("wait", p))
12976 result = PRAGMA_OACC_CLAUSE_WAIT;
12977 else if (!strcmp ("worker", p))
12978 result = PRAGMA_OACC_CLAUSE_WORKER;
12983 if (result != PRAGMA_OMP_CLAUSE_NONE)
12984 c_parser_consume_token (parser);
12989 /* Validate that a clause of the given type does not already exist. */
12992 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
12995 if (tree c = omp_find_clause (clauses, code))
12996 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
13000 Parse wait clause or wait directive parameters. */
13003 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
13005 vec<tree, va_gc> *args;
13008 matching_parens parens;
13009 if (!parens.require_open (parser))
13012 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
13013 args_tree = build_tree_list_vec (args);
13015 for (t = args_tree; t; t = TREE_CHAIN (t))
13017 tree targ = TREE_VALUE (t);
13019 if (targ != error_mark_node)
13021 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
13023 c_parser_error (parser, "expression must be integral");
13024 targ = error_mark_node;
13028 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
13030 OMP_CLAUSE_DECL (c) = targ;
13031 OMP_CLAUSE_CHAIN (c) = list;
13037 release_tree_vector (args);
13038 parens.require_close (parser);
13042 /* OpenACC 2.0, OpenMP 2.5:
13045 variable-list , identifier
13047 If KIND is nonzero, create the appropriate node and install the
13048 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
13049 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
13051 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
13052 return the list created.
13054 The optional ALLOW_DEREF argument is true if list items can use the deref
13059 tree low_bound, length;
13062 omp_dim (tree lb, tree len, location_t lo, bool nc)
13063 : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
13067 c_parser_omp_variable_list (c_parser *parser,
13068 location_t clause_loc,
13069 enum omp_clause_code kind, tree list,
13070 bool allow_deref = false)
13072 auto_vec<omp_dim> dims;
13073 bool array_section_p;
13074 auto_vec<c_token> tokens;
13075 unsigned int tokens_avail = 0;
13080 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13082 if (c_parser_next_token_is_not (parser, CPP_NAME)
13083 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
13085 struct c_expr expr;
13086 if (kind == OMP_CLAUSE_DEPEND
13087 && c_parser_next_token_is_keyword (parser,
13088 RID_OMP_ALL_MEMORY)
13089 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
13090 || (c_parser_peek_2nd_token (parser)->type
13091 == CPP_CLOSE_PAREN)))
13093 expr.value = ridpointers[RID_OMP_ALL_MEMORY];
13094 c_parser_consume_token (parser);
13097 expr = c_parser_expr_no_commas (parser, NULL);
13098 if (expr.value != error_mark_node)
13100 tree u = build_omp_clause (clause_loc, kind);
13101 OMP_CLAUSE_DECL (u) = expr.value;
13102 OMP_CLAUSE_CHAIN (u) = list;
13106 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13109 c_parser_consume_token (parser);
13114 tokens.truncate (0);
13115 unsigned int nesting_depth = 0;
13118 c_token *token = c_parser_peek_token (parser);
13119 switch (token->type)
13122 case CPP_PRAGMA_EOL:
13124 case CPP_OPEN_BRACE:
13125 case CPP_OPEN_PAREN:
13126 case CPP_OPEN_SQUARE:
13129 case CPP_CLOSE_BRACE:
13130 case CPP_CLOSE_PAREN:
13131 case CPP_CLOSE_SQUARE:
13132 if (nesting_depth-- == 0)
13136 if (nesting_depth == 0)
13141 tokens.safe_push (*token);
13142 c_parser_consume_token (parser);
13148 /* Make sure nothing tries to read past the end of the tokens. */
13150 memset (&eof_token, 0, sizeof (eof_token));
13151 eof_token.type = CPP_EOF;
13152 tokens.safe_push (eof_token);
13153 tokens.safe_push (eof_token);
13155 tokens_avail = parser->tokens_avail;
13156 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
13157 parser->tokens = tokens.address ();
13158 parser->tokens_avail = tokens.length ();
13161 tree t = NULL_TREE;
13163 if (c_parser_next_token_is (parser, CPP_NAME)
13164 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
13166 t = lookup_name (c_parser_peek_token (parser)->value);
13168 if (t == NULL_TREE)
13170 undeclared_variable (c_parser_peek_token (parser)->location,
13171 c_parser_peek_token (parser)->value);
13172 t = error_mark_node;
13175 c_parser_consume_token (parser);
13177 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
13178 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
13179 || (c_parser_peek_token (parser)->keyword
13180 == RID_PRETTY_FUNCTION_NAME)
13181 || (c_parser_peek_token (parser)->keyword
13182 == RID_C99_FUNCTION_NAME)))
13183 t = c_parser_predefined_identifier (parser).value;
13187 c_parser_error (parser, "expected identifier");
13191 if (t == error_mark_node)
13193 else if (kind != 0)
13197 case OMP_CLAUSE__CACHE_:
13198 /* The OpenACC cache directive explicitly only allows "array
13199 elements or subarrays". */
13200 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
13202 c_parser_error (parser, "expected %<[%>");
13203 t = error_mark_node;
13207 case OMP_CLAUSE_MAP:
13208 case OMP_CLAUSE_FROM:
13209 case OMP_CLAUSE_TO:
13210 start_component_ref:
13211 while (c_parser_next_token_is (parser, CPP_DOT)
13213 && c_parser_next_token_is (parser, CPP_DEREF)))
13215 location_t op_loc = c_parser_peek_token (parser)->location;
13216 location_t arrow_loc = UNKNOWN_LOCATION;
13217 if (c_parser_next_token_is (parser, CPP_DEREF))
13221 t_expr.original_code = ERROR_MARK;
13222 t_expr.original_type = NULL;
13223 set_c_expr_source_range (&t_expr, op_loc, op_loc);
13224 t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
13226 t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
13227 arrow_loc = t_expr.get_location ();
13229 c_parser_consume_token (parser);
13230 if (!c_parser_next_token_is (parser, CPP_NAME))
13232 c_parser_error (parser, "expected identifier");
13233 t = error_mark_node;
13237 c_token *comp_tok = c_parser_peek_token (parser);
13238 tree ident = comp_tok->value;
13239 location_t comp_loc = comp_tok->location;
13240 c_parser_consume_token (parser);
13241 t = build_component_ref (op_loc, t, ident, comp_loc,
13245 case OMP_CLAUSE_AFFINITY:
13246 case OMP_CLAUSE_DEPEND:
13247 case OMP_CLAUSE_REDUCTION:
13248 case OMP_CLAUSE_IN_REDUCTION:
13249 case OMP_CLAUSE_TASK_REDUCTION:
13250 case OMP_CLAUSE_HAS_DEVICE_ADDR:
13251 array_section_p = false;
13253 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13255 location_t loc = UNKNOWN_LOCATION;
13256 tree low_bound = NULL_TREE, length = NULL_TREE;
13257 bool no_colon = false;
13259 c_parser_consume_token (parser);
13260 if (!c_parser_next_token_is (parser, CPP_COLON))
13262 location_t expr_loc
13263 = c_parser_peek_token (parser)->location;
13264 c_expr expr = c_parser_expression (parser);
13265 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13267 low_bound = expr.value;
13270 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13272 length = integer_one_node;
13277 /* Look for `:'. */
13278 if (!c_parser_require (parser, CPP_COLON,
13281 t = error_mark_node;
13284 array_section_p = true;
13285 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13287 location_t expr_loc
13288 = c_parser_peek_token (parser)->location;
13289 c_expr expr = c_parser_expression (parser);
13290 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13292 length = expr.value;
13295 /* Look for the closing `]'. */
13296 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13299 t = error_mark_node;
13303 dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
13306 if (t != error_mark_node)
13308 if ((kind == OMP_CLAUSE_MAP
13309 || kind == OMP_CLAUSE_FROM
13310 || kind == OMP_CLAUSE_TO)
13311 && !array_section_p
13312 && (c_parser_next_token_is (parser, CPP_DOT)
13314 && c_parser_next_token_is (parser,
13317 for (unsigned i = 0; i < dims.length (); i++)
13319 gcc_assert (dims[i].length == integer_one_node);
13320 t = build_array_ref (dims[i].loc,
13321 t, dims[i].low_bound);
13323 goto start_component_ref;
13326 for (unsigned i = 0; i < dims.length (); i++)
13327 t = tree_cons (dims[i].low_bound, dims[i].length, t);
13330 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13331 && t != error_mark_node
13332 && parser->tokens_avail != 2)
13334 if (array_section_p)
13336 error_at (c_parser_peek_token (parser)->location,
13337 "expected %<)%> or %<,%>");
13338 t = error_mark_node;
13342 parser->tokens = tokens.address ();
13343 parser->tokens_avail = tokens.length ();
13345 t = c_parser_expr_no_commas (parser, NULL).value;
13346 if (t != error_mark_node && parser->tokens_avail != 2)
13348 error_at (c_parser_peek_token (parser)->location,
13349 "expected %<)%> or %<,%>");
13350 t = error_mark_node;
13359 if (t != error_mark_node)
13361 tree u = build_omp_clause (clause_loc, kind);
13362 OMP_CLAUSE_DECL (u) = t;
13363 OMP_CLAUSE_CHAIN (u) = list;
13368 list = tree_cons (t, NULL_TREE, list);
13370 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13372 parser->tokens = &parser->tokens_buf[0];
13373 parser->tokens_avail = tokens_avail;
13375 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13378 c_parser_consume_token (parser);
13385 /* Similarly, but expect leading and trailing parenthesis. This is a very
13386 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13387 argument is true if list items can use the deref (->) operator. */
13390 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
13391 tree list, bool allow_deref = false)
13393 /* The clauses location. */
13394 location_t loc = c_parser_peek_token (parser)->location;
13396 matching_parens parens;
13397 if (parens.require_open (parser))
13399 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
13400 parens.skip_until_found_close (parser);
13406 copy ( variable-list )
13407 copyin ( variable-list )
13408 copyout ( variable-list )
13409 create ( variable-list )
13410 delete ( variable-list )
13411 present ( variable-list )
13414 no_create ( variable-list )
13415 attach ( variable-list )
13416 detach ( variable-list ) */
13419 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13422 enum gomp_map_kind kind;
13425 case PRAGMA_OACC_CLAUSE_ATTACH:
13426 kind = GOMP_MAP_ATTACH;
13428 case PRAGMA_OACC_CLAUSE_COPY:
13429 kind = GOMP_MAP_TOFROM;
13431 case PRAGMA_OACC_CLAUSE_COPYIN:
13432 kind = GOMP_MAP_TO;
13434 case PRAGMA_OACC_CLAUSE_COPYOUT:
13435 kind = GOMP_MAP_FROM;
13437 case PRAGMA_OACC_CLAUSE_CREATE:
13438 kind = GOMP_MAP_ALLOC;
13440 case PRAGMA_OACC_CLAUSE_DELETE:
13441 kind = GOMP_MAP_RELEASE;
13443 case PRAGMA_OACC_CLAUSE_DETACH:
13444 kind = GOMP_MAP_DETACH;
13446 case PRAGMA_OACC_CLAUSE_DEVICE:
13447 kind = GOMP_MAP_FORCE_TO;
13449 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13450 kind = GOMP_MAP_DEVICE_RESIDENT;
13452 case PRAGMA_OACC_CLAUSE_HOST:
13453 kind = GOMP_MAP_FORCE_FROM;
13455 case PRAGMA_OACC_CLAUSE_LINK:
13456 kind = GOMP_MAP_LINK;
13458 case PRAGMA_OACC_CLAUSE_NO_CREATE:
13459 kind = GOMP_MAP_IF_PRESENT;
13461 case PRAGMA_OACC_CLAUSE_PRESENT:
13462 kind = GOMP_MAP_FORCE_PRESENT;
13465 gcc_unreachable ();
13468 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
13470 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13471 OMP_CLAUSE_SET_MAP_KIND (c, kind);
13477 deviceptr ( variable-list ) */
13480 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13482 location_t loc = c_parser_peek_token (parser)->location;
13485 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13486 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13487 variable-list must only allow for pointer variables. */
13488 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13489 for (t = vars; t && t; t = TREE_CHAIN (t))
13491 tree v = TREE_PURPOSE (t);
13493 /* FIXME diagnostics: Ideally we should keep individual
13494 locations for all the variables in the var list to make the
13495 following errors more precise. Perhaps
13496 c_parser_omp_var_list_parens() should construct a list of
13497 locations to go along with the var list. */
13499 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
13500 error_at (loc, "%qD is not a variable", v);
13501 else if (TREE_TYPE (v) == error_mark_node)
13503 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13504 error_at (loc, "%qD is not a pointer variable", v);
13506 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13507 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13508 OMP_CLAUSE_DECL (u) = v;
13509 OMP_CLAUSE_CHAIN (u) = list;
13516 /* OpenACC 2.0, OpenMP 3.0:
13517 collapse ( constant-expression ) */
13520 c_parser_omp_clause_collapse (c_parser *parser, tree list)
13522 tree c, num = error_mark_node;
13526 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13527 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13529 loc = c_parser_peek_token (parser)->location;
13530 matching_parens parens;
13531 if (parens.require_open (parser))
13533 num = c_parser_expr_no_commas (parser, NULL).value;
13534 parens.skip_until_found_close (parser);
13536 if (num == error_mark_node)
13538 mark_exp_read (num);
13539 num = c_fully_fold (num, false, NULL);
13540 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13541 || !tree_fits_shwi_p (num)
13542 || (n = tree_to_shwi (num)) <= 0
13546 "collapse argument needs positive constant integer expression");
13549 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
13550 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13551 OMP_CLAUSE_CHAIN (c) = list;
13556 copyin ( variable-list ) */
13559 c_parser_omp_clause_copyin (c_parser *parser, tree list)
13561 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13565 copyprivate ( variable-list ) */
13568 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13570 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13574 default ( none | shared )
13577 default ( private | firstprivate )
13580 default ( none | present ) */
13583 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
13585 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
13586 location_t loc = c_parser_peek_token (parser)->location;
13589 matching_parens parens;
13590 if (!parens.require_open (parser))
13592 if (c_parser_next_token_is (parser, CPP_NAME))
13594 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13599 if (strcmp ("none", p) != 0)
13601 kind = OMP_CLAUSE_DEFAULT_NONE;
13607 if (strcmp ("present", p) != 0)
13609 kind = OMP_CLAUSE_DEFAULT_PRESENT;
13613 if (strcmp ("private", p) != 0)
13615 kind = OMP_CLAUSE_DEFAULT_PRIVATE;
13620 if (strcmp ("firstprivate", p) != 0 || is_oacc)
13622 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
13626 if (strcmp ("shared", p) != 0 || is_oacc)
13628 kind = OMP_CLAUSE_DEFAULT_SHARED;
13635 c_parser_consume_token (parser);
13641 c_parser_error (parser, "expected %<none%> or %<present%>");
13643 c_parser_error (parser, "expected %<none%>, %<shared%>, "
13644 "%<private%> or %<firstprivate%>");
13646 parens.skip_until_found_close (parser);
13648 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13651 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
13652 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
13653 OMP_CLAUSE_CHAIN (c) = list;
13654 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13660 firstprivate ( variable-list ) */
13663 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13665 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13669 final ( expression ) */
13672 c_parser_omp_clause_final (c_parser *parser, tree list)
13674 location_t loc = c_parser_peek_token (parser)->location;
13675 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13677 matching_parens parens;
13679 if (!parens.require_open (parser))
13680 t = error_mark_node;
13683 location_t eloc = c_parser_peek_token (parser)->location;
13684 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13685 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13686 t = c_objc_common_truthvalue_conversion (eloc, t);
13687 t = c_fully_fold (t, false, NULL);
13688 parens.skip_until_found_close (parser);
13691 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13693 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13694 OMP_CLAUSE_FINAL_EXPR (c) = t;
13695 OMP_CLAUSE_CHAIN (c) = list;
13699 c_parser_error (parser, "expected %<(%>");
13704 /* OpenACC, OpenMP 2.5:
13708 if ( directive-name-modifier : expression )
13710 directive-name-modifier:
13711 parallel | task | taskloop | target data | target | target update
13712 | target enter data | target exit data
13715 directive-name-modifier:
13716 ... | simd | cancel */
13719 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
13721 location_t location = c_parser_peek_token (parser)->location;
13722 enum tree_code if_modifier = ERROR_MARK;
13724 matching_parens parens;
13725 if (!parens.require_open (parser))
13728 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
13730 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13732 if (strcmp (p, "cancel") == 0)
13733 if_modifier = VOID_CST;
13734 else if (strcmp (p, "parallel") == 0)
13735 if_modifier = OMP_PARALLEL;
13736 else if (strcmp (p, "simd") == 0)
13737 if_modifier = OMP_SIMD;
13738 else if (strcmp (p, "task") == 0)
13739 if_modifier = OMP_TASK;
13740 else if (strcmp (p, "taskloop") == 0)
13741 if_modifier = OMP_TASKLOOP;
13742 else if (strcmp (p, "target") == 0)
13744 if_modifier = OMP_TARGET;
13745 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13747 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
13748 if (strcmp ("data", p) == 0)
13749 if_modifier = OMP_TARGET_DATA;
13750 else if (strcmp ("update", p) == 0)
13751 if_modifier = OMP_TARGET_UPDATE;
13752 else if (strcmp ("enter", p) == 0)
13753 if_modifier = OMP_TARGET_ENTER_DATA;
13754 else if (strcmp ("exit", p) == 0)
13755 if_modifier = OMP_TARGET_EXIT_DATA;
13756 if (if_modifier != OMP_TARGET)
13759 c_parser_consume_token (parser);
13763 location_t loc = c_parser_peek_2nd_token (parser)->location;
13764 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
13766 if_modifier = ERROR_MARK;
13768 if (if_modifier == OMP_TARGET_ENTER_DATA
13769 || if_modifier == OMP_TARGET_EXIT_DATA)
13771 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13773 p = IDENTIFIER_POINTER
13774 (c_parser_peek_2nd_token (parser)->value);
13775 if (strcmp ("data", p) == 0)
13779 c_parser_consume_token (parser);
13783 = c_parser_peek_2nd_token (parser)->location;
13784 error_at (loc, "expected %<data%>");
13785 if_modifier = ERROR_MARK;
13790 if (if_modifier != ERROR_MARK)
13792 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13794 c_parser_consume_token (parser);
13795 c_parser_consume_token (parser);
13801 location_t loc = c_parser_peek_2nd_token (parser)->location;
13802 error_at (loc, "expected %<:%>");
13804 if_modifier = ERROR_MARK;
13809 location_t loc = c_parser_peek_token (parser)->location;
13810 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13811 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
13812 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
13813 t = c_fully_fold (t, false, NULL);
13814 parens.skip_until_found_close (parser);
13816 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13817 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
13819 if (if_modifier != ERROR_MARK
13820 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13822 const char *p = NULL;
13823 switch (if_modifier)
13825 case VOID_CST: p = "cancel"; break;
13826 case OMP_PARALLEL: p = "parallel"; break;
13827 case OMP_SIMD: p = "simd"; break;
13828 case OMP_TASK: p = "task"; break;
13829 case OMP_TASKLOOP: p = "taskloop"; break;
13830 case OMP_TARGET_DATA: p = "target data"; break;
13831 case OMP_TARGET: p = "target"; break;
13832 case OMP_TARGET_UPDATE: p = "target update"; break;
13833 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
13834 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
13835 default: gcc_unreachable ();
13837 error_at (location, "too many %<if%> clauses with %qs modifier",
13841 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13844 error_at (location, "too many %<if%> clauses");
13846 error_at (location, "too many %<if%> clauses without modifier");
13849 else if (if_modifier == ERROR_MARK
13850 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
13852 error_at (location, "if any %<if%> clause has modifier, then all "
13853 "%<if%> clauses have to use modifier");
13858 c = build_omp_clause (location, OMP_CLAUSE_IF);
13859 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
13860 OMP_CLAUSE_IF_EXPR (c) = t;
13861 OMP_CLAUSE_CHAIN (c) = list;
13866 lastprivate ( variable-list )
13869 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13872 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
13874 /* The clauses location. */
13875 location_t loc = c_parser_peek_token (parser)->location;
13877 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13879 bool conditional = false;
13880 if (c_parser_next_token_is (parser, CPP_NAME)
13881 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13884 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13885 if (strcmp (p, "conditional") == 0)
13887 conditional = true;
13888 c_parser_consume_token (parser);
13889 c_parser_consume_token (parser);
13892 tree nlist = c_parser_omp_variable_list (parser, loc,
13893 OMP_CLAUSE_LASTPRIVATE, list);
13894 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
13896 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
13897 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
13907 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13911 /* FIXME: Should we allow duplicates? */
13912 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
13914 c = build_omp_clause (c_parser_peek_token (parser)->location,
13915 OMP_CLAUSE_MERGEABLE);
13916 OMP_CLAUSE_CHAIN (c) = list;
13925 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13928 location_t loc = c_parser_peek_token (parser)->location;
13930 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
13932 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
13933 OMP_CLAUSE_CHAIN (c) = list;
13938 num_threads ( expression ) */
13941 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
13943 location_t num_threads_loc = c_parser_peek_token (parser)->location;
13944 matching_parens parens;
13945 if (parens.require_open (parser))
13947 location_t expr_loc = c_parser_peek_token (parser)->location;
13948 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13949 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13950 tree c, t = expr.value;
13951 t = c_fully_fold (t, false, NULL);
13953 parens.skip_until_found_close (parser);
13955 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13957 c_parser_error (parser, "expected integer expression");
13961 /* Attempt to statically determine when the number isn't positive. */
13962 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13963 build_int_cst (TREE_TYPE (t), 0));
13964 protected_set_expr_location (c, expr_loc);
13965 if (c == boolean_true_node)
13967 warning_at (expr_loc, 0,
13968 "%<num_threads%> value must be positive");
13969 t = integer_one_node;
13972 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
13974 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
13975 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
13976 OMP_CLAUSE_CHAIN (c) = list;
13984 num_tasks ( expression )
13987 num_tasks ( strict : expression ) */
13990 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
13992 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
13993 matching_parens parens;
13994 if (parens.require_open (parser))
13996 bool strict = false;
13997 if (c_parser_next_token_is (parser, CPP_NAME)
13998 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
13999 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
14003 c_parser_consume_token (parser);
14004 c_parser_consume_token (parser);
14007 location_t expr_loc = c_parser_peek_token (parser)->location;
14008 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14009 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14010 tree c, t = expr.value;
14011 t = c_fully_fold (t, false, NULL);
14013 parens.skip_until_found_close (parser);
14015 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14017 c_parser_error (parser, "expected integer expression");
14021 /* Attempt to statically determine when the number isn't positive. */
14022 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14023 build_int_cst (TREE_TYPE (t), 0));
14024 if (CAN_HAVE_LOCATION_P (c))
14025 SET_EXPR_LOCATION (c, expr_loc);
14026 if (c == boolean_true_node)
14028 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
14029 t = integer_one_node;
14032 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
14034 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
14035 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
14036 OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
14037 OMP_CLAUSE_CHAIN (c) = list;
14045 grainsize ( expression )
14048 grainsize ( strict : expression ) */
14051 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
14053 location_t grainsize_loc = c_parser_peek_token (parser)->location;
14054 matching_parens parens;
14055 if (parens.require_open (parser))
14057 bool strict = false;
14058 if (c_parser_next_token_is (parser, CPP_NAME)
14059 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
14060 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
14064 c_parser_consume_token (parser);
14065 c_parser_consume_token (parser);
14068 location_t expr_loc = c_parser_peek_token (parser)->location;
14069 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14070 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14071 tree c, t = expr.value;
14072 t = c_fully_fold (t, false, NULL);
14074 parens.skip_until_found_close (parser);
14076 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14078 c_parser_error (parser, "expected integer expression");
14082 /* Attempt to statically determine when the number isn't positive. */
14083 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14084 build_int_cst (TREE_TYPE (t), 0));
14085 if (CAN_HAVE_LOCATION_P (c))
14086 SET_EXPR_LOCATION (c, expr_loc);
14087 if (c == boolean_true_node)
14089 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
14090 t = integer_one_node;
14093 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
14095 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
14096 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
14097 OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
14098 OMP_CLAUSE_CHAIN (c) = list;
14106 priority ( expression ) */
14109 c_parser_omp_clause_priority (c_parser *parser, tree list)
14111 location_t priority_loc = c_parser_peek_token (parser)->location;
14112 matching_parens parens;
14113 if (parens.require_open (parser))
14115 location_t expr_loc = c_parser_peek_token (parser)->location;
14116 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14117 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14118 tree c, t = expr.value;
14119 t = c_fully_fold (t, false, NULL);
14121 parens.skip_until_found_close (parser);
14123 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14125 c_parser_error (parser, "expected integer expression");
14129 /* Attempt to statically determine when the number isn't
14131 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
14132 build_int_cst (TREE_TYPE (t), 0));
14133 if (CAN_HAVE_LOCATION_P (c))
14134 SET_EXPR_LOCATION (c, expr_loc);
14135 if (c == boolean_true_node)
14137 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
14138 t = integer_one_node;
14141 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
14143 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
14144 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
14145 OMP_CLAUSE_CHAIN (c) = list;
14153 hint ( expression ) */
14156 c_parser_omp_clause_hint (c_parser *parser, tree list)
14158 location_t hint_loc = c_parser_peek_token (parser)->location;
14159 matching_parens parens;
14160 if (parens.require_open (parser))
14162 location_t expr_loc = c_parser_peek_token (parser)->location;
14163 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14164 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14165 tree c, t = expr.value;
14166 t = c_fully_fold (t, false, NULL);
14167 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
14168 || TREE_CODE (t) != INTEGER_CST
14169 || tree_int_cst_sgn (t) == -1)
14171 c_parser_error (parser, "expected constant integer expression "
14172 "with valid sync-hint value");
14175 parens.skip_until_found_close (parser);
14176 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
14178 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
14179 OMP_CLAUSE_HINT_EXPR (c) = t;
14180 OMP_CLAUSE_CHAIN (c) = list;
14188 filter ( integer-expression ) */
14191 c_parser_omp_clause_filter (c_parser *parser, tree list)
14193 location_t hint_loc = c_parser_peek_token (parser)->location;
14194 matching_parens parens;
14195 if (parens.require_open (parser))
14197 location_t expr_loc = c_parser_peek_token (parser)->location;
14198 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14199 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14200 tree c, t = expr.value;
14201 t = c_fully_fold (t, false, NULL);
14202 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14204 c_parser_error (parser, "expected integer expression");
14207 parens.skip_until_found_close (parser);
14208 check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
14210 c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
14211 OMP_CLAUSE_FILTER_EXPR (c) = t;
14212 OMP_CLAUSE_CHAIN (c) = list;
14220 defaultmap ( tofrom : scalar )
14223 defaultmap ( implicit-behavior [ : variable-category ] ) */
14226 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
14228 location_t loc = c_parser_peek_token (parser)->location;
14231 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14232 enum omp_clause_defaultmap_kind category
14233 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
14235 matching_parens parens;
14236 if (!parens.require_open (parser))
14238 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14240 else if (!c_parser_next_token_is (parser, CPP_NAME))
14243 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
14244 "%<tofrom%>, %<firstprivate%>, %<none%> "
14249 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14254 if (strcmp ("alloc", p) == 0)
14255 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
14257 goto invalid_behavior;
14261 if (strcmp ("default", p) == 0)
14262 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14264 goto invalid_behavior;
14268 if (strcmp ("firstprivate", p) == 0)
14269 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
14270 else if (strcmp ("from", p) == 0)
14271 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
14273 goto invalid_behavior;
14277 if (strcmp ("none", p) == 0)
14278 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
14280 goto invalid_behavior;
14284 if (strcmp ("tofrom", p) == 0)
14285 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
14286 else if (strcmp ("to", p) == 0)
14287 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
14289 goto invalid_behavior;
14293 goto invalid_behavior;
14295 c_parser_consume_token (parser);
14297 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14299 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14301 if (!c_parser_next_token_is (parser, CPP_NAME))
14304 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
14308 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14312 if (strcmp ("aggregate", p) == 0)
14313 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
14315 goto invalid_category;
14319 if (strcmp ("pointer", p) == 0)
14320 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
14322 goto invalid_category;
14326 if (strcmp ("scalar", p) == 0)
14327 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
14329 goto invalid_category;
14333 goto invalid_category;
14336 c_parser_consume_token (parser);
14338 parens.skip_until_found_close (parser);
14340 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14341 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
14342 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14343 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
14344 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
14345 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
14347 enum omp_clause_defaultmap_kind cat = category;
14348 location_t loc = OMP_CLAUSE_LOCATION (c);
14349 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14350 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14354 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14357 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14360 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14363 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14367 gcc_unreachable ();
14370 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14373 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14378 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
14379 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
14380 OMP_CLAUSE_CHAIN (c) = list;
14384 parens.skip_until_found_close (parser);
14389 use_device ( variable-list )
14392 use_device_ptr ( variable-list ) */
14395 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14397 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14402 use_device_addr ( variable-list ) */
14405 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14407 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14412 has_device_addr ( variable-list ) */
14415 c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
14417 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
14422 is_device_ptr ( variable-list ) */
14425 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14427 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14431 num_gangs ( expression )
14432 num_workers ( expression )
14433 vector_length ( expression ) */
14436 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14439 location_t loc = c_parser_peek_token (parser)->location;
14441 matching_parens parens;
14442 if (!parens.require_open (parser))
14445 location_t expr_loc = c_parser_peek_token (parser)->location;
14446 c_expr expr = c_parser_expression (parser);
14447 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14448 tree c, t = expr.value;
14449 t = c_fully_fold (t, false, NULL);
14451 parens.skip_until_found_close (parser);
14453 if (t == error_mark_node)
14455 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14457 error_at (expr_loc, "%qs expression must be integral",
14458 omp_clause_code_name[code]);
14462 /* Attempt to statically determine when the number isn't positive. */
14463 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14464 build_int_cst (TREE_TYPE (t), 0));
14465 protected_set_expr_location (c, expr_loc);
14466 if (c == boolean_true_node)
14468 warning_at (expr_loc, 0,
14469 "%qs value must be positive",
14470 omp_clause_code_name[code]);
14471 t = integer_one_node;
14474 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14476 c = build_omp_clause (loc, code);
14477 OMP_CLAUSE_OPERAND (c, 0) = t;
14478 OMP_CLAUSE_CHAIN (c) = list;
14484 gang [( gang-arg-list )]
14485 worker [( [num:] int-expr )]
14486 vector [( [length:] int-expr )]
14488 where gang-arg is one of:
14493 and size-expr may be:
14500 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14501 omp_clause_code kind,
14502 const char *str, tree list)
14504 const char *id = "num";
14505 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
14507 if (kind == OMP_CLAUSE_VECTOR)
14510 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14512 c_parser_consume_token (parser);
14516 c_token *next = c_parser_peek_token (parser);
14519 /* Gang static argument. */
14520 if (kind == OMP_CLAUSE_GANG
14521 && c_parser_next_token_is_keyword (parser, RID_STATIC))
14523 c_parser_consume_token (parser);
14525 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14526 goto cleanup_error;
14529 if (ops[idx] != NULL_TREE)
14531 c_parser_error (parser, "too many %<static%> arguments");
14532 goto cleanup_error;
14535 /* Check for the '*' argument. */
14536 if (c_parser_next_token_is (parser, CPP_MULT)
14537 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14538 || c_parser_peek_2nd_token (parser)->type
14539 == CPP_CLOSE_PAREN))
14541 c_parser_consume_token (parser);
14542 ops[idx] = integer_minus_one_node;
14544 if (c_parser_next_token_is (parser, CPP_COMMA))
14546 c_parser_consume_token (parser);
14553 /* Worker num: argument and vector length: arguments. */
14554 else if (c_parser_next_token_is (parser, CPP_NAME)
14555 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14556 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14558 c_parser_consume_token (parser); /* id */
14559 c_parser_consume_token (parser); /* ':' */
14562 /* Now collect the actual argument. */
14563 if (ops[idx] != NULL_TREE)
14565 c_parser_error (parser, "unexpected argument");
14566 goto cleanup_error;
14569 location_t expr_loc = c_parser_peek_token (parser)->location;
14570 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14571 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14572 tree expr = cexpr.value;
14573 if (expr == error_mark_node)
14574 goto cleanup_error;
14576 expr = c_fully_fold (expr, false, NULL);
14578 /* Attempt to statically determine when the number isn't a
14579 positive integer. */
14581 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14583 c_parser_error (parser, "expected integer expression");
14587 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14588 build_int_cst (TREE_TYPE (expr), 0));
14589 if (c == boolean_true_node)
14591 warning_at (loc, 0,
14592 "%qs value must be positive", str);
14593 expr = integer_one_node;
14598 if (kind == OMP_CLAUSE_GANG
14599 && c_parser_next_token_is (parser, CPP_COMMA))
14601 c_parser_consume_token (parser);
14608 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14609 goto cleanup_error;
14612 check_no_duplicate_clause (list, kind, str);
14614 c = build_omp_clause (loc, kind);
14617 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14619 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14620 OMP_CLAUSE_CHAIN (c) = list;
14625 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14637 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
14640 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14642 tree c = build_omp_clause (loc, code);
14643 OMP_CLAUSE_CHAIN (c) = list;
14649 async [( int-expr )] */
14652 c_parser_oacc_clause_async (c_parser *parser, tree list)
14655 location_t loc = c_parser_peek_token (parser)->location;
14657 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14659 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14661 c_parser_consume_token (parser);
14663 t = c_parser_expr_no_commas (parser, NULL).value;
14664 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14665 c_parser_error (parser, "expected integer expression");
14666 else if (t == error_mark_node
14667 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14671 t = c_fully_fold (t, false, NULL);
14673 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14675 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14676 OMP_CLAUSE_ASYNC_EXPR (c) = t;
14677 OMP_CLAUSE_CHAIN (c) = list;
14684 tile ( size-expr-list ) */
14687 c_parser_oacc_clause_tile (c_parser *parser, tree list)
14689 tree c, expr = error_mark_node;
14691 tree tile = NULL_TREE;
14693 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14694 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14696 loc = c_parser_peek_token (parser)->location;
14697 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14702 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14705 if (c_parser_next_token_is (parser, CPP_MULT)
14706 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14707 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14709 c_parser_consume_token (parser);
14710 expr = integer_zero_node;
14714 location_t expr_loc = c_parser_peek_token (parser)->location;
14715 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14716 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14717 expr = cexpr.value;
14719 if (expr == error_mark_node)
14721 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14726 expr = c_fully_fold (expr, false, NULL);
14728 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14729 || !tree_fits_shwi_p (expr)
14730 || tree_to_shwi (expr) <= 0)
14732 error_at (expr_loc, "%<tile%> argument needs positive"
14733 " integral constant");
14734 expr = integer_zero_node;
14738 tile = tree_cons (NULL_TREE, expr, tile);
14740 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
14742 /* Consume the trailing ')'. */
14743 c_parser_consume_token (parser);
14745 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
14746 tile = nreverse (tile);
14747 OMP_CLAUSE_TILE_LIST (c) = tile;
14748 OMP_CLAUSE_CHAIN (c) = list;
14753 wait [( int-expr-list )] */
14756 c_parser_oacc_clause_wait (c_parser *parser, tree list)
14758 location_t clause_loc = c_parser_peek_token (parser)->location;
14760 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14761 list = c_parser_oacc_wait_list (parser, clause_loc, list);
14764 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
14766 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14767 OMP_CLAUSE_CHAIN (c) = list;
14776 order ( concurrent )
14779 order ( order-modifier : concurrent )
14786 c_parser_omp_clause_order (c_parser *parser, tree list)
14788 location_t loc = c_parser_peek_token (parser)->location;
14791 bool unconstrained = false;
14792 bool reproducible = false;
14794 matching_parens parens;
14795 if (!parens.require_open (parser))
14797 if (c_parser_next_token_is (parser, CPP_NAME)
14798 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14800 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14801 if (strcmp (p, "unconstrained") == 0)
14802 unconstrained = true;
14803 else if (strcmp (p, "reproducible") == 0)
14804 reproducible = true;
14807 c_parser_error (parser, "expected %<reproducible%> or "
14808 "%<unconstrained%>");
14811 c_parser_consume_token (parser);
14812 c_parser_consume_token (parser);
14814 if (!c_parser_next_token_is (parser, CPP_NAME))
14816 c_parser_error (parser, "expected %<concurrent%>");
14819 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14820 if (strcmp (p, "concurrent") != 0)
14822 c_parser_error (parser, "expected %<concurrent%>");
14825 c_parser_consume_token (parser);
14826 parens.skip_until_found_close (parser);
14827 check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
14828 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
14829 OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
14830 OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
14831 OMP_CLAUSE_CHAIN (c) = list;
14835 parens.skip_until_found_close (parser);
14841 bind ( teams | parallel | thread ) */
14844 c_parser_omp_clause_bind (c_parser *parser, tree list)
14846 location_t loc = c_parser_peek_token (parser)->location;
14849 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
14851 matching_parens parens;
14852 if (!parens.require_open (parser))
14854 if (!c_parser_next_token_is (parser, CPP_NAME))
14857 c_parser_error (parser,
14858 "expected %<teams%>, %<parallel%> or %<thread%>");
14859 parens.skip_until_found_close (parser);
14862 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14863 if (strcmp (p, "teams") == 0)
14864 kind = OMP_CLAUSE_BIND_TEAMS;
14865 else if (strcmp (p, "parallel") == 0)
14866 kind = OMP_CLAUSE_BIND_PARALLEL;
14867 else if (strcmp (p, "thread") != 0)
14869 c_parser_consume_token (parser);
14870 parens.skip_until_found_close (parser);
14871 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14872 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
14873 OMP_CLAUSE_BIND_KIND (c) = kind;
14874 OMP_CLAUSE_CHAIN (c) = list;
14883 ordered ( constant-expression ) */
14886 c_parser_omp_clause_ordered (c_parser *parser, tree list)
14888 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
14890 tree c, num = NULL_TREE;
14892 location_t loc = c_parser_peek_token (parser)->location;
14893 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14895 matching_parens parens;
14896 parens.consume_open (parser);
14897 num = c_parser_expr_no_commas (parser, NULL).value;
14898 parens.skip_until_found_close (parser);
14900 if (num == error_mark_node)
14904 mark_exp_read (num);
14905 num = c_fully_fold (num, false, NULL);
14906 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14907 || !tree_fits_shwi_p (num)
14908 || (n = tree_to_shwi (num)) <= 0
14911 error_at (loc, "ordered argument needs positive "
14912 "constant integer expression");
14916 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
14917 OMP_CLAUSE_ORDERED_EXPR (c) = num;
14918 OMP_CLAUSE_CHAIN (c) = list;
14923 private ( variable-list ) */
14926 c_parser_omp_clause_private (c_parser *parser, tree list)
14928 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
14932 reduction ( reduction-operator : variable-list )
14934 reduction-operator:
14935 One of: + * - & ^ | && ||
14939 reduction-operator:
14940 One of: + * - & ^ | && || max min
14944 reduction-operator:
14945 One of: + * - & ^ | && ||
14949 reduction ( reduction-modifier, reduction-operator : variable-list )
14950 in_reduction ( reduction-operator : variable-list )
14951 task_reduction ( reduction-operator : variable-list ) */
14954 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
14955 bool is_omp, tree list)
14957 location_t clause_loc = c_parser_peek_token (parser)->location;
14958 matching_parens parens;
14959 if (parens.require_open (parser))
14962 bool inscan = false;
14963 enum tree_code code = ERROR_MARK;
14964 tree reduc_id = NULL_TREE;
14966 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
14968 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
14969 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14971 c_parser_consume_token (parser);
14972 c_parser_consume_token (parser);
14974 else if (c_parser_next_token_is (parser, CPP_NAME)
14975 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14978 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14979 if (strcmp (p, "task") == 0)
14981 else if (strcmp (p, "inscan") == 0)
14983 if (task || inscan)
14985 c_parser_consume_token (parser);
14986 c_parser_consume_token (parser);
14991 switch (c_parser_peek_token (parser)->type)
15003 code = BIT_AND_EXPR;
15006 code = BIT_XOR_EXPR;
15009 code = BIT_IOR_EXPR;
15012 code = TRUTH_ANDIF_EXPR;
15015 code = TRUTH_ORIF_EXPR;
15020 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15021 if (strcmp (p, "min") == 0)
15026 if (strcmp (p, "max") == 0)
15031 reduc_id = c_parser_peek_token (parser)->value;
15035 c_parser_error (parser,
15036 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
15037 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
15038 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15041 c_parser_consume_token (parser);
15042 reduc_id = c_omp_reduction_id (code, reduc_id);
15043 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15047 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
15048 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15050 tree d = OMP_CLAUSE_DECL (c), type;
15051 if (TREE_CODE (d) != TREE_LIST)
15052 type = TREE_TYPE (d);
15057 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
15059 type = TREE_TYPE (t);
15062 if (TREE_CODE (type) != POINTER_TYPE
15063 && TREE_CODE (type) != ARRAY_TYPE)
15065 type = TREE_TYPE (type);
15069 while (TREE_CODE (type) == ARRAY_TYPE)
15070 type = TREE_TYPE (type);
15071 OMP_CLAUSE_REDUCTION_CODE (c) = code;
15073 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
15075 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
15076 if (code == ERROR_MARK
15077 || !(INTEGRAL_TYPE_P (type)
15078 || TREE_CODE (type) == REAL_TYPE
15079 || TREE_CODE (type) == COMPLEX_TYPE))
15080 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
15081 = c_omp_reduction_lookup (reduc_id,
15082 TYPE_MAIN_VARIANT (type));
15087 parens.skip_until_found_close (parser);
15093 schedule ( schedule-kind )
15094 schedule ( schedule-kind , expression )
15097 static | dynamic | guided | runtime | auto
15100 schedule ( schedule-modifier : schedule-kind )
15101 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15109 c_parser_omp_clause_schedule (c_parser *parser, tree list)
15112 location_t loc = c_parser_peek_token (parser)->location;
15113 int modifiers = 0, nmodifiers = 0;
15115 matching_parens parens;
15116 if (!parens.require_open (parser))
15119 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
15121 location_t comma = UNKNOWN_LOCATION;
15122 while (c_parser_next_token_is (parser, CPP_NAME))
15124 tree kind = c_parser_peek_token (parser)->value;
15125 const char *p = IDENTIFIER_POINTER (kind);
15126 if (strcmp ("simd", p) == 0)
15127 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
15128 else if (strcmp ("monotonic", p) == 0)
15129 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
15130 else if (strcmp ("nonmonotonic", p) == 0)
15131 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
15134 comma = UNKNOWN_LOCATION;
15135 c_parser_consume_token (parser);
15136 if (nmodifiers++ == 0
15137 && c_parser_next_token_is (parser, CPP_COMMA))
15139 comma = c_parser_peek_token (parser)->location;
15140 c_parser_consume_token (parser);
15144 c_parser_require (parser, CPP_COLON, "expected %<:%>");
15148 if (comma != UNKNOWN_LOCATION)
15149 error_at (comma, "expected %<:%>");
15151 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
15152 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15153 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15154 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15156 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15161 if (c_parser_next_token_is (parser, CPP_NAME))
15163 tree kind = c_parser_peek_token (parser)->value;
15164 const char *p = IDENTIFIER_POINTER (kind);
15169 if (strcmp ("dynamic", p) != 0)
15171 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
15175 if (strcmp ("guided", p) != 0)
15177 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
15181 if (strcmp ("runtime", p) != 0)
15183 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
15190 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
15191 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
15192 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
15193 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
15197 c_parser_consume_token (parser);
15198 if (c_parser_next_token_is (parser, CPP_COMMA))
15201 c_parser_consume_token (parser);
15203 here = c_parser_peek_token (parser)->location;
15204 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15205 expr = convert_lvalue_to_rvalue (here, expr, false, true);
15207 t = c_fully_fold (t, false, NULL);
15209 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
15210 error_at (here, "schedule %<runtime%> does not take "
15211 "a %<chunk_size%> parameter");
15212 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
15214 "schedule %<auto%> does not take "
15215 "a %<chunk_size%> parameter");
15216 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
15218 /* Attempt to statically determine when the number isn't
15220 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
15221 build_int_cst (TREE_TYPE (t), 0));
15222 protected_set_expr_location (s, loc);
15223 if (s == boolean_true_node)
15225 warning_at (loc, 0,
15226 "chunk size value must be positive");
15227 t = integer_one_node;
15229 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
15232 c_parser_error (parser, "expected integer expression");
15234 parens.skip_until_found_close (parser);
15237 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15238 "expected %<,%> or %<)%>");
15240 OMP_CLAUSE_SCHEDULE_KIND (c)
15241 = (enum omp_clause_schedule_kind)
15242 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
15244 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
15245 OMP_CLAUSE_CHAIN (c) = list;
15249 c_parser_error (parser, "invalid schedule kind");
15250 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15255 shared ( variable-list ) */
15258 c_parser_omp_clause_shared (c_parser *parser, tree list)
15260 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
15267 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15271 /* FIXME: Should we allow duplicates? */
15272 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
15274 c = build_omp_clause (c_parser_peek_token (parser)->location,
15275 OMP_CLAUSE_UNTIED);
15276 OMP_CLAUSE_CHAIN (c) = list;
15286 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
15287 enum omp_clause_code code, tree list)
15289 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15291 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15292 OMP_CLAUSE_CHAIN (c) = list;
15304 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
15305 enum omp_clause_code code, tree list)
15307 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15308 OMP_CLAUSE_CHAIN (c) = list;
15317 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15319 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
15320 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
15321 OMP_CLAUSE_NOGROUP);
15322 OMP_CLAUSE_CHAIN (c) = list;
15331 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
15332 enum omp_clause_code code, tree list)
15334 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15335 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15336 OMP_CLAUSE_CHAIN (c) = list;
15341 num_teams ( expression )
15344 num_teams ( expression : expression ) */
15347 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
15349 location_t num_teams_loc = c_parser_peek_token (parser)->location;
15350 matching_parens parens;
15351 if (parens.require_open (parser))
15353 location_t upper_loc = c_parser_peek_token (parser)->location;
15354 location_t lower_loc = UNKNOWN_LOCATION;
15355 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15356 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15357 tree c, upper = expr.value, lower = NULL_TREE;
15358 upper = c_fully_fold (upper, false, NULL);
15360 if (c_parser_next_token_is (parser, CPP_COLON))
15362 c_parser_consume_token (parser);
15363 lower_loc = upper_loc;
15365 upper_loc = c_parser_peek_token (parser)->location;
15366 expr = c_parser_expr_no_commas (parser, NULL);
15367 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15368 upper = expr.value;
15369 upper = c_fully_fold (upper, false, NULL);
15372 parens.skip_until_found_close (parser);
15374 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
15375 || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
15377 c_parser_error (parser, "expected integer expression");
15381 /* Attempt to statically determine when the number isn't positive. */
15382 c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
15383 build_int_cst (TREE_TYPE (upper), 0));
15384 protected_set_expr_location (c, upper_loc);
15385 if (c == boolean_true_node)
15387 warning_at (upper_loc, 0, "%<num_teams%> value must be positive");
15388 upper = integer_one_node;
15392 c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
15393 build_int_cst (TREE_TYPE (lower), 0));
15394 protected_set_expr_location (c, lower_loc);
15395 if (c == boolean_true_node)
15397 warning_at (lower_loc, 0, "%<num_teams%> value must be positive");
15400 else if (TREE_CODE (lower) == INTEGER_CST
15401 && TREE_CODE (upper) == INTEGER_CST
15402 && tree_int_cst_lt (upper, lower))
15404 warning_at (lower_loc, 0, "%<num_teams%> lower bound %qE bigger "
15405 "than upper bound %qE", lower, upper);
15410 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
15412 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
15413 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
15414 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
15415 OMP_CLAUSE_CHAIN (c) = list;
15423 thread_limit ( expression ) */
15426 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
15428 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
15429 matching_parens parens;
15430 if (parens.require_open (parser))
15432 location_t expr_loc = c_parser_peek_token (parser)->location;
15433 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15434 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15435 tree c, t = expr.value;
15436 t = c_fully_fold (t, false, NULL);
15438 parens.skip_until_found_close (parser);
15440 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15442 c_parser_error (parser, "expected integer expression");
15446 /* Attempt to statically determine when the number isn't positive. */
15447 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15448 build_int_cst (TREE_TYPE (t), 0));
15449 protected_set_expr_location (c, expr_loc);
15450 if (c == boolean_true_node)
15452 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15453 t = integer_one_node;
15456 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15459 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15460 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15461 OMP_CLAUSE_CHAIN (c) = list;
15469 aligned ( variable-list )
15470 aligned ( variable-list : constant-expression ) */
15473 c_parser_omp_clause_aligned (c_parser *parser, tree list)
15475 location_t clause_loc = c_parser_peek_token (parser)->location;
15478 matching_parens parens;
15479 if (!parens.require_open (parser))
15482 nl = c_parser_omp_variable_list (parser, clause_loc,
15483 OMP_CLAUSE_ALIGNED, list);
15485 if (c_parser_next_token_is (parser, CPP_COLON))
15487 c_parser_consume_token (parser);
15488 location_t expr_loc = c_parser_peek_token (parser)->location;
15489 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15490 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15491 tree alignment = expr.value;
15492 alignment = c_fully_fold (alignment, false, NULL);
15493 if (TREE_CODE (alignment) != INTEGER_CST
15494 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15495 || tree_int_cst_sgn (alignment) != 1)
15497 error_at (clause_loc, "%<aligned%> clause alignment expression must "
15498 "be positive constant integer expression");
15499 alignment = NULL_TREE;
15502 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15503 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15506 parens.skip_until_found_close (parser);
15511 allocate ( variable-list )
15512 allocate ( expression : variable-list )
15515 allocate ( allocator-modifier : variable-list )
15516 allocate ( allocator-modifier , allocator-modifier : variable-list )
15518 allocator-modifier:
15519 allocator ( expression )
15520 align ( expression ) */
15523 c_parser_omp_clause_allocate (c_parser *parser, tree list)
15525 location_t clause_loc = c_parser_peek_token (parser)->location;
15527 tree allocator = NULL_TREE;
15528 tree align = NULL_TREE;
15530 matching_parens parens;
15531 if (!parens.require_open (parser))
15534 if ((c_parser_next_token_is_not (parser, CPP_NAME)
15535 && c_parser_next_token_is_not (parser, CPP_KEYWORD))
15536 || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
15537 && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
15539 bool has_modifiers = false;
15540 tree orig_type = NULL_TREE;
15541 if (c_parser_next_token_is (parser, CPP_NAME)
15542 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
15544 unsigned int n = 3;
15546 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15547 if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
15548 && c_parser_check_balanced_raw_token_sequence (parser, &n)
15549 && (c_parser_peek_nth_token_raw (parser, n)->type
15550 == CPP_CLOSE_PAREN))
15552 if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15554 has_modifiers = true;
15555 else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15557 && (c_parser_peek_nth_token_raw (parser, n + 2)->type
15559 && (c_parser_peek_nth_token_raw (parser, n + 3)->type
15560 == CPP_OPEN_PAREN))
15562 c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
15563 const char *q = IDENTIFIER_POINTER (tok->value);
15565 if ((strcmp (q, "allocator") == 0
15566 || strcmp (q, "align") == 0)
15567 && c_parser_check_balanced_raw_token_sequence (parser,
15569 && (c_parser_peek_nth_token_raw (parser, n)->type
15570 == CPP_CLOSE_PAREN)
15571 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
15573 has_modifiers = true;
15578 c_parser_consume_token (parser);
15579 matching_parens parens2;;
15580 parens2.require_open (parser);
15581 location_t expr_loc = c_parser_peek_token (parser)->location;
15582 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15583 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15584 if (strcmp (p, "allocator") == 0)
15586 allocator = expr.value;
15587 allocator = c_fully_fold (allocator, false, NULL);
15588 orig_type = expr.original_type
15589 ? expr.original_type : TREE_TYPE (allocator);
15590 orig_type = TYPE_MAIN_VARIANT (orig_type);
15594 align = expr.value;
15595 align = c_fully_fold (align, false, NULL);
15597 parens2.skip_until_found_close (parser);
15598 if (c_parser_next_token_is (parser, CPP_COMMA))
15600 c_parser_consume_token (parser);
15601 c_token *tok = c_parser_peek_token (parser);
15602 const char *q = "";
15603 if (c_parser_next_token_is (parser, CPP_NAME))
15604 q = IDENTIFIER_POINTER (tok->value);
15605 if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
15607 c_parser_error (parser, "expected %<allocator%> or "
15609 parens.skip_until_found_close (parser);
15612 else if (strcmp (p, q) == 0)
15614 error_at (tok->location, "duplicate %qs modifier", p);
15615 parens.skip_until_found_close (parser);
15618 c_parser_consume_token (parser);
15619 if (!parens2.require_open (parser))
15621 parens.skip_until_found_close (parser);
15624 expr_loc = c_parser_peek_token (parser)->location;
15625 expr = c_parser_expr_no_commas (parser, NULL);
15626 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
15628 if (strcmp (q, "allocator") == 0)
15630 allocator = expr.value;
15631 allocator = c_fully_fold (allocator, false, NULL);
15632 orig_type = expr.original_type
15633 ? expr.original_type : TREE_TYPE (allocator);
15634 orig_type = TYPE_MAIN_VARIANT (orig_type);
15638 align = expr.value;
15639 align = c_fully_fold (align, false, NULL);
15641 parens2.skip_until_found_close (parser);
15645 if (!has_modifiers)
15647 location_t expr_loc = c_parser_peek_token (parser)->location;
15648 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15649 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15650 allocator = expr.value;
15651 allocator = c_fully_fold (allocator, false, NULL);
15652 orig_type = expr.original_type
15653 ? expr.original_type : TREE_TYPE (allocator);
15654 orig_type = TYPE_MAIN_VARIANT (orig_type);
15657 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
15658 || TREE_CODE (orig_type) != ENUMERAL_TYPE
15659 || (TYPE_NAME (orig_type)
15660 != get_identifier ("omp_allocator_handle_t"))))
15662 error_at (clause_loc, "%<allocate%> clause allocator expression "
15663 "has type %qT rather than "
15664 "%<omp_allocator_handle_t%>",
15665 TREE_TYPE (allocator));
15666 allocator = NULL_TREE;
15669 && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
15670 || !tree_fits_uhwi_p (align)
15671 || !integer_pow2p (align)))
15673 error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
15674 "argument needs to be positive constant "
15675 "power of two integer expression");
15678 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15680 parens.skip_until_found_close (parser);
15685 nl = c_parser_omp_variable_list (parser, clause_loc,
15686 OMP_CLAUSE_ALLOCATE, list);
15688 if (allocator || align)
15689 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15691 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
15692 OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
15695 parens.skip_until_found_close (parser);
15700 linear ( variable-list )
15701 linear ( variable-list : expression )
15704 linear ( modifier ( variable-list ) )
15705 linear ( modifier ( variable-list ) : expression )
15711 linear ( variable-list : modifiers-list )
15715 step ( expression ) */
15718 c_parser_omp_clause_linear (c_parser *parser, tree list)
15720 location_t clause_loc = c_parser_peek_token (parser)->location;
15722 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
15723 bool old_linear_modifier = false;
15725 matching_parens parens;
15726 if (!parens.require_open (parser))
15729 if (c_parser_next_token_is (parser, CPP_NAME))
15731 c_token *tok = c_parser_peek_token (parser);
15732 const char *p = IDENTIFIER_POINTER (tok->value);
15733 if (strcmp ("val", p) == 0)
15734 kind = OMP_CLAUSE_LINEAR_VAL;
15735 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
15736 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15737 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15739 old_linear_modifier = true;
15740 c_parser_consume_token (parser);
15741 c_parser_consume_token (parser);
15745 nl = c_parser_omp_variable_list (parser, clause_loc,
15746 OMP_CLAUSE_LINEAR, list);
15748 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15749 parens.skip_until_found_close (parser);
15751 if (c_parser_next_token_is (parser, CPP_COLON))
15753 c_parser_consume_token (parser);
15754 location_t expr_loc = c_parser_peek_token (parser)->location;
15755 bool has_modifiers = false;
15756 if (kind == OMP_CLAUSE_LINEAR_DEFAULT
15757 && c_parser_next_token_is (parser, CPP_NAME))
15759 c_token *tok = c_parser_peek_token (parser);
15760 const char *p = IDENTIFIER_POINTER (tok->value);
15761 unsigned int pos = 0;
15762 if (strcmp ("val", p) == 0)
15764 else if (strcmp ("step", p) == 0
15765 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
15768 if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
15769 && (c_parser_peek_nth_token_raw (parser, pos)->type
15770 == CPP_CLOSE_PAREN))
15777 tok = c_parser_peek_nth_token_raw (parser, pos);
15778 if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
15779 has_modifiers = true;
15785 while (c_parser_next_token_is (parser, CPP_NAME))
15787 c_token *tok = c_parser_peek_token (parser);
15788 const char *p = IDENTIFIER_POINTER (tok->value);
15789 if (strcmp ("val", p) == 0)
15791 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15792 error_at (tok->location, "multiple linear modifiers");
15793 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15794 c_parser_consume_token (parser);
15796 else if (strcmp ("step", p) == 0)
15798 c_parser_consume_token (parser);
15799 matching_parens parens2;
15800 if (parens2.require_open (parser))
15803 error_at (tok->location,
15804 "multiple %<step%> modifiers");
15805 expr_loc = c_parser_peek_token (parser)->location;
15806 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15807 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
15809 step = c_fully_fold (expr.value, false, NULL);
15810 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15812 error_at (clause_loc, "%<linear%> clause step "
15813 "expression must be integral");
15814 step = integer_one_node;
15816 parens2.skip_until_found_close (parser);
15823 if (c_parser_next_token_is (parser, CPP_COMMA))
15825 c_parser_consume_token (parser);
15831 step = integer_one_node;
15835 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15836 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15837 step = c_fully_fold (expr.value, false, NULL);
15838 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15840 error_at (clause_loc, "%<linear%> clause step expression must "
15842 step = integer_one_node;
15848 step = integer_one_node;
15850 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15852 OMP_CLAUSE_LINEAR_STEP (c) = step;
15853 OMP_CLAUSE_LINEAR_KIND (c) = kind;
15854 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
15857 parens.skip_until_found_close (parser);
15862 nontemporal ( variable-list ) */
15865 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
15867 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
15871 safelen ( constant-expression ) */
15874 c_parser_omp_clause_safelen (c_parser *parser, tree list)
15876 location_t clause_loc = c_parser_peek_token (parser)->location;
15879 matching_parens parens;
15880 if (!parens.require_open (parser))
15883 location_t expr_loc = c_parser_peek_token (parser)->location;
15884 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15885 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15887 t = c_fully_fold (t, false, NULL);
15888 if (TREE_CODE (t) != INTEGER_CST
15889 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15890 || tree_int_cst_sgn (t) != 1)
15892 error_at (clause_loc, "%<safelen%> clause expression must "
15893 "be positive constant integer expression");
15897 parens.skip_until_found_close (parser);
15898 if (t == NULL_TREE || t == error_mark_node)
15901 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
15903 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
15904 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
15905 OMP_CLAUSE_CHAIN (c) = list;
15910 simdlen ( constant-expression ) */
15913 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
15915 location_t clause_loc = c_parser_peek_token (parser)->location;
15918 matching_parens parens;
15919 if (!parens.require_open (parser))
15922 location_t expr_loc = c_parser_peek_token (parser)->location;
15923 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15924 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15926 t = c_fully_fold (t, false, NULL);
15927 if (TREE_CODE (t) != INTEGER_CST
15928 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15929 || tree_int_cst_sgn (t) != 1)
15931 error_at (clause_loc, "%<simdlen%> clause expression must "
15932 "be positive constant integer expression");
15936 parens.skip_until_found_close (parser);
15937 if (t == NULL_TREE || t == error_mark_node)
15940 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
15942 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
15943 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
15944 OMP_CLAUSE_CHAIN (c) = list;
15950 identifier [+/- integer]
15951 vec , identifier [+/- integer]
15955 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
15959 if (c_parser_next_token_is_not (parser, CPP_NAME)
15960 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15962 c_parser_error (parser, "expected identifier");
15966 while (c_parser_next_token_is (parser, CPP_NAME)
15967 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15969 tree t = lookup_name (c_parser_peek_token (parser)->value);
15970 tree addend = NULL;
15972 if (t == NULL_TREE)
15974 undeclared_variable (c_parser_peek_token (parser)->location,
15975 c_parser_peek_token (parser)->value);
15976 t = error_mark_node;
15979 c_parser_consume_token (parser);
15982 if (c_parser_next_token_is (parser, CPP_MINUS))
15984 else if (!c_parser_next_token_is (parser, CPP_PLUS))
15986 addend = integer_zero_node;
15988 goto add_to_vector;
15990 c_parser_consume_token (parser);
15992 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
15994 c_parser_error (parser, "expected integer");
15998 addend = c_parser_peek_token (parser)->value;
15999 if (TREE_CODE (addend) != INTEGER_CST)
16001 c_parser_error (parser, "expected integer");
16004 c_parser_consume_token (parser);
16007 if (t != error_mark_node)
16009 vec = tree_cons (addend, t, vec);
16011 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
16014 if (c_parser_next_token_is_not (parser, CPP_COMMA)
16015 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
16016 || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
16019 c_parser_consume_token (parser);
16022 if (vec == NULL_TREE)
16025 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
16026 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
16027 OMP_CLAUSE_DECL (u) = nreverse (vec);
16028 OMP_CLAUSE_CHAIN (u) = list;
16033 iterators ( iterators-definition )
16035 iterators-definition:
16037 iterator-specifier , iterators-definition
16039 iterator-specifier:
16040 identifier = range-specification
16041 iterator-type identifier = range-specification
16043 range-specification:
16045 begin : end : step */
16048 c_parser_omp_iterators (c_parser *parser)
16050 tree ret = NULL_TREE, *last = &ret;
16051 c_parser_consume_token (parser);
16055 matching_parens parens;
16056 if (!parens.require_open (parser))
16057 return error_mark_node;
16061 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
16062 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
16064 struct c_type_name *type = c_parser_type_name (parser);
16066 iter_type = groktypename (type, &type_expr, NULL);
16068 if (iter_type == NULL_TREE)
16069 iter_type = integer_type_node;
16071 location_t loc = c_parser_peek_token (parser)->location;
16072 if (!c_parser_next_token_is (parser, CPP_NAME))
16074 c_parser_error (parser, "expected identifier");
16078 tree id = c_parser_peek_token (parser)->value;
16079 c_parser_consume_token (parser);
16081 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
16084 location_t eloc = c_parser_peek_token (parser)->location;
16085 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16086 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16087 tree begin = expr.value;
16089 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16092 eloc = c_parser_peek_token (parser)->location;
16093 expr = c_parser_expr_no_commas (parser, NULL);
16094 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16095 tree end = expr.value;
16097 tree step = integer_one_node;
16098 if (c_parser_next_token_is (parser, CPP_COLON))
16100 c_parser_consume_token (parser);
16101 eloc = c_parser_peek_token (parser)->location;
16102 expr = c_parser_expr_no_commas (parser, NULL);
16103 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16107 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
16108 DECL_ARTIFICIAL (iter_var) = 1;
16109 DECL_CONTEXT (iter_var) = current_function_decl;
16110 pushdecl (iter_var);
16112 *last = make_tree_vec (6);
16113 TREE_VEC_ELT (*last, 0) = iter_var;
16114 TREE_VEC_ELT (*last, 1) = begin;
16115 TREE_VEC_ELT (*last, 2) = end;
16116 TREE_VEC_ELT (*last, 3) = step;
16117 last = &TREE_CHAIN (*last);
16119 if (c_parser_next_token_is (parser, CPP_COMMA))
16121 c_parser_consume_token (parser);
16128 parens.skip_until_found_close (parser);
16129 return ret ? ret : error_mark_node;
16133 affinity ( [aff-modifier :] variable-list )
16135 iterator ( iterators-definition ) */
16138 c_parser_omp_clause_affinity (c_parser *parser, tree list)
16140 location_t clause_loc = c_parser_peek_token (parser)->location;
16141 tree nl, iterators = NULL_TREE;
16143 matching_parens parens;
16144 if (!parens.require_open (parser))
16147 if (c_parser_next_token_is (parser, CPP_NAME))
16149 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16150 bool parse_iter = ((strcmp ("iterator", p) == 0)
16151 && (c_parser_peek_2nd_token (parser)->type
16152 == CPP_OPEN_PAREN));
16156 parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
16157 && (c_parser_peek_nth_token_raw (parser, n)->type
16158 == CPP_CLOSE_PAREN)
16159 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
16164 iterators = c_parser_omp_iterators (parser);
16165 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16169 parens.skip_until_found_close (parser);
16174 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
16178 tree block = pop_scope ();
16179 if (iterators != error_mark_node)
16181 TREE_VEC_ELT (iterators, 5) = block;
16182 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16183 OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
16184 OMP_CLAUSE_DECL (c));
16188 parens.skip_until_found_close (parser);
16194 depend ( depend-kind: variable-list )
16202 depend ( sink : vec )
16205 depend ( depend-modifier , depend-kind: variable-list )
16208 in | out | inout | mutexinoutset | depobj | inoutset
16211 iterator ( iterators-definition ) */
16214 c_parser_omp_clause_depend (c_parser *parser, tree list)
16216 location_t clause_loc = c_parser_peek_token (parser)->location;
16217 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
16218 tree nl, c, iterators = NULL_TREE;
16220 matching_parens parens;
16221 if (!parens.require_open (parser))
16226 if (c_parser_next_token_is_not (parser, CPP_NAME))
16229 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16230 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
16232 iterators = c_parser_omp_iterators (parser);
16233 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
16236 if (strcmp ("in", p) == 0)
16237 kind = OMP_CLAUSE_DEPEND_IN;
16238 else if (strcmp ("inout", p) == 0)
16239 kind = OMP_CLAUSE_DEPEND_INOUT;
16240 else if (strcmp ("inoutset", p) == 0)
16241 kind = OMP_CLAUSE_DEPEND_INOUTSET;
16242 else if (strcmp ("mutexinoutset", p) == 0)
16243 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
16244 else if (strcmp ("out", p) == 0)
16245 kind = OMP_CLAUSE_DEPEND_OUT;
16246 else if (strcmp ("depobj", p) == 0)
16247 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
16248 else if (strcmp ("sink", p) == 0)
16249 kind = OMP_CLAUSE_DEPEND_SINK;
16250 else if (strcmp ("source", p) == 0)
16251 kind = OMP_CLAUSE_DEPEND_SOURCE;
16258 c_parser_consume_token (parser);
16261 && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
16264 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
16265 kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
16266 iterators = NULL_TREE;
16269 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
16271 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
16272 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16273 OMP_CLAUSE_DECL (c) = NULL_TREE;
16274 OMP_CLAUSE_CHAIN (c) = list;
16275 parens.skip_until_found_close (parser);
16279 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16282 if (kind == OMP_CLAUSE_DEPEND_SINK)
16283 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
16286 nl = c_parser_omp_variable_list (parser, clause_loc,
16287 OMP_CLAUSE_DEPEND, list);
16291 tree block = pop_scope ();
16292 if (iterators == error_mark_node)
16293 iterators = NULL_TREE;
16295 TREE_VEC_ELT (iterators, 5) = block;
16298 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16300 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16302 OMP_CLAUSE_DECL (c)
16303 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
16307 parens.skip_until_found_close (parser);
16311 c_parser_error (parser, "invalid depend kind");
16313 parens.skip_until_found_close (parser);
16320 map ( map-kind: variable-list )
16321 map ( variable-list )
16324 alloc | to | from | tofrom
16328 alloc | to | from | tofrom | release | delete
16330 map ( always [,] map-kind: variable-list )
16333 map ( [map-type-modifier[,] ...] map-kind: variable-list )
16339 c_parser_omp_clause_map (c_parser *parser, tree list)
16341 location_t clause_loc = c_parser_peek_token (parser)->location;
16342 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
16345 matching_parens parens;
16346 if (!parens.require_open (parser))
16350 int map_kind_pos = 0;
16351 while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
16353 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
16355 map_kind_pos = pos;
16359 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
16364 int always_modifier = 0;
16365 int close_modifier = 0;
16366 for (int pos = 1; pos < map_kind_pos; ++pos)
16368 c_token *tok = c_parser_peek_token (parser);
16370 if (tok->type == CPP_COMMA)
16372 c_parser_consume_token (parser);
16376 const char *p = IDENTIFIER_POINTER (tok->value);
16377 if (strcmp ("always", p) == 0)
16379 if (always_modifier)
16381 c_parser_error (parser, "too many %<always%> modifiers");
16382 parens.skip_until_found_close (parser);
16387 else if (strcmp ("close", p) == 0)
16389 if (close_modifier)
16391 c_parser_error (parser, "too many %<close%> modifiers");
16392 parens.skip_until_found_close (parser);
16399 c_parser_error (parser, "%<#pragma omp target%> with "
16400 "modifier other than %<always%> or "
16401 "%<close%> on %<map%> clause");
16402 parens.skip_until_found_close (parser);
16406 c_parser_consume_token (parser);
16409 if (c_parser_next_token_is (parser, CPP_NAME)
16410 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16412 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16413 if (strcmp ("alloc", p) == 0)
16414 kind = GOMP_MAP_ALLOC;
16415 else if (strcmp ("to", p) == 0)
16416 kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
16417 else if (strcmp ("from", p) == 0)
16418 kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
16419 else if (strcmp ("tofrom", p) == 0)
16420 kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
16421 else if (strcmp ("release", p) == 0)
16422 kind = GOMP_MAP_RELEASE;
16423 else if (strcmp ("delete", p) == 0)
16424 kind = GOMP_MAP_DELETE;
16427 c_parser_error (parser, "invalid map kind");
16428 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16432 c_parser_consume_token (parser);
16433 c_parser_consume_token (parser);
16436 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
16439 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16440 OMP_CLAUSE_SET_MAP_KIND (c, kind);
16442 parens.skip_until_found_close (parser);
16447 device ( expression )
16450 device ( [device-modifier :] integer-expression )
16453 ancestor | device_num */
16456 c_parser_omp_clause_device (c_parser *parser, tree list)
16458 location_t clause_loc = c_parser_peek_token (parser)->location;
16459 location_t expr_loc;
16462 bool ancestor = false;
16464 matching_parens parens;
16465 if (!parens.require_open (parser))
16468 if (c_parser_next_token_is (parser, CPP_NAME)
16469 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16471 c_token *tok = c_parser_peek_token (parser);
16472 const char *p = IDENTIFIER_POINTER (tok->value);
16473 if (strcmp ("ancestor", p) == 0)
16475 /* A requires directive with the reverse_offload clause must be
16477 if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
16479 error_at (tok->location, "%<ancestor%> device modifier not "
16480 "preceded by %<requires%> directive "
16481 "with %<reverse_offload%> clause");
16482 parens.skip_until_found_close (parser);
16487 else if (strcmp ("device_num", p) == 0)
16491 error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
16492 parens.skip_until_found_close (parser);
16495 c_parser_consume_token (parser);
16496 c_parser_consume_token (parser);
16499 expr_loc = c_parser_peek_token (parser)->location;
16500 expr = c_parser_expr_no_commas (parser, NULL);
16501 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16503 t = c_fully_fold (t, false, NULL);
16505 parens.skip_until_found_close (parser);
16507 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16509 c_parser_error (parser, "expected integer expression");
16512 if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
16514 error_at (expr_loc, "the %<device%> clause expression must evaluate to "
16519 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
16521 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
16523 OMP_CLAUSE_DEVICE_ID (c) = t;
16524 OMP_CLAUSE_CHAIN (c) = list;
16525 OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
16532 dist_schedule ( static )
16533 dist_schedule ( static , expression ) */
16536 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
16538 tree c, t = NULL_TREE;
16539 location_t loc = c_parser_peek_token (parser)->location;
16541 matching_parens parens;
16542 if (!parens.require_open (parser))
16545 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
16547 c_parser_error (parser, "invalid dist_schedule kind");
16548 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16553 c_parser_consume_token (parser);
16554 if (c_parser_next_token_is (parser, CPP_COMMA))
16556 c_parser_consume_token (parser);
16558 location_t expr_loc = c_parser_peek_token (parser)->location;
16559 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16560 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16562 t = c_fully_fold (t, false, NULL);
16563 parens.skip_until_found_close (parser);
16566 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16567 "expected %<,%> or %<)%>");
16569 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
16570 "dist_schedule"); */
16571 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
16572 warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
16573 if (t == error_mark_node)
16576 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
16577 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
16578 OMP_CLAUSE_CHAIN (c) = list;
16583 proc_bind ( proc-bind-kind )
16586 primary | master | close | spread
16587 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
16590 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
16592 location_t clause_loc = c_parser_peek_token (parser)->location;
16593 enum omp_clause_proc_bind_kind kind;
16596 matching_parens parens;
16597 if (!parens.require_open (parser))
16600 if (c_parser_next_token_is (parser, CPP_NAME))
16602 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16603 if (strcmp ("primary", p) == 0)
16604 kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
16605 else if (strcmp ("master", p) == 0)
16606 kind = OMP_CLAUSE_PROC_BIND_MASTER;
16607 else if (strcmp ("close", p) == 0)
16608 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
16609 else if (strcmp ("spread", p) == 0)
16610 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
16617 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
16618 c_parser_consume_token (parser);
16619 parens.skip_until_found_close (parser);
16620 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
16621 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
16622 OMP_CLAUSE_CHAIN (c) = list;
16626 c_parser_error (parser, "invalid proc_bind kind");
16627 parens.skip_until_found_close (parser);
16632 device_type ( host | nohost | any ) */
16635 c_parser_omp_clause_device_type (c_parser *parser, tree list)
16637 location_t clause_loc = c_parser_peek_token (parser)->location;
16638 enum omp_clause_device_type_kind kind;
16641 matching_parens parens;
16642 if (!parens.require_open (parser))
16645 if (c_parser_next_token_is (parser, CPP_NAME))
16647 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16648 if (strcmp ("host", p) == 0)
16649 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
16650 else if (strcmp ("nohost", p) == 0)
16651 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
16652 else if (strcmp ("any", p) == 0)
16653 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
16660 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
16662 c_parser_consume_token (parser);
16663 parens.skip_until_found_close (parser);
16664 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
16665 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
16666 OMP_CLAUSE_CHAIN (c) = list;
16670 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
16671 parens.skip_until_found_close (parser);
16676 to ( variable-list ) */
16679 c_parser_omp_clause_to (c_parser *parser, tree list)
16681 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list, true);
16685 from ( variable-list ) */
16688 c_parser_omp_clause_from (c_parser *parser, tree list)
16690 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list, true);
16694 uniform ( variable-list ) */
16697 c_parser_omp_clause_uniform (c_parser *parser, tree list)
16699 /* The clauses location. */
16700 location_t loc = c_parser_peek_token (parser)->location;
16702 matching_parens parens;
16703 if (parens.require_open (parser))
16705 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
16707 parens.skip_until_found_close (parser);
16713 detach ( event-handle ) */
16716 c_parser_omp_clause_detach (c_parser *parser, tree list)
16718 matching_parens parens;
16719 location_t clause_loc = c_parser_peek_token (parser)->location;
16721 if (!parens.require_open (parser))
16724 if (c_parser_next_token_is_not (parser, CPP_NAME)
16725 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
16727 c_parser_error (parser, "expected identifier");
16728 parens.skip_until_found_close (parser);
16732 tree t = lookup_name (c_parser_peek_token (parser)->value);
16733 if (t == NULL_TREE)
16735 undeclared_variable (c_parser_peek_token (parser)->location,
16736 c_parser_peek_token (parser)->value);
16737 parens.skip_until_found_close (parser);
16740 c_parser_consume_token (parser);
16742 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
16743 if (!INTEGRAL_TYPE_P (type)
16744 || TREE_CODE (type) != ENUMERAL_TYPE
16745 || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
16747 error_at (clause_loc, "%<detach%> clause event handle "
16748 "has type %qT rather than "
16749 "%<omp_event_handle_t%>",
16751 parens.skip_until_found_close (parser);
16755 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
16756 OMP_CLAUSE_DECL (u) = t;
16757 OMP_CLAUSE_CHAIN (u) = list;
16758 parens.skip_until_found_close (parser);
16762 /* Parse all OpenACC clauses. The set clauses allowed by the directive
16763 is a bitmask in MASK. Return the list of clauses found. */
16766 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
16767 const char *where, bool finish_p = true)
16769 tree clauses = NULL;
16772 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16775 pragma_omp_clause c_kind;
16776 const char *c_name;
16777 tree prev = clauses;
16779 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
16780 c_parser_consume_token (parser);
16782 here = c_parser_peek_token (parser)->location;
16783 c_kind = c_parser_omp_clause_name (parser);
16787 case PRAGMA_OACC_CLAUSE_ASYNC:
16788 clauses = c_parser_oacc_clause_async (parser, clauses);
16791 case PRAGMA_OACC_CLAUSE_AUTO:
16792 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
16796 case PRAGMA_OACC_CLAUSE_ATTACH:
16797 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16800 case PRAGMA_OACC_CLAUSE_COLLAPSE:
16801 clauses = c_parser_omp_clause_collapse (parser, clauses);
16802 c_name = "collapse";
16804 case PRAGMA_OACC_CLAUSE_COPY:
16805 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16808 case PRAGMA_OACC_CLAUSE_COPYIN:
16809 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16812 case PRAGMA_OACC_CLAUSE_COPYOUT:
16813 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16814 c_name = "copyout";
16816 case PRAGMA_OACC_CLAUSE_CREATE:
16817 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16820 case PRAGMA_OACC_CLAUSE_DELETE:
16821 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16824 case PRAGMA_OMP_CLAUSE_DEFAULT:
16825 clauses = c_parser_omp_clause_default (parser, clauses, true);
16826 c_name = "default";
16828 case PRAGMA_OACC_CLAUSE_DETACH:
16829 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16832 case PRAGMA_OACC_CLAUSE_DEVICE:
16833 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16836 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
16837 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
16838 c_name = "deviceptr";
16840 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
16841 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16842 c_name = "device_resident";
16844 case PRAGMA_OACC_CLAUSE_FINALIZE:
16845 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
16847 c_name = "finalize";
16849 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
16850 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16851 c_name = "firstprivate";
16853 case PRAGMA_OACC_CLAUSE_GANG:
16855 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
16858 case PRAGMA_OACC_CLAUSE_HOST:
16859 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16862 case PRAGMA_OACC_CLAUSE_IF:
16863 clauses = c_parser_omp_clause_if (parser, clauses, false);
16866 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
16867 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
16869 c_name = "if_present";
16871 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
16872 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
16874 c_name = "independent";
16876 case PRAGMA_OACC_CLAUSE_LINK:
16877 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16880 case PRAGMA_OACC_CLAUSE_NO_CREATE:
16881 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16882 c_name = "no_create";
16884 case PRAGMA_OACC_CLAUSE_NOHOST:
16885 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
16889 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
16890 clauses = c_parser_oacc_single_int_clause (parser,
16891 OMP_CLAUSE_NUM_GANGS,
16893 c_name = "num_gangs";
16895 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
16896 clauses = c_parser_oacc_single_int_clause (parser,
16897 OMP_CLAUSE_NUM_WORKERS,
16899 c_name = "num_workers";
16901 case PRAGMA_OACC_CLAUSE_PRESENT:
16902 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16903 c_name = "present";
16905 case PRAGMA_OACC_CLAUSE_PRIVATE:
16906 clauses = c_parser_omp_clause_private (parser, clauses);
16907 c_name = "private";
16909 case PRAGMA_OACC_CLAUSE_REDUCTION:
16911 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16913 c_name = "reduction";
16915 case PRAGMA_OACC_CLAUSE_SEQ:
16916 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
16920 case PRAGMA_OACC_CLAUSE_TILE:
16921 clauses = c_parser_oacc_clause_tile (parser, clauses);
16924 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
16925 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16926 c_name = "use_device";
16928 case PRAGMA_OACC_CLAUSE_VECTOR:
16930 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
16933 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
16934 clauses = c_parser_oacc_single_int_clause (parser,
16935 OMP_CLAUSE_VECTOR_LENGTH,
16937 c_name = "vector_length";
16939 case PRAGMA_OACC_CLAUSE_WAIT:
16940 clauses = c_parser_oacc_clause_wait (parser, clauses);
16943 case PRAGMA_OACC_CLAUSE_WORKER:
16945 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
16949 c_parser_error (parser, "expected %<#pragma acc%> clause");
16955 if (((mask >> c_kind) & 1) == 0)
16957 /* Remove the invalid clause(s) from the list to avoid
16958 confusing the rest of the compiler. */
16960 error_at (here, "%qs is not valid for %qs", c_name, where);
16965 c_parser_skip_to_pragma_eol (parser);
16968 return c_finish_omp_clauses (clauses, C_ORT_ACC);
16973 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16974 is a bitmask in MASK. Return the list of clauses found.
16975 FINISH_P set if c_finish_omp_clauses should be called.
16976 NESTED non-zero if clauses should be terminated by closing paren instead
16977 of end of pragma. If it is 2, additionally commas are required in between
16981 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
16982 const char *where, bool finish_p = true,
16985 tree clauses = NULL;
16988 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16991 pragma_omp_clause c_kind;
16992 const char *c_name;
16993 tree prev = clauses;
16995 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
17000 if (c_parser_next_token_is (parser, CPP_COMMA))
17001 c_parser_consume_token (parser);
17002 else if (nested == 2)
17003 error_at (c_parser_peek_token (parser)->location,
17004 "clauses in %<simd%> trait should be separated "
17008 here = c_parser_peek_token (parser)->location;
17009 c_kind = c_parser_omp_clause_name (parser);
17013 case PRAGMA_OMP_CLAUSE_BIND:
17014 clauses = c_parser_omp_clause_bind (parser, clauses);
17017 case PRAGMA_OMP_CLAUSE_COLLAPSE:
17018 clauses = c_parser_omp_clause_collapse (parser, clauses);
17019 c_name = "collapse";
17021 case PRAGMA_OMP_CLAUSE_COPYIN:
17022 clauses = c_parser_omp_clause_copyin (parser, clauses);
17025 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
17026 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
17027 c_name = "copyprivate";
17029 case PRAGMA_OMP_CLAUSE_DEFAULT:
17030 clauses = c_parser_omp_clause_default (parser, clauses, false);
17031 c_name = "default";
17033 case PRAGMA_OMP_CLAUSE_DETACH:
17034 clauses = c_parser_omp_clause_detach (parser, clauses);
17037 case PRAGMA_OMP_CLAUSE_FILTER:
17038 clauses = c_parser_omp_clause_filter (parser, clauses);
17041 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
17042 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
17043 c_name = "firstprivate";
17045 case PRAGMA_OMP_CLAUSE_FINAL:
17046 clauses = c_parser_omp_clause_final (parser, clauses);
17049 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
17050 clauses = c_parser_omp_clause_grainsize (parser, clauses);
17051 c_name = "grainsize";
17053 case PRAGMA_OMP_CLAUSE_HINT:
17054 clauses = c_parser_omp_clause_hint (parser, clauses);
17057 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
17058 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
17059 c_name = "defaultmap";
17061 case PRAGMA_OMP_CLAUSE_IF:
17062 clauses = c_parser_omp_clause_if (parser, clauses, true);
17065 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
17067 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
17069 c_name = "in_reduction";
17071 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
17072 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
17073 c_name = "lastprivate";
17075 case PRAGMA_OMP_CLAUSE_MERGEABLE:
17076 clauses = c_parser_omp_clause_mergeable (parser, clauses);
17077 c_name = "mergeable";
17079 case PRAGMA_OMP_CLAUSE_NOWAIT:
17080 clauses = c_parser_omp_clause_nowait (parser, clauses);
17083 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
17084 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
17085 c_name = "num_tasks";
17087 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
17088 clauses = c_parser_omp_clause_num_threads (parser, clauses);
17089 c_name = "num_threads";
17091 case PRAGMA_OMP_CLAUSE_ORDER:
17092 clauses = c_parser_omp_clause_order (parser, clauses);
17095 case PRAGMA_OMP_CLAUSE_ORDERED:
17096 clauses = c_parser_omp_clause_ordered (parser, clauses);
17097 c_name = "ordered";
17099 case PRAGMA_OMP_CLAUSE_PRIORITY:
17100 clauses = c_parser_omp_clause_priority (parser, clauses);
17101 c_name = "priority";
17103 case PRAGMA_OMP_CLAUSE_PRIVATE:
17104 clauses = c_parser_omp_clause_private (parser, clauses);
17105 c_name = "private";
17107 case PRAGMA_OMP_CLAUSE_REDUCTION:
17109 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
17111 c_name = "reduction";
17113 case PRAGMA_OMP_CLAUSE_SCHEDULE:
17114 clauses = c_parser_omp_clause_schedule (parser, clauses);
17115 c_name = "schedule";
17117 case PRAGMA_OMP_CLAUSE_SHARED:
17118 clauses = c_parser_omp_clause_shared (parser, clauses);
17121 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
17123 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
17125 c_name = "task_reduction";
17127 case PRAGMA_OMP_CLAUSE_UNTIED:
17128 clauses = c_parser_omp_clause_untied (parser, clauses);
17131 case PRAGMA_OMP_CLAUSE_INBRANCH:
17132 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
17134 c_name = "inbranch";
17136 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
17137 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
17138 c_name = "nontemporal";
17140 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
17141 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
17143 c_name = "notinbranch";
17145 case PRAGMA_OMP_CLAUSE_PARALLEL:
17147 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
17149 c_name = "parallel";
17153 error_at (here, "%qs must be the first clause of %qs",
17158 case PRAGMA_OMP_CLAUSE_FOR:
17160 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
17164 goto clause_not_first;
17166 case PRAGMA_OMP_CLAUSE_SECTIONS:
17168 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
17170 c_name = "sections";
17172 goto clause_not_first;
17174 case PRAGMA_OMP_CLAUSE_TASKGROUP:
17176 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
17178 c_name = "taskgroup";
17180 goto clause_not_first;
17182 case PRAGMA_OMP_CLAUSE_LINK:
17184 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
17187 case PRAGMA_OMP_CLAUSE_TO:
17188 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
17190 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
17192 for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
17193 OMP_CLAUSE_ENTER_TO (c) = 1;
17197 clauses = c_parser_omp_clause_to (parser, clauses);
17200 case PRAGMA_OMP_CLAUSE_FROM:
17201 clauses = c_parser_omp_clause_from (parser, clauses);
17204 case PRAGMA_OMP_CLAUSE_UNIFORM:
17205 clauses = c_parser_omp_clause_uniform (parser, clauses);
17206 c_name = "uniform";
17208 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
17209 clauses = c_parser_omp_clause_num_teams (parser, clauses);
17210 c_name = "num_teams";
17212 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
17213 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
17214 c_name = "thread_limit";
17216 case PRAGMA_OMP_CLAUSE_ALIGNED:
17217 clauses = c_parser_omp_clause_aligned (parser, clauses);
17218 c_name = "aligned";
17220 case PRAGMA_OMP_CLAUSE_ALLOCATE:
17221 clauses = c_parser_omp_clause_allocate (parser, clauses);
17222 c_name = "allocate";
17224 case PRAGMA_OMP_CLAUSE_LINEAR:
17225 clauses = c_parser_omp_clause_linear (parser, clauses);
17228 case PRAGMA_OMP_CLAUSE_AFFINITY:
17229 clauses = c_parser_omp_clause_affinity (parser, clauses);
17230 c_name = "affinity";
17232 case PRAGMA_OMP_CLAUSE_DEPEND:
17233 clauses = c_parser_omp_clause_depend (parser, clauses);
17236 case PRAGMA_OMP_CLAUSE_MAP:
17237 clauses = c_parser_omp_clause_map (parser, clauses);
17240 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
17241 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
17242 c_name = "use_device_ptr";
17244 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
17245 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
17246 c_name = "use_device_addr";
17248 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
17249 clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
17250 c_name = "has_device_addr";
17252 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
17253 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
17254 c_name = "is_device_ptr";
17256 case PRAGMA_OMP_CLAUSE_DEVICE:
17257 clauses = c_parser_omp_clause_device (parser, clauses);
17260 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
17261 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
17262 c_name = "dist_schedule";
17264 case PRAGMA_OMP_CLAUSE_PROC_BIND:
17265 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
17266 c_name = "proc_bind";
17268 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
17269 clauses = c_parser_omp_clause_device_type (parser, clauses);
17270 c_name = "device_type";
17272 case PRAGMA_OMP_CLAUSE_SAFELEN:
17273 clauses = c_parser_omp_clause_safelen (parser, clauses);
17274 c_name = "safelen";
17276 case PRAGMA_OMP_CLAUSE_SIMDLEN:
17277 clauses = c_parser_omp_clause_simdlen (parser, clauses);
17278 c_name = "simdlen";
17280 case PRAGMA_OMP_CLAUSE_NOGROUP:
17281 clauses = c_parser_omp_clause_nogroup (parser, clauses);
17282 c_name = "nogroup";
17284 case PRAGMA_OMP_CLAUSE_THREADS:
17286 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
17288 c_name = "threads";
17290 case PRAGMA_OMP_CLAUSE_SIMD:
17292 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
17296 case PRAGMA_OMP_CLAUSE_ENTER:
17298 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
17303 c_parser_error (parser, "expected %<#pragma omp%> clause");
17309 if (((mask >> c_kind) & 1) == 0)
17311 /* Remove the invalid clause(s) from the list to avoid
17312 confusing the rest of the compiler. */
17314 error_at (here, "%qs is not valid for %qs", c_name, where);
17320 c_parser_skip_to_pragma_eol (parser);
17324 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
17325 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
17326 return c_finish_omp_clauses (clauses, C_ORT_OMP);
17332 /* OpenACC 2.0, OpenMP 2.5:
17336 In practice, we're also interested in adding the statement to an
17337 outer node. So it is convenient if we work around the fact that
17338 c_parser_statement calls add_stmt. */
17341 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
17343 tree stmt = push_stmt_list ();
17344 c_parser_statement (parser, if_p);
17345 return pop_stmt_list (stmt);
17349 # pragma acc cache (variable-list) new-line
17351 LOC is the location of the #pragma token.
17355 c_parser_oacc_cache (location_t loc, c_parser *parser)
17357 tree stmt, clauses;
17359 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
17360 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17362 c_parser_skip_to_pragma_eol (parser);
17364 stmt = make_node (OACC_CACHE);
17365 TREE_TYPE (stmt) = void_type_node;
17366 OACC_CACHE_CLAUSES (stmt) = clauses;
17367 SET_EXPR_LOCATION (stmt, loc);
17374 # pragma acc data oacc-data-clause[optseq] new-line
17377 LOC is the location of the #pragma token.
17380 #define OACC_DATA_CLAUSE_MASK \
17381 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17382 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17383 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17384 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17385 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17386 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17387 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17388 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17389 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17392 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
17394 tree stmt, clauses, block;
17396 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
17397 "#pragma acc data");
17399 block = c_begin_omp_parallel ();
17400 add_stmt (c_parser_omp_structured_block (parser, if_p));
17402 stmt = c_finish_oacc_data (loc, clauses, block);
17408 # pragma acc declare oacc-data-clause[optseq] new-line
17411 #define OACC_DECLARE_CLAUSE_MASK \
17412 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17413 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17414 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17415 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17416 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17417 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
17418 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
17419 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17422 c_parser_oacc_declare (c_parser *parser)
17424 location_t pragma_loc = c_parser_peek_token (parser)->location;
17425 tree clauses, stmt, t, decl;
17427 bool error = false;
17429 c_parser_consume_pragma (parser);
17431 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
17432 "#pragma acc declare");
17435 error_at (pragma_loc,
17436 "no valid clauses specified in %<#pragma acc declare%>");
17440 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
17442 location_t loc = OMP_CLAUSE_LOCATION (t);
17443 decl = OMP_CLAUSE_DECL (t);
17444 if (!DECL_P (decl))
17446 error_at (loc, "array section in %<#pragma acc declare%>");
17451 switch (OMP_CLAUSE_MAP_KIND (t))
17453 case GOMP_MAP_FIRSTPRIVATE_POINTER:
17454 case GOMP_MAP_ALLOC:
17456 case GOMP_MAP_FORCE_DEVICEPTR:
17457 case GOMP_MAP_DEVICE_RESIDENT:
17460 case GOMP_MAP_LINK:
17461 if (!global_bindings_p ()
17462 && (TREE_STATIC (decl)
17463 || !DECL_EXTERNAL (decl)))
17466 "%qD must be a global variable in "
17467 "%<#pragma acc declare link%>",
17475 if (global_bindings_p ())
17477 error_at (loc, "invalid OpenACC clause at file scope");
17481 if (DECL_EXTERNAL (decl))
17484 "invalid use of %<extern%> variable %qD "
17485 "in %<#pragma acc declare%>", decl);
17489 else if (TREE_PUBLIC (decl))
17492 "invalid use of %<global%> variable %qD "
17493 "in %<#pragma acc declare%>", decl);
17500 if (!c_check_in_current_scope (decl))
17503 "%qD must be a variable declared in the same scope as "
17504 "%<#pragma acc declare%>", decl);
17509 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
17510 || lookup_attribute ("omp declare target link",
17511 DECL_ATTRIBUTES (decl)))
17513 error_at (loc, "variable %qD used more than once with "
17514 "%<#pragma acc declare%>", decl);
17523 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
17524 id = get_identifier ("omp declare target link");
17526 id = get_identifier ("omp declare target");
17528 DECL_ATTRIBUTES (decl)
17529 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
17531 if (global_bindings_p ())
17533 symtab_node *node = symtab_node::get (decl);
17536 node->offloadable = 1;
17537 if (ENABLE_OFFLOADING)
17539 g->have_offload = true;
17540 if (is_a <varpool_node *> (node))
17541 vec_safe_push (offload_vars, decl);
17548 if (error || global_bindings_p ())
17551 stmt = make_node (OACC_DECLARE);
17552 TREE_TYPE (stmt) = void_type_node;
17553 OACC_DECLARE_CLAUSES (stmt) = clauses;
17554 SET_EXPR_LOCATION (stmt, pragma_loc);
17562 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
17566 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
17569 LOC is the location of the #pragma token.
17572 #define OACC_ENTER_DATA_CLAUSE_MASK \
17573 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17574 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17575 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17576 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17577 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17578 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17580 #define OACC_EXIT_DATA_CLAUSE_MASK \
17581 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17582 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17583 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17584 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
17585 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
17586 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
17587 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17590 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
17592 location_t loc = c_parser_peek_token (parser)->location;
17593 tree clauses, stmt;
17594 const char *p = "";
17596 c_parser_consume_pragma (parser);
17598 if (c_parser_next_token_is (parser, CPP_NAME))
17600 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17601 c_parser_consume_token (parser);
17604 if (strcmp (p, "data") != 0)
17606 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
17607 enter ? "enter" : "exit");
17608 parser->error = true;
17609 c_parser_skip_to_pragma_eol (parser);
17614 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
17615 "#pragma acc enter data");
17617 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
17618 "#pragma acc exit data");
17620 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17622 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
17623 enter ? "enter" : "exit");
17627 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
17628 TREE_TYPE (stmt) = void_type_node;
17629 OMP_STANDALONE_CLAUSES (stmt) = clauses;
17630 SET_EXPR_LOCATION (stmt, loc);
17636 # pragma acc host_data oacc-data-clause[optseq] new-line
17640 #define OACC_HOST_DATA_CLAUSE_MASK \
17641 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
17642 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17643 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
17646 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
17648 tree stmt, clauses, block;
17650 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
17651 "#pragma acc host_data");
17653 block = c_begin_omp_parallel ();
17654 add_stmt (c_parser_omp_structured_block (parser, if_p));
17655 stmt = c_finish_oacc_host_data (loc, clauses, block);
17662 # pragma acc loop oacc-loop-clause[optseq] new-line
17665 LOC is the location of the #pragma token.
17668 #define OACC_LOOP_CLAUSE_MASK \
17669 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
17670 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17671 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17672 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17673 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17674 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17675 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
17676 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
17677 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17678 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
17680 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
17681 omp_clause_mask mask, tree *cclauses, bool *if_p)
17683 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
17685 strcat (p_name, " loop");
17686 mask |= OACC_LOOP_CLAUSE_MASK;
17688 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
17692 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
17694 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
17696 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17699 tree block = c_begin_compound_stmt (true);
17700 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
17702 block = c_end_compound_stmt (loc, block, true);
17709 # pragma acc kernels oacc-kernels-clause[optseq] new-line
17714 # pragma acc parallel oacc-parallel-clause[optseq] new-line
17719 # pragma acc serial oacc-serial-clause[optseq] new-line
17722 LOC is the location of the #pragma token.
17725 #define OACC_KERNELS_CLAUSE_MASK \
17726 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17727 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17728 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17729 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17730 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17731 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17732 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17733 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17742 #define OACC_PARALLEL_CLAUSE_MASK \
17743 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17745 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17746 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17749 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17750 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17751 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17752 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17753 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17754 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17755 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17756 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17757 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17758 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17759 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17760 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17762 #define OACC_SERIAL_CLAUSE_MASK \
17763 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17764 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17765 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17766 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17767 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17768 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17769 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17770 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17771 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17772 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17773 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17774 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17775 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17776 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17777 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17780 c_parser_oacc_compute (location_t loc, c_parser *parser,
17781 enum pragma_kind p_kind, char *p_name, bool *if_p)
17783 omp_clause_mask mask;
17784 enum tree_code code;
17787 case PRAGMA_OACC_KERNELS:
17788 strcat (p_name, " kernels");
17789 mask = OACC_KERNELS_CLAUSE_MASK;
17790 code = OACC_KERNELS;
17792 case PRAGMA_OACC_PARALLEL:
17793 strcat (p_name, " parallel");
17794 mask = OACC_PARALLEL_CLAUSE_MASK;
17795 code = OACC_PARALLEL;
17797 case PRAGMA_OACC_SERIAL:
17798 strcat (p_name, " serial");
17799 mask = OACC_SERIAL_CLAUSE_MASK;
17800 code = OACC_SERIAL;
17803 gcc_unreachable ();
17806 if (c_parser_next_token_is (parser, CPP_NAME))
17808 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17809 if (strcmp (p, "loop") == 0)
17811 c_parser_consume_token (parser);
17812 tree block = c_begin_omp_parallel ();
17814 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
17815 return c_finish_omp_construct (loc, code, block, clauses);
17819 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
17821 tree block = c_begin_omp_parallel ();
17822 add_stmt (c_parser_omp_structured_block (parser, if_p));
17824 return c_finish_omp_construct (loc, code, block, clauses);
17828 # pragma acc routine oacc-routine-clause[optseq] new-line
17829 function-definition
17831 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
17834 #define OACC_ROUTINE_CLAUSE_MASK \
17835 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17836 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17837 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17838 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17839 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
17841 /* Parse an OpenACC routine directive. For named directives, we apply
17842 immediately to the named function. For unnamed ones we then parse
17843 a declaration or definition, which must be for a function. */
17846 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
17848 gcc_checking_assert (context == pragma_external);
17850 oacc_routine_data data;
17851 data.error_seen = false;
17852 data.fndecl_seen = false;
17853 data.loc = c_parser_peek_token (parser)->location;
17855 c_parser_consume_pragma (parser);
17857 /* Look for optional '( name )'. */
17858 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17860 c_parser_consume_token (parser); /* '(' */
17862 tree decl = NULL_TREE;
17863 c_token *name_token = c_parser_peek_token (parser);
17864 location_t name_loc = name_token->location;
17865 if (name_token->type == CPP_NAME
17866 && (name_token->id_kind == C_ID_ID
17867 || name_token->id_kind == C_ID_TYPENAME))
17869 decl = lookup_name (name_token->value);
17871 error_at (name_loc,
17872 "%qE has not been declared", name_token->value);
17873 c_parser_consume_token (parser);
17876 c_parser_error (parser, "expected function name");
17879 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17881 c_parser_skip_to_pragma_eol (parser, false);
17886 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17887 "#pragma acc routine");
17888 /* The clauses are in reverse order; fix that to make later diagnostic
17889 emission easier. */
17890 data.clauses = nreverse (data.clauses);
17892 if (TREE_CODE (decl) != FUNCTION_DECL)
17894 error_at (name_loc, "%qD does not refer to a function", decl);
17898 c_finish_oacc_routine (&data, decl, false);
17900 else /* No optional '( name )'. */
17903 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17904 "#pragma acc routine");
17905 /* The clauses are in reverse order; fix that to make later diagnostic
17906 emission easier. */
17907 data.clauses = nreverse (data.clauses);
17909 /* Emit a helpful diagnostic if there's another pragma following this
17910 one. Also don't allow a static assertion declaration, as in the
17911 following we'll just parse a *single* "declaration or function
17912 definition", and the static assertion counts an one. */
17913 if (c_parser_next_token_is (parser, CPP_PRAGMA)
17914 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
17916 error_at (data.loc,
17917 "%<#pragma acc routine%> not immediately followed by"
17918 " function declaration or definition");
17919 /* ..., and then just keep going. */
17923 /* We only have to consider the pragma_external case here. */
17924 if (c_parser_next_token_is (parser, CPP_KEYWORD)
17925 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17927 int ext = disable_extension_diagnostics ();
17929 c_parser_consume_token (parser);
17930 while (c_parser_next_token_is (parser, CPP_KEYWORD)
17931 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17932 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17933 NULL, NULL, false, NULL, &data);
17934 restore_extension_diagnostics (ext);
17937 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17938 NULL, NULL, false, NULL, &data);
17942 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17943 IS_DEFN is true if we're applying it to the definition. */
17946 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
17949 /* Keep going if we're in error reporting mode. */
17950 if (data->error_seen
17951 || fndecl == error_mark_node)
17954 if (data->fndecl_seen)
17956 error_at (data->loc,
17957 "%<#pragma acc routine%> not immediately followed by"
17958 " a single function declaration or definition");
17959 data->error_seen = true;
17962 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
17964 error_at (data->loc,
17965 "%<#pragma acc routine%> not immediately followed by"
17966 " function declaration or definition");
17967 data->error_seen = true;
17972 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
17973 "#pragma acc routine");
17974 if (compatible < 0)
17976 data->error_seen = true;
17979 if (compatible > 0)
17984 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
17986 error_at (data->loc,
17988 ? G_("%<#pragma acc routine%> must be applied before use")
17989 : G_("%<#pragma acc routine%> must be applied before"
17991 data->error_seen = true;
17995 /* Set the routine's level of parallelism. */
17996 tree dims = oacc_build_routine_dims (data->clauses);
17997 oacc_replace_fn_attrib (fndecl, dims);
17999 /* Add an "omp declare target" attribute. */
18000 DECL_ATTRIBUTES (fndecl)
18001 = tree_cons (get_identifier ("omp declare target"),
18002 data->clauses, DECL_ATTRIBUTES (fndecl));
18005 /* Remember that we've used this "#pragma acc routine". */
18006 data->fndecl_seen = true;
18010 # pragma acc update oacc-update-clause[optseq] new-line
18013 #define OACC_UPDATE_CLAUSE_MASK \
18014 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18015 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
18016 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
18017 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18018 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
18019 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18022 c_parser_oacc_update (c_parser *parser)
18024 location_t loc = c_parser_peek_token (parser)->location;
18026 c_parser_consume_pragma (parser);
18028 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
18029 "#pragma acc update");
18030 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
18033 "%<#pragma acc update%> must contain at least one "
18034 "%<device%> or %<host%> or %<self%> clause");
18041 tree stmt = make_node (OACC_UPDATE);
18042 TREE_TYPE (stmt) = void_type_node;
18043 OACC_UPDATE_CLAUSES (stmt) = clauses;
18044 SET_EXPR_LOCATION (stmt, loc);
18049 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
18051 LOC is the location of the #pragma token.
18054 #define OACC_WAIT_CLAUSE_MASK \
18055 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
18058 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
18060 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
18062 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
18063 list = c_parser_oacc_wait_list (parser, loc, list);
18065 strcpy (p_name, " wait");
18066 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
18067 stmt = c_finish_oacc_wait (loc, list, clauses);
18074 # pragma omp allocate (list) [allocator(allocator)] */
18077 c_parser_omp_allocate (location_t loc, c_parser *parser)
18079 tree allocator = NULL_TREE;
18080 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
18081 if (c_parser_next_token_is (parser, CPP_NAME))
18083 matching_parens parens;
18084 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18085 c_parser_consume_token (parser);
18086 if (strcmp ("allocator", p) != 0)
18087 error_at (c_parser_peek_token (parser)->location,
18088 "expected %<allocator%>");
18089 else if (parens.require_open (parser))
18091 location_t expr_loc = c_parser_peek_token (parser)->location;
18092 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18093 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18094 allocator = expr.value;
18095 allocator = c_fully_fold (allocator, false, NULL);
18097 = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
18098 orig_type = TYPE_MAIN_VARIANT (orig_type);
18099 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
18100 || TREE_CODE (orig_type) != ENUMERAL_TYPE
18101 || TYPE_NAME (orig_type)
18102 != get_identifier ("omp_allocator_handle_t"))
18104 error_at (expr_loc, "%<allocator%> clause allocator expression "
18105 "has type %qT rather than "
18106 "%<omp_allocator_handle_t%>",
18107 TREE_TYPE (allocator));
18108 allocator = NULL_TREE;
18110 parens.skip_until_found_close (parser);
18113 c_parser_skip_to_pragma_eol (parser);
18116 for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
18117 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
18119 sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
18123 # pragma omp atomic new-line
18127 x binop= expr | x++ | ++x | x-- | --x
18129 +, *, -, /, &, ^, |, <<, >>
18131 where x is an lvalue expression with scalar type.
18134 # pragma omp atomic new-line
18137 # pragma omp atomic read new-line
18140 # pragma omp atomic write new-line
18143 # pragma omp atomic update new-line
18146 # pragma omp atomic capture new-line
18149 # pragma omp atomic capture new-line
18157 expression-stmt | x = x binop expr
18159 v = expression-stmt
18161 { v = x; update-stmt; } | { update-stmt; v = x; }
18165 expression-stmt | x = x binop expr | x = expr binop x
18169 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
18172 # pragma omp atomic compare new-line
18173 conditional-update-atomic
18175 # pragma omp atomic compare capture new-line
18176 conditional-update-capture-atomic
18178 conditional-update-atomic:
18179 cond-expr-stmt | cond-update-stmt
18181 x = expr ordop x ? expr : x;
18182 x = x ordop expr ? expr : x;
18183 x = x == e ? d : x;
18185 if (expr ordop x) { x = expr; }
18186 if (x ordop expr) { x = expr; }
18187 if (x == e) { x = d; }
18190 conditional-update-capture-atomic:
18192 { v = x; cond-expr-stmt }
18193 { cond-expr-stmt v = x; }
18194 { v = x; cond-update-stmt }
18195 { cond-update-stmt v = x; }
18196 if (x == e) { x = d; } else { v = x; }
18197 { r = x == e; if (r) { x = d; } }
18198 { r = x == e; if (r) { x = d; } else { v = x; } }
18200 where x, r and v are lvalue expressions with scalar type,
18201 expr, e and d are expressions with scalar type and e might be
18204 LOC is the location of the #pragma token. */
18207 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
18209 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
18210 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
18211 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
18212 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
18213 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
18214 struct c_expr expr;
18216 bool structured_block = false;
18217 bool swapped = false;
18220 tree clauses = NULL_TREE;
18221 bool capture = false;
18222 bool compare = false;
18224 enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18225 bool no_semicolon = false;
18226 bool extra_scope = false;
18228 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
18231 && c_parser_next_token_is (parser, CPP_COMMA)
18232 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
18233 c_parser_consume_token (parser);
18237 if (c_parser_next_token_is (parser, CPP_NAME))
18240 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18241 location_t cloc = c_parser_peek_token (parser)->location;
18242 enum tree_code new_code = ERROR_MARK;
18243 enum omp_memory_order new_memory_order
18244 = OMP_MEMORY_ORDER_UNSPECIFIED;
18245 bool new_capture = false;
18246 bool new_compare = false;
18247 bool new_weak = false;
18248 enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18250 if (!strcmp (p, "read"))
18251 new_code = OMP_ATOMIC_READ;
18252 else if (!strcmp (p, "write"))
18253 new_code = NOP_EXPR;
18254 else if (!strcmp (p, "update"))
18255 new_code = OMP_ATOMIC;
18256 else if (openacc && !strcmp (p, "capture"))
18257 new_code = OMP_ATOMIC_CAPTURE_NEW;
18261 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18262 "or %<capture%> clause");
18264 else if (!strcmp (p, "capture"))
18265 new_capture = true;
18266 else if (!strcmp (p, "compare"))
18267 new_compare = true;
18268 else if (!strcmp (p, "weak"))
18270 else if (!strcmp (p, "fail"))
18272 matching_parens parens;
18274 c_parser_consume_token (parser);
18275 if (!parens.require_open (parser))
18278 if (c_parser_next_token_is (parser, CPP_NAME))
18281 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18283 if (!strcmp (q, "seq_cst"))
18284 new_fail = OMP_MEMORY_ORDER_SEQ_CST;
18285 else if (!strcmp (q, "acquire"))
18286 new_fail = OMP_MEMORY_ORDER_ACQUIRE;
18287 else if (!strcmp (q, "relaxed"))
18288 new_fail = OMP_MEMORY_ORDER_RELAXED;
18291 if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18293 c_parser_consume_token (parser);
18294 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18295 error_at (cloc, "too many %qs clauses", "fail");
18300 c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
18302 parens.skip_until_found_close (parser);
18305 else if (!strcmp (p, "seq_cst"))
18306 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18307 else if (!strcmp (p, "acq_rel"))
18308 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18309 else if (!strcmp (p, "release"))
18310 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
18311 else if (!strcmp (p, "acquire"))
18312 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18313 else if (!strcmp (p, "relaxed"))
18314 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
18315 else if (!strcmp (p, "hint"))
18317 c_parser_consume_token (parser);
18318 clauses = c_parser_omp_clause_hint (parser, clauses);
18324 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18325 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
18326 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
18327 "%<relaxed%> or %<hint%> clause");
18331 if (new_code != ERROR_MARK)
18333 /* OpenACC permits 'update capture'. */
18335 && code == OMP_ATOMIC
18336 && new_code == OMP_ATOMIC_CAPTURE_NEW)
18338 else if (code != ERROR_MARK)
18339 error_at (cloc, "too many atomic clauses");
18343 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18345 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18346 error_at (cloc, "too many memory order clauses");
18348 memory_order = new_memory_order;
18350 else if (new_capture)
18353 error_at (cloc, "too many %qs clauses", "capture");
18357 else if (new_compare)
18360 error_at (cloc, "too many %qs clauses", "compare");
18367 error_at (cloc, "too many %qs clauses", "weak");
18371 c_parser_consume_token (parser);
18377 c_parser_skip_to_pragma_eol (parser);
18379 if (code == ERROR_MARK)
18383 if (code != OMP_ATOMIC)
18384 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18385 "clauses", "capture");
18387 code = OMP_ATOMIC_CAPTURE_NEW;
18389 if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
18391 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18392 "clauses", "compare");
18395 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
18397 error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
18398 fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18400 if (weak && !compare)
18402 error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
18406 memory_order = OMP_MEMORY_ORDER_RELAXED;
18407 else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
18410 = (enum omp_requires) (omp_requires_mask
18411 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
18412 switch ((enum omp_memory_order)
18413 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
18415 case OMP_MEMORY_ORDER_UNSPECIFIED:
18416 case OMP_MEMORY_ORDER_RELAXED:
18417 memory_order = OMP_MEMORY_ORDER_RELAXED;
18419 case OMP_MEMORY_ORDER_SEQ_CST:
18420 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18422 case OMP_MEMORY_ORDER_ACQ_REL:
18425 case OMP_ATOMIC_READ:
18426 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18428 case NOP_EXPR: /* atomic write */
18429 memory_order = OMP_MEMORY_ORDER_RELEASE;
18432 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18437 gcc_unreachable ();
18443 case OMP_ATOMIC_READ:
18444 if (memory_order == OMP_MEMORY_ORDER_RELEASE)
18446 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
18447 "%<release%> clause");
18448 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18450 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18451 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18453 case NOP_EXPR: /* atomic write */
18454 if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
18456 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
18457 "%<acquire%> clause");
18458 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18460 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18461 memory_order = OMP_MEMORY_ORDER_RELEASE;
18466 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18468 = (enum omp_memory_order) (memory_order
18469 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
18473 case OMP_ATOMIC_READ:
18474 case NOP_EXPR: /* atomic write */
18475 v = c_parser_cast_expression (parser, NULL).value;
18476 non_lvalue_p = !lvalue_p (v);
18477 v = c_fully_fold (v, false, NULL, true);
18478 if (v == error_mark_node)
18481 v = non_lvalue (v);
18482 loc = c_parser_peek_token (parser)->location;
18483 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18485 if (code == NOP_EXPR)
18487 lhs = c_parser_expression (parser).value;
18488 lhs = c_fully_fold (lhs, false, NULL);
18489 if (lhs == error_mark_node)
18494 lhs = c_parser_cast_expression (parser, NULL).value;
18495 non_lvalue_p = !lvalue_p (lhs);
18496 lhs = c_fully_fold (lhs, false, NULL, true);
18497 if (lhs == error_mark_node)
18500 lhs = non_lvalue (lhs);
18502 if (code == NOP_EXPR)
18504 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
18512 case OMP_ATOMIC_CAPTURE_NEW:
18513 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18515 c_parser_consume_token (parser);
18516 structured_block = true;
18519 && c_parser_next_token_is_keyword (parser, RID_IF))
18523 v = c_parser_cast_expression (parser, NULL).value;
18524 non_lvalue_p = !lvalue_p (v);
18525 v = c_fully_fold (v, false, NULL, true);
18526 if (v == error_mark_node)
18529 v = non_lvalue (v);
18530 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18532 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18534 eloc = c_parser_peek_token (parser)->location;
18535 error_at (eloc, "expected expression");
18544 /* For structured_block case we don't know yet whether
18545 old or new x should be captured. */
18547 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18549 c_parser_consume_token (parser);
18551 matching_parens parens;
18552 if (!parens.require_open (parser))
18554 eloc = c_parser_peek_token (parser)->location;
18558 cmp_expr = c_parser_cast_expression (parser, NULL);
18559 cmp_expr = default_function_array_conversion (eloc, cmp_expr);
18562 cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
18563 parens.skip_until_found_close (parser);
18564 if (cmp_expr.value == error_mark_node)
18568 if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
18570 cmp_expr.value = rhs1;
18572 gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
18574 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18576 else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18578 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18579 "expected %<==%> comparison in %<if%> condition");
18582 else if (TREE_CODE (cmp_expr.value) != GT_EXPR
18583 && TREE_CODE (cmp_expr.value) != LT_EXPR)
18585 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18586 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
18590 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18593 extra_scope = true;
18594 eloc = c_parser_peek_token (parser)->location;
18595 expr = c_parser_cast_expression (parser, NULL);
18597 expr = default_function_array_conversion (eloc, expr);
18598 unfolded_lhs = expr.value;
18599 lhs = c_fully_fold (lhs, false, NULL, true);
18601 if (lhs == error_mark_node)
18603 if (!lvalue_p (unfolded_lhs))
18604 lhs = non_lvalue (lhs);
18605 if (!c_parser_next_token_is (parser, CPP_EQ))
18607 c_parser_error (parser, "expected %<=%>");
18610 c_parser_consume_token (parser);
18611 eloc = c_parser_peek_token (parser)->location;
18612 expr = c_parser_expr_no_commas (parser, NULL);
18615 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18618 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18621 extra_scope = false;
18622 no_semicolon = true;
18624 if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
18626 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18628 opcode = COND_EXPR;
18629 rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18630 false, NULL, true);
18631 rhs1 = c_fully_fold (rhs1, false, NULL, true);
18633 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
18635 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18636 ? MIN_EXPR : MAX_EXPR);
18637 rhs = c_fully_fold (rhs1, false, NULL, true);
18638 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
18639 false, NULL, true);
18644 else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18646 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
18647 && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
18649 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18650 ? MAX_EXPR : MIN_EXPR);
18651 rhs = c_fully_fold (rhs1, false, NULL, true);
18652 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18653 false, NULL, true);
18658 c_parser_error (parser,
18659 "invalid form of %<#pragma omp atomic compare%>");
18663 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
18665 if (code != OMP_ATOMIC_CAPTURE_NEW
18666 || (structured_block && r == NULL_TREE)
18667 || TREE_CODE (cmp_expr.value) != EQ_EXPR)
18669 eloc = c_parser_peek_token (parser)->location;
18670 error_at (eloc, "unexpected %<else%>");
18674 c_parser_consume_token (parser);
18676 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18679 extra_scope = true;
18680 v = c_parser_cast_expression (parser, NULL).value;
18681 non_lvalue_p = !lvalue_p (v);
18682 v = c_fully_fold (v, false, NULL, true);
18683 if (v == error_mark_node)
18686 v = non_lvalue (v);
18687 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18690 expr = c_parser_expr_no_commas (parser, NULL);
18692 if (!c_tree_equal (expr.value, unfolded_lhs))
18695 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18698 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18701 extra_scope = false;
18702 code = OMP_ATOMIC_CAPTURE_OLD;
18703 if (r == NULL_TREE)
18704 /* Signal to c_finish_omp_atomic that in
18705 if (x == e) { x = d; } else { v = x; }
18706 case the store to v should be conditional. */
18707 r = void_list_node;
18709 else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18711 c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
18714 else if (code == OMP_ATOMIC_CAPTURE_NEW
18720 eloc = c_parser_peek_token (parser)->location;
18721 expr = c_parser_cast_expression (parser, NULL);
18723 expr = default_function_array_conversion (eloc, expr);
18724 unfolded_lhs = expr.value;
18725 lhs = c_fully_fold (lhs, false, NULL, true);
18727 switch (TREE_CODE (lhs))
18730 error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
18734 c_parser_skip_to_end_of_block_or_statement (parser);
18735 if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18736 c_parser_consume_token (parser);
18737 if (structured_block)
18739 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18740 c_parser_consume_token (parser);
18741 else if (code == OMP_ATOMIC_CAPTURE_NEW)
18743 c_parser_skip_to_end_of_block_or_statement (parser);
18744 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18745 c_parser_consume_token (parser);
18750 case POSTINCREMENT_EXPR:
18751 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18752 code = OMP_ATOMIC_CAPTURE_OLD;
18754 case PREINCREMENT_EXPR:
18755 lhs = TREE_OPERAND (lhs, 0);
18756 unfolded_lhs = NULL_TREE;
18757 opcode = PLUS_EXPR;
18758 rhs = integer_one_node;
18760 goto invalid_compare;
18763 case POSTDECREMENT_EXPR:
18764 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18765 code = OMP_ATOMIC_CAPTURE_OLD;
18767 case PREDECREMENT_EXPR:
18768 lhs = TREE_OPERAND (lhs, 0);
18769 unfolded_lhs = NULL_TREE;
18770 opcode = MINUS_EXPR;
18771 rhs = integer_one_node;
18773 goto invalid_compare;
18776 case COMPOUND_EXPR:
18777 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
18778 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
18779 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
18780 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
18781 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
18782 (TREE_OPERAND (lhs, 1), 0), 0)))
18784 /* Undo effects of boolean_increment for post {in,de}crement. */
18785 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
18788 if (TREE_CODE (lhs) == MODIFY_EXPR
18789 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
18791 /* Undo effects of boolean_increment. */
18792 if (integer_onep (TREE_OPERAND (lhs, 1)))
18794 /* This is pre or post increment. */
18795 rhs = TREE_OPERAND (lhs, 1);
18796 lhs = TREE_OPERAND (lhs, 0);
18797 unfolded_lhs = NULL_TREE;
18799 if (code == OMP_ATOMIC_CAPTURE_NEW
18800 && !structured_block
18801 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18802 code = OMP_ATOMIC_CAPTURE_OLD;
18804 goto invalid_compare;
18807 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
18808 && TREE_OPERAND (lhs, 0)
18809 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
18811 /* This is pre or post decrement. */
18812 rhs = TREE_OPERAND (lhs, 1);
18813 lhs = TREE_OPERAND (lhs, 0);
18814 unfolded_lhs = NULL_TREE;
18816 if (code == OMP_ATOMIC_CAPTURE_NEW
18817 && !structured_block
18818 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18819 code = OMP_ATOMIC_CAPTURE_OLD;
18821 goto invalid_compare;
18827 if (!lvalue_p (unfolded_lhs))
18828 lhs = non_lvalue (lhs);
18829 if (compare && !c_parser_next_token_is (parser, CPP_EQ))
18831 c_parser_error (parser, "expected %<=%>");
18834 switch (c_parser_peek_token (parser)->type)
18837 opcode = MULT_EXPR;
18840 opcode = TRUNC_DIV_EXPR;
18843 opcode = PLUS_EXPR;
18846 opcode = MINUS_EXPR;
18848 case CPP_LSHIFT_EQ:
18849 opcode = LSHIFT_EXPR;
18851 case CPP_RSHIFT_EQ:
18852 opcode = RSHIFT_EXPR;
18855 opcode = BIT_AND_EXPR;
18858 opcode = BIT_IOR_EXPR;
18861 opcode = BIT_XOR_EXPR;
18864 c_parser_consume_token (parser);
18865 eloc = c_parser_peek_token (parser)->location;
18866 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
18868 switch (TREE_CODE (rhs1))
18871 case TRUNC_DIV_EXPR:
18882 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
18884 opcode = TREE_CODE (rhs1);
18885 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18887 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
18891 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
18893 opcode = TREE_CODE (rhs1);
18894 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
18896 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18898 swapped = !commutative_tree_code (opcode);
18905 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
18906 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
18907 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
18909 if (!TREE_OPERAND (rhs1, 1))
18911 if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
18913 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
18916 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
18918 opcode = COND_EXPR;
18919 rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18921 false, NULL, true);
18922 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
18926 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
18927 TREE_OPERAND (rhs1, 1)))
18929 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
18930 ? MIN_EXPR : MAX_EXPR);
18931 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18933 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18935 false, NULL, true);
18939 else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
18941 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
18944 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
18945 TREE_OPERAND (rhs1, 1)))
18947 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
18948 ? MAX_EXPR : MIN_EXPR);
18949 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18951 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18953 false, NULL, true);
18960 || code != OMP_ATOMIC_CAPTURE_NEW
18961 || !structured_block
18965 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
18966 && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
18970 c_parser_consume_token (parser);
18979 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
18981 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18983 code = OMP_ATOMIC_CAPTURE_OLD;
18986 expr = default_function_array_read_conversion (eloc, expr);
18987 unfolded_lhs1 = expr.value;
18988 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
18990 c_parser_consume_token (parser);
18993 if (structured_block && !compare)
18996 expr = default_function_array_read_conversion (eloc, expr);
18997 rhs = c_fully_fold (expr.value, false, NULL, true);
19002 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
19005 c_parser_error (parser,
19006 "invalid operator for %<#pragma omp atomic%>");
19010 /* Arrange to pass the location of the assignment operator to
19011 c_finish_omp_atomic. */
19012 loc = c_parser_peek_token (parser)->location;
19013 c_parser_consume_token (parser);
19014 eloc = c_parser_peek_token (parser)->location;
19015 expr = c_parser_expression (parser);
19016 expr = default_function_array_read_conversion (eloc, expr);
19018 rhs = c_fully_fold (rhs, false, NULL, true);
19022 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
19025 && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
19027 no_semicolon = false;
19028 v = c_parser_cast_expression (parser, NULL).value;
19029 non_lvalue_p = !lvalue_p (v);
19030 v = c_fully_fold (v, false, NULL, true);
19031 if (v == error_mark_node)
19034 v = non_lvalue (v);
19035 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
19037 eloc = c_parser_peek_token (parser)->location;
19038 expr = c_parser_cast_expression (parser, NULL);
19040 expr = default_function_array_read_conversion (eloc, expr);
19041 unfolded_lhs1 = expr.value;
19042 lhs1 = c_fully_fold (lhs1, false, NULL, true);
19043 if (lhs1 == error_mark_node)
19045 if (!lvalue_p (unfolded_lhs1))
19046 lhs1 = non_lvalue (lhs1);
19048 if (structured_block)
19051 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19052 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
19055 if (weak && opcode != COND_EXPR)
19057 error_at (loc, "%<weak%> clause requires atomic equality comparison");
19060 if (unfolded_lhs && unfolded_lhs1
19061 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
19063 error ("%<#pragma omp atomic capture%> uses two different "
19064 "expressions for memory");
19065 stmt = error_mark_node;
19068 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
19069 swapped, memory_order, weak);
19070 if (stmt != error_mark_node)
19073 if (!structured_block && !no_semicolon)
19074 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19079 # pragma omp barrier new-line
19083 c_parser_omp_barrier (c_parser *parser)
19085 location_t loc = c_parser_peek_token (parser)->location;
19086 c_parser_consume_pragma (parser);
19087 c_parser_skip_to_pragma_eol (parser);
19089 c_finish_omp_barrier (loc);
19093 # pragma omp critical [(name)] new-line
19097 # pragma omp critical [(name) [hint(expression)]] new-line
19099 LOC is the location of the #pragma itself. */
19101 #define OMP_CRITICAL_CLAUSE_MASK \
19102 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
19105 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
19107 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
19109 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19111 c_parser_consume_token (parser);
19112 if (c_parser_next_token_is (parser, CPP_NAME))
19114 name = c_parser_peek_token (parser)->value;
19115 c_parser_consume_token (parser);
19116 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
19119 c_parser_error (parser, "expected identifier");
19121 if (c_parser_next_token_is (parser, CPP_COMMA)
19122 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
19123 c_parser_consume_token (parser);
19125 clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
19126 "#pragma omp critical");
19127 stmt = c_parser_omp_structured_block (parser, if_p);
19128 return c_finish_omp_critical (loc, stmt, name, clauses);
19132 # pragma omp depobj ( depobj ) depobj-clause new-line
19135 depend (dependence-type : locator)
19137 update (dependence-type)
19146 c_parser_omp_depobj (c_parser *parser)
19148 location_t loc = c_parser_peek_token (parser)->location;
19149 c_parser_consume_pragma (parser);
19150 matching_parens parens;
19151 if (!parens.require_open (parser))
19153 c_parser_skip_to_pragma_eol (parser);
19157 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
19158 if (depobj != error_mark_node)
19160 if (!lvalue_p (depobj))
19162 error_at (EXPR_LOC_OR_LOC (depobj, loc),
19163 "%<depobj%> expression is not lvalue expression");
19164 depobj = error_mark_node;
19168 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
19170 if (addr == error_mark_node)
19171 depobj = error_mark_node;
19173 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
19174 addr, RO_UNARY_STAR);
19178 parens.skip_until_found_close (parser);
19179 tree clause = NULL_TREE;
19180 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
19181 location_t c_loc = c_parser_peek_token (parser)->location;
19182 if (c_parser_next_token_is (parser, CPP_NAME))
19184 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19186 c_parser_consume_token (parser);
19187 if (!strcmp ("depend", p))
19189 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
19190 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
19192 clause = error_mark_node;
19194 else if (!strcmp ("destroy", p))
19195 kind = OMP_CLAUSE_DEPEND_LAST;
19196 else if (!strcmp ("update", p))
19198 matching_parens c_parens;
19199 if (c_parens.require_open (parser))
19201 location_t c2_loc = c_parser_peek_token (parser)->location;
19202 if (c_parser_next_token_is (parser, CPP_NAME))
19205 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19207 c_parser_consume_token (parser);
19208 if (!strcmp ("in", p2))
19209 kind = OMP_CLAUSE_DEPEND_IN;
19210 else if (!strcmp ("out", p2))
19211 kind = OMP_CLAUSE_DEPEND_OUT;
19212 else if (!strcmp ("inout", p2))
19213 kind = OMP_CLAUSE_DEPEND_INOUT;
19214 else if (!strcmp ("mutexinoutset", p2))
19215 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
19216 else if (!strcmp ("inoutset", p2))
19217 kind = OMP_CLAUSE_DEPEND_INOUTSET;
19219 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
19221 clause = error_mark_node;
19222 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
19223 "%<mutexinoutset%> or %<inoutset%>");
19225 c_parens.skip_until_found_close (parser);
19228 clause = error_mark_node;
19231 if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
19233 clause = error_mark_node;
19234 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
19236 c_parser_skip_to_pragma_eol (parser);
19238 c_finish_omp_depobj (loc, depobj, kind, clause);
19243 # pragma omp flush flush-vars[opt] new-line
19249 # pragma omp flush memory-order-clause new-line */
19252 c_parser_omp_flush (c_parser *parser)
19254 location_t loc = c_parser_peek_token (parser)->location;
19255 c_parser_consume_pragma (parser);
19256 enum memmodel mo = MEMMODEL_LAST;
19257 if (c_parser_next_token_is (parser, CPP_NAME))
19260 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19262 if (!strcmp (p, "seq_cst"))
19263 mo = MEMMODEL_SEQ_CST;
19264 else if (!strcmp (p, "acq_rel"))
19265 mo = MEMMODEL_ACQ_REL;
19266 else if (!strcmp (p, "release"))
19267 mo = MEMMODEL_RELEASE;
19268 else if (!strcmp (p, "acquire"))
19269 mo = MEMMODEL_ACQUIRE;
19271 error_at (c_parser_peek_token (parser)->location,
19272 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
19274 c_parser_consume_token (parser);
19276 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19278 if (mo != MEMMODEL_LAST)
19279 error_at (c_parser_peek_token (parser)->location,
19280 "%<flush%> list specified together with memory order "
19282 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
19284 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19285 c_parser_error (parser, "expected %<(%> or end of line");
19286 c_parser_skip_to_pragma_eol (parser);
19288 c_finish_omp_flush (loc, mo);
19291 /* Parse an OpenMP structured block sequence. KIND is the corresponding
19292 separating directive. */
19295 c_parser_omp_structured_block_sequence (c_parser *parser,
19296 enum pragma_kind kind)
19298 tree stmt = push_stmt_list ();
19299 c_parser_statement (parser, NULL);
19302 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19304 if (c_parser_next_token_is (parser, CPP_EOF))
19307 if (kind != PRAGMA_NONE
19308 && c_parser_peek_token (parser)->pragma_kind == kind)
19310 c_parser_statement (parser, NULL);
19313 return pop_stmt_list (stmt);
19319 { structured-block scan-directive structured-block } */
19322 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
19326 tree clauses = NULL_TREE;
19328 loc = c_parser_peek_token (parser)->location;
19329 if (!open_brace_parsed
19330 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
19332 /* Avoid skipping until the end of the block. */
19333 parser->error = false;
19337 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
19338 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
19339 SET_EXPR_LOCATION (substmt, loc);
19340 add_stmt (substmt);
19342 loc = c_parser_peek_token (parser)->location;
19343 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
19345 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
19347 c_parser_consume_pragma (parser);
19349 if (c_parser_next_token_is (parser, CPP_NAME))
19352 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19353 if (strcmp (p, "inclusive") == 0)
19354 clause = OMP_CLAUSE_INCLUSIVE;
19355 else if (strcmp (p, "exclusive") == 0)
19356 clause = OMP_CLAUSE_EXCLUSIVE;
19358 if (clause != OMP_CLAUSE_ERROR)
19360 c_parser_consume_token (parser);
19361 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
19364 c_parser_error (parser, "expected %<inclusive%> or "
19365 "%<exclusive%> clause");
19366 c_parser_skip_to_pragma_eol (parser);
19369 error ("expected %<#pragma omp scan%>");
19371 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
19372 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
19373 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
19374 SET_EXPR_LOCATION (substmt, loc);
19375 add_stmt (substmt);
19377 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
19381 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
19382 The real trick here is to determine the loop control variable early
19383 so that we can push a new decl if necessary to make it private.
19384 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
19388 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
19389 tree clauses, tree *cclauses, bool *if_p)
19391 tree decl, cond, incr, body, init, stmt, cl;
19392 unsigned char save_in_statement;
19393 tree declv, condv, incrv, initv, ret = NULL_TREE;
19394 tree pre_body = NULL_TREE, this_pre_body;
19395 tree ordered_cl = NULL_TREE;
19396 bool fail = false, open_brace_parsed = false;
19397 int i, collapse = 1, ordered = 0, count, nbraces = 0;
19398 location_t for_loc;
19399 bool tiling = false;
19400 bool inscan = false;
19401 vec<tree, va_gc> *for_block = make_tree_vector ();
19403 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
19404 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
19405 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
19406 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
19409 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
19411 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
19412 && OMP_CLAUSE_ORDERED_EXPR (cl))
19415 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
19417 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
19418 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
19419 && (code == OMP_SIMD || code == OMP_FOR))
19422 if (ordered && ordered < collapse)
19424 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
19425 "%<ordered%> clause parameter is less than %<collapse%>");
19426 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
19427 = build_int_cst (NULL_TREE, collapse);
19428 ordered = collapse;
19432 for (tree *pc = &clauses; *pc; )
19433 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
19435 error_at (OMP_CLAUSE_LOCATION (*pc),
19436 "%<linear%> clause may not be specified together "
19437 "with %<ordered%> clause with a parameter");
19438 *pc = OMP_CLAUSE_CHAIN (*pc);
19441 pc = &OMP_CLAUSE_CHAIN (*pc);
19444 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
19445 count = ordered ? ordered : collapse;
19447 declv = make_tree_vec (count);
19448 initv = make_tree_vec (count);
19449 condv = make_tree_vec (count);
19450 incrv = make_tree_vec (count);
19452 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
19454 c_parser_error (parser, "for statement expected");
19457 for_loc = c_parser_peek_token (parser)->location;
19458 c_parser_consume_token (parser);
19460 /* Forbid break/continue in the loop initializer, condition, and
19461 increment expressions. */
19462 save_in_statement = in_statement;
19463 in_statement = IN_OMP_BLOCK;
19465 for (i = 0; i < count; i++)
19467 int bracecount = 0;
19469 matching_parens parens;
19470 if (!parens.require_open (parser))
19473 /* Parse the initialization declaration or expression. */
19474 if (c_parser_next_tokens_start_declaration (parser))
19477 vec_safe_push (for_block, c_begin_compound_stmt (true));
19478 this_pre_body = push_stmt_list ();
19479 c_in_omp_for = true;
19480 c_parser_declaration_or_fndef (parser, true, true, true, true, true);
19481 c_in_omp_for = false;
19484 this_pre_body = pop_stmt_list (this_pre_body);
19488 pre_body = push_stmt_list ();
19490 add_stmt (this_pre_body);
19491 pre_body = pop_stmt_list (pre_body);
19494 pre_body = this_pre_body;
19496 decl = check_for_loop_decls (for_loc, flag_isoc99);
19499 if (DECL_INITIAL (decl) == error_mark_node)
19500 decl = error_mark_node;
19503 else if (c_parser_next_token_is (parser, CPP_NAME)
19504 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
19506 struct c_expr decl_exp;
19507 struct c_expr init_exp;
19508 location_t init_loc;
19510 decl_exp = c_parser_postfix_expression (parser);
19511 decl = decl_exp.value;
19513 c_parser_require (parser, CPP_EQ, "expected %<=%>");
19515 init_loc = c_parser_peek_token (parser)->location;
19516 init_exp = c_parser_expr_no_commas (parser, NULL);
19517 init_exp = default_function_array_read_conversion (init_loc,
19519 c_in_omp_for = true;
19520 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
19521 NOP_EXPR, init_loc, init_exp.value,
19522 init_exp.original_type);
19523 c_in_omp_for = false;
19524 init = c_process_expr_stmt (init_loc, init);
19526 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19531 c_parser_error (parser,
19532 "expected iteration declaration or initialization");
19533 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
19539 /* Parse the loop condition. */
19541 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
19543 location_t cond_loc = c_parser_peek_token (parser)->location;
19544 c_in_omp_for = true;
19545 struct c_expr cond_expr
19546 = c_parser_binary_expression (parser, NULL, NULL_TREE);
19547 c_in_omp_for = false;
19549 cond = cond_expr.value;
19550 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
19551 switch (cond_expr.original_code)
19559 if (code != OACC_LOOP)
19563 /* Can't be cond = error_mark_node, because we want to preserve
19564 the location until c_finish_omp_for. */
19565 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
19568 protected_set_expr_location (cond, cond_loc);
19570 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19572 /* Parse the increment expression. */
19574 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
19576 location_t incr_loc = c_parser_peek_token (parser)->location;
19578 incr = c_process_expr_stmt (incr_loc,
19579 c_parser_expression (parser).value);
19581 parens.skip_until_found_close (parser);
19583 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
19587 TREE_VEC_ELT (declv, i) = decl;
19588 TREE_VEC_ELT (initv, i) = init;
19589 TREE_VEC_ELT (condv, i) = cond;
19590 TREE_VEC_ELT (incrv, i) = incr;
19594 if (i == count - 1)
19597 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
19598 in between the collapsed for loops to be still considered perfectly
19599 nested. Hopefully the final version clarifies this.
19600 For now handle (multiple) {'s and empty statements. */
19603 if (c_parser_next_token_is_keyword (parser, RID_FOR))
19605 c_parser_consume_token (parser);
19608 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
19610 c_parser_consume_token (parser);
19613 else if (bracecount
19614 && c_parser_next_token_is (parser, CPP_SEMICOLON))
19615 c_parser_consume_token (parser);
19618 c_parser_error (parser, "not enough perfectly nested loops");
19621 open_brace_parsed = true;
19631 nbraces += bracecount;
19637 in_statement = IN_OMP_FOR;
19638 body = push_stmt_list ();
19641 c_parser_omp_scan_loop_body (parser, open_brace_parsed);
19642 else if (open_brace_parsed)
19644 location_t here = c_parser_peek_token (parser)->location;
19645 stmt = c_begin_compound_stmt (true);
19646 c_parser_compound_statement_nostart (parser);
19647 add_stmt (c_end_compound_stmt (here, stmt, true));
19650 add_stmt (c_parser_c99_block_statement (parser, if_p));
19652 body = pop_stmt_list (body);
19653 in_statement = save_in_statement;
19657 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19659 c_parser_consume_token (parser);
19662 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
19663 c_parser_consume_token (parser);
19666 c_parser_error (parser, "collapsed loops not perfectly nested");
19669 location_t here = c_parser_peek_token (parser)->location;
19670 stmt = c_begin_compound_stmt (true);
19672 c_parser_compound_statement_nostart (parser);
19673 body = c_end_compound_stmt (here, stmt, true);
19680 /* Only bother calling c_finish_omp_for if we haven't already generated
19681 an error from the initialization parsing. */
19684 c_in_omp_for = true;
19685 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
19686 incrv, body, pre_body, true);
19687 c_in_omp_for = false;
19689 /* Check for iterators appearing in lb, b or incr expressions. */
19690 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
19697 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
19699 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
19700 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
19701 tree decl = TREE_OPERAND (init, 0);
19702 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
19703 gcc_assert (COMPARISON_CLASS_P (cond));
19704 gcc_assert (TREE_OPERAND (cond, 0) == decl);
19706 tree op0 = TREE_OPERAND (init, 1);
19707 if (!OMP_FOR_NON_RECTANGULAR (stmt)
19708 || TREE_CODE (op0) != TREE_VEC)
19709 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
19712 TREE_VEC_ELT (op0, 1)
19713 = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
19714 TREE_VEC_ELT (op0, 2)
19715 = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
19718 tree op1 = TREE_OPERAND (cond, 1);
19719 if (!OMP_FOR_NON_RECTANGULAR (stmt)
19720 || TREE_CODE (op1) != TREE_VEC)
19721 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
19724 TREE_VEC_ELT (op1, 1)
19725 = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
19726 TREE_VEC_ELT (op1, 2)
19727 = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
19731 if (cclauses != NULL
19732 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
19735 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
19736 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
19737 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
19738 c = &OMP_CLAUSE_CHAIN (*c);
19741 for (i = 0; i < count; i++)
19742 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
19745 c = &OMP_CLAUSE_CHAIN (*c);
19746 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
19749 "iteration variable %qD should not be firstprivate",
19750 OMP_CLAUSE_DECL (*c));
19751 *c = OMP_CLAUSE_CHAIN (*c);
19755 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
19757 *c = OMP_CLAUSE_CHAIN (*c);
19758 if (code == OMP_SIMD)
19760 OMP_CLAUSE_CHAIN (l)
19761 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19762 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
19766 OMP_CLAUSE_CHAIN (l) = clauses;
19772 OMP_FOR_CLAUSES (stmt) = clauses;
19777 while (!for_block->is_empty ())
19779 /* FIXME diagnostics: LOC below should be the actual location of
19780 this particular for block. We need to build a list of
19781 locations to go along with FOR_BLOCK. */
19782 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
19785 release_tree_vector (for_block);
19789 /* Helper function for OpenMP parsing, split clauses and call
19790 finish_omp_clauses on each of the set of clauses afterwards. */
19793 omp_split_clauses (location_t loc, enum tree_code code,
19794 omp_clause_mask mask, tree clauses, tree *cclauses)
19797 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
19798 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
19800 cclauses[i] = c_finish_omp_clauses (cclauses[i],
19801 i == C_OMP_CLAUSE_SPLIT_TARGET
19802 ? C_ORT_OMP_TARGET : C_ORT_OMP);
19806 #pragma omp loop loop-clause[optseq] new-line
19809 LOC is the location of the #pragma token.
19812 #define OMP_LOOP_CLAUSE_MASK \
19813 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19815 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19816 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19817 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
19818 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19821 c_parser_omp_loop (location_t loc, c_parser *parser,
19822 char *p_name, omp_clause_mask mask, tree *cclauses,
19825 tree block, clauses, ret;
19827 strcat (p_name, " loop");
19828 mask |= OMP_LOOP_CLAUSE_MASK;
19830 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19833 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
19834 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
19837 block = c_begin_compound_stmt (true);
19838 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
19839 block = c_end_compound_stmt (loc, block, true);
19846 #pragma omp simd simd-clause[optseq] new-line
19849 LOC is the location of the #pragma token.
19852 #define OMP_SIMD_CLAUSE_MASK \
19853 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
19854 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19855 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19856 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19857 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19858 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19859 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19860 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19861 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19862 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
19863 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19866 c_parser_omp_simd (location_t loc, c_parser *parser,
19867 char *p_name, omp_clause_mask mask, tree *cclauses,
19870 tree block, clauses, ret;
19872 strcat (p_name, " simd");
19873 mask |= OMP_SIMD_CLAUSE_MASK;
19875 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19878 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
19879 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
19880 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
19881 OMP_CLAUSE_ORDERED);
19882 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
19884 error_at (OMP_CLAUSE_LOCATION (c),
19885 "%<ordered%> clause with parameter may not be specified "
19886 "on %qs construct", p_name);
19887 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
19891 block = c_begin_compound_stmt (true);
19892 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
19893 block = c_end_compound_stmt (loc, block, true);
19900 #pragma omp for for-clause[optseq] new-line
19904 #pragma omp for simd for-simd-clause[optseq] new-line
19907 LOC is the location of the #pragma token.
19910 #define OMP_FOR_CLAUSE_MASK \
19911 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19912 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19913 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19914 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19915 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19916 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
19917 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
19918 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19919 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19920 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19921 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19924 c_parser_omp_for (location_t loc, c_parser *parser,
19925 char *p_name, omp_clause_mask mask, tree *cclauses,
19928 tree block, clauses, ret;
19930 strcat (p_name, " for");
19931 mask |= OMP_FOR_CLAUSE_MASK;
19932 /* parallel for{, simd} disallows nowait clause, but for
19933 target {teams distribute ,}parallel for{, simd} it should be accepted. */
19934 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
19935 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
19936 /* Composite distribute parallel for{, simd} disallows ordered clause. */
19937 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19938 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
19940 if (c_parser_next_token_is (parser, CPP_NAME))
19942 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19944 if (strcmp (p, "simd") == 0)
19946 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19947 if (cclauses == NULL)
19948 cclauses = cclauses_buf;
19950 c_parser_consume_token (parser);
19951 if (!flag_openmp) /* flag_openmp_simd */
19952 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19954 block = c_begin_compound_stmt (true);
19955 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
19956 block = c_end_compound_stmt (loc, block, true);
19957 if (ret == NULL_TREE)
19959 ret = make_node (OMP_FOR);
19960 TREE_TYPE (ret) = void_type_node;
19961 OMP_FOR_BODY (ret) = block;
19962 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19963 SET_EXPR_LOCATION (ret, loc);
19968 if (!flag_openmp) /* flag_openmp_simd */
19970 c_parser_skip_to_pragma_eol (parser, false);
19974 /* Composite distribute parallel for disallows linear clause. */
19975 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19976 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
19978 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19981 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
19982 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19985 block = c_begin_compound_stmt (true);
19986 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
19987 block = c_end_compound_stmt (loc, block, true);
19993 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
19994 omp_clause_mask, tree *, bool *);
19997 # pragma omp master new-line
20000 LOC is the location of the #pragma token.
20004 c_parser_omp_master (location_t loc, c_parser *parser,
20005 char *p_name, omp_clause_mask mask, tree *cclauses,
20008 tree block, clauses, ret;
20010 strcat (p_name, " master");
20012 if (c_parser_next_token_is (parser, CPP_NAME))
20014 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20016 if (strcmp (p, "taskloop") == 0)
20018 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20019 if (cclauses == NULL)
20020 cclauses = cclauses_buf;
20022 c_parser_consume_token (parser);
20023 if (!flag_openmp) /* flag_openmp_simd */
20024 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20026 block = c_begin_compound_stmt (true);
20027 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20029 block = c_end_compound_stmt (loc, block, true);
20030 if (ret == NULL_TREE)
20032 ret = c_finish_omp_master (loc, block);
20033 OMP_MASTER_COMBINED (ret) = 1;
20037 if (!flag_openmp) /* flag_openmp_simd */
20039 c_parser_skip_to_pragma_eol (parser, false);
20045 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
20046 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
20049 c_parser_skip_to_pragma_eol (parser);
20051 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
20056 # pragma omp masked masked-clauses new-line
20059 LOC is the location of the #pragma token.
20062 #define OMP_MASKED_CLAUSE_MASK \
20063 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
20066 c_parser_omp_masked (location_t loc, c_parser *parser,
20067 char *p_name, omp_clause_mask mask, tree *cclauses,
20070 tree block, clauses, ret;
20072 strcat (p_name, " masked");
20073 mask |= OMP_MASKED_CLAUSE_MASK;
20075 if (c_parser_next_token_is (parser, CPP_NAME))
20077 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20079 if (strcmp (p, "taskloop") == 0)
20081 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20082 if (cclauses == NULL)
20083 cclauses = cclauses_buf;
20085 c_parser_consume_token (parser);
20086 if (!flag_openmp) /* flag_openmp_simd */
20087 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20089 block = c_begin_compound_stmt (true);
20090 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20092 block = c_end_compound_stmt (loc, block, true);
20093 if (ret == NULL_TREE)
20095 ret = c_finish_omp_masked (loc, block,
20096 cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
20097 OMP_MASKED_COMBINED (ret) = 1;
20101 if (!flag_openmp) /* flag_openmp_simd */
20103 c_parser_skip_to_pragma_eol (parser, false);
20107 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20110 omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
20111 clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
20114 return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
20120 # pragma omp ordered new-line
20124 # pragma omp ordered ordered-clauses new-line
20127 # pragma omp ordered depend-clauses new-line */
20129 #define OMP_ORDERED_CLAUSE_MASK \
20130 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
20131 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
20133 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
20134 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
20137 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
20140 location_t loc = c_parser_peek_token (parser)->location;
20141 c_parser_consume_pragma (parser);
20143 if (context != pragma_stmt && context != pragma_compound)
20145 c_parser_error (parser, "expected declaration specifiers");
20146 c_parser_skip_to_pragma_eol (parser, false);
20150 if (c_parser_next_token_is (parser, CPP_NAME))
20152 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20154 if (!strcmp ("depend", p))
20156 if (!flag_openmp) /* flag_openmp_simd */
20158 c_parser_skip_to_pragma_eol (parser, false);
20161 if (context == pragma_stmt)
20164 "%<#pragma omp ordered%> with %<depend%> clause may "
20165 "only be used in compound statements");
20166 c_parser_skip_to_pragma_eol (parser, false);
20171 = c_parser_omp_all_clauses (parser,
20172 OMP_ORDERED_DEPEND_CLAUSE_MASK,
20173 "#pragma omp ordered");
20174 c_finish_omp_ordered (loc, clauses, NULL_TREE);
20179 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
20180 "#pragma omp ordered");
20182 if (!flag_openmp /* flag_openmp_simd */
20183 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
20186 c_finish_omp_ordered (loc, clauses,
20187 c_parser_omp_structured_block (parser, if_p));
20194 { section-sequence }
20197 section-directive[opt] structured-block
20198 section-sequence section-directive structured-block
20200 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20202 SECTIONS_LOC is the location of the #pragma omp sections. */
20205 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
20207 tree stmt, substmt;
20208 bool error_suppress = false;
20211 loc = c_parser_peek_token (parser)->location;
20212 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
20214 /* Avoid skipping until the end of the block. */
20215 parser->error = false;
20219 stmt = push_stmt_list ();
20221 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
20223 substmt = c_parser_omp_structured_block_sequence (parser,
20224 PRAGMA_OMP_SECTION);
20225 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20226 SET_EXPR_LOCATION (substmt, loc);
20227 add_stmt (substmt);
20232 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
20234 if (c_parser_next_token_is (parser, CPP_EOF))
20237 loc = c_parser_peek_token (parser)->location;
20238 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
20240 c_parser_consume_pragma (parser);
20241 c_parser_skip_to_pragma_eol (parser);
20242 error_suppress = false;
20244 else if (!error_suppress)
20246 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
20247 error_suppress = true;
20250 substmt = c_parser_omp_structured_block_sequence (parser,
20251 PRAGMA_OMP_SECTION);
20252 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20253 SET_EXPR_LOCATION (substmt, loc);
20254 add_stmt (substmt);
20256 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
20257 "expected %<#pragma omp section%> or %<}%>");
20259 substmt = pop_stmt_list (stmt);
20261 stmt = make_node (OMP_SECTIONS);
20262 SET_EXPR_LOCATION (stmt, sections_loc);
20263 TREE_TYPE (stmt) = void_type_node;
20264 OMP_SECTIONS_BODY (stmt) = substmt;
20266 return add_stmt (stmt);
20270 # pragma omp sections sections-clause[optseq] newline
20273 LOC is the location of the #pragma token.
20276 #define OMP_SECTIONS_CLAUSE_MASK \
20277 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20278 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20279 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20280 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20281 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20282 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20285 c_parser_omp_sections (location_t loc, c_parser *parser,
20286 char *p_name, omp_clause_mask mask, tree *cclauses)
20288 tree block, clauses, ret;
20290 strcat (p_name, " sections");
20291 mask |= OMP_SECTIONS_CLAUSE_MASK;
20293 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
20295 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20298 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
20299 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
20302 block = c_begin_compound_stmt (true);
20303 ret = c_parser_omp_sections_scope (loc, parser);
20305 OMP_SECTIONS_CLAUSES (ret) = clauses;
20306 block = c_end_compound_stmt (loc, block, true);
20313 # pragma omp parallel parallel-clause[optseq] new-line
20315 # pragma omp parallel for parallel-for-clause[optseq] new-line
20317 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
20321 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
20324 LOC is the location of the #pragma token.
20327 #define OMP_PARALLEL_CLAUSE_MASK \
20328 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20329 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20330 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20331 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20332 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20333 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
20334 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20335 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
20336 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20337 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
20340 c_parser_omp_parallel (location_t loc, c_parser *parser,
20341 char *p_name, omp_clause_mask mask, tree *cclauses,
20344 tree stmt, clauses, block;
20346 strcat (p_name, " parallel");
20347 mask |= OMP_PARALLEL_CLAUSE_MASK;
20348 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
20349 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
20350 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
20351 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
20353 if (c_parser_next_token_is_keyword (parser, RID_FOR))
20355 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20356 if (cclauses == NULL)
20357 cclauses = cclauses_buf;
20359 c_parser_consume_token (parser);
20360 if (!flag_openmp) /* flag_openmp_simd */
20361 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20362 block = c_begin_omp_parallel ();
20363 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20365 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20367 if (ret == NULL_TREE)
20369 OMP_PARALLEL_COMBINED (stmt) = 1;
20372 /* When combined with distribute, parallel has to be followed by for.
20373 #pragma omp target parallel is allowed though. */
20375 && (mask & (OMP_CLAUSE_MASK_1
20376 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20378 error_at (loc, "expected %<for%> after %qs", p_name);
20379 c_parser_skip_to_pragma_eol (parser);
20382 else if (c_parser_next_token_is (parser, CPP_NAME))
20384 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20385 if (cclauses == NULL && strcmp (p, "masked") == 0)
20387 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20388 cclauses = cclauses_buf;
20390 c_parser_consume_token (parser);
20391 if (!flag_openmp) /* flag_openmp_simd */
20392 return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20394 block = c_begin_omp_parallel ();
20395 tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20397 stmt = c_finish_omp_parallel (loc,
20398 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20402 /* masked does have just filter clause, but during gimplification
20403 isn't represented by a gimplification omp context, so for
20404 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
20406 #pragma omp parallel masked
20407 #pragma omp taskloop simd lastprivate (x)
20408 isn't confused with
20409 #pragma omp parallel masked taskloop simd lastprivate (x) */
20410 if (OMP_MASKED_COMBINED (ret))
20411 OMP_PARALLEL_COMBINED (stmt) = 1;
20414 else if (cclauses == NULL && strcmp (p, "master") == 0)
20416 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20417 cclauses = cclauses_buf;
20419 c_parser_consume_token (parser);
20420 if (!flag_openmp) /* flag_openmp_simd */
20421 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20423 block = c_begin_omp_parallel ();
20424 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20426 stmt = c_finish_omp_parallel (loc,
20427 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20431 /* master doesn't have any clauses and during gimplification
20432 isn't represented by a gimplification omp context, so for
20433 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
20435 #pragma omp parallel master
20436 #pragma omp taskloop simd lastprivate (x)
20437 isn't confused with
20438 #pragma omp parallel master taskloop simd lastprivate (x) */
20439 if (OMP_MASTER_COMBINED (ret))
20440 OMP_PARALLEL_COMBINED (stmt) = 1;
20443 else if (strcmp (p, "loop") == 0)
20445 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20446 if (cclauses == NULL)
20447 cclauses = cclauses_buf;
20449 c_parser_consume_token (parser);
20450 if (!flag_openmp) /* flag_openmp_simd */
20451 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20453 block = c_begin_omp_parallel ();
20454 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20457 = c_finish_omp_parallel (loc,
20458 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20460 if (ret == NULL_TREE)
20462 OMP_PARALLEL_COMBINED (stmt) = 1;
20465 else if (!flag_openmp) /* flag_openmp_simd */
20467 c_parser_skip_to_pragma_eol (parser, false);
20470 else if (cclauses == NULL && strcmp (p, "sections") == 0)
20472 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20473 cclauses = cclauses_buf;
20475 c_parser_consume_token (parser);
20476 block = c_begin_omp_parallel ();
20477 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
20478 stmt = c_finish_omp_parallel (loc,
20479 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20481 OMP_PARALLEL_COMBINED (stmt) = 1;
20485 else if (!flag_openmp) /* flag_openmp_simd */
20487 c_parser_skip_to_pragma_eol (parser, false);
20491 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20494 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
20495 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
20498 block = c_begin_omp_parallel ();
20499 c_parser_statement (parser, if_p);
20500 stmt = c_finish_omp_parallel (loc, clauses, block);
20506 # pragma omp single single-clause[optseq] new-line
20509 LOC is the location of the #pragma.
20512 #define OMP_SINGLE_CLAUSE_MASK \
20513 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20514 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20515 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
20516 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20517 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20520 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
20522 tree stmt = make_node (OMP_SINGLE);
20523 SET_EXPR_LOCATION (stmt, loc);
20524 TREE_TYPE (stmt) = void_type_node;
20526 OMP_SINGLE_CLAUSES (stmt)
20527 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
20528 "#pragma omp single");
20529 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20531 return add_stmt (stmt);
20535 # pragma omp scope scope-clause[optseq] new-line
20538 LOC is the location of the #pragma.
20541 #define OMP_SCOPE_CLAUSE_MASK \
20542 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20549 c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
20551 tree stmt = make_node (OMP_SCOPE);
20552 SET_EXPR_LOCATION (stmt, loc);
20553 TREE_TYPE (stmt) = void_type_node;
20555 OMP_SCOPE_CLAUSES (stmt)
20556 = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
20557 "#pragma omp scope");
20558 OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20560 return add_stmt (stmt);
20564 # pragma omp task task-clause[optseq] new-line
20566 LOC is the location of the #pragma.
20569 #define OMP_TASK_CLAUSE_MASK \
20570 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20571 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
20572 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20574 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20575 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20576 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
20577 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
20578 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20579 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
20580 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20581 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
20582 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
20583 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
20586 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
20588 tree clauses, block;
20590 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
20591 "#pragma omp task");
20593 block = c_begin_omp_task ();
20594 c_parser_statement (parser, if_p);
20595 return c_finish_omp_task (loc, clauses, block);
20599 # pragma omp taskwait new-line
20602 # pragma omp taskwait taskwait-clause[optseq] new-line
20605 #define OMP_TASKWAIT_CLAUSE_MASK \
20606 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20607 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20610 c_parser_omp_taskwait (c_parser *parser)
20612 location_t loc = c_parser_peek_token (parser)->location;
20613 c_parser_consume_pragma (parser);
20616 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
20617 "#pragma omp taskwait");
20621 tree stmt = make_node (OMP_TASK);
20622 TREE_TYPE (stmt) = void_node;
20623 OMP_TASK_CLAUSES (stmt) = clauses;
20624 OMP_TASK_BODY (stmt) = NULL_TREE;
20625 SET_EXPR_LOCATION (stmt, loc);
20629 c_finish_omp_taskwait (loc);
20633 # pragma omp taskyield new-line
20637 c_parser_omp_taskyield (c_parser *parser)
20639 location_t loc = c_parser_peek_token (parser)->location;
20640 c_parser_consume_pragma (parser);
20641 c_parser_skip_to_pragma_eol (parser);
20643 c_finish_omp_taskyield (loc);
20647 # pragma omp taskgroup new-line
20650 # pragma omp taskgroup taskgroup-clause[optseq] new-line
20653 #define OMP_TASKGROUP_CLAUSE_MASK \
20654 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20655 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
20658 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
20660 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
20661 "#pragma omp taskgroup");
20663 tree body = c_parser_omp_structured_block (parser, if_p);
20664 return c_finish_omp_taskgroup (loc, body, clauses);
20668 # pragma omp cancel cancel-clause[optseq] new-line
20670 LOC is the location of the #pragma.
20673 #define OMP_CANCEL_CLAUSE_MASK \
20674 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20675 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20676 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20677 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
20678 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
20681 c_parser_omp_cancel (c_parser *parser)
20683 location_t loc = c_parser_peek_token (parser)->location;
20685 c_parser_consume_pragma (parser);
20686 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
20687 "#pragma omp cancel");
20689 c_finish_omp_cancel (loc, clauses);
20693 # pragma omp cancellation point cancelpt-clause[optseq] new-line
20695 LOC is the location of the #pragma.
20698 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
20699 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20700 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20701 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20702 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
20705 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
20707 location_t loc = c_parser_peek_token (parser)->location;
20709 bool point_seen = false;
20711 c_parser_consume_pragma (parser);
20712 if (c_parser_next_token_is (parser, CPP_NAME))
20714 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20715 if (strcmp (p, "point") == 0)
20717 c_parser_consume_token (parser);
20723 c_parser_error (parser, "expected %<point%>");
20724 c_parser_skip_to_pragma_eol (parser);
20728 if (context != pragma_compound)
20730 if (context == pragma_stmt)
20732 "%<#pragma %s%> may only be used in compound statements",
20733 "omp cancellation point");
20735 c_parser_error (parser, "expected declaration specifiers");
20736 c_parser_skip_to_pragma_eol (parser, false);
20741 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
20742 "#pragma omp cancellation point");
20744 c_finish_omp_cancellation_point (loc, clauses);
20749 #pragma omp distribute distribute-clause[optseq] new-line
20752 #define OMP_DISTRIBUTE_CLAUSE_MASK \
20753 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20754 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20755 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20756 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
20757 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20758 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20759 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20762 c_parser_omp_distribute (location_t loc, c_parser *parser,
20763 char *p_name, omp_clause_mask mask, tree *cclauses,
20766 tree clauses, block, ret;
20768 strcat (p_name, " distribute");
20769 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
20771 if (c_parser_next_token_is (parser, CPP_NAME))
20773 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20775 bool parallel = false;
20777 if (strcmp (p, "simd") == 0)
20780 parallel = strcmp (p, "parallel") == 0;
20781 if (parallel || simd)
20783 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20784 if (cclauses == NULL)
20785 cclauses = cclauses_buf;
20786 c_parser_consume_token (parser);
20787 if (!flag_openmp) /* flag_openmp_simd */
20790 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20793 return c_parser_omp_parallel (loc, parser, p_name, mask,
20796 block = c_begin_compound_stmt (true);
20798 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20801 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
20803 block = c_end_compound_stmt (loc, block, true);
20806 ret = make_node (OMP_DISTRIBUTE);
20807 TREE_TYPE (ret) = void_type_node;
20808 OMP_FOR_BODY (ret) = block;
20809 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20810 SET_EXPR_LOCATION (ret, loc);
20815 if (!flag_openmp) /* flag_openmp_simd */
20817 c_parser_skip_to_pragma_eol (parser, false);
20821 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20824 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
20825 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20828 block = c_begin_compound_stmt (true);
20829 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
20831 block = c_end_compound_stmt (loc, block, true);
20838 # pragma omp teams teams-clause[optseq] new-line
20839 structured-block */
20841 #define OMP_TEAMS_CLAUSE_MASK \
20842 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20843 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20844 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20845 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20846 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
20847 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
20848 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20849 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
20852 c_parser_omp_teams (location_t loc, c_parser *parser,
20853 char *p_name, omp_clause_mask mask, tree *cclauses,
20856 tree clauses, block, ret;
20858 strcat (p_name, " teams");
20859 mask |= OMP_TEAMS_CLAUSE_MASK;
20861 if (c_parser_next_token_is (parser, CPP_NAME))
20863 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20864 if (strcmp (p, "distribute") == 0)
20866 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20867 if (cclauses == NULL)
20868 cclauses = cclauses_buf;
20870 c_parser_consume_token (parser);
20871 if (!flag_openmp) /* flag_openmp_simd */
20872 return c_parser_omp_distribute (loc, parser, p_name, mask,
20874 block = c_begin_omp_parallel ();
20875 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
20877 block = c_end_compound_stmt (loc, block, true);
20880 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20881 ret = make_node (OMP_TEAMS);
20882 TREE_TYPE (ret) = void_type_node;
20883 OMP_TEAMS_CLAUSES (ret) = clauses;
20884 OMP_TEAMS_BODY (ret) = block;
20885 OMP_TEAMS_COMBINED (ret) = 1;
20886 SET_EXPR_LOCATION (ret, loc);
20887 return add_stmt (ret);
20889 else if (strcmp (p, "loop") == 0)
20891 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20892 if (cclauses == NULL)
20893 cclauses = cclauses_buf;
20895 c_parser_consume_token (parser);
20896 if (!flag_openmp) /* flag_openmp_simd */
20897 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20899 block = c_begin_omp_parallel ();
20900 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
20901 block = c_end_compound_stmt (loc, block, true);
20904 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20905 ret = make_node (OMP_TEAMS);
20906 TREE_TYPE (ret) = void_type_node;
20907 OMP_TEAMS_CLAUSES (ret) = clauses;
20908 OMP_TEAMS_BODY (ret) = block;
20909 OMP_TEAMS_COMBINED (ret) = 1;
20910 SET_EXPR_LOCATION (ret, loc);
20911 return add_stmt (ret);
20914 if (!flag_openmp) /* flag_openmp_simd */
20916 c_parser_skip_to_pragma_eol (parser, false);
20920 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20923 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
20924 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20927 tree stmt = make_node (OMP_TEAMS);
20928 TREE_TYPE (stmt) = void_type_node;
20929 OMP_TEAMS_CLAUSES (stmt) = clauses;
20930 block = c_begin_omp_parallel ();
20931 add_stmt (c_parser_omp_structured_block (parser, if_p));
20932 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
20933 SET_EXPR_LOCATION (stmt, loc);
20935 return add_stmt (stmt);
20939 # pragma omp target data target-data-clause[optseq] new-line
20940 structured-block */
20942 #define OMP_TARGET_DATA_CLAUSE_MASK \
20943 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20944 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20945 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20946 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
20947 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
20950 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
20954 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
20957 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
20958 "#pragma omp target data");
20959 c_omp_adjust_map_clauses (clauses, false);
20961 for (tree *pc = &clauses; *pc;)
20963 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
20964 switch (OMP_CLAUSE_MAP_KIND (*pc))
20967 case GOMP_MAP_ALWAYS_TO:
20968 case GOMP_MAP_FROM:
20969 case GOMP_MAP_ALWAYS_FROM:
20970 case GOMP_MAP_TOFROM:
20971 case GOMP_MAP_ALWAYS_TOFROM:
20972 case GOMP_MAP_ALLOC:
20975 case GOMP_MAP_FIRSTPRIVATE_POINTER:
20976 case GOMP_MAP_ALWAYS_POINTER:
20977 case GOMP_MAP_ATTACH_DETACH:
20981 error_at (OMP_CLAUSE_LOCATION (*pc),
20982 "%<#pragma omp target data%> with map-type other "
20983 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
20984 "on %<map%> clause");
20985 *pc = OMP_CLAUSE_CHAIN (*pc);
20988 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
20989 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
20991 pc = &OMP_CLAUSE_CHAIN (*pc);
20998 "%<#pragma omp target data%> must contain at least "
20999 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
21004 tree stmt = make_node (OMP_TARGET_DATA);
21005 TREE_TYPE (stmt) = void_type_node;
21006 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
21007 keep_next_level ();
21008 tree block = c_begin_compound_stmt (true);
21009 add_stmt (c_parser_omp_structured_block (parser, if_p));
21010 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21012 SET_EXPR_LOCATION (stmt, loc);
21013 return add_stmt (stmt);
21017 # pragma omp target update target-update-clause[optseq] new-line */
21019 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
21020 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
21021 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
21022 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21023 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21024 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21025 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21028 c_parser_omp_target_update (location_t loc, c_parser *parser,
21029 enum pragma_context context)
21031 if (context == pragma_stmt)
21033 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21034 "omp target update");
21035 c_parser_skip_to_pragma_eol (parser, false);
21040 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
21041 "#pragma omp target update");
21042 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
21043 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
21046 "%<#pragma omp target update%> must contain at least one "
21047 "%<from%> or %<to%> clauses");
21053 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21055 tree stmt = make_node (OMP_TARGET_UPDATE);
21056 TREE_TYPE (stmt) = void_type_node;
21057 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
21058 SET_EXPR_LOCATION (stmt, loc);
21064 # pragma omp target enter data target-data-clause[optseq] new-line */
21066 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
21067 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21068 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21069 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21070 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21071 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21074 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
21075 enum pragma_context context)
21077 bool data_seen = false;
21078 if (c_parser_next_token_is (parser, CPP_NAME))
21080 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21081 if (strcmp (p, "data") == 0)
21083 c_parser_consume_token (parser);
21089 c_parser_error (parser, "expected %<data%>");
21090 c_parser_skip_to_pragma_eol (parser);
21094 if (context == pragma_stmt)
21096 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21097 "omp target enter data");
21098 c_parser_skip_to_pragma_eol (parser, false);
21104 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21107 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
21108 "#pragma omp target enter data");
21109 c_omp_adjust_map_clauses (clauses, false);
21111 for (tree *pc = &clauses; *pc;)
21113 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21114 switch (OMP_CLAUSE_MAP_KIND (*pc))
21117 case GOMP_MAP_ALWAYS_TO:
21118 case GOMP_MAP_ALLOC:
21121 case GOMP_MAP_TOFROM:
21122 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
21125 case GOMP_MAP_ALWAYS_TOFROM:
21126 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
21129 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21130 case GOMP_MAP_ALWAYS_POINTER:
21131 case GOMP_MAP_ATTACH_DETACH:
21135 error_at (OMP_CLAUSE_LOCATION (*pc),
21136 "%<#pragma omp target enter data%> with map-type other "
21137 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
21138 *pc = OMP_CLAUSE_CHAIN (*pc);
21141 pc = &OMP_CLAUSE_CHAIN (*pc);
21148 "%<#pragma omp target enter data%> must contain at least "
21149 "one %<map%> clause");
21153 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
21154 TREE_TYPE (stmt) = void_type_node;
21155 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
21156 SET_EXPR_LOCATION (stmt, loc);
21162 # pragma omp target exit data target-data-clause[optseq] new-line */
21164 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
21165 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21166 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21167 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21168 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21169 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21172 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
21173 enum pragma_context context)
21175 bool data_seen = false;
21176 if (c_parser_next_token_is (parser, CPP_NAME))
21178 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21179 if (strcmp (p, "data") == 0)
21181 c_parser_consume_token (parser);
21187 c_parser_error (parser, "expected %<data%>");
21188 c_parser_skip_to_pragma_eol (parser);
21192 if (context == pragma_stmt)
21194 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21195 "omp target exit data");
21196 c_parser_skip_to_pragma_eol (parser, false);
21202 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21205 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
21206 "#pragma omp target exit data");
21207 c_omp_adjust_map_clauses (clauses, false);
21209 for (tree *pc = &clauses; *pc;)
21211 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21212 switch (OMP_CLAUSE_MAP_KIND (*pc))
21214 case GOMP_MAP_FROM:
21215 case GOMP_MAP_ALWAYS_FROM:
21216 case GOMP_MAP_RELEASE:
21217 case GOMP_MAP_DELETE:
21220 case GOMP_MAP_TOFROM:
21221 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
21224 case GOMP_MAP_ALWAYS_TOFROM:
21225 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
21228 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21229 case GOMP_MAP_ALWAYS_POINTER:
21230 case GOMP_MAP_ATTACH_DETACH:
21234 error_at (OMP_CLAUSE_LOCATION (*pc),
21235 "%<#pragma omp target exit data%> with map-type other "
21236 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
21237 "on %<map%> clause");
21238 *pc = OMP_CLAUSE_CHAIN (*pc);
21241 pc = &OMP_CLAUSE_CHAIN (*pc);
21248 "%<#pragma omp target exit data%> must contain at least one "
21253 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
21254 TREE_TYPE (stmt) = void_type_node;
21255 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
21256 SET_EXPR_LOCATION (stmt, loc);
21262 # pragma omp target target-clause[optseq] new-line
21263 structured-block */
21265 #define OMP_TARGET_CLAUSE_MASK \
21266 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21267 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21268 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21269 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21270 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
21271 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21272 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21273 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21274 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
21275 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
21276 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21277 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
21278 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
21281 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
21283 location_t loc = c_parser_peek_token (parser)->location;
21284 c_parser_consume_pragma (parser);
21285 tree *pc = NULL, stmt, block;
21287 if (context != pragma_stmt && context != pragma_compound)
21289 c_parser_error (parser, "expected declaration specifiers");
21290 c_parser_skip_to_pragma_eol (parser);
21296 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21298 if (c_parser_next_token_is (parser, CPP_NAME))
21300 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21301 enum tree_code ccode = ERROR_MARK;
21303 if (strcmp (p, "teams") == 0)
21305 else if (strcmp (p, "parallel") == 0)
21306 ccode = OMP_PARALLEL;
21307 else if (strcmp (p, "simd") == 0)
21309 if (ccode != ERROR_MARK)
21311 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
21312 char p_name[sizeof ("#pragma omp target teams distribute "
21313 "parallel for simd")];
21315 c_parser_consume_token (parser);
21316 strcpy (p_name, "#pragma omp target");
21317 if (!flag_openmp) /* flag_openmp_simd */
21323 stmt = c_parser_omp_teams (loc, parser, p_name,
21324 OMP_TARGET_CLAUSE_MASK,
21328 stmt = c_parser_omp_parallel (loc, parser, p_name,
21329 OMP_TARGET_CLAUSE_MASK,
21333 stmt = c_parser_omp_simd (loc, parser, p_name,
21334 OMP_TARGET_CLAUSE_MASK,
21338 gcc_unreachable ();
21340 return stmt != NULL_TREE;
21342 keep_next_level ();
21343 tree block = c_begin_compound_stmt (true), ret;
21347 ret = c_parser_omp_teams (loc, parser, p_name,
21348 OMP_TARGET_CLAUSE_MASK, cclauses,
21352 ret = c_parser_omp_parallel (loc, parser, p_name,
21353 OMP_TARGET_CLAUSE_MASK, cclauses,
21357 ret = c_parser_omp_simd (loc, parser, p_name,
21358 OMP_TARGET_CLAUSE_MASK, cclauses,
21362 gcc_unreachable ();
21364 block = c_end_compound_stmt (loc, block, true);
21365 if (ret == NULL_TREE)
21367 if (ccode == OMP_TEAMS)
21368 /* For combined target teams, ensure the num_teams and
21369 thread_limit clause expressions are evaluated on the host,
21370 before entering the target construct. */
21371 for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21372 c; c = OMP_CLAUSE_CHAIN (c))
21373 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
21374 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
21376 i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
21377 if (OMP_CLAUSE_OPERAND (c, i)
21378 && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
21380 tree expr = OMP_CLAUSE_OPERAND (c, i);
21381 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
21382 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
21383 expr, NULL_TREE, NULL_TREE);
21385 OMP_CLAUSE_OPERAND (c, i) = expr;
21386 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
21387 OMP_CLAUSE_FIRSTPRIVATE);
21388 OMP_CLAUSE_DECL (tc) = tmp;
21389 OMP_CLAUSE_CHAIN (tc)
21390 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21391 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
21393 tree stmt = make_node (OMP_TARGET);
21394 TREE_TYPE (stmt) = void_type_node;
21395 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21396 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21397 OMP_TARGET_BODY (stmt) = block;
21398 OMP_TARGET_COMBINED (stmt) = 1;
21399 SET_EXPR_LOCATION (stmt, loc);
21401 pc = &OMP_TARGET_CLAUSES (stmt);
21402 goto check_clauses;
21404 else if (!flag_openmp) /* flag_openmp_simd */
21406 c_parser_skip_to_pragma_eol (parser, false);
21409 else if (strcmp (p, "data") == 0)
21411 c_parser_consume_token (parser);
21412 c_parser_omp_target_data (loc, parser, if_p);
21415 else if (strcmp (p, "enter") == 0)
21417 c_parser_consume_token (parser);
21418 return c_parser_omp_target_enter_data (loc, parser, context);
21420 else if (strcmp (p, "exit") == 0)
21422 c_parser_consume_token (parser);
21423 return c_parser_omp_target_exit_data (loc, parser, context);
21425 else if (strcmp (p, "update") == 0)
21427 c_parser_consume_token (parser);
21428 return c_parser_omp_target_update (loc, parser, context);
21431 if (!flag_openmp) /* flag_openmp_simd */
21433 c_parser_skip_to_pragma_eol (parser, false);
21437 stmt = make_node (OMP_TARGET);
21438 TREE_TYPE (stmt) = void_type_node;
21440 OMP_TARGET_CLAUSES (stmt)
21441 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
21442 "#pragma omp target", false);
21443 for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
21444 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
21446 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
21447 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
21448 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
21449 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
21450 OMP_CLAUSE_CHAIN (c) = nc;
21452 OMP_TARGET_CLAUSES (stmt)
21453 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
21454 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21456 pc = &OMP_TARGET_CLAUSES (stmt);
21457 keep_next_level ();
21458 block = c_begin_compound_stmt (true);
21459 add_stmt (c_parser_omp_structured_block (parser, if_p));
21460 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21462 SET_EXPR_LOCATION (stmt, loc);
21468 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21469 switch (OMP_CLAUSE_MAP_KIND (*pc))
21472 case GOMP_MAP_ALWAYS_TO:
21473 case GOMP_MAP_FROM:
21474 case GOMP_MAP_ALWAYS_FROM:
21475 case GOMP_MAP_TOFROM:
21476 case GOMP_MAP_ALWAYS_TOFROM:
21477 case GOMP_MAP_ALLOC:
21478 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21479 case GOMP_MAP_ALWAYS_POINTER:
21480 case GOMP_MAP_ATTACH_DETACH:
21483 error_at (OMP_CLAUSE_LOCATION (*pc),
21484 "%<#pragma omp target%> with map-type other "
21485 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21486 "on %<map%> clause");
21487 *pc = OMP_CLAUSE_CHAIN (*pc);
21490 pc = &OMP_CLAUSE_CHAIN (*pc);
21492 cfun->has_omp_target = true;
21497 # pragma omp declare simd declare-simd-clauses[optseq] new-line
21500 # pragma omp declare variant (identifier) match(context-selector) new-line
21503 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
21504 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
21505 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
21506 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
21507 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
21508 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
21509 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
21512 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
21514 c_token *token = c_parser_peek_token (parser);
21515 gcc_assert (token->type == CPP_NAME);
21516 tree kind = token->value;
21517 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
21518 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
21520 auto_vec<c_token> clauses;
21521 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21523 c_token *token = c_parser_peek_token (parser);
21524 if (token->type == CPP_EOF)
21526 c_parser_skip_to_pragma_eol (parser);
21529 clauses.safe_push (*token);
21530 c_parser_consume_token (parser);
21532 clauses.safe_push (*c_parser_peek_token (parser));
21533 c_parser_skip_to_pragma_eol (parser);
21535 while (c_parser_next_token_is (parser, CPP_PRAGMA))
21537 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
21538 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
21539 || c_parser_peek_2nd_token (parser)->value != kind)
21541 error ("%<#pragma omp declare %s%> must be followed by "
21542 "function declaration or definition or another "
21543 "%<#pragma omp declare %s%>",
21544 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
21547 c_parser_consume_pragma (parser);
21548 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21550 c_token *token = c_parser_peek_token (parser);
21551 if (token->type == CPP_EOF)
21553 c_parser_skip_to_pragma_eol (parser);
21556 clauses.safe_push (*token);
21557 c_parser_consume_token (parser);
21559 clauses.safe_push (*c_parser_peek_token (parser));
21560 c_parser_skip_to_pragma_eol (parser);
21563 /* Make sure nothing tries to read past the end of the tokens. */
21565 memset (&eof_token, 0, sizeof (eof_token));
21566 eof_token.type = CPP_EOF;
21567 clauses.safe_push (eof_token);
21568 clauses.safe_push (eof_token);
21572 case pragma_external:
21573 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21574 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21576 int ext = disable_extension_diagnostics ();
21578 c_parser_consume_token (parser);
21579 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21580 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21581 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21583 restore_extension_diagnostics (ext);
21586 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21589 case pragma_struct:
21592 error ("%<#pragma omp declare %s%> must be followed by "
21593 "function declaration or definition",
21594 IDENTIFIER_POINTER (kind));
21596 case pragma_compound:
21597 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21598 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21600 int ext = disable_extension_diagnostics ();
21602 c_parser_consume_token (parser);
21603 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21604 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21605 if (c_parser_next_tokens_start_declaration (parser))
21607 c_parser_declaration_or_fndef (parser, true, true, true, true,
21608 true, NULL, &clauses);
21609 restore_extension_diagnostics (ext);
21612 restore_extension_diagnostics (ext);
21614 else if (c_parser_next_tokens_start_declaration (parser))
21616 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
21620 error ("%<#pragma omp declare %s%> must be followed by "
21621 "function declaration or definition",
21622 IDENTIFIER_POINTER (kind));
21625 gcc_unreachable ();
21629 static const char *const omp_construct_selectors[] = {
21630 "simd", "target", "teams", "parallel", "for", NULL };
21631 static const char *const omp_device_selectors[] = {
21632 "kind", "isa", "arch", NULL };
21633 static const char *const omp_implementation_selectors[] = {
21634 "vendor", "extension", "atomic_default_mem_order", "unified_address",
21635 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
21636 static const char *const omp_user_selectors[] = {
21637 "condition", NULL };
21642 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
21645 score(score-expression) */
21648 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
21650 tree ret = NULL_TREE;
21654 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21655 || c_parser_next_token_is (parser, CPP_NAME))
21656 selector = c_parser_peek_token (parser)->value;
21659 c_parser_error (parser, "expected trait selector name");
21660 return error_mark_node;
21663 tree properties = NULL_TREE;
21664 const char *const *selectors = NULL;
21665 bool allow_score = true;
21666 bool allow_user = false;
21667 int property_limit = 0;
21668 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
21669 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
21670 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
21671 switch (IDENTIFIER_POINTER (set)[0])
21673 case 'c': /* construct */
21674 selectors = omp_construct_selectors;
21675 allow_score = false;
21676 property_limit = 1;
21677 property_kind = CTX_PROPERTY_SIMD;
21679 case 'd': /* device */
21680 selectors = omp_device_selectors;
21681 allow_score = false;
21683 property_limit = 3;
21684 property_kind = CTX_PROPERTY_NAME_LIST;
21686 case 'i': /* implementation */
21687 selectors = omp_implementation_selectors;
21689 property_limit = 3;
21690 property_kind = CTX_PROPERTY_NAME_LIST;
21692 case 'u': /* user */
21693 selectors = omp_user_selectors;
21694 property_limit = 1;
21695 property_kind = CTX_PROPERTY_EXPR;
21698 gcc_unreachable ();
21700 for (int i = 0; ; i++)
21702 if (selectors[i] == NULL)
21706 property_kind = CTX_PROPERTY_USER;
21711 error_at (c_parser_peek_token (parser)->location,
21712 "selector %qs not allowed for context selector "
21713 "set %qs", IDENTIFIER_POINTER (selector),
21714 IDENTIFIER_POINTER (set));
21715 c_parser_consume_token (parser);
21716 return error_mark_node;
21719 if (i == property_limit)
21720 property_kind = CTX_PROPERTY_NONE;
21721 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
21724 if (property_kind == CTX_PROPERTY_NAME_LIST
21725 && IDENTIFIER_POINTER (set)[0] == 'i'
21726 && strcmp (IDENTIFIER_POINTER (selector),
21727 "atomic_default_mem_order") == 0)
21728 property_kind = CTX_PROPERTY_ID;
21730 c_parser_consume_token (parser);
21732 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21734 if (property_kind == CTX_PROPERTY_NONE)
21736 error_at (c_parser_peek_token (parser)->location,
21737 "selector %qs does not accept any properties",
21738 IDENTIFIER_POINTER (selector));
21739 return error_mark_node;
21742 matching_parens parens;
21743 parens.require_open (parser);
21745 c_token *token = c_parser_peek_token (parser);
21747 && c_parser_next_token_is (parser, CPP_NAME)
21748 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
21749 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
21751 c_parser_consume_token (parser);
21753 matching_parens parens2;
21754 parens2.require_open (parser);
21755 tree score = c_parser_expr_no_commas (parser, NULL).value;
21756 parens2.skip_until_found_close (parser);
21757 c_parser_require (parser, CPP_COLON, "expected %<:%>");
21758 if (score != error_mark_node)
21760 mark_exp_read (score);
21761 score = c_fully_fold (score, false, NULL);
21762 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
21763 || TREE_CODE (score) != INTEGER_CST)
21764 error_at (token->location, "score argument must be "
21765 "constant integer expression");
21766 else if (tree_int_cst_sgn (score) < 0)
21767 error_at (token->location, "score argument must be "
21770 properties = tree_cons (get_identifier (" score"),
21771 score, properties);
21773 token = c_parser_peek_token (parser);
21776 switch (property_kind)
21779 case CTX_PROPERTY_USER:
21782 t = c_parser_expr_no_commas (parser, NULL).value;
21783 if (TREE_CODE (t) == STRING_CST)
21784 properties = tree_cons (NULL_TREE, t, properties);
21785 else if (t != error_mark_node)
21788 t = c_fully_fold (t, false, NULL);
21789 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21790 || !tree_fits_shwi_p (t))
21791 error_at (token->location, "property must be "
21792 "constant integer expression or string "
21795 properties = tree_cons (NULL_TREE, t, properties);
21798 return error_mark_node;
21800 if (c_parser_next_token_is (parser, CPP_COMMA))
21801 c_parser_consume_token (parser);
21807 case CTX_PROPERTY_ID:
21808 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21809 || c_parser_next_token_is (parser, CPP_NAME))
21811 tree prop = c_parser_peek_token (parser)->value;
21812 c_parser_consume_token (parser);
21813 properties = tree_cons (prop, NULL_TREE, properties);
21817 c_parser_error (parser, "expected identifier");
21818 return error_mark_node;
21821 case CTX_PROPERTY_NAME_LIST:
21824 tree prop = NULL_TREE, value = NULL_TREE;
21825 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21826 || c_parser_next_token_is (parser, CPP_NAME))
21828 prop = c_parser_peek_token (parser)->value;
21829 c_parser_consume_token (parser);
21831 else if (c_parser_next_token_is (parser, CPP_STRING))
21832 value = c_parser_string_literal (parser, false,
21836 c_parser_error (parser, "expected identifier or "
21838 return error_mark_node;
21841 properties = tree_cons (prop, value, properties);
21843 if (c_parser_next_token_is (parser, CPP_COMMA))
21844 c_parser_consume_token (parser);
21850 case CTX_PROPERTY_EXPR:
21851 t = c_parser_expr_no_commas (parser, NULL).value;
21852 if (t != error_mark_node)
21855 t = c_fully_fold (t, false, NULL);
21856 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21857 || !tree_fits_shwi_p (t))
21858 error_at (token->location, "property must be "
21859 "constant integer expression");
21861 properties = tree_cons (NULL_TREE, t, properties);
21864 return error_mark_node;
21866 case CTX_PROPERTY_SIMD:
21867 if (parms == NULL_TREE)
21869 error_at (token->location, "properties for %<simd%> "
21870 "selector may not be specified in "
21871 "%<metadirective%>");
21872 return error_mark_node;
21875 c = c_parser_omp_all_clauses (parser,
21876 OMP_DECLARE_SIMD_CLAUSE_MASK,
21878 c = c_omp_declare_simd_clauses_to_numbers (parms
21880 ? NULL_TREE : parms,
21885 gcc_unreachable ();
21888 parens.skip_until_found_close (parser);
21889 properties = nreverse (properties);
21891 else if (property_kind == CTX_PROPERTY_NAME_LIST
21892 || property_kind == CTX_PROPERTY_ID
21893 || property_kind == CTX_PROPERTY_EXPR)
21895 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
21896 return error_mark_node;
21899 ret = tree_cons (selector, properties, ret);
21901 if (c_parser_next_token_is (parser, CPP_COMMA))
21902 c_parser_consume_token (parser);
21908 return nreverse (ret);
21913 trait-set-selector[,trait-set-selector[,...]]
21915 trait-set-selector:
21916 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
21918 trait-set-selector-name:
21925 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
21927 tree ret = NULL_TREE;
21930 const char *setp = "";
21931 if (c_parser_next_token_is (parser, CPP_NAME))
21932 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21936 if (strcmp (setp, "construct") == 0)
21940 if (strcmp (setp, "device") == 0)
21944 if (strcmp (setp, "implementation") == 0)
21948 if (strcmp (setp, "user") == 0)
21956 c_parser_error (parser, "expected %<construct%>, %<device%>, "
21957 "%<implementation%> or %<user%>");
21958 return error_mark_node;
21961 tree set = c_parser_peek_token (parser)->value;
21962 c_parser_consume_token (parser);
21964 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21965 return error_mark_node;
21967 matching_braces braces;
21968 if (!braces.require_open (parser))
21969 return error_mark_node;
21971 tree selectors = c_parser_omp_context_selector (parser, set, parms);
21972 if (selectors == error_mark_node)
21973 ret = error_mark_node;
21974 else if (ret != error_mark_node)
21975 ret = tree_cons (set, selectors, ret);
21977 braces.skip_until_found_close (parser);
21979 if (c_parser_next_token_is (parser, CPP_COMMA))
21980 c_parser_consume_token (parser);
21986 if (ret == error_mark_node)
21988 return nreverse (ret);
21991 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
21992 that into "omp declare variant base" attribute. */
21995 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
21997 matching_parens parens;
21998 if (!parens.require_open (parser))
22001 c_parser_skip_to_pragma_eol (parser, false);
22005 if (c_parser_next_token_is_not (parser, CPP_NAME)
22006 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
22008 c_parser_error (parser, "expected identifier");
22012 c_token *token = c_parser_peek_token (parser);
22013 tree variant = lookup_name (token->value);
22015 if (variant == NULL_TREE)
22017 undeclared_variable (token->location, token->value);
22018 variant = error_mark_node;
22021 c_parser_consume_token (parser);
22023 parens.require_close (parser);
22025 const char *clause = "";
22026 location_t match_loc = c_parser_peek_token (parser)->location;
22027 if (c_parser_next_token_is (parser, CPP_NAME))
22028 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22029 if (strcmp (clause, "match"))
22031 c_parser_error (parser, "expected %<match%>");
22035 c_parser_consume_token (parser);
22037 if (!parens.require_open (parser))
22040 if (parms == NULL_TREE)
22041 parms = error_mark_node;
22043 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
22044 if (ctx == error_mark_node)
22046 ctx = omp_check_context_selector (match_loc, ctx);
22047 if (ctx != error_mark_node && variant != error_mark_node)
22049 if (TREE_CODE (variant) != FUNCTION_DECL)
22051 error_at (token->location, "variant %qD is not a function", variant);
22052 variant = error_mark_node;
22054 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
22055 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
22057 error_at (token->location, "variant %qD and base %qD have "
22058 "incompatible types", variant, fndecl);
22059 variant = error_mark_node;
22061 else if (fndecl_built_in_p (variant)
22062 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22063 "__builtin_", strlen ("__builtin_")) == 0
22064 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22065 "__sync_", strlen ("__sync_")) == 0
22066 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22067 "__atomic_", strlen ("__atomic_")) == 0))
22069 error_at (token->location, "variant %qD is a built-in", variant);
22070 variant = error_mark_node;
22072 if (variant != error_mark_node)
22074 C_DECL_USED (variant) = 1;
22075 tree construct = omp_get_context_selector (ctx, "construct", NULL);
22076 omp_mark_declare_variant (match_loc, variant, construct);
22077 if (omp_context_selector_matches (ctx))
22080 = tree_cons (get_identifier ("omp declare variant base"),
22081 build_tree_list (variant, ctx),
22082 DECL_ATTRIBUTES (fndecl));
22083 DECL_ATTRIBUTES (fndecl) = attr;
22088 parens.require_close (parser);
22089 c_parser_skip_to_pragma_eol (parser);
22092 /* Finalize #pragma omp declare simd or #pragma omp declare variant
22093 clauses after FNDECL has been parsed, and put that into "omp declare simd"
22094 or "omp declare variant base" attribute. */
22097 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
22098 vec<c_token> *pclauses)
22100 vec<c_token> &clauses = *pclauses;
22102 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
22103 indicates error has been reported and CPP_PRAGMA that
22104 c_finish_omp_declare_simd has already processed the tokens. */
22105 if (clauses.exists () && clauses[0].type == CPP_EOF)
22107 const char *kind = "simd";
22108 if (clauses.exists ()
22109 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
22110 kind = IDENTIFIER_POINTER (clauses[0].value);
22111 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
22112 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
22114 error ("%<#pragma omp declare %s%> not immediately followed by "
22115 "a function declaration or definition", kind);
22116 clauses[0].type = CPP_EOF;
22119 if (clauses.exists () && clauses[0].type != CPP_NAME)
22121 error_at (DECL_SOURCE_LOCATION (fndecl),
22122 "%<#pragma omp declare %s%> not immediately followed by "
22123 "a single function declaration or definition", kind);
22124 clauses[0].type = CPP_EOF;
22128 if (parms == NULL_TREE)
22129 parms = DECL_ARGUMENTS (fndecl);
22131 unsigned int tokens_avail = parser->tokens_avail;
22132 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22134 parser->tokens = clauses.address ();
22135 parser->tokens_avail = clauses.length ();
22137 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
22138 while (parser->tokens_avail > 3)
22140 c_token *token = c_parser_peek_token (parser);
22141 gcc_assert (token->type == CPP_NAME
22142 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
22143 c_parser_consume_token (parser);
22144 parser->in_pragma = true;
22146 if (strcmp (kind, "simd") == 0)
22149 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
22150 "#pragma omp declare simd");
22151 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
22152 if (c != NULL_TREE)
22153 c = tree_cons (NULL_TREE, c, NULL_TREE);
22154 c = build_tree_list (get_identifier ("omp declare simd"), c);
22155 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
22156 DECL_ATTRIBUTES (fndecl) = c;
22160 gcc_assert (strcmp (kind, "variant") == 0);
22161 c_finish_omp_declare_variant (parser, fndecl, parms);
22165 parser->tokens = &parser->tokens_buf[0];
22166 parser->tokens_avail = tokens_avail;
22167 if (clauses.exists ())
22168 clauses[0].type = CPP_PRAGMA;
22173 # pragma omp declare target new-line
22174 declarations and definitions
22175 # pragma omp end declare target new-line
22178 # pragma omp declare target ( extended-list ) new-line
22180 # pragma omp declare target declare-target-clauses[seq] new-line */
22182 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
22183 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
22184 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
22185 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
22186 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
22189 c_parser_omp_declare_target (c_parser *parser)
22191 tree clauses = NULL_TREE;
22192 int device_type = 0;
22193 bool only_device_type = true;
22194 if (c_parser_next_token_is (parser, CPP_NAME))
22195 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
22196 "#pragma omp declare target");
22197 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
22199 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
22201 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
22202 c_parser_skip_to_pragma_eol (parser);
22206 c_parser_skip_to_pragma_eol (parser);
22207 current_omp_declare_target_attribute++;
22210 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22211 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22212 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
22213 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22215 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22217 tree t = OMP_CLAUSE_DECL (c), id;
22218 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
22219 tree at2 = lookup_attribute ("omp declare target link",
22220 DECL_ATTRIBUTES (t));
22221 only_device_type = false;
22222 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
22224 id = get_identifier ("omp declare target link");
22225 std::swap (at1, at2);
22228 id = get_identifier ("omp declare target");
22231 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
22232 error_at (OMP_CLAUSE_LOCATION (c),
22233 "%qD specified both in declare target %<link%> and %qs"
22234 " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
22236 error_at (OMP_CLAUSE_LOCATION (c),
22237 "%qD specified both in declare target %<link%> and "
22238 "%<to%> or %<enter%> clauses", t);
22243 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22244 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
22247 symtab_node *node = symtab_node::get (t);
22250 node->offloadable = 1;
22251 if (ENABLE_OFFLOADING)
22253 g->have_offload = true;
22254 if (is_a <varpool_node *> (node))
22255 vec_safe_push (offload_vars, t);
22259 if (TREE_CODE (t) != FUNCTION_DECL)
22261 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
22263 tree at3 = lookup_attribute ("omp declare target host",
22264 DECL_ATTRIBUTES (t));
22265 if (at3 == NULL_TREE)
22267 id = get_identifier ("omp declare target host");
22268 DECL_ATTRIBUTES (t)
22269 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22272 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
22274 tree at3 = lookup_attribute ("omp declare target nohost",
22275 DECL_ATTRIBUTES (t));
22276 if (at3 == NULL_TREE)
22278 id = get_identifier ("omp declare target nohost");
22279 DECL_ATTRIBUTES (t)
22280 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22284 if (device_type && only_device_type)
22285 warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
22286 "directive with only %<device_type%> clauses ignored");
22290 c_parser_omp_end_declare_target (c_parser *parser)
22292 location_t loc = c_parser_peek_token (parser)->location;
22293 c_parser_consume_pragma (parser);
22294 if (c_parser_next_token_is (parser, CPP_NAME)
22295 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22298 c_parser_consume_token (parser);
22299 if (c_parser_next_token_is (parser, CPP_NAME)
22300 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22302 c_parser_consume_token (parser);
22305 c_parser_error (parser, "expected %<target%>");
22306 c_parser_skip_to_pragma_eol (parser);
22312 c_parser_error (parser, "expected %<declare%>");
22313 c_parser_skip_to_pragma_eol (parser);
22316 c_parser_skip_to_pragma_eol (parser);
22317 if (!current_omp_declare_target_attribute)
22318 error_at (loc, "%<#pragma omp end declare target%> without corresponding "
22319 "%<#pragma omp declare target%>");
22321 current_omp_declare_target_attribute--;
22326 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22327 initializer-clause[opt] new-line
22329 initializer-clause:
22330 initializer (omp_priv = initializer)
22331 initializer (function-name (argument-list)) */
22334 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
22336 unsigned int tokens_avail = 0, i;
22337 vec<tree> types = vNULL;
22338 vec<c_token> clauses = vNULL;
22339 enum tree_code reduc_code = ERROR_MARK;
22340 tree reduc_id = NULL_TREE;
22342 location_t rloc = c_parser_peek_token (parser)->location;
22344 if (context == pragma_struct || context == pragma_param)
22346 error ("%<#pragma omp declare reduction%> not at file or block scope");
22350 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22353 switch (c_parser_peek_token (parser)->type)
22356 reduc_code = PLUS_EXPR;
22359 reduc_code = MULT_EXPR;
22362 reduc_code = MINUS_EXPR;
22365 reduc_code = BIT_AND_EXPR;
22368 reduc_code = BIT_XOR_EXPR;
22371 reduc_code = BIT_IOR_EXPR;
22374 reduc_code = TRUTH_ANDIF_EXPR;
22377 reduc_code = TRUTH_ORIF_EXPR;
22381 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22382 if (strcmp (p, "min") == 0)
22384 reduc_code = MIN_EXPR;
22387 if (strcmp (p, "max") == 0)
22389 reduc_code = MAX_EXPR;
22392 reduc_id = c_parser_peek_token (parser)->value;
22395 c_parser_error (parser,
22396 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
22397 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
22401 tree orig_reduc_id, reduc_decl;
22402 orig_reduc_id = reduc_id;
22403 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
22404 reduc_decl = c_omp_reduction_decl (reduc_id);
22405 c_parser_consume_token (parser);
22407 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
22412 location_t loc = c_parser_peek_token (parser)->location;
22413 struct c_type_name *ctype = c_parser_type_name (parser);
22416 type = groktypename (ctype, NULL, NULL);
22417 if (type == error_mark_node)
22419 else if ((INTEGRAL_TYPE_P (type)
22420 || TREE_CODE (type) == REAL_TYPE
22421 || TREE_CODE (type) == COMPLEX_TYPE)
22422 && orig_reduc_id == NULL_TREE)
22423 error_at (loc, "predeclared arithmetic type in "
22424 "%<#pragma omp declare reduction%>");
22425 else if (TREE_CODE (type) == FUNCTION_TYPE
22426 || TREE_CODE (type) == ARRAY_TYPE)
22427 error_at (loc, "function or array type in "
22428 "%<#pragma omp declare reduction%>");
22429 else if (TYPE_ATOMIC (type))
22430 error_at (loc, "%<_Atomic%> qualified type in "
22431 "%<#pragma omp declare reduction%>");
22432 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
22433 error_at (loc, "const, volatile or restrict qualified type in "
22434 "%<#pragma omp declare reduction%>");
22438 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
22439 if (comptypes (TREE_PURPOSE (t), type))
22441 error_at (loc, "redeclaration of %qs "
22442 "%<#pragma omp declare reduction%> for "
22444 IDENTIFIER_POINTER (reduc_id)
22445 + sizeof ("omp declare reduction ") - 1,
22448 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
22450 error_at (ploc, "previous %<#pragma omp declare "
22454 if (t == NULL_TREE)
22455 types.safe_push (type);
22457 if (c_parser_next_token_is (parser, CPP_COMMA))
22458 c_parser_consume_token (parser);
22466 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
22467 || types.is_empty ())
22470 clauses.release ();
22474 c_token *token = c_parser_peek_token (parser);
22475 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
22477 c_parser_consume_token (parser);
22479 c_parser_skip_to_pragma_eol (parser);
22483 if (types.length () > 1)
22485 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22487 c_token *token = c_parser_peek_token (parser);
22488 if (token->type == CPP_EOF)
22490 clauses.safe_push (*token);
22491 c_parser_consume_token (parser);
22493 clauses.safe_push (*c_parser_peek_token (parser));
22494 c_parser_skip_to_pragma_eol (parser);
22496 /* Make sure nothing tries to read past the end of the tokens. */
22498 memset (&eof_token, 0, sizeof (eof_token));
22499 eof_token.type = CPP_EOF;
22500 clauses.safe_push (eof_token);
22501 clauses.safe_push (eof_token);
22504 int errs = errorcount;
22505 FOR_EACH_VEC_ELT (types, i, type)
22507 tokens_avail = parser->tokens_avail;
22508 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22509 if (!clauses.is_empty ())
22511 parser->tokens = clauses.address ();
22512 parser->tokens_avail = clauses.length ();
22513 parser->in_pragma = true;
22516 bool nested = current_function_decl != NULL_TREE;
22518 c_push_function_context ();
22519 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
22520 reduc_id, default_function_type);
22521 current_function_decl = fndecl;
22522 allocate_struct_function (fndecl, true);
22524 tree stmt = push_stmt_list ();
22525 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
22526 warn about these. */
22527 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
22528 get_identifier ("omp_out"), type);
22529 DECL_ARTIFICIAL (omp_out) = 1;
22530 DECL_CONTEXT (omp_out) = fndecl;
22531 pushdecl (omp_out);
22532 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
22533 get_identifier ("omp_in"), type);
22534 DECL_ARTIFICIAL (omp_in) = 1;
22535 DECL_CONTEXT (omp_in) = fndecl;
22537 struct c_expr combiner = c_parser_expression (parser);
22538 struct c_expr initializer;
22539 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
22541 initializer.set_error ();
22542 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22544 else if (c_parser_next_token_is (parser, CPP_NAME)
22545 && strcmp (IDENTIFIER_POINTER
22546 (c_parser_peek_token (parser)->value),
22547 "initializer") == 0)
22549 c_parser_consume_token (parser);
22552 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
22553 get_identifier ("omp_priv"), type);
22554 DECL_ARTIFICIAL (omp_priv) = 1;
22555 DECL_INITIAL (omp_priv) = error_mark_node;
22556 DECL_CONTEXT (omp_priv) = fndecl;
22557 pushdecl (omp_priv);
22558 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
22559 get_identifier ("omp_orig"), type);
22560 DECL_ARTIFICIAL (omp_orig) = 1;
22561 DECL_CONTEXT (omp_orig) = fndecl;
22562 pushdecl (omp_orig);
22563 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22565 else if (!c_parser_next_token_is (parser, CPP_NAME))
22567 c_parser_error (parser, "expected %<omp_priv%> or "
22571 else if (strcmp (IDENTIFIER_POINTER
22572 (c_parser_peek_token (parser)->value),
22575 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
22576 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
22578 c_parser_error (parser, "expected function-name %<(%>");
22582 initializer = c_parser_postfix_expression (parser);
22583 if (initializer.value
22584 && TREE_CODE (initializer.value) == CALL_EXPR)
22587 tree c = initializer.value;
22588 for (j = 0; j < call_expr_nargs (c); j++)
22590 tree a = CALL_EXPR_ARG (c, j);
22592 if (TREE_CODE (a) == ADDR_EXPR
22593 && TREE_OPERAND (a, 0) == omp_priv)
22596 if (j == call_expr_nargs (c))
22597 error ("one of the initializer call arguments should be "
22603 c_parser_consume_token (parser);
22604 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
22608 tree st = push_stmt_list ();
22609 location_t loc = c_parser_peek_token (parser)->location;
22610 rich_location richloc (line_table, loc);
22611 start_init (omp_priv, NULL_TREE, 0, &richloc);
22612 struct c_expr init = c_parser_initializer (parser, omp_priv);
22614 finish_decl (omp_priv, loc, init.value,
22615 init.original_type, NULL_TREE);
22616 pop_stmt_list (st);
22620 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22626 c_parser_skip_to_pragma_eol (parser);
22628 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
22629 DECL_INITIAL (reduc_decl));
22630 DECL_INITIAL (reduc_decl) = t;
22631 DECL_SOURCE_LOCATION (omp_out) = rloc;
22632 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
22633 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
22634 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
22635 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
22636 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
22639 DECL_SOURCE_LOCATION (omp_priv) = rloc;
22640 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
22641 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
22642 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
22643 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
22644 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22645 walk_tree (&DECL_INITIAL (omp_priv),
22646 c_check_omp_declare_reduction_r,
22647 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22651 pop_stmt_list (stmt);
22653 if (cfun->language != NULL)
22655 ggc_free (cfun->language);
22656 cfun->language = NULL;
22659 current_function_decl = NULL_TREE;
22661 c_pop_function_context ();
22663 if (!clauses.is_empty ())
22665 parser->tokens = &parser->tokens_buf[0];
22666 parser->tokens_avail = tokens_avail;
22670 if (errs != errorcount)
22674 clauses.release ();
22680 #pragma omp declare simd declare-simd-clauses[optseq] new-line
22681 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22682 initializer-clause[opt] new-line
22683 #pragma omp declare target new-line
22686 #pragma omp declare variant (identifier) match (context-selector) */
22689 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
22691 c_parser_consume_pragma (parser);
22692 if (c_parser_next_token_is (parser, CPP_NAME))
22694 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22695 if (strcmp (p, "simd") == 0)
22697 /* c_parser_consume_token (parser); done in
22698 c_parser_omp_declare_simd. */
22699 c_parser_omp_declare_simd (parser, context);
22702 if (strcmp (p, "reduction") == 0)
22704 c_parser_consume_token (parser);
22705 c_parser_omp_declare_reduction (parser, context);
22708 if (!flag_openmp) /* flag_openmp_simd */
22710 c_parser_skip_to_pragma_eol (parser, false);
22713 if (strcmp (p, "target") == 0)
22715 c_parser_consume_token (parser);
22716 c_parser_omp_declare_target (parser);
22719 if (strcmp (p, "variant") == 0)
22721 /* c_parser_consume_token (parser); done in
22722 c_parser_omp_declare_simd. */
22723 c_parser_omp_declare_simd (parser, context);
22728 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
22729 "%<target%> or %<variant%>");
22730 c_parser_skip_to_pragma_eol (parser);
22735 #pragma omp requires clauses[optseq] new-line */
22738 c_parser_omp_requires (c_parser *parser)
22741 enum omp_requires new_req = (enum omp_requires) 0;
22743 c_parser_consume_pragma (parser);
22745 location_t loc = c_parser_peek_token (parser)->location;
22746 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22749 && c_parser_next_token_is (parser, CPP_COMMA)
22750 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
22751 c_parser_consume_token (parser);
22755 if (c_parser_next_token_is (parser, CPP_NAME))
22758 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22759 location_t cloc = c_parser_peek_token (parser)->location;
22760 enum omp_requires this_req = (enum omp_requires) 0;
22762 if (!strcmp (p, "unified_address"))
22763 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
22764 else if (!strcmp (p, "unified_shared_memory"))
22765 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
22766 else if (!strcmp (p, "dynamic_allocators"))
22767 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
22768 else if (!strcmp (p, "reverse_offload"))
22769 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
22770 else if (!strcmp (p, "atomic_default_mem_order"))
22772 c_parser_consume_token (parser);
22774 matching_parens parens;
22775 if (parens.require_open (parser))
22777 if (c_parser_next_token_is (parser, CPP_NAME))
22779 tree v = c_parser_peek_token (parser)->value;
22780 p = IDENTIFIER_POINTER (v);
22782 if (!strcmp (p, "seq_cst"))
22784 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
22785 else if (!strcmp (p, "relaxed"))
22787 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
22788 else if (!strcmp (p, "acq_rel"))
22790 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
22794 error_at (c_parser_peek_token (parser)->location,
22795 "expected %<seq_cst%>, %<relaxed%> or "
22797 switch (c_parser_peek_token (parser)->type)
22800 case CPP_PRAGMA_EOL:
22801 case CPP_CLOSE_PAREN:
22804 if (c_parser_peek_2nd_token (parser)->type
22805 == CPP_CLOSE_PAREN)
22806 c_parser_consume_token (parser);
22811 c_parser_consume_token (parser);
22813 parens.skip_until_found_close (parser);
22816 c_parser_skip_to_pragma_eol (parser, false);
22824 error_at (cloc, "expected %<unified_address%>, "
22825 "%<unified_shared_memory%>, "
22826 "%<dynamic_allocators%>, "
22827 "%<reverse_offload%> "
22828 "or %<atomic_default_mem_order%> clause");
22829 c_parser_skip_to_pragma_eol (parser, false);
22833 c_parser_consume_token (parser);
22836 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22838 if ((this_req & new_req) != 0)
22839 error_at (cloc, "too many %qs clauses", p);
22840 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
22841 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
22842 error_at (cloc, "%qs clause used lexically after first "
22843 "target construct or offloading API", p);
22845 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22847 error_at (cloc, "too many %qs clauses",
22848 "atomic_default_mem_order");
22849 this_req = (enum omp_requires) 0;
22851 else if ((omp_requires_mask
22852 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22854 error_at (cloc, "more than one %<atomic_default_mem_order%>"
22855 " clause in a single compilation unit");
22857 = (enum omp_requires)
22859 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
22861 else if ((omp_requires_mask
22862 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
22863 error_at (cloc, "%<atomic_default_mem_order%> clause used "
22864 "lexically after first %<atomic%> construct "
22865 "without memory order clause");
22866 new_req = (enum omp_requires) (new_req | this_req);
22868 = (enum omp_requires) (omp_requires_mask | this_req);
22874 c_parser_skip_to_pragma_eol (parser);
22877 error_at (loc, "%<pragma omp requires%> requires at least one clause");
22880 /* Helper function for c_parser_omp_taskloop.
22881 Disallow zero sized or potentially zero sized task reductions. */
22884 c_finish_taskloop_clauses (tree clauses)
22886 tree *pc = &clauses;
22887 for (tree c = clauses; c; c = *pc)
22889 bool remove = false;
22890 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
22892 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
22893 if (integer_zerop (TYPE_SIZE_UNIT (type)))
22895 error_at (OMP_CLAUSE_LOCATION (c),
22896 "zero sized type %qT in %<reduction%> clause", type);
22899 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
22901 error_at (OMP_CLAUSE_LOCATION (c),
22902 "variable sized type %qT in %<reduction%> clause",
22908 *pc = OMP_CLAUSE_CHAIN (c);
22910 pc = &OMP_CLAUSE_CHAIN (c);
22916 #pragma omp taskloop taskloop-clause[optseq] new-line
22919 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
22922 #define OMP_TASKLOOP_CLAUSE_MASK \
22923 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
22924 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22925 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22926 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22927 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
22928 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
22929 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
22930 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22931 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
22932 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22933 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
22934 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
22935 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
22936 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
22937 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22938 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22939 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
22942 c_parser_omp_taskloop (location_t loc, c_parser *parser,
22943 char *p_name, omp_clause_mask mask, tree *cclauses,
22946 tree clauses, block, ret;
22948 strcat (p_name, " taskloop");
22949 mask |= OMP_TASKLOOP_CLAUSE_MASK;
22950 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
22952 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
22953 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
22955 if (c_parser_next_token_is (parser, CPP_NAME))
22957 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22959 if (strcmp (p, "simd") == 0)
22961 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22962 if (cclauses == NULL)
22963 cclauses = cclauses_buf;
22964 c_parser_consume_token (parser);
22965 if (!flag_openmp) /* flag_openmp_simd */
22966 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
22968 block = c_begin_compound_stmt (true);
22969 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
22970 block = c_end_compound_stmt (loc, block, true);
22973 ret = make_node (OMP_TASKLOOP);
22974 TREE_TYPE (ret) = void_type_node;
22975 OMP_FOR_BODY (ret) = block;
22976 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
22977 OMP_FOR_CLAUSES (ret)
22978 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
22979 SET_EXPR_LOCATION (ret, loc);
22984 if (!flag_openmp) /* flag_openmp_simd */
22986 c_parser_skip_to_pragma_eol (parser, false);
22990 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22993 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
22994 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
22997 clauses = c_finish_taskloop_clauses (clauses);
22998 block = c_begin_compound_stmt (true);
22999 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
23000 block = c_end_compound_stmt (loc, block, true);
23007 #pragma omp nothing new-line */
23010 c_parser_omp_nothing (c_parser *parser)
23012 c_parser_consume_pragma (parser);
23013 c_parser_skip_to_pragma_eol (parser);
23017 #pragma omp error clauses[optseq] new-line */
23020 c_parser_omp_error (c_parser *parser, enum pragma_context context)
23022 int at_compilation = -1;
23023 int severity_fatal = -1;
23024 tree message = NULL_TREE;
23027 location_t loc = c_parser_peek_token (parser)->location;
23029 c_parser_consume_pragma (parser);
23031 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
23034 && c_parser_next_token_is (parser, CPP_COMMA)
23035 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
23036 c_parser_consume_token (parser);
23040 if (!c_parser_next_token_is (parser, CPP_NAME))
23044 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23045 location_t cloc = c_parser_peek_token (parser)->location;
23046 static const char *args[] = {
23047 "execution", "compilation", "warning", "fatal"
23050 int idx = 0, n = -1;
23051 tree m = NULL_TREE;
23053 if (!strcmp (p, "at"))
23054 v = &at_compilation;
23055 else if (!strcmp (p, "severity"))
23057 v = &severity_fatal;
23060 else if (strcmp (p, "message"))
23063 "expected %<at%>, %<severity%> or %<message%> clause");
23064 c_parser_skip_to_pragma_eol (parser, false);
23068 c_parser_consume_token (parser);
23070 matching_parens parens;
23071 if (parens.require_open (parser))
23075 location_t expr_loc = c_parser_peek_token (parser)->location;
23076 c_expr expr = c_parser_expr_no_commas (parser, NULL);
23077 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
23078 m = convert (const_string_type_node, expr.value);
23079 m = c_fully_fold (m, false, NULL);
23083 if (c_parser_next_token_is (parser, CPP_NAME))
23085 tree val = c_parser_peek_token (parser)->value;
23086 const char *q = IDENTIFIER_POINTER (val);
23088 if (!strcmp (q, args[idx]))
23090 else if (!strcmp (q, args[idx + 1]))
23095 error_at (c_parser_peek_token (parser)->location,
23096 "expected %qs or %qs", args[idx], args[idx + 1]);
23098 switch (c_parser_peek_token (parser)->type)
23101 case CPP_PRAGMA_EOL:
23102 case CPP_CLOSE_PAREN:
23105 if (c_parser_peek_2nd_token (parser)->type
23106 == CPP_CLOSE_PAREN)
23107 c_parser_consume_token (parser);
23112 c_parser_consume_token (parser);
23115 parens.skip_until_found_close (parser);
23121 error_at (cloc, "too many %qs clauses", p);
23131 error_at (cloc, "too many %qs clauses", p);
23141 c_parser_skip_to_pragma_eol (parser);
23145 if (at_compilation == -1)
23146 at_compilation = 1;
23147 if (severity_fatal == -1)
23148 severity_fatal = 1;
23149 if (!at_compilation)
23151 if (context != pragma_compound)
23153 error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
23154 "may only be used in compound statements");
23158 = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
23159 : BUILT_IN_GOMP_WARNING);
23161 message = build_zero_cst (const_string_type_node);
23162 tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
23163 build_all_ones_cst (size_type_node));
23167 const char *msg = NULL;
23170 msg = c_getstr (message);
23172 msg = _("<message unknown at compile time>");
23175 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
23176 "%<pragma omp error%> encountered: %s", msg);
23178 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
23179 "%<pragma omp error%> encountered");
23183 /* Main entry point to parsing most OpenMP pragmas. */
23186 c_parser_omp_construct (c_parser *parser, bool *if_p)
23188 enum pragma_kind p_kind;
23191 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
23192 omp_clause_mask mask (0);
23194 loc = c_parser_peek_token (parser)->location;
23195 p_kind = c_parser_peek_token (parser)->pragma_kind;
23196 c_parser_consume_pragma (parser);
23200 case PRAGMA_OACC_ATOMIC:
23201 c_parser_omp_atomic (loc, parser, true);
23203 case PRAGMA_OACC_CACHE:
23204 strcpy (p_name, "#pragma acc");
23205 stmt = c_parser_oacc_cache (loc, parser);
23207 case PRAGMA_OACC_DATA:
23208 stmt = c_parser_oacc_data (loc, parser, if_p);
23210 case PRAGMA_OACC_HOST_DATA:
23211 stmt = c_parser_oacc_host_data (loc, parser, if_p);
23213 case PRAGMA_OACC_KERNELS:
23214 case PRAGMA_OACC_PARALLEL:
23215 case PRAGMA_OACC_SERIAL:
23216 strcpy (p_name, "#pragma acc");
23217 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
23219 case PRAGMA_OACC_LOOP:
23220 strcpy (p_name, "#pragma acc");
23221 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
23223 case PRAGMA_OACC_WAIT:
23224 strcpy (p_name, "#pragma wait");
23225 stmt = c_parser_oacc_wait (loc, parser, p_name);
23227 case PRAGMA_OMP_ALLOCATE:
23228 c_parser_omp_allocate (loc, parser);
23230 case PRAGMA_OMP_ATOMIC:
23231 c_parser_omp_atomic (loc, parser, false);
23233 case PRAGMA_OMP_CRITICAL:
23234 stmt = c_parser_omp_critical (loc, parser, if_p);
23236 case PRAGMA_OMP_DISTRIBUTE:
23237 strcpy (p_name, "#pragma omp");
23238 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
23240 case PRAGMA_OMP_FOR:
23241 strcpy (p_name, "#pragma omp");
23242 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
23244 case PRAGMA_OMP_LOOP:
23245 strcpy (p_name, "#pragma omp");
23246 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
23248 case PRAGMA_OMP_MASKED:
23249 strcpy (p_name, "#pragma omp");
23250 stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
23252 case PRAGMA_OMP_MASTER:
23253 strcpy (p_name, "#pragma omp");
23254 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
23256 case PRAGMA_OMP_PARALLEL:
23257 strcpy (p_name, "#pragma omp");
23258 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
23260 case PRAGMA_OMP_SCOPE:
23261 stmt = c_parser_omp_scope (loc, parser, if_p);
23263 case PRAGMA_OMP_SECTIONS:
23264 strcpy (p_name, "#pragma omp");
23265 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
23267 case PRAGMA_OMP_SIMD:
23268 strcpy (p_name, "#pragma omp");
23269 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
23271 case PRAGMA_OMP_SINGLE:
23272 stmt = c_parser_omp_single (loc, parser, if_p);
23274 case PRAGMA_OMP_TASK:
23275 stmt = c_parser_omp_task (loc, parser, if_p);
23277 case PRAGMA_OMP_TASKGROUP:
23278 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
23280 case PRAGMA_OMP_TASKLOOP:
23281 strcpy (p_name, "#pragma omp");
23282 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
23284 case PRAGMA_OMP_TEAMS:
23285 strcpy (p_name, "#pragma omp");
23286 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
23289 gcc_unreachable ();
23292 if (stmt && stmt != error_mark_node)
23293 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
23298 # pragma omp threadprivate (variable-list) */
23301 c_parser_omp_threadprivate (c_parser *parser)
23306 c_parser_consume_pragma (parser);
23307 loc = c_parser_peek_token (parser)->location;
23308 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
23310 /* Mark every variable in VARS to be assigned thread local storage. */
23311 for (t = vars; t; t = TREE_CHAIN (t))
23313 tree v = TREE_PURPOSE (t);
23315 /* FIXME diagnostics: Ideally we should keep individual
23316 locations for all the variables in the var list to make the
23317 following errors more precise. Perhaps
23318 c_parser_omp_var_list_parens() should construct a list of
23319 locations to go along with the var list. */
23321 /* If V had already been marked threadprivate, it doesn't matter
23322 whether it had been used prior to this point. */
23324 error_at (loc, "%qD is not a variable", v);
23325 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
23326 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
23327 else if (! is_global_var (v))
23328 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
23329 else if (TREE_TYPE (v) == error_mark_node)
23331 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
23332 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
23335 if (! DECL_THREAD_LOCAL_P (v))
23337 set_decl_tls_model (v, decl_default_tls_model (v));
23338 /* If rtl has been already set for this var, call
23339 make_decl_rtl once again, so that encode_section_info
23340 has a chance to look at the new decl flags. */
23341 if (DECL_RTL_SET_P (v))
23344 C_DECL_THREADPRIVATE_P (v) = 1;
23348 c_parser_skip_to_pragma_eol (parser);
23351 /* Parse a transaction attribute (GCC Extension).
23353 transaction-attribute:
23355 attribute-specifier
23359 c_parser_transaction_attributes (c_parser *parser)
23361 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
23362 return c_parser_gnu_attributes (parser);
23364 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
23366 return c_parser_std_attribute_specifier (parser, true);
23369 /* Parse a __transaction_atomic or __transaction_relaxed statement
23372 transaction-statement:
23373 __transaction_atomic transaction-attribute[opt] compound-statement
23374 __transaction_relaxed compound-statement
23376 Note that the only valid attribute is: "outer".
23380 c_parser_transaction (c_parser *parser, enum rid keyword)
23382 unsigned int old_in = parser->in_transaction;
23383 unsigned int this_in = 1, new_in;
23384 location_t loc = c_parser_peek_token (parser)->location;
23387 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23388 || keyword == RID_TRANSACTION_RELAXED)
23389 && c_parser_next_token_is_keyword (parser, keyword));
23390 c_parser_consume_token (parser);
23392 if (keyword == RID_TRANSACTION_RELAXED)
23393 this_in |= TM_STMT_ATTR_RELAXED;
23396 attrs = c_parser_transaction_attributes (parser);
23398 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
23401 /* Keep track if we're in the lexical scope of an outer transaction. */
23402 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
23404 parser->in_transaction = new_in;
23405 stmt = c_parser_compound_statement (parser);
23406 parser->in_transaction = old_in;
23409 stmt = c_finish_transaction (loc, stmt, this_in);
23411 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23412 "%<__transaction_atomic%> without transactional memory support enabled"
23413 : "%<__transaction_relaxed %> "
23414 "without transactional memory support enabled"));
23419 /* Parse a __transaction_atomic or __transaction_relaxed expression
23422 transaction-expression:
23423 __transaction_atomic ( expression )
23424 __transaction_relaxed ( expression )
23427 static struct c_expr
23428 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
23431 unsigned int old_in = parser->in_transaction;
23432 unsigned int this_in = 1;
23433 location_t loc = c_parser_peek_token (parser)->location;
23436 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23437 || keyword == RID_TRANSACTION_RELAXED)
23438 && c_parser_next_token_is_keyword (parser, keyword));
23439 c_parser_consume_token (parser);
23441 if (keyword == RID_TRANSACTION_RELAXED)
23442 this_in |= TM_STMT_ATTR_RELAXED;
23445 attrs = c_parser_transaction_attributes (parser);
23447 this_in |= parse_tm_stmt_attr (attrs, 0);
23450 parser->in_transaction = this_in;
23451 matching_parens parens;
23452 if (parens.require_open (parser))
23454 tree expr = c_parser_expression (parser).value;
23455 ret.original_type = TREE_TYPE (expr);
23456 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
23457 if (this_in & TM_STMT_ATTR_RELAXED)
23458 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
23459 SET_EXPR_LOCATION (ret.value, loc);
23460 ret.original_code = TRANSACTION_EXPR;
23461 if (!parens.require_close (parser))
23463 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
23471 ret.original_code = ERROR_MARK;
23472 ret.original_type = NULL;
23474 parser->in_transaction = old_in;
23477 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23478 "%<__transaction_atomic%> without transactional memory support enabled"
23479 : "%<__transaction_relaxed %> "
23480 "without transactional memory support enabled"));
23482 set_c_expr_source_range (&ret, loc, loc);
23487 /* Parse a __transaction_cancel statement (GCC Extension).
23489 transaction-cancel-statement:
23490 __transaction_cancel transaction-attribute[opt] ;
23492 Note that the only valid attribute is "outer".
23496 c_parser_transaction_cancel (c_parser *parser)
23498 location_t loc = c_parser_peek_token (parser)->location;
23500 bool is_outer = false;
23502 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
23503 c_parser_consume_token (parser);
23505 attrs = c_parser_transaction_attributes (parser);
23507 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
23511 error_at (loc, "%<__transaction_cancel%> without "
23512 "transactional memory support enabled");
23515 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
23517 error_at (loc, "%<__transaction_cancel%> within a "
23518 "%<__transaction_relaxed%>");
23523 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
23524 && !is_tm_may_cancel_outer (current_function_decl))
23526 error_at (loc, "outer %<__transaction_cancel%> not "
23527 "within outer %<__transaction_atomic%> or "
23528 "a %<transaction_may_cancel_outer%> function");
23532 else if (parser->in_transaction == 0)
23534 error_at (loc, "%<__transaction_cancel%> not within "
23535 "%<__transaction_atomic%>");
23539 return add_stmt (build_tm_abort_call (loc, is_outer));
23542 return build1 (NOP_EXPR, void_type_node, error_mark_node);
23545 /* Parse a single source file. */
23548 c_parse_file (void)
23550 /* Use local storage to begin. If the first token is a pragma, parse it.
23551 If it is #pragma GCC pch_preprocess, then this will load a PCH file
23552 which will cause garbage collection. */
23555 memset (&tparser, 0, sizeof tparser);
23556 tparser.translate_strings_p = true;
23557 tparser.tokens = &tparser.tokens_buf[0];
23558 the_parser = &tparser;
23560 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
23561 c_parser_pragma_pch_preprocess (&tparser);
23563 c_common_no_more_pch ();
23565 the_parser = ggc_alloc<c_parser> ();
23566 *the_parser = tparser;
23567 if (tparser.tokens == &tparser.tokens_buf[0])
23568 the_parser->tokens = &the_parser->tokens_buf[0];
23570 /* Initialize EH, if we've been told to do so. */
23571 if (flag_exceptions)
23572 using_eh_for_cleanups ();
23574 c_parser_translation_unit (the_parser);
23578 /* Parse the body of a function declaration marked with "__RTL".
23580 The RTL parser works on the level of characters read from a
23581 FILE *, whereas c_parser works at the level of tokens.
23582 Square this circle by consuming all of the tokens up to and
23583 including the closing brace, recording the start/end of the RTL
23584 fragment, and reopening the file and re-reading the relevant
23585 lines within the RTL parser.
23587 This requires the opening and closing braces of the C function
23588 to be on separate lines from the RTL they wrap.
23590 Take ownership of START_WITH_PASS, if non-NULL. */
23593 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
23595 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
23597 free (start_with_pass);
23598 return c_parser_peek_token (parser)->location;
23601 location_t start_loc = c_parser_peek_token (parser)->location;
23603 /* Consume all tokens, up to the closing brace, handling
23604 matching pairs of braces in the rtl dump. */
23605 int num_open_braces = 1;
23608 switch (c_parser_peek_token (parser)->type)
23610 case CPP_OPEN_BRACE:
23613 case CPP_CLOSE_BRACE:
23614 if (--num_open_braces == 0)
23615 goto found_closing_brace;
23618 error_at (start_loc, "no closing brace");
23619 free (start_with_pass);
23620 return c_parser_peek_token (parser)->location;
23624 c_parser_consume_token (parser);
23627 found_closing_brace:
23628 /* At the closing brace; record its location. */
23629 location_t end_loc = c_parser_peek_token (parser)->location;
23631 /* Consume the closing brace. */
23632 c_parser_consume_token (parser);
23634 /* Invoke the RTL parser. */
23635 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
23637 free (start_with_pass);
23641 /* Run the backend on the cfun created above, transferring ownership of
23642 START_WITH_PASS. */
23643 run_rtl_passes (start_with_pass);
23647 #include "gt-c-c-parser.h"