1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2020 Free Software Foundation, Inc.
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 Make sure all relevant comments, and all relevant code from all
26 actions, brought over from old parser. Verify exact correspondence
29 Add testcases covering every input symbol in every state in old and
32 Include full syntax for GNU C, including erroneous cases accepted
33 with error messages, in syntax productions in comments.
35 Make more diagnostics in the front end generally take an explicit
36 location rather than implicitly using input_location. */
39 #define INCLUDE_UNIQUE_PTR
41 #include "coretypes.h"
46 #include "stringpool.h"
49 #include "stor-layout.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
54 #include "c-family/c-objc.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
63 #include "gcc-rich-location.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
73 /* We need to walk over decls with incomplete struct/union/enum types
74 after parsing the whole translation unit.
75 In finish_decl(), if the decl is static, has incomplete
76 struct/union/enum type, it is appeneded to incomplete_record_decls.
77 In c_parser_translation_unit(), we iterate over incomplete_record_decls
78 and report error if any of the decls are still incomplete. */
80 vec
<tree
> incomplete_record_decls
;
83 set_c_expr_source_range (c_expr
*expr
,
84 location_t start
, location_t finish
)
86 expr
->src_range
.m_start
= start
;
87 expr
->src_range
.m_finish
= finish
;
89 set_source_range (expr
->value
, start
, finish
);
93 set_c_expr_source_range (c_expr
*expr
,
94 source_range src_range
)
96 expr
->src_range
= src_range
;
98 set_source_range (expr
->value
, src_range
);
102 /* Initialization routine for this file. */
107 /* The only initialization required is of the reserved word
113 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
114 the c_token structure. */
115 gcc_assert (RID_MAX
<= 255);
122 mask
|= D_ASM
| D_EXT
;
126 if (!c_dialect_objc ())
127 mask
|= D_OBJC
| D_CXX_OBJC
;
129 ridpointers
= ggc_cleared_vec_alloc
<tree
> ((int) RID_MAX
);
130 for (i
= 0; i
< num_c_common_reswords
; i
++)
132 /* If a keyword is disabled, do not enter it into the table
133 and so create a canonical spelling that isn't a keyword. */
134 if (c_common_reswords
[i
].disable
& mask
)
137 && (c_common_reswords
[i
].disable
& D_CXXWARN
))
139 id
= get_identifier (c_common_reswords
[i
].word
);
140 C_SET_RID_CODE (id
, RID_CXX_COMPAT_WARN
);
141 C_IS_RESERVED_WORD (id
) = 1;
146 id
= get_identifier (c_common_reswords
[i
].word
);
147 C_SET_RID_CODE (id
, c_common_reswords
[i
].rid
);
148 C_IS_RESERVED_WORD (id
) = 1;
149 ridpointers
[(int) c_common_reswords
[i
].rid
] = id
;
152 for (i
= 0; i
< NUM_INT_N_ENTS
; i
++)
154 /* We always create the symbols but they aren't always supported. */
156 sprintf (name
, "__int%d", int_n_data
[i
].bitsize
);
157 id
= get_identifier (name
);
158 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
159 C_IS_RESERVED_WORD (id
) = 1;
161 sprintf (name
, "__int%d__", int_n_data
[i
].bitsize
);
162 id
= get_identifier (name
);
163 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
164 C_IS_RESERVED_WORD (id
) = 1;
168 /* A parser structure recording information about the state and
169 context of parsing. Includes lexer information with up to two
170 tokens of look-ahead; more are not needed for C. */
171 struct GTY(()) c_parser
{
172 /* The look-ahead tokens. */
173 c_token
* GTY((skip
)) tokens
;
174 /* Buffer for look-ahead tokens. */
175 c_token tokens_buf
[4];
176 /* How many look-ahead tokens are available (0 - 4, or
177 more if parsing from pre-lexed tokens). */
178 unsigned int tokens_avail
;
179 /* Raw look-ahead tokens, used only for checking in Objective-C
180 whether '[[' starts attributes. */
181 vec
<c_token
, va_gc
> *raw_tokens
;
182 /* The number of raw look-ahead tokens that have since been fully
184 unsigned int raw_tokens_used
;
185 /* True if a syntax error is being recovered from; false otherwise.
186 c_parser_error sets this flag. It should clear this flag when
187 enough tokens have been consumed to recover from the error. */
188 BOOL_BITFIELD error
: 1;
189 /* True if we're processing a pragma, and shouldn't automatically
190 consume CPP_PRAGMA_EOL. */
191 BOOL_BITFIELD in_pragma
: 1;
192 /* True if we're parsing the outermost block of an if statement. */
193 BOOL_BITFIELD in_if_block
: 1;
194 /* True if we want to lex a translated, joined string (for an
195 initial #pragma pch_preprocess). Otherwise the parser is
196 responsible for concatenating strings and translating to the
197 execution character set as needed. */
198 BOOL_BITFIELD lex_joined_string
: 1;
199 /* True if, when the parser is concatenating string literals, it
200 should translate them to the execution character set (false
201 inside attributes). */
202 BOOL_BITFIELD translate_strings_p
: 1;
204 /* Objective-C specific parser/lexer information. */
206 /* True if we are in a context where the Objective-C "PQ" keywords
207 are considered keywords. */
208 BOOL_BITFIELD objc_pq_context
: 1;
209 /* True if we are parsing a (potential) Objective-C foreach
210 statement. This is set to true after we parsed 'for (' and while
211 we wait for 'in' or ';' to decide if it's a standard C for loop or an
212 Objective-C foreach loop. */
213 BOOL_BITFIELD objc_could_be_foreach_context
: 1;
214 /* The following flag is needed to contextualize Objective-C lexical
215 analysis. In some cases (e.g., 'int NSObject;'), it is
216 undesirable to bind an identifier to an Objective-C class, even
217 if a class with that name exists. */
218 BOOL_BITFIELD objc_need_raw_identifier
: 1;
219 /* Nonzero if we're processing a __transaction statement. The value
220 is 1 | TM_STMT_ATTR_*. */
221 unsigned int in_transaction
: 4;
222 /* True if we are in a context where the Objective-C "Property attribute"
223 keywords are valid. */
224 BOOL_BITFIELD objc_property_attr_context
: 1;
226 /* Location of the last consumed token. */
227 location_t last_token_location
;
230 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
233 c_parser_tokens_buf (c_parser
*parser
, unsigned n
)
235 return &parser
->tokens_buf
[n
];
238 /* Return the error state of PARSER. */
241 c_parser_error (c_parser
*parser
)
243 return parser
->error
;
246 /* Set the error state of PARSER to ERR. */
249 c_parser_set_error (c_parser
*parser
, bool err
)
255 /* The actual parser and external interface. ??? Does this need to be
256 garbage-collected? */
258 static GTY (()) c_parser
*the_parser
;
260 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
261 context-sensitive postprocessing of the token is not done. */
264 c_lex_one_token (c_parser
*parser
, c_token
*token
, bool raw
= false)
266 timevar_push (TV_LEX
);
268 if (raw
|| vec_safe_length (parser
->raw_tokens
) == 0)
270 token
->type
= c_lex_with_flags (&token
->value
, &token
->location
,
272 (parser
->lex_joined_string
273 ? 0 : C_LEX_STRING_NO_JOIN
));
274 token
->id_kind
= C_ID_NONE
;
275 token
->keyword
= RID_MAX
;
276 token
->pragma_kind
= PRAGMA_NONE
;
280 /* Use a token previously lexed as a raw look-ahead token, and
281 complete the processing on it. */
282 *token
= (*parser
->raw_tokens
)[parser
->raw_tokens_used
];
283 ++parser
->raw_tokens_used
;
284 if (parser
->raw_tokens_used
== vec_safe_length (parser
->raw_tokens
))
286 vec_free (parser
->raw_tokens
);
287 parser
->raw_tokens_used
= 0;
300 bool objc_force_identifier
= parser
->objc_need_raw_identifier
;
301 if (c_dialect_objc ())
302 parser
->objc_need_raw_identifier
= false;
304 if (C_IS_RESERVED_WORD (token
->value
))
306 enum rid rid_code
= C_RID_CODE (token
->value
);
308 if (rid_code
== RID_CXX_COMPAT_WARN
)
310 warning_at (token
->location
,
312 "identifier %qE conflicts with C++ keyword",
315 else if (rid_code
>= RID_FIRST_ADDR_SPACE
316 && rid_code
<= RID_LAST_ADDR_SPACE
)
319 as
= (addr_space_t
) (rid_code
- RID_FIRST_ADDR_SPACE
);
320 targetm
.addr_space
.diagnose_usage (as
, token
->location
);
321 token
->id_kind
= C_ID_ADDRSPACE
;
322 token
->keyword
= rid_code
;
325 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code
))
327 /* We found an Objective-C "pq" keyword (in, out,
328 inout, bycopy, byref, oneway). They need special
329 care because the interpretation depends on the
331 if (parser
->objc_pq_context
)
333 token
->type
= CPP_KEYWORD
;
334 token
->keyword
= rid_code
;
337 else if (parser
->objc_could_be_foreach_context
338 && rid_code
== RID_IN
)
340 /* We are in Objective-C, inside a (potential)
341 foreach context (which means after having
342 parsed 'for (', but before having parsed ';'),
343 and we found 'in'. We consider it the keyword
344 which terminates the declaration at the
345 beginning of a foreach-statement. Note that
346 this means you can't use 'in' for anything else
347 in that context; in particular, in Objective-C
348 you can't use 'in' as the name of the running
349 variable in a C for loop. We could potentially
350 try to add code here to disambiguate, but it
351 seems a reasonable limitation. */
352 token
->type
= CPP_KEYWORD
;
353 token
->keyword
= rid_code
;
356 /* Else, "pq" keywords outside of the "pq" context are
357 not keywords, and we fall through to the code for
360 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code
))
362 /* We found an Objective-C "property attribute"
363 keyword (getter, setter, readonly, etc). These are
364 only valid in the property context. */
365 if (parser
->objc_property_attr_context
)
367 token
->type
= CPP_KEYWORD
;
368 token
->keyword
= rid_code
;
371 /* Else they are not special keywords.
374 else if (c_dialect_objc ()
375 && (OBJC_IS_AT_KEYWORD (rid_code
)
376 || OBJC_IS_CXX_KEYWORD (rid_code
)))
378 /* We found one of the Objective-C "@" keywords (defs,
379 selector, synchronized, etc) or one of the
380 Objective-C "cxx" keywords (class, private,
381 protected, public, try, catch, throw) without a
382 preceding '@' sign. Do nothing and fall through to
383 the code for normal tokens (in C++ we would still
384 consider the CXX ones keywords, but not in C). */
389 token
->type
= CPP_KEYWORD
;
390 token
->keyword
= rid_code
;
395 decl
= lookup_name (token
->value
);
398 if (TREE_CODE (decl
) == TYPE_DECL
)
400 token
->id_kind
= C_ID_TYPENAME
;
404 else if (c_dialect_objc ())
406 tree objc_interface_decl
= objc_is_class_name (token
->value
);
407 /* Objective-C class names are in the same namespace as
408 variables and typedefs, and hence are shadowed by local
410 if (objc_interface_decl
411 && (!objc_force_identifier
|| global_bindings_p ()))
413 token
->value
= objc_interface_decl
;
414 token
->id_kind
= C_ID_CLASSNAME
;
418 token
->id_kind
= C_ID_ID
;
422 /* This only happens in Objective-C; it must be a keyword. */
423 token
->type
= CPP_KEYWORD
;
424 switch (C_RID_CODE (token
->value
))
426 /* Replace 'class' with '@class', 'private' with '@private',
427 etc. This prevents confusion with the C++ keyword
428 'class', and makes the tokens consistent with other
429 Objective-C 'AT' keywords. For example '@class' is
430 reported as RID_AT_CLASS which is consistent with
431 '@synchronized', which is reported as
434 case RID_CLASS
: token
->keyword
= RID_AT_CLASS
; break;
435 case RID_PRIVATE
: token
->keyword
= RID_AT_PRIVATE
; break;
436 case RID_PROTECTED
: token
->keyword
= RID_AT_PROTECTED
; break;
437 case RID_PUBLIC
: token
->keyword
= RID_AT_PUBLIC
; break;
438 case RID_THROW
: token
->keyword
= RID_AT_THROW
; break;
439 case RID_TRY
: token
->keyword
= RID_AT_TRY
; break;
440 case RID_CATCH
: token
->keyword
= RID_AT_CATCH
; break;
441 case RID_SYNCHRONIZED
: token
->keyword
= RID_AT_SYNCHRONIZED
; break;
442 default: token
->keyword
= C_RID_CODE (token
->value
);
447 case CPP_CLOSE_PAREN
:
449 /* These tokens may affect the interpretation of any identifiers
450 following, if doing Objective-C. */
451 if (c_dialect_objc ())
452 parser
->objc_need_raw_identifier
= false;
455 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
456 token
->pragma_kind
= (enum pragma_kind
) TREE_INT_CST_LOW (token
->value
);
463 timevar_pop (TV_LEX
);
466 /* Return a pointer to the next token from PARSER, reading it in if
470 c_parser_peek_token (c_parser
*parser
)
472 if (parser
->tokens_avail
== 0)
474 c_lex_one_token (parser
, &parser
->tokens
[0]);
475 parser
->tokens_avail
= 1;
477 return &parser
->tokens
[0];
480 /* Return a pointer to the next-but-one token from PARSER, reading it
481 in if necessary. The next token is already read in. */
484 c_parser_peek_2nd_token (c_parser
*parser
)
486 if (parser
->tokens_avail
>= 2)
487 return &parser
->tokens
[1];
488 gcc_assert (parser
->tokens_avail
== 1);
489 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
490 gcc_assert (parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
491 c_lex_one_token (parser
, &parser
->tokens
[1]);
492 parser
->tokens_avail
= 2;
493 return &parser
->tokens
[1];
496 /* Return a pointer to the Nth token from PARSER, reading it
497 in if necessary. The N-1th token is already read in. */
500 c_parser_peek_nth_token (c_parser
*parser
, unsigned int n
)
502 /* N is 1-based, not zero-based. */
505 if (parser
->tokens_avail
>= n
)
506 return &parser
->tokens
[n
- 1];
507 gcc_assert (parser
->tokens_avail
== n
- 1);
508 c_lex_one_token (parser
, &parser
->tokens
[n
- 1]);
509 parser
->tokens_avail
= n
;
510 return &parser
->tokens
[n
- 1];
513 /* Return a pointer to the Nth token from PARSER, reading it in as a
514 raw look-ahead token if necessary. The N-1th token is already read
515 in. Raw look-ahead tokens remain available for when the non-raw
516 functions above are called. */
519 c_parser_peek_nth_token_raw (c_parser
*parser
, unsigned int n
)
521 /* N is 1-based, not zero-based. */
524 if (parser
->tokens_avail
>= n
)
525 return &parser
->tokens
[n
- 1];
526 unsigned int raw_len
= vec_safe_length (parser
->raw_tokens
);
527 unsigned int raw_avail
528 = parser
->tokens_avail
+ raw_len
- parser
->raw_tokens_used
;
529 gcc_assert (raw_avail
>= n
- 1);
531 return &(*parser
->raw_tokens
)[parser
->raw_tokens_used
532 + n
- 1 - parser
->tokens_avail
];
533 vec_safe_reserve (parser
->raw_tokens
, 1);
534 parser
->raw_tokens
->quick_grow (raw_len
+ 1);
535 c_lex_one_token (parser
, &(*parser
->raw_tokens
)[raw_len
], true);
536 return &(*parser
->raw_tokens
)[raw_len
];
540 c_keyword_starts_typename (enum rid keyword
)
575 if (keyword
>= RID_FIRST_INT_N
576 && keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
577 && int_n_enabled_p
[keyword
- RID_FIRST_INT_N
])
583 /* Return true if TOKEN can start a type name,
586 c_token_starts_typename (c_token
*token
)
591 switch (token
->id_kind
)
600 gcc_assert (c_dialect_objc ());
606 return c_keyword_starts_typename (token
->keyword
);
608 if (c_dialect_objc ())
616 /* Return true if the next token from PARSER can start a type name,
617 false otherwise. LA specifies how to do lookahead in order to
618 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
621 c_parser_next_tokens_start_typename (c_parser
*parser
, enum c_lookahead_kind la
)
623 c_token
*token
= c_parser_peek_token (parser
);
624 if (c_token_starts_typename (token
))
627 /* Try a bit harder to detect an unknown typename. */
628 if (la
!= cla_prefer_id
629 && token
->type
== CPP_NAME
630 && token
->id_kind
== C_ID_ID
632 /* Do not try too hard when we could have "object in array". */
633 && !parser
->objc_could_be_foreach_context
635 && (la
== cla_prefer_type
636 || c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
637 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
639 /* Only unknown identifiers. */
640 && !lookup_name (token
->value
))
646 /* Return true if TOKEN is a type qualifier, false otherwise. */
648 c_token_is_qualifier (c_token
*token
)
653 switch (token
->id_kind
)
661 switch (token
->keyword
)
679 /* Return true if the next token from PARSER is a type qualifier,
682 c_parser_next_token_is_qualifier (c_parser
*parser
)
684 c_token
*token
= c_parser_peek_token (parser
);
685 return c_token_is_qualifier (token
);
688 /* Return true if TOKEN can start declaration specifiers (not
689 including standard attributes), false otherwise. */
691 c_token_starts_declspecs (c_token
*token
)
696 switch (token
->id_kind
)
705 gcc_assert (c_dialect_objc ());
711 switch (token
->keyword
)
752 if (token
->keyword
>= RID_FIRST_INT_N
753 && token
->keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
754 && int_n_enabled_p
[token
->keyword
- RID_FIRST_INT_N
])
759 if (c_dialect_objc ())
768 /* Return true if TOKEN can start declaration specifiers (not
769 including standard attributes) or a static assertion, false
772 c_token_starts_declaration (c_token
*token
)
774 if (c_token_starts_declspecs (token
)
775 || token
->keyword
== RID_STATIC_ASSERT
)
781 /* Return true if the next token from PARSER can start declaration
782 specifiers (not including standard attributes), false
785 c_parser_next_token_starts_declspecs (c_parser
*parser
)
787 c_token
*token
= c_parser_peek_token (parser
);
789 /* In Objective-C, a classname normally starts a declspecs unless it
790 is immediately followed by a dot. In that case, it is the
791 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
792 setter/getter on the class. c_token_starts_declspecs() can't
793 differentiate between the two cases because it only checks the
794 current token, so we have a special check here. */
795 if (c_dialect_objc ()
796 && token
->type
== CPP_NAME
797 && token
->id_kind
== C_ID_CLASSNAME
798 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
801 return c_token_starts_declspecs (token
);
804 /* Return true if the next tokens from PARSER can start declaration
805 specifiers (not including standard attributes) or a static
806 assertion, false otherwise. */
808 c_parser_next_tokens_start_declaration (c_parser
*parser
)
810 c_token
*token
= c_parser_peek_token (parser
);
813 if (c_dialect_objc ()
814 && token
->type
== CPP_NAME
815 && token
->id_kind
== C_ID_CLASSNAME
816 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
819 /* Labels do not start declarations. */
820 if (token
->type
== CPP_NAME
821 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
824 if (c_token_starts_declaration (token
))
827 if (c_parser_next_tokens_start_typename (parser
, cla_nonabstract_decl
))
833 /* Consume the next token from PARSER. */
836 c_parser_consume_token (c_parser
*parser
)
838 gcc_assert (parser
->tokens_avail
>= 1);
839 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
840 gcc_assert (!parser
->in_pragma
|| parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
841 gcc_assert (parser
->error
|| parser
->tokens
[0].type
!= CPP_PRAGMA
);
842 parser
->last_token_location
= parser
->tokens
[0].location
;
843 if (parser
->tokens
!= &parser
->tokens_buf
[0])
845 else if (parser
->tokens_avail
>= 2)
847 parser
->tokens
[0] = parser
->tokens
[1];
848 if (parser
->tokens_avail
>= 3)
849 parser
->tokens
[1] = parser
->tokens
[2];
851 parser
->tokens_avail
--;
854 /* Expect the current token to be a #pragma. Consume it and remember
855 that we've begun parsing a pragma. */
858 c_parser_consume_pragma (c_parser
*parser
)
860 gcc_assert (!parser
->in_pragma
);
861 gcc_assert (parser
->tokens_avail
>= 1);
862 gcc_assert (parser
->tokens
[0].type
== CPP_PRAGMA
);
863 if (parser
->tokens
!= &parser
->tokens_buf
[0])
865 else if (parser
->tokens_avail
>= 2)
867 parser
->tokens
[0] = parser
->tokens
[1];
868 if (parser
->tokens_avail
>= 3)
869 parser
->tokens
[1] = parser
->tokens
[2];
871 parser
->tokens_avail
--;
872 parser
->in_pragma
= true;
875 /* Update the global input_location from TOKEN. */
877 c_parser_set_source_position_from_token (c_token
*token
)
879 if (token
->type
!= CPP_EOF
)
881 input_location
= token
->location
;
885 /* Helper function for c_parser_error.
886 Having peeked a token of kind TOK1_KIND that might signify
887 a conflict marker, peek successor tokens to determine
888 if we actually do have a conflict marker.
889 Specifically, we consider a run of 7 '<', '=' or '>' characters
890 at the start of a line as a conflict marker.
891 These come through the lexer as three pairs and a single,
892 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
893 If it returns true, *OUT_LOC is written to with the location/range
897 c_parser_peek_conflict_marker (c_parser
*parser
, enum cpp_ttype tok1_kind
,
900 c_token
*token2
= c_parser_peek_2nd_token (parser
);
901 if (token2
->type
!= tok1_kind
)
903 c_token
*token3
= c_parser_peek_nth_token (parser
, 3);
904 if (token3
->type
!= tok1_kind
)
906 c_token
*token4
= c_parser_peek_nth_token (parser
, 4);
907 if (token4
->type
!= conflict_marker_get_final_tok_kind (tok1_kind
))
910 /* It must be at the start of the line. */
911 location_t start_loc
= c_parser_peek_token (parser
)->location
;
912 if (LOCATION_COLUMN (start_loc
) != 1)
915 /* We have a conflict marker. Construct a location of the form:
918 with start == caret, finishing at the end of the marker. */
919 location_t finish_loc
= get_finish (token4
->location
);
920 *out_loc
= make_location (start_loc
, start_loc
, finish_loc
);
925 /* Issue a diagnostic of the form
926 FILE:LINE: MESSAGE before TOKEN
927 where TOKEN is the next token in the input stream of PARSER.
928 MESSAGE (specified by the caller) is usually of the form "expected
931 Use RICHLOC as the location of the diagnostic.
933 Do not issue a diagnostic if still recovering from an error.
935 Return true iff an error was actually emitted.
937 ??? This is taken from the C++ parser, but building up messages in
938 this way is not i18n-friendly and some other approach should be
942 c_parser_error_richloc (c_parser
*parser
, const char *gmsgid
,
943 rich_location
*richloc
)
945 c_token
*token
= c_parser_peek_token (parser
);
948 parser
->error
= true;
952 /* If this is actually a conflict marker, report it as such. */
953 if (token
->type
== CPP_LSHIFT
954 || token
->type
== CPP_RSHIFT
955 || token
->type
== CPP_EQ_EQ
)
958 if (c_parser_peek_conflict_marker (parser
, token
->type
, &loc
))
960 error_at (loc
, "version control conflict marker in file");
965 c_parse_error (gmsgid
,
966 /* Because c_parse_error does not understand
967 CPP_KEYWORD, keywords are treated like
969 (token
->type
== CPP_KEYWORD
? CPP_NAME
: token
->type
),
970 /* ??? The C parser does not save the cpp flags of a
971 token, we need to pass 0 here and we will not get
972 the source spelling of some tokens but rather the
973 canonical spelling. */
974 token
->value
, /*flags=*/0, richloc
);
978 /* As c_parser_error_richloc, but issue the message at the
979 location of PARSER's next token, or at input_location
980 if the next token is EOF. */
983 c_parser_error (c_parser
*parser
, const char *gmsgid
)
985 c_token
*token
= c_parser_peek_token (parser
);
986 c_parser_set_source_position_from_token (token
);
987 rich_location
richloc (line_table
, input_location
);
988 return c_parser_error_richloc (parser
, gmsgid
, &richloc
);
991 /* Some tokens naturally come in pairs e.g.'(' and ')'.
992 This class is for tracking such a matching pair of symbols.
993 In particular, it tracks the location of the first token,
994 so that if the second token is missing, we can highlight the
995 location of the first token when notifying the user about the
998 template <typename traits_t
>
1002 /* token_pair's ctor. */
1003 token_pair () : m_open_loc (UNKNOWN_LOCATION
) {}
1005 /* If the next token is the opening symbol for this pair, consume it and
1007 Otherwise, issue an error and return false.
1008 In either case, record the location of the opening token. */
1010 bool require_open (c_parser
*parser
)
1012 c_token
*token
= c_parser_peek_token (parser
);
1014 m_open_loc
= token
->location
;
1016 return c_parser_require (parser
, traits_t::open_token_type
,
1017 traits_t::open_gmsgid
);
1020 /* Consume the next token from PARSER, recording its location as
1021 that of the opening token within the pair. */
1023 void consume_open (c_parser
*parser
)
1025 c_token
*token
= c_parser_peek_token (parser
);
1026 gcc_assert (token
->type
== traits_t::open_token_type
);
1027 m_open_loc
= token
->location
;
1028 c_parser_consume_token (parser
);
1031 /* If the next token is the closing symbol for this pair, consume it
1033 Otherwise, issue an error, highlighting the location of the
1034 corresponding opening token, and return false. */
1036 bool require_close (c_parser
*parser
) const
1038 return c_parser_require (parser
, traits_t::close_token_type
,
1039 traits_t::close_gmsgid
, m_open_loc
);
1042 /* Like token_pair::require_close, except that tokens will be skipped
1043 until the desired token is found. An error message is still produced
1044 if the next token is not as expected. */
1046 void skip_until_found_close (c_parser
*parser
) const
1048 c_parser_skip_until_found (parser
, traits_t::close_token_type
,
1049 traits_t::close_gmsgid
, m_open_loc
);
1053 location_t m_open_loc
;
1056 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1058 struct matching_paren_traits
1060 static const enum cpp_ttype open_token_type
= CPP_OPEN_PAREN
;
1061 static const char * const open_gmsgid
;
1062 static const enum cpp_ttype close_token_type
= CPP_CLOSE_PAREN
;
1063 static const char * const close_gmsgid
;
1066 const char * const matching_paren_traits::open_gmsgid
= "expected %<(%>";
1067 const char * const matching_paren_traits::close_gmsgid
= "expected %<)%>";
1069 /* "matching_parens" is a token_pair<T> class for tracking matching
1070 pairs of parentheses. */
1072 typedef token_pair
<matching_paren_traits
> matching_parens
;
1074 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1076 struct matching_brace_traits
1078 static const enum cpp_ttype open_token_type
= CPP_OPEN_BRACE
;
1079 static const char * const open_gmsgid
;
1080 static const enum cpp_ttype close_token_type
= CPP_CLOSE_BRACE
;
1081 static const char * const close_gmsgid
;
1084 const char * const matching_brace_traits::open_gmsgid
= "expected %<{%>";
1085 const char * const matching_brace_traits::close_gmsgid
= "expected %<}%>";
1087 /* "matching_braces" is a token_pair<T> class for tracking matching
1090 typedef token_pair
<matching_brace_traits
> matching_braces
;
1092 /* Get a description of the matching symbol to TYPE e.g. "(" for
1096 get_matching_symbol (enum cpp_ttype type
)
1103 case CPP_CLOSE_PAREN
:
1105 case CPP_CLOSE_BRACE
:
1110 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1111 issue the error MSGID. If MSGID is NULL then a message has already
1112 been produced and no message will be produced this time. Returns
1113 true if found, false otherwise.
1115 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1116 within any error as the location of an "opening" token matching
1117 the close token TYPE (e.g. the location of the '(' when TYPE is
1120 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1121 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1122 attempt to generate a fix-it hint for the problem.
1123 Otherwise msgid describes multiple token types (e.g.
1124 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1125 generate a fix-it hint. */
1128 c_parser_require (c_parser
*parser
,
1129 enum cpp_ttype type
,
1131 location_t matching_location
,
1132 bool type_is_unique
)
1134 if (c_parser_next_token_is (parser
, type
))
1136 c_parser_consume_token (parser
);
1141 location_t next_token_loc
= c_parser_peek_token (parser
)->location
;
1142 gcc_rich_location
richloc (next_token_loc
);
1144 /* Potentially supply a fix-it hint, suggesting to add the
1145 missing token immediately after the *previous* token.
1146 This may move the primary location within richloc. */
1147 if (!parser
->error
&& type_is_unique
)
1148 maybe_suggest_missing_token_insertion (&richloc
, type
,
1149 parser
->last_token_location
);
1151 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1152 Attempt to consolidate diagnostics by printing it as a
1153 secondary range within the main diagnostic. */
1154 bool added_matching_location
= false;
1155 if (matching_location
!= UNKNOWN_LOCATION
)
1156 added_matching_location
1157 = richloc
.add_location_if_nearby (matching_location
);
1159 if (c_parser_error_richloc (parser
, msgid
, &richloc
))
1160 /* If we weren't able to consolidate matching_location, then
1161 print it as a secondary diagnostic. */
1162 if (matching_location
!= UNKNOWN_LOCATION
&& !added_matching_location
)
1163 inform (matching_location
, "to match this %qs",
1164 get_matching_symbol (type
));
1170 /* If the next token is the indicated keyword, consume it. Otherwise,
1171 issue the error MSGID. Returns true if found, false otherwise. */
1174 c_parser_require_keyword (c_parser
*parser
,
1178 if (c_parser_next_token_is_keyword (parser
, keyword
))
1180 c_parser_consume_token (parser
);
1185 c_parser_error (parser
, msgid
);
1190 /* Like c_parser_require, except that tokens will be skipped until the
1191 desired token is found. An error message is still produced if the
1192 next token is not as expected. If MSGID is NULL then a message has
1193 already been produced and no message will be produced this
1196 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1197 within any error as the location of an "opening" token matching
1198 the close token TYPE (e.g. the location of the '(' when TYPE is
1199 CPP_CLOSE_PAREN). */
1202 c_parser_skip_until_found (c_parser
*parser
,
1203 enum cpp_ttype type
,
1205 location_t matching_location
)
1207 unsigned nesting_depth
= 0;
1209 if (c_parser_require (parser
, type
, msgid
, matching_location
))
1212 /* Skip tokens until the desired token is found. */
1215 /* Peek at the next token. */
1216 c_token
*token
= c_parser_peek_token (parser
);
1217 /* If we've reached the token we want, consume it and stop. */
1218 if (token
->type
== type
&& !nesting_depth
)
1220 c_parser_consume_token (parser
);
1224 /* If we've run out of tokens, stop. */
1225 if (token
->type
== CPP_EOF
)
1227 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1229 if (token
->type
== CPP_OPEN_BRACE
1230 || token
->type
== CPP_OPEN_PAREN
1231 || token
->type
== CPP_OPEN_SQUARE
)
1233 else if (token
->type
== CPP_CLOSE_BRACE
1234 || token
->type
== CPP_CLOSE_PAREN
1235 || token
->type
== CPP_CLOSE_SQUARE
)
1237 if (nesting_depth
-- == 0)
1240 /* Consume this token. */
1241 c_parser_consume_token (parser
);
1243 parser
->error
= false;
1246 /* Skip tokens until the end of a parameter is found, but do not
1247 consume the comma, semicolon or closing delimiter. */
1250 c_parser_skip_to_end_of_parameter (c_parser
*parser
)
1252 unsigned nesting_depth
= 0;
1256 c_token
*token
= c_parser_peek_token (parser
);
1257 if ((token
->type
== CPP_COMMA
|| token
->type
== CPP_SEMICOLON
)
1260 /* If we've run out of tokens, stop. */
1261 if (token
->type
== CPP_EOF
)
1263 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1265 if (token
->type
== CPP_OPEN_BRACE
1266 || token
->type
== CPP_OPEN_PAREN
1267 || token
->type
== CPP_OPEN_SQUARE
)
1269 else if (token
->type
== CPP_CLOSE_BRACE
1270 || token
->type
== CPP_CLOSE_PAREN
1271 || token
->type
== CPP_CLOSE_SQUARE
)
1273 if (nesting_depth
-- == 0)
1276 /* Consume this token. */
1277 c_parser_consume_token (parser
);
1279 parser
->error
= false;
1282 /* Expect to be at the end of the pragma directive and consume an
1283 end of line marker. */
1286 c_parser_skip_to_pragma_eol (c_parser
*parser
, bool error_if_not_eol
= true)
1288 gcc_assert (parser
->in_pragma
);
1289 parser
->in_pragma
= false;
1291 if (error_if_not_eol
&& c_parser_peek_token (parser
)->type
!= CPP_PRAGMA_EOL
)
1292 c_parser_error (parser
, "expected end of line");
1294 cpp_ttype token_type
;
1297 c_token
*token
= c_parser_peek_token (parser
);
1298 token_type
= token
->type
;
1299 if (token_type
== CPP_EOF
)
1301 c_parser_consume_token (parser
);
1303 while (token_type
!= CPP_PRAGMA_EOL
);
1305 parser
->error
= false;
1308 /* Skip tokens until we have consumed an entire block, or until we
1309 have consumed a non-nested ';'. */
1312 c_parser_skip_to_end_of_block_or_statement (c_parser
*parser
)
1314 unsigned nesting_depth
= 0;
1315 bool save_error
= parser
->error
;
1321 /* Peek at the next token. */
1322 token
= c_parser_peek_token (parser
);
1324 switch (token
->type
)
1329 case CPP_PRAGMA_EOL
:
1330 if (parser
->in_pragma
)
1335 /* If the next token is a ';', we have reached the
1336 end of the statement. */
1339 /* Consume the ';'. */
1340 c_parser_consume_token (parser
);
1345 case CPP_CLOSE_BRACE
:
1346 /* If the next token is a non-nested '}', then we have
1347 reached the end of the current block. */
1348 if (nesting_depth
== 0 || --nesting_depth
== 0)
1350 c_parser_consume_token (parser
);
1355 case CPP_OPEN_BRACE
:
1356 /* If it the next token is a '{', then we are entering a new
1357 block. Consume the entire block. */
1362 /* If we see a pragma, consume the whole thing at once. We
1363 have some safeguards against consuming pragmas willy-nilly.
1364 Normally, we'd expect to be here with parser->error set,
1365 which disables these safeguards. But it's possible to get
1366 here for secondary error recovery, after parser->error has
1368 c_parser_consume_pragma (parser
);
1369 c_parser_skip_to_pragma_eol (parser
);
1370 parser
->error
= save_error
;
1377 c_parser_consume_token (parser
);
1381 parser
->error
= false;
1384 /* CPP's options (initialized by c-opts.c). */
1385 extern cpp_options
*cpp_opts
;
1387 /* Save the warning flags which are controlled by __extension__. */
1390 disable_extension_diagnostics (void)
1393 | (warn_pointer_arith
<< 1)
1394 | (warn_traditional
<< 2)
1396 | (warn_long_long
<< 4)
1397 | (warn_cxx_compat
<< 5)
1398 | (warn_overlength_strings
<< 6)
1399 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1400 play tricks to properly restore it. */
1401 | ((warn_c90_c99_compat
== 1) << 7)
1402 | ((warn_c90_c99_compat
== -1) << 8)
1403 /* Similarly for warn_c99_c11_compat. */
1404 | ((warn_c99_c11_compat
== 1) << 9)
1405 | ((warn_c99_c11_compat
== -1) << 10)
1406 /* Similarly for warn_c11_c2x_compat. */
1407 | ((warn_c11_c2x_compat
== 1) << 11)
1408 | ((warn_c11_c2x_compat
== -1) << 12)
1410 cpp_opts
->cpp_pedantic
= pedantic
= 0;
1411 warn_pointer_arith
= 0;
1412 cpp_opts
->cpp_warn_traditional
= warn_traditional
= 0;
1414 cpp_opts
->cpp_warn_long_long
= warn_long_long
= 0;
1415 warn_cxx_compat
= 0;
1416 warn_overlength_strings
= 0;
1417 warn_c90_c99_compat
= 0;
1418 warn_c99_c11_compat
= 0;
1419 warn_c11_c2x_compat
= 0;
1423 /* Restore the warning flags which are controlled by __extension__.
1424 FLAGS is the return value from disable_extension_diagnostics. */
1427 restore_extension_diagnostics (int flags
)
1429 cpp_opts
->cpp_pedantic
= pedantic
= flags
& 1;
1430 warn_pointer_arith
= (flags
>> 1) & 1;
1431 cpp_opts
->cpp_warn_traditional
= warn_traditional
= (flags
>> 2) & 1;
1432 flag_iso
= (flags
>> 3) & 1;
1433 cpp_opts
->cpp_warn_long_long
= warn_long_long
= (flags
>> 4) & 1;
1434 warn_cxx_compat
= (flags
>> 5) & 1;
1435 warn_overlength_strings
= (flags
>> 6) & 1;
1436 /* See above for why is this needed. */
1437 warn_c90_c99_compat
= (flags
>> 7) & 1 ? 1 : ((flags
>> 8) & 1 ? -1 : 0);
1438 warn_c99_c11_compat
= (flags
>> 9) & 1 ? 1 : ((flags
>> 10) & 1 ? -1 : 0);
1439 warn_c11_c2x_compat
= (flags
>> 11) & 1 ? 1 : ((flags
>> 12) & 1 ? -1 : 0);
1442 /* Helper data structure for parsing #pragma acc routine. */
1443 struct oacc_routine_data
{
1444 bool error_seen
; /* Set if error has been reported. */
1445 bool fndecl_seen
; /* Set if one fn decl/definition has been seen already. */
1450 static bool c_parser_nth_token_starts_std_attributes (c_parser
*,
1452 static tree
c_parser_std_attribute_specifier_sequence (c_parser
*);
1453 static void c_parser_external_declaration (c_parser
*);
1454 static void c_parser_asm_definition (c_parser
*);
1455 static void c_parser_declaration_or_fndef (c_parser
*, bool, bool, bool,
1456 bool, bool, tree
*, vec
<c_token
>,
1457 bool have_attrs
= false,
1459 struct oacc_routine_data
* = NULL
,
1461 static void c_parser_static_assert_declaration_no_semi (c_parser
*);
1462 static void c_parser_static_assert_declaration (c_parser
*);
1463 static struct c_typespec
c_parser_enum_specifier (c_parser
*);
1464 static struct c_typespec
c_parser_struct_or_union_specifier (c_parser
*);
1465 static tree
c_parser_struct_declaration (c_parser
*);
1466 static struct c_typespec
c_parser_typeof_specifier (c_parser
*);
1467 static tree
c_parser_alignas_specifier (c_parser
*);
1468 static struct c_declarator
*c_parser_direct_declarator (c_parser
*, bool,
1470 static struct c_declarator
*c_parser_direct_declarator_inner (c_parser
*,
1472 struct c_declarator
*);
1473 static struct c_arg_info
*c_parser_parms_declarator (c_parser
*, bool, tree
,
1475 static struct c_arg_info
*c_parser_parms_list_declarator (c_parser
*, tree
,
1477 static struct c_parm
*c_parser_parameter_declaration (c_parser
*, tree
, bool);
1478 static tree
c_parser_simple_asm_expr (c_parser
*);
1479 static tree
c_parser_gnu_attributes (c_parser
*);
1480 static struct c_expr
c_parser_initializer (c_parser
*);
1481 static struct c_expr
c_parser_braced_init (c_parser
*, tree
, bool,
1483 static void c_parser_initelt (c_parser
*, struct obstack
*);
1484 static void c_parser_initval (c_parser
*, struct c_expr
*,
1486 static tree
c_parser_compound_statement (c_parser
*);
1487 static void c_parser_compound_statement_nostart (c_parser
*);
1488 static void c_parser_label (c_parser
*);
1489 static void c_parser_statement (c_parser
*, bool *, location_t
* = NULL
);
1490 static void c_parser_statement_after_labels (c_parser
*, bool *,
1491 vec
<tree
> * = NULL
);
1492 static tree
c_parser_c99_block_statement (c_parser
*, bool *,
1493 location_t
* = NULL
);
1494 static void c_parser_if_statement (c_parser
*, bool *, vec
<tree
> *);
1495 static void c_parser_switch_statement (c_parser
*, bool *);
1496 static void c_parser_while_statement (c_parser
*, bool, unsigned short, bool *);
1497 static void c_parser_do_statement (c_parser
*, bool, unsigned short);
1498 static void c_parser_for_statement (c_parser
*, bool, unsigned short, bool *);
1499 static tree
c_parser_asm_statement (c_parser
*);
1500 static tree
c_parser_asm_operands (c_parser
*);
1501 static tree
c_parser_asm_goto_operands (c_parser
*);
1502 static tree
c_parser_asm_clobbers (c_parser
*);
1503 static struct c_expr
c_parser_expr_no_commas (c_parser
*, struct c_expr
*,
1505 static struct c_expr
c_parser_conditional_expression (c_parser
*,
1506 struct c_expr
*, tree
);
1507 static struct c_expr
c_parser_binary_expression (c_parser
*, struct c_expr
*,
1509 static struct c_expr
c_parser_cast_expression (c_parser
*, struct c_expr
*);
1510 static struct c_expr
c_parser_unary_expression (c_parser
*);
1511 static struct c_expr
c_parser_sizeof_expression (c_parser
*);
1512 static struct c_expr
c_parser_alignof_expression (c_parser
*);
1513 static struct c_expr
c_parser_postfix_expression (c_parser
*);
1514 static struct c_expr
c_parser_postfix_expression_after_paren_type (c_parser
*,
1515 struct c_type_name
*,
1517 static struct c_expr
c_parser_postfix_expression_after_primary (c_parser
*,
1520 static tree
c_parser_transaction (c_parser
*, enum rid
);
1521 static struct c_expr
c_parser_transaction_expression (c_parser
*, enum rid
);
1522 static tree
c_parser_transaction_cancel (c_parser
*);
1523 static struct c_expr
c_parser_expression (c_parser
*);
1524 static struct c_expr
c_parser_expression_conv (c_parser
*);
1525 static vec
<tree
, va_gc
> *c_parser_expr_list (c_parser
*, bool, bool,
1526 vec
<tree
, va_gc
> **, location_t
*,
1527 tree
*, vec
<location_t
> *,
1528 unsigned int * = NULL
);
1529 static struct c_expr
c_parser_has_attribute_expression (c_parser
*);
1531 static void c_parser_oacc_declare (c_parser
*);
1532 static void c_parser_oacc_enter_exit_data (c_parser
*, bool);
1533 static void c_parser_oacc_update (c_parser
*);
1534 static void c_parser_omp_construct (c_parser
*, bool *);
1535 static void c_parser_omp_threadprivate (c_parser
*);
1536 static void c_parser_omp_barrier (c_parser
*);
1537 static void c_parser_omp_depobj (c_parser
*);
1538 static void c_parser_omp_flush (c_parser
*);
1539 static tree
c_parser_omp_for_loop (location_t
, c_parser
*, enum tree_code
,
1540 tree
, tree
*, bool *);
1541 static void c_parser_omp_taskwait (c_parser
*);
1542 static void c_parser_omp_taskyield (c_parser
*);
1543 static void c_parser_omp_cancel (c_parser
*);
1545 enum pragma_context
{ pragma_external
, pragma_struct
, pragma_param
,
1546 pragma_stmt
, pragma_compound
};
1547 static bool c_parser_pragma (c_parser
*, enum pragma_context
, bool *);
1548 static void c_parser_omp_cancellation_point (c_parser
*, enum pragma_context
);
1549 static bool c_parser_omp_target (c_parser
*, enum pragma_context
, bool *);
1550 static void c_parser_omp_end_declare_target (c_parser
*);
1551 static void c_parser_omp_declare (c_parser
*, enum pragma_context
);
1552 static void c_parser_omp_requires (c_parser
*);
1553 static bool c_parser_omp_ordered (c_parser
*, enum pragma_context
, bool *);
1554 static void c_parser_oacc_routine (c_parser
*, enum pragma_context
);
1556 /* These Objective-C parser functions are only ever called when
1557 compiling Objective-C. */
1558 static void c_parser_objc_class_definition (c_parser
*, tree
);
1559 static void c_parser_objc_class_instance_variables (c_parser
*);
1560 static void c_parser_objc_class_declaration (c_parser
*);
1561 static void c_parser_objc_alias_declaration (c_parser
*);
1562 static void c_parser_objc_protocol_definition (c_parser
*, tree
);
1563 static bool c_parser_objc_method_type (c_parser
*);
1564 static void c_parser_objc_method_definition (c_parser
*);
1565 static void c_parser_objc_methodprotolist (c_parser
*);
1566 static void c_parser_objc_methodproto (c_parser
*);
1567 static tree
c_parser_objc_method_decl (c_parser
*, bool, tree
*, tree
*);
1568 static tree
c_parser_objc_type_name (c_parser
*);
1569 static tree
c_parser_objc_protocol_refs (c_parser
*);
1570 static void c_parser_objc_try_catch_finally_statement (c_parser
*);
1571 static void c_parser_objc_synchronized_statement (c_parser
*);
1572 static tree
c_parser_objc_selector (c_parser
*);
1573 static tree
c_parser_objc_selector_arg (c_parser
*);
1574 static tree
c_parser_objc_receiver (c_parser
*);
1575 static tree
c_parser_objc_message_args (c_parser
*);
1576 static tree
c_parser_objc_keywordexpr (c_parser
*);
1577 static void c_parser_objc_at_property_declaration (c_parser
*);
1578 static void c_parser_objc_at_synthesize_declaration (c_parser
*);
1579 static void c_parser_objc_at_dynamic_declaration (c_parser
*);
1580 static bool c_parser_objc_diagnose_bad_element_prefix
1581 (c_parser
*, struct c_declspecs
*);
1583 static void c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
);
1585 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1588 external-declarations
1590 external-declarations:
1591 external-declaration
1592 external-declarations external-declaration
1601 c_parser_translation_unit (c_parser
*parser
)
1603 if (c_parser_next_token_is (parser
, CPP_EOF
))
1605 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1606 "ISO C forbids an empty translation unit");
1610 void *obstack_position
= obstack_alloc (&parser_obstack
, 0);
1611 mark_valid_location_for_stdc_pragma (false);
1615 c_parser_external_declaration (parser
);
1616 obstack_free (&parser_obstack
, obstack_position
);
1618 while (c_parser_next_token_is_not (parser
, CPP_EOF
));
1623 FOR_EACH_VEC_ELT (incomplete_record_decls
, i
, decl
)
1624 if (DECL_SIZE (decl
) == NULL_TREE
&& TREE_TYPE (decl
) != error_mark_node
)
1625 error ("storage size of %q+D isn%'t known", decl
);
1627 if (current_omp_declare_target_attribute
)
1630 error ("%<#pragma omp declare target%> without corresponding "
1631 "%<#pragma omp end declare target%>");
1632 current_omp_declare_target_attribute
= 0;
1636 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1638 external-declaration:
1644 external-declaration:
1647 __extension__ external-declaration
1651 external-declaration:
1652 objc-class-definition
1653 objc-class-declaration
1654 objc-alias-declaration
1655 objc-protocol-definition
1656 objc-method-definition
1661 c_parser_external_declaration (c_parser
*parser
)
1664 switch (c_parser_peek_token (parser
)->type
)
1667 switch (c_parser_peek_token (parser
)->keyword
)
1670 ext
= disable_extension_diagnostics ();
1671 c_parser_consume_token (parser
);
1672 c_parser_external_declaration (parser
);
1673 restore_extension_diagnostics (ext
);
1676 c_parser_asm_definition (parser
);
1678 case RID_AT_INTERFACE
:
1679 case RID_AT_IMPLEMENTATION
:
1680 gcc_assert (c_dialect_objc ());
1681 c_parser_objc_class_definition (parser
, NULL_TREE
);
1684 gcc_assert (c_dialect_objc ());
1685 c_parser_objc_class_declaration (parser
);
1688 gcc_assert (c_dialect_objc ());
1689 c_parser_objc_alias_declaration (parser
);
1691 case RID_AT_PROTOCOL
:
1692 gcc_assert (c_dialect_objc ());
1693 c_parser_objc_protocol_definition (parser
, NULL_TREE
);
1695 case RID_AT_PROPERTY
:
1696 gcc_assert (c_dialect_objc ());
1697 c_parser_objc_at_property_declaration (parser
);
1699 case RID_AT_SYNTHESIZE
:
1700 gcc_assert (c_dialect_objc ());
1701 c_parser_objc_at_synthesize_declaration (parser
);
1703 case RID_AT_DYNAMIC
:
1704 gcc_assert (c_dialect_objc ());
1705 c_parser_objc_at_dynamic_declaration (parser
);
1708 gcc_assert (c_dialect_objc ());
1709 c_parser_consume_token (parser
);
1710 objc_finish_implementation ();
1717 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1718 "ISO C does not allow extra %<;%> outside of a function");
1719 c_parser_consume_token (parser
);
1722 mark_valid_location_for_stdc_pragma (true);
1723 c_parser_pragma (parser
, pragma_external
, NULL
);
1724 mark_valid_location_for_stdc_pragma (false);
1728 if (c_dialect_objc ())
1730 c_parser_objc_method_definition (parser
);
1733 /* Else fall through, and yield a syntax error trying to parse
1734 as a declaration or function definition. */
1738 /* A declaration or a function definition (or, in Objective-C,
1739 an @interface or @protocol with prefix attributes). We can
1740 only tell which after parsing the declaration specifiers, if
1741 any, and the first declarator. */
1742 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
1748 static void c_finish_omp_declare_simd (c_parser
*, tree
, tree
, vec
<c_token
>);
1749 static void c_finish_oacc_routine (struct oacc_routine_data
*, tree
, bool);
1751 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1754 add_debug_begin_stmt (location_t loc
)
1756 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1757 if (!MAY_HAVE_DEBUG_MARKER_STMTS
|| !building_stmt_list_p ())
1760 tree stmt
= build0 (DEBUG_BEGIN_STMT
, void_type_node
);
1761 SET_EXPR_LOCATION (stmt
, loc
);
1765 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1766 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1767 is accepted; otherwise (old-style parameter declarations) only other
1768 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1769 assertion is accepted; otherwise (old-style parameter declarations)
1770 it is not. If NESTED is true, we are inside a function or parsing
1771 old-style parameter declarations; any functions encountered are
1772 nested functions and declaration specifiers are required; otherwise
1773 we are at top level and functions are normal functions and
1774 declaration specifiers may be optional. If EMPTY_OK is true, empty
1775 declarations are OK (subject to all other constraints); otherwise
1776 (old-style parameter declarations) they are diagnosed. If
1777 START_ATTR_OK is true, the declaration specifiers may start with
1778 attributes (GNU or standard); otherwise they may not.
1779 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1780 declaration when parsing an Objective-C foreach statement.
1781 FALLTHRU_ATTR_P is used to signal whether this function parsed
1782 "__attribute__((fallthrough));". ATTRS are any standard attributes
1783 parsed in the caller (in contexts where such attributes had to be
1784 parsed to determine whether what follows is a declaration or a
1785 statement); HAVE_ATTRS says whether there were any such attributes
1789 declaration-specifiers init-declarator-list[opt] ;
1790 static_assert-declaration
1792 function-definition:
1793 declaration-specifiers[opt] declarator declaration-list[opt]
1798 declaration-list declaration
1800 init-declarator-list:
1802 init-declarator-list , init-declarator
1805 declarator simple-asm-expr[opt] gnu-attributes[opt]
1806 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1810 nested-function-definition:
1811 declaration-specifiers declarator declaration-list[opt]
1817 gnu-attributes objc-class-definition
1818 gnu-attributes objc-category-definition
1819 gnu-attributes objc-protocol-definition
1821 The simple-asm-expr and gnu-attributes are GNU extensions.
1823 This function does not handle __extension__; that is handled in its
1824 callers. ??? Following the old parser, __extension__ may start
1825 external declarations, declarations in functions and declarations
1826 at the start of "for" loops, but not old-style parameter
1829 C99 requires declaration specifiers in a function definition; the
1830 absence is diagnosed through the diagnosis of implicit int. In GNU
1831 C we also allow but diagnose declarations without declaration
1832 specifiers, but only at top level (elsewhere they conflict with
1835 In Objective-C, declarations of the looping variable in a foreach
1836 statement are exceptionally terminated by 'in' (for example, 'for
1837 (NSObject *object in array) { ... }').
1842 threadprivate-directive
1846 gimple-function-definition:
1847 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1848 declaration-list[opt] compound-statement
1850 rtl-function-definition:
1851 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1852 declaration-list[opt] compound-statement */
1855 c_parser_declaration_or_fndef (c_parser
*parser
, bool fndef_ok
,
1856 bool static_assert_ok
, bool empty_ok
,
1857 bool nested
, bool start_attr_ok
,
1858 tree
*objc_foreach_object_declaration
,
1859 vec
<c_token
> omp_declare_simd_clauses
,
1860 bool have_attrs
, tree attrs
,
1861 struct oacc_routine_data
*oacc_routine_data
,
1862 bool *fallthru_attr_p
)
1864 struct c_declspecs
*specs
;
1866 tree all_prefix_attrs
;
1867 bool diagnosed_no_specs
= false;
1868 location_t here
= c_parser_peek_token (parser
)->location
;
1870 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
1872 if (static_assert_ok
1873 && c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
1875 c_parser_static_assert_declaration (parser
);
1878 specs
= build_null_declspecs ();
1880 /* Handle any standard attributes parsed in the caller. */
1883 declspecs_add_attrs (here
, specs
, attrs
);
1884 specs
->non_std_attrs_seen_p
= false;
1887 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1888 if (c_parser_peek_token (parser
)->type
== CPP_NAME
1889 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
1890 && (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
1891 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
1892 && (!nested
|| !lookup_name (c_parser_peek_token (parser
)->value
)))
1894 tree name
= c_parser_peek_token (parser
)->value
;
1896 /* Issue a warning about NAME being an unknown type name, perhaps
1897 with some kind of hint.
1898 If the user forgot a "struct" etc, suggest inserting
1899 it. Otherwise, attempt to look for misspellings. */
1900 gcc_rich_location
richloc (here
);
1901 if (tag_exists_p (RECORD_TYPE
, name
))
1903 /* This is not C++ with its implicit typedef. */
1904 richloc
.add_fixit_insert_before ("struct ");
1906 "unknown type name %qE;"
1907 " use %<struct%> keyword to refer to the type",
1910 else if (tag_exists_p (UNION_TYPE
, name
))
1912 richloc
.add_fixit_insert_before ("union ");
1914 "unknown type name %qE;"
1915 " use %<union%> keyword to refer to the type",
1918 else if (tag_exists_p (ENUMERAL_TYPE
, name
))
1920 richloc
.add_fixit_insert_before ("enum ");
1922 "unknown type name %qE;"
1923 " use %<enum%> keyword to refer to the type",
1928 auto_diagnostic_group d
;
1929 name_hint hint
= lookup_name_fuzzy (name
, FUZZY_LOOKUP_TYPENAME
,
1931 if (const char *suggestion
= hint
.suggestion ())
1933 richloc
.add_fixit_replace (suggestion
);
1935 "unknown type name %qE; did you mean %qs?",
1939 error_at (here
, "unknown type name %qE", name
);
1942 /* Parse declspecs normally to get a correct pointer type, but avoid
1943 a further "fails to be a type name" error. Refuse nested functions
1944 since it is not how the user likely wants us to recover. */
1945 c_parser_peek_token (parser
)->type
= CPP_KEYWORD
;
1946 c_parser_peek_token (parser
)->keyword
= RID_VOID
;
1947 c_parser_peek_token (parser
)->value
= error_mark_node
;
1951 /* When there are standard attributes at the start of the
1952 declaration (to apply to the entity being declared), an
1953 init-declarator-list or function definition must be present. */
1954 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
1957 c_parser_declspecs (parser
, specs
, true, true, start_attr_ok
,
1958 true, true, start_attr_ok
, true, cla_nonabstract_decl
);
1961 c_parser_skip_to_end_of_block_or_statement (parser
);
1964 if (nested
&& !specs
->declspecs_seen_p
)
1966 c_parser_error (parser
, "expected declaration specifiers");
1967 c_parser_skip_to_end_of_block_or_statement (parser
);
1971 finish_declspecs (specs
);
1972 bool auto_type_p
= specs
->typespec_word
== cts_auto_type
;
1973 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
1976 error_at (here
, "%<__auto_type%> in empty declaration");
1977 else if (specs
->typespec_kind
== ctsk_none
1978 && attribute_fallthrough_p (specs
->attrs
))
1980 if (fallthru_attr_p
!= NULL
)
1981 *fallthru_attr_p
= true;
1984 tree fn
= build_call_expr_internal_loc (here
, IFN_FALLTHROUGH
,
1989 pedwarn (here
, OPT_Wattributes
,
1990 "%<fallthrough%> attribute at top level");
1992 else if (empty_ok
&& !(have_attrs
1993 && specs
->non_std_attrs_seen_p
))
1997 shadow_tag_warned (specs
, 1);
1998 pedwarn (here
, 0, "empty declaration");
2000 c_parser_consume_token (parser
);
2001 if (oacc_routine_data
)
2002 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2006 /* Provide better error recovery. Note that a type name here is usually
2007 better diagnosed as a redeclaration. */
2009 && specs
->typespec_kind
== ctsk_tagdef
2010 && c_parser_next_token_starts_declspecs (parser
)
2011 && !c_parser_next_token_is (parser
, CPP_NAME
))
2013 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
2014 parser
->error
= false;
2015 shadow_tag_warned (specs
, 1);
2018 else if (c_dialect_objc () && !auto_type_p
)
2020 /* Prefix attributes are an error on method decls. */
2021 switch (c_parser_peek_token (parser
)->type
)
2025 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2029 warning_at (c_parser_peek_token (parser
)->location
,
2031 "prefix attributes are ignored for methods");
2032 specs
->attrs
= NULL_TREE
;
2035 c_parser_objc_method_definition (parser
);
2037 c_parser_objc_methodproto (parser
);
2043 /* This is where we parse 'attributes @interface ...',
2044 'attributes @implementation ...', 'attributes @protocol ...'
2045 (where attributes could be, for example, __attribute__
2048 switch (c_parser_peek_token (parser
)->keyword
)
2050 case RID_AT_INTERFACE
:
2052 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2054 c_parser_objc_class_definition (parser
, specs
->attrs
);
2058 case RID_AT_IMPLEMENTATION
:
2060 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2064 warning_at (c_parser_peek_token (parser
)->location
,
2066 "prefix attributes are ignored for implementations");
2067 specs
->attrs
= NULL_TREE
;
2069 c_parser_objc_class_definition (parser
, NULL_TREE
);
2073 case RID_AT_PROTOCOL
:
2075 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2077 c_parser_objc_protocol_definition (parser
, specs
->attrs
);
2084 case RID_AT_PROPERTY
:
2087 c_parser_error (parser
, "unexpected attribute");
2088 specs
->attrs
= NULL
;
2095 else if (attribute_fallthrough_p (specs
->attrs
))
2096 warning_at (here
, OPT_Wattributes
,
2097 "%<fallthrough%> attribute not followed by %<;%>");
2099 pending_xref_error ();
2100 prefix_attrs
= specs
->attrs
;
2101 all_prefix_attrs
= prefix_attrs
;
2102 specs
->attrs
= NULL_TREE
;
2105 struct c_declarator
*declarator
;
2108 tree fnbody
= NULL_TREE
;
2109 /* Declaring either one or more declarators (in which case we
2110 should diagnose if there were no declaration specifiers) or a
2111 function definition (in which case the diagnostic for
2112 implicit int suffices). */
2113 declarator
= c_parser_declarator (parser
,
2114 specs
->typespec_kind
!= ctsk_none
,
2115 C_DTR_NORMAL
, &dummy
);
2116 if (declarator
== NULL
)
2118 if (omp_declare_simd_clauses
.exists ())
2119 c_finish_omp_declare_simd (parser
, NULL_TREE
, NULL_TREE
,
2120 omp_declare_simd_clauses
);
2121 if (oacc_routine_data
)
2122 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2123 c_parser_skip_to_end_of_block_or_statement (parser
);
2126 if (auto_type_p
&& declarator
->kind
!= cdk_id
)
2129 "%<__auto_type%> requires a plain identifier"
2131 c_parser_skip_to_end_of_block_or_statement (parser
);
2134 if (c_parser_next_token_is (parser
, CPP_EQ
)
2135 || c_parser_next_token_is (parser
, CPP_COMMA
)
2136 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
2137 || c_parser_next_token_is_keyword (parser
, RID_ASM
)
2138 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
)
2139 || c_parser_next_token_is_keyword (parser
, RID_IN
))
2141 tree asm_name
= NULL_TREE
;
2142 tree postfix_attrs
= NULL_TREE
;
2143 if (!diagnosed_no_specs
&& !specs
->declspecs_seen_p
)
2145 diagnosed_no_specs
= true;
2146 pedwarn (here
, 0, "data definition has no type or storage class");
2148 /* Having seen a data definition, there cannot now be a
2149 function definition. */
2151 if (c_parser_next_token_is_keyword (parser
, RID_ASM
))
2152 asm_name
= c_parser_simple_asm_expr (parser
);
2153 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2155 postfix_attrs
= c_parser_gnu_attributes (parser
);
2156 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2158 /* This means there is an attribute specifier after
2159 the declarator in a function definition. Provide
2160 some more information for the user. */
2161 error_at (here
, "attributes should be specified before the "
2162 "declarator in a function definition");
2163 c_parser_skip_to_end_of_block_or_statement (parser
);
2167 if (c_parser_next_token_is (parser
, CPP_EQ
))
2171 location_t init_loc
;
2172 c_parser_consume_token (parser
);
2175 init_loc
= c_parser_peek_token (parser
)->location
;
2176 rich_location
richloc (line_table
, init_loc
);
2177 start_init (NULL_TREE
, asm_name
, global_bindings_p (), &richloc
);
2178 /* A parameter is initialized, which is invalid. Don't
2179 attempt to instrument the initializer. */
2180 int flag_sanitize_save
= flag_sanitize
;
2181 if (nested
&& !empty_ok
)
2183 init
= c_parser_expr_no_commas (parser
, NULL
);
2184 flag_sanitize
= flag_sanitize_save
;
2185 if (TREE_CODE (init
.value
) == COMPONENT_REF
2186 && DECL_C_BIT_FIELD (TREE_OPERAND (init
.value
, 1)))
2188 "%<__auto_type%> used with a bit-field"
2190 init
= convert_lvalue_to_rvalue (init_loc
, init
, true, true);
2191 tree init_type
= TREE_TYPE (init
.value
);
2192 /* As with typeof, remove all qualifiers from atomic types. */
2193 if (init_type
!= error_mark_node
&& TYPE_ATOMIC (init_type
))
2195 = c_build_qualified_type (init_type
, TYPE_UNQUALIFIED
);
2196 bool vm_type
= variably_modified_type_p (init_type
,
2199 init
.value
= save_expr (init
.value
);
2201 specs
->typespec_kind
= ctsk_typeof
;
2202 specs
->locations
[cdw_typedef
] = init_loc
;
2203 specs
->typedef_p
= true;
2204 specs
->type
= init_type
;
2207 bool maybe_const
= true;
2208 tree type_expr
= c_fully_fold (init
.value
, false,
2210 specs
->expr_const_operands
&= maybe_const
;
2212 specs
->expr
= build2 (COMPOUND_EXPR
,
2213 TREE_TYPE (type_expr
),
2214 specs
->expr
, type_expr
);
2216 specs
->expr
= type_expr
;
2218 d
= start_decl (declarator
, specs
, true,
2219 chainon (postfix_attrs
, all_prefix_attrs
));
2221 d
= error_mark_node
;
2222 if (omp_declare_simd_clauses
.exists ())
2223 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2224 omp_declare_simd_clauses
);
2228 /* The declaration of the variable is in effect while
2229 its initializer is parsed. */
2230 d
= start_decl (declarator
, specs
, true,
2231 chainon (postfix_attrs
, all_prefix_attrs
));
2233 d
= error_mark_node
;
2234 if (omp_declare_simd_clauses
.exists ())
2235 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2236 omp_declare_simd_clauses
);
2237 init_loc
= c_parser_peek_token (parser
)->location
;
2238 rich_location
richloc (line_table
, init_loc
);
2239 start_init (d
, asm_name
, global_bindings_p (), &richloc
);
2240 /* A parameter is initialized, which is invalid. Don't
2241 attempt to instrument the initializer. */
2242 int flag_sanitize_save
= flag_sanitize
;
2243 if (TREE_CODE (d
) == PARM_DECL
)
2245 init
= c_parser_initializer (parser
);
2246 flag_sanitize
= flag_sanitize_save
;
2249 if (oacc_routine_data
)
2250 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2251 if (d
!= error_mark_node
)
2253 maybe_warn_string_init (init_loc
, TREE_TYPE (d
), init
);
2254 finish_decl (d
, init_loc
, init
.value
,
2255 init
.original_type
, asm_name
);
2263 "%<__auto_type%> requires an initialized "
2264 "data declaration");
2265 c_parser_skip_to_end_of_block_or_statement (parser
);
2268 tree d
= start_decl (declarator
, specs
, false,
2269 chainon (postfix_attrs
,
2272 && TREE_CODE (d
) == FUNCTION_DECL
2273 && DECL_ARGUMENTS (d
) == NULL_TREE
2274 && DECL_INITIAL (d
) == NULL_TREE
)
2276 /* Find the innermost declarator that is neither cdk_id
2278 const struct c_declarator
*decl
= declarator
;
2279 const struct c_declarator
*last_non_id_attrs
= NULL
;
2287 last_non_id_attrs
= decl
;
2288 decl
= decl
->declarator
;
2292 decl
= decl
->declarator
;
2303 /* If it exists and is cdk_function, use its parameters. */
2304 if (last_non_id_attrs
2305 && last_non_id_attrs
->kind
== cdk_function
)
2306 DECL_ARGUMENTS (d
) = last_non_id_attrs
->u
.arg_info
->parms
;
2308 if (omp_declare_simd_clauses
.exists ())
2310 tree parms
= NULL_TREE
;
2311 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2313 struct c_declarator
*ce
= declarator
;
2315 if (ce
->kind
== cdk_function
)
2317 parms
= ce
->u
.arg_info
->parms
;
2321 ce
= ce
->declarator
;
2324 temp_store_parm_decls (d
, parms
);
2325 c_finish_omp_declare_simd (parser
, d
, parms
,
2326 omp_declare_simd_clauses
);
2328 temp_pop_parm_decls ();
2330 if (oacc_routine_data
)
2331 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2333 finish_decl (d
, UNKNOWN_LOCATION
, NULL_TREE
,
2334 NULL_TREE
, asm_name
);
2336 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2339 *objc_foreach_object_declaration
= d
;
2341 *objc_foreach_object_declaration
= error_mark_node
;
2344 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2349 "%<__auto_type%> may only be used with"
2350 " a single declarator");
2351 c_parser_skip_to_end_of_block_or_statement (parser
);
2354 c_parser_consume_token (parser
);
2355 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2356 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
2359 all_prefix_attrs
= prefix_attrs
;
2362 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2364 c_parser_consume_token (parser
);
2367 else if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2369 /* This can only happen in Objective-C: we found the
2370 'in' that terminates the declaration inside an
2371 Objective-C foreach statement. Do not consume the
2372 token, so that the caller can use it to determine
2373 that this indeed is a foreach context. */
2378 c_parser_error (parser
, "expected %<,%> or %<;%>");
2379 c_parser_skip_to_end_of_block_or_statement (parser
);
2383 else if (auto_type_p
)
2386 "%<__auto_type%> requires an initialized data declaration");
2387 c_parser_skip_to_end_of_block_or_statement (parser
);
2392 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, "
2393 "%<asm%> or %<__attribute__%>");
2394 c_parser_skip_to_end_of_block_or_statement (parser
);
2397 /* Function definition (nested or otherwise). */
2400 pedwarn (here
, OPT_Wpedantic
, "ISO C forbids nested functions");
2401 c_push_function_context ();
2403 if (!start_function (specs
, declarator
, all_prefix_attrs
))
2405 /* At this point we've consumed:
2406 declaration-specifiers declarator
2407 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2408 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2410 declaration-specifiers declarator
2411 aren't grokkable as a function definition, so we have
2413 gcc_assert (!c_parser_next_token_is (parser
, CPP_SEMICOLON
));
2414 if (c_parser_next_token_starts_declspecs (parser
))
2417 declaration-specifiers declarator decl-specs
2418 then assume we have a missing semicolon, which would
2420 declaration-specifiers declarator decl-specs
2423 <~~~~~~~~~ declaration ~~~~~~~~~~>
2424 Use c_parser_require to get an error with a fix-it hint. */
2425 c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>");
2426 parser
->error
= false;
2430 /* This can appear in many cases looking nothing like a
2431 function definition, so we don't give a more specific
2432 error suggesting there was one. */
2433 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2434 "or %<__attribute__%>");
2437 c_pop_function_context ();
2441 if (DECL_DECLARED_INLINE_P (current_function_decl
))
2442 tv
= TV_PARSE_INLINE
;
2445 auto_timevar
at (g_timer
, tv
);
2447 /* Parse old-style parameter declarations. ??? Attributes are
2448 not allowed to start declaration specifiers here because of a
2449 syntax conflict between a function declaration with attribute
2450 suffix and a function definition with an attribute prefix on
2451 first old-style parameter declaration. Following the old
2452 parser, they are not accepted on subsequent old-style
2453 parameter declarations either. However, there is no
2454 ambiguity after the first declaration, nor indeed on the
2455 first as long as we don't allow postfix attributes after a
2456 declarator with a nonempty identifier list in a definition;
2457 and postfix attributes have never been accepted here in
2458 function definitions either. */
2459 while (c_parser_next_token_is_not (parser
, CPP_EOF
)
2460 && c_parser_next_token_is_not (parser
, CPP_OPEN_BRACE
))
2461 c_parser_declaration_or_fndef (parser
, false, false, false,
2462 true, false, NULL
, vNULL
);
2463 store_parm_decls ();
2464 if (omp_declare_simd_clauses
.exists ())
2465 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2466 omp_declare_simd_clauses
);
2467 if (oacc_routine_data
)
2468 c_finish_oacc_routine (oacc_routine_data
, current_function_decl
, true);
2469 DECL_STRUCT_FUNCTION (current_function_decl
)->function_start_locus
2470 = c_parser_peek_token (parser
)->location
;
2472 /* If the definition was marked with __RTL, use the RTL parser now,
2473 consuming the function body. */
2474 if (specs
->declspec_il
== cdil_rtl
)
2476 c_parser_parse_rtl_body (parser
, specs
->gimple_or_rtl_pass
);
2478 /* Normally, store_parm_decls sets next_is_function_body,
2479 anticipating a function body. We need a push_scope/pop_scope
2480 pair to flush out this state, or subsequent function parsing
2488 /* If the definition was marked with __GIMPLE then parse the
2489 function body as GIMPLE. */
2490 else if (specs
->declspec_il
!= cdil_none
)
2492 bool saved
= in_late_binary_op
;
2493 in_late_binary_op
= true;
2494 c_parser_parse_gimple_body (parser
, specs
->gimple_or_rtl_pass
,
2496 specs
->entry_bb_count
);
2497 in_late_binary_op
= saved
;
2500 fnbody
= c_parser_compound_statement (parser
);
2501 tree fndecl
= current_function_decl
;
2504 tree decl
= current_function_decl
;
2505 /* Mark nested functions as needing static-chain initially.
2506 lower_nested_functions will recompute it but the
2507 DECL_STATIC_CHAIN flag is also used before that happens,
2508 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2509 DECL_STATIC_CHAIN (decl
) = 1;
2512 c_pop_function_context ();
2513 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl
), DECL_EXPR
, decl
));
2521 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2522 if (specs
->declspec_il
!= cdil_none
)
2523 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
2529 /* Parse an asm-definition (asm() outside a function body). This is a
2537 c_parser_asm_definition (c_parser
*parser
)
2539 tree asm_str
= c_parser_simple_asm_expr (parser
);
2541 symtab
->finalize_toplevel_asm (asm_str
);
2542 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
2545 /* Parse a static assertion (C11 6.7.10).
2547 static_assert-declaration:
2548 static_assert-declaration-no-semi ;
2552 c_parser_static_assert_declaration (c_parser
*parser
)
2554 c_parser_static_assert_declaration_no_semi (parser
);
2556 || !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
2557 c_parser_skip_to_end_of_block_or_statement (parser
);
2560 /* Parse a static assertion (C11 6.7.10), without the trailing
2563 static_assert-declaration-no-semi:
2564 _Static_assert ( constant-expression , string-literal )
2567 static_assert-declaration-no-semi:
2568 _Static_assert ( constant-expression )
2572 c_parser_static_assert_declaration_no_semi (c_parser
*parser
)
2574 location_t assert_loc
, value_loc
;
2576 tree string
= NULL_TREE
;
2578 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
));
2579 assert_loc
= c_parser_peek_token (parser
)->location
;
2581 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2582 "ISO C99 does not support %<_Static_assert%>");
2584 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2585 "ISO C90 does not support %<_Static_assert%>");
2586 c_parser_consume_token (parser
);
2587 matching_parens parens
;
2588 if (!parens
.require_open (parser
))
2590 location_t value_tok_loc
= c_parser_peek_token (parser
)->location
;
2591 value
= c_parser_expr_no_commas (parser
, NULL
).value
;
2592 value_loc
= EXPR_LOC_OR_LOC (value
, value_tok_loc
);
2593 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2595 c_parser_consume_token (parser
);
2596 switch (c_parser_peek_token (parser
)->type
)
2602 case CPP_UTF8STRING
:
2603 string
= c_parser_string_literal (parser
, false, true).value
;
2606 c_parser_error (parser
, "expected string literal");
2610 else if (flag_isoc11
)
2611 /* If pedantic for pre-C11, the use of _Static_assert itself will
2612 have been diagnosed, so do not also diagnose the use of this
2613 new C2X feature of _Static_assert. */
2614 pedwarn_c11 (assert_loc
, OPT_Wpedantic
,
2615 "ISO C11 does not support omitting the string in "
2616 "%<_Static_assert%>");
2617 parens
.require_close (parser
);
2619 if (!INTEGRAL_TYPE_P (TREE_TYPE (value
)))
2621 error_at (value_loc
, "expression in static assertion is not an integer");
2624 if (TREE_CODE (value
) != INTEGER_CST
)
2626 value
= c_fully_fold (value
, false, NULL
);
2627 /* Strip no-op conversions. */
2628 STRIP_TYPE_NOPS (value
);
2629 if (TREE_CODE (value
) == INTEGER_CST
)
2630 pedwarn (value_loc
, OPT_Wpedantic
, "expression in static assertion "
2631 "is not an integer constant expression");
2633 if (TREE_CODE (value
) != INTEGER_CST
)
2635 error_at (value_loc
, "expression in static assertion is not constant");
2638 constant_expression_warning (value
);
2639 if (integer_zerop (value
))
2642 error_at (assert_loc
, "static assertion failed: %E", string
);
2644 error_at (assert_loc
, "static assertion failed");
2648 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2649 6.7, C11 6.7), adding them to SPECS (which may already include some).
2650 Storage class specifiers are accepted iff SCSPEC_OK; type
2651 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2652 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2653 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2654 addition to the syntax shown, standard attributes are accepted at
2655 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2656 unlike gnu-attributes, they are not accepted in the middle of the
2657 list. (This combines various different syntax productions in the C
2658 standard, and in some cases gnu-attributes and standard attributes
2659 at the start may already have been parsed before this function is
2662 declaration-specifiers:
2663 storage-class-specifier declaration-specifiers[opt]
2664 type-specifier declaration-specifiers[opt]
2665 type-qualifier declaration-specifiers[opt]
2666 function-specifier declaration-specifiers[opt]
2667 alignment-specifier declaration-specifiers[opt]
2669 Function specifiers (inline) are from C99, and are currently
2670 handled as storage class specifiers, as is __thread. Alignment
2671 specifiers are from C11.
2673 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2674 storage-class-specifier:
2682 (_Thread_local is new in C11.)
2684 C99 6.7.4, C11 6.7.4:
2689 (_Noreturn is new in C11.)
2691 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2704 [_Imaginary removed in C99 TC2]
2705 struct-or-union-specifier
2708 atomic-type-specifier
2710 (_Bool and _Complex are new in C99.)
2711 (atomic-type-specifier is new in C11.)
2713 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2719 address-space-qualifier
2722 (restrict is new in C99.)
2723 (_Atomic is new in C11.)
2727 declaration-specifiers:
2728 gnu-attributes declaration-specifiers[opt]
2734 identifier recognized by the target
2736 storage-class-specifier:
2750 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2751 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2753 atomic-type-specifier
2754 _Atomic ( type-name )
2759 class-name objc-protocol-refs[opt]
2760 typedef-name objc-protocol-refs
2765 c_parser_declspecs (c_parser
*parser
, struct c_declspecs
*specs
,
2766 bool scspec_ok
, bool typespec_ok
, bool start_attr_ok
,
2767 bool alignspec_ok
, bool auto_type_ok
,
2768 bool start_std_attr_ok
, bool end_std_attr_ok
,
2769 enum c_lookahead_kind la
)
2771 bool attrs_ok
= start_attr_ok
;
2772 bool seen_type
= specs
->typespec_kind
!= ctsk_none
;
2775 gcc_assert (la
== cla_prefer_id
);
2777 if (start_std_attr_ok
2778 && c_parser_nth_token_starts_std_attributes (parser
, 1))
2780 gcc_assert (!specs
->non_std_attrs_seen_p
);
2781 location_t loc
= c_parser_peek_token (parser
)->location
;
2782 tree attrs
= c_parser_std_attribute_specifier_sequence (parser
);
2783 declspecs_add_attrs (loc
, specs
, attrs
);
2784 specs
->non_std_attrs_seen_p
= false;
2787 while (c_parser_next_token_is (parser
, CPP_NAME
)
2788 || c_parser_next_token_is (parser
, CPP_KEYWORD
)
2789 || (c_dialect_objc () && c_parser_next_token_is (parser
, CPP_LESS
)))
2791 struct c_typespec t
;
2794 location_t loc
= c_parser_peek_token (parser
)->location
;
2796 /* If we cannot accept a type, exit if the next token must start
2797 one. Also, if we already have seen a tagged definition,
2798 a typename would be an error anyway and likely the user
2799 has simply forgotten a semicolon, so we exit. */
2800 if ((!typespec_ok
|| specs
->typespec_kind
== ctsk_tagdef
)
2801 && c_parser_next_tokens_start_typename (parser
, la
)
2802 && !c_parser_next_token_is_qualifier (parser
)
2803 && !c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
))
2806 if (c_parser_next_token_is (parser
, CPP_NAME
))
2808 c_token
*name_token
= c_parser_peek_token (parser
);
2809 tree value
= name_token
->value
;
2810 c_id_kind kind
= name_token
->id_kind
;
2812 if (kind
== C_ID_ADDRSPACE
)
2815 = name_token
->keyword
- RID_FIRST_ADDR_SPACE
;
2816 declspecs_add_addrspace (name_token
->location
, specs
, as
);
2817 c_parser_consume_token (parser
);
2822 gcc_assert (!c_parser_next_token_is_qualifier (parser
));
2824 /* If we cannot accept a type, and the next token must start one,
2825 exit. Do the same if we already have seen a tagged definition,
2826 since it would be an error anyway and likely the user has simply
2827 forgotten a semicolon. */
2828 if (seen_type
|| !c_parser_next_tokens_start_typename (parser
, la
))
2831 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2832 a C_ID_CLASSNAME. */
2833 c_parser_consume_token (parser
);
2836 if (kind
== C_ID_ID
)
2838 error_at (loc
, "unknown type name %qE", value
);
2839 t
.kind
= ctsk_typedef
;
2840 t
.spec
= error_mark_node
;
2842 else if (kind
== C_ID_TYPENAME
2843 && (!c_dialect_objc ()
2844 || c_parser_next_token_is_not (parser
, CPP_LESS
)))
2846 t
.kind
= ctsk_typedef
;
2847 /* For a typedef name, record the meaning, not the name.
2848 In case of 'foo foo, bar;'. */
2849 t
.spec
= lookup_name (value
);
2853 tree proto
= NULL_TREE
;
2854 gcc_assert (c_dialect_objc ());
2856 if (c_parser_next_token_is (parser
, CPP_LESS
))
2857 proto
= c_parser_objc_protocol_refs (parser
);
2858 t
.spec
= objc_get_protocol_qualified_type (value
, proto
);
2861 t
.expr_const_operands
= true;
2862 declspecs_add_type (name_token
->location
, specs
, t
);
2865 if (c_parser_next_token_is (parser
, CPP_LESS
))
2867 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2868 nisse@lysator.liu.se. */
2870 gcc_assert (c_dialect_objc ());
2871 if (!typespec_ok
|| seen_type
)
2873 proto
= c_parser_objc_protocol_refs (parser
);
2875 t
.spec
= objc_get_protocol_qualified_type (NULL_TREE
, proto
);
2877 t
.expr_const_operands
= true;
2878 declspecs_add_type (loc
, specs
, t
);
2881 gcc_assert (c_parser_next_token_is (parser
, CPP_KEYWORD
));
2882 switch (c_parser_peek_token (parser
)->keyword
)
2895 /* TODO: Distinguish between function specifiers (inline, noreturn)
2896 and storage class specifiers, either here or in
2897 declspecs_add_scspec. */
2898 declspecs_add_scspec (loc
, specs
,
2899 c_parser_peek_token (parser
)->value
);
2900 c_parser_consume_token (parser
);
2932 if (c_dialect_objc ())
2933 parser
->objc_need_raw_identifier
= true;
2934 t
.kind
= ctsk_resword
;
2935 t
.spec
= c_parser_peek_token (parser
)->value
;
2937 t
.expr_const_operands
= true;
2938 declspecs_add_type (loc
, specs
, t
);
2939 c_parser_consume_token (parser
);
2946 t
= c_parser_enum_specifier (parser
);
2947 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
2948 declspecs_add_type (loc
, specs
, t
);
2956 t
= c_parser_struct_or_union_specifier (parser
);
2957 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
2958 declspecs_add_type (loc
, specs
, t
);
2961 /* ??? The old parser rejected typeof after other type
2962 specifiers, but is a syntax error the best way of
2964 if (!typespec_ok
|| seen_type
)
2968 t
= c_parser_typeof_specifier (parser
);
2969 declspecs_add_type (loc
, specs
, t
);
2972 /* C parser handling of Objective-C constructs needs
2973 checking for correct lvalue-to-rvalue conversions, and
2974 the code in build_modify_expr handling various
2975 Objective-C cases, and that in build_unary_op handling
2976 Objective-C cases for increment / decrement, also needs
2977 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
2978 and objc_types_are_equivalent may also need updates. */
2979 if (c_dialect_objc ())
2980 sorry ("%<_Atomic%> in Objective-C");
2982 pedwarn_c99 (loc
, OPT_Wpedantic
,
2983 "ISO C99 does not support the %<_Atomic%> qualifier");
2985 pedwarn_c99 (loc
, OPT_Wpedantic
,
2986 "ISO C90 does not support the %<_Atomic%> qualifier");
2989 value
= c_parser_peek_token (parser
)->value
;
2990 c_parser_consume_token (parser
);
2991 if (typespec_ok
&& c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
2993 /* _Atomic ( type-name ). */
2995 c_parser_consume_token (parser
);
2996 struct c_type_name
*type
= c_parser_type_name (parser
);
2997 t
.kind
= ctsk_typeof
;
2998 t
.spec
= error_mark_node
;
3000 t
.expr_const_operands
= true;
3002 t
.spec
= groktypename (type
, &t
.expr
,
3003 &t
.expr_const_operands
);
3004 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3006 if (t
.spec
!= error_mark_node
)
3008 if (TREE_CODE (t
.spec
) == ARRAY_TYPE
)
3009 error_at (loc
, "%<_Atomic%>-qualified array type");
3010 else if (TREE_CODE (t
.spec
) == FUNCTION_TYPE
)
3011 error_at (loc
, "%<_Atomic%>-qualified function type");
3012 else if (TYPE_QUALS (t
.spec
) != TYPE_UNQUALIFIED
)
3013 error_at (loc
, "%<_Atomic%> applied to a qualified type");
3015 t
.spec
= c_build_qualified_type (t
.spec
, TYPE_QUAL_ATOMIC
);
3017 declspecs_add_type (loc
, specs
, t
);
3020 declspecs_add_qual (loc
, specs
, value
);
3026 declspecs_add_qual (loc
, specs
, c_parser_peek_token (parser
)->value
);
3027 c_parser_consume_token (parser
);
3032 attrs
= c_parser_gnu_attributes (parser
);
3033 declspecs_add_attrs (loc
, specs
, attrs
);
3038 align
= c_parser_alignas_specifier (parser
);
3039 declspecs_add_alignas (loc
, specs
, align
);
3043 error_at (loc
, "%<__GIMPLE%> only valid with %<-fgimple%>");
3044 c_parser_consume_token (parser
);
3045 specs
->declspec_il
= cdil_gimple
;
3046 specs
->locations
[cdw_gimple
] = loc
;
3047 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3050 c_parser_consume_token (parser
);
3051 specs
->declspec_il
= cdil_rtl
;
3052 specs
->locations
[cdw_rtl
] = loc
;
3053 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3061 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3062 specs
->postfix_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3065 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3068 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3070 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3072 enum gnu-attributes[opt] identifier
3074 The form with trailing comma is new in C99. The forms with
3075 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3076 without commas in the syntax (assignment expressions, not just
3077 conditional expressions); assignment expressions will be diagnosed
3082 enumerator-list , enumerator
3085 enumeration-constant attribute-specifier-sequence[opt]
3086 enumeration-constant attribute-specifier-sequence[opt]
3087 = constant-expression
3092 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3093 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3094 = constant-expression
3098 static struct c_typespec
3099 c_parser_enum_specifier (c_parser
*parser
)
3101 struct c_typespec ret
;
3102 bool have_std_attrs
;
3103 tree std_attrs
= NULL_TREE
;
3105 tree ident
= NULL_TREE
;
3106 location_t enum_loc
;
3107 location_t ident_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3108 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ENUM
));
3109 c_parser_consume_token (parser
);
3110 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3112 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3113 attrs
= c_parser_gnu_attributes (parser
);
3114 enum_loc
= c_parser_peek_token (parser
)->location
;
3115 /* Set the location in case we create a decl now. */
3116 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3117 if (c_parser_next_token_is (parser
, CPP_NAME
))
3119 ident
= c_parser_peek_token (parser
)->value
;
3120 ident_loc
= c_parser_peek_token (parser
)->location
;
3121 enum_loc
= ident_loc
;
3122 c_parser_consume_token (parser
);
3124 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3126 /* Parse an enum definition. */
3127 struct c_enum_contents the_enum
;
3130 /* We chain the enumerators in reverse order, then put them in
3131 forward order at the end. */
3133 timevar_push (TV_PARSE_ENUM
);
3134 type
= start_enum (enum_loc
, &the_enum
, ident
);
3136 c_parser_consume_token (parser
);
3144 location_t comma_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3145 location_t decl_loc
, value_loc
;
3146 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
3148 /* Give a nicer error for "enum {}". */
3149 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3152 error_at (c_parser_peek_token (parser
)->location
,
3153 "empty enum is invalid");
3154 parser
->error
= true;
3157 c_parser_error (parser
, "expected identifier");
3158 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3159 values
= error_mark_node
;
3162 token
= c_parser_peek_token (parser
);
3163 enum_id
= token
->value
;
3164 /* Set the location in case we create a decl now. */
3165 c_parser_set_source_position_from_token (token
);
3166 decl_loc
= value_loc
= token
->location
;
3167 c_parser_consume_token (parser
);
3168 /* Parse any specified attributes. */
3169 tree std_attrs
= NULL_TREE
;
3170 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3171 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3172 tree enum_attrs
= chainon (std_attrs
,
3173 c_parser_gnu_attributes (parser
));
3174 if (c_parser_next_token_is (parser
, CPP_EQ
))
3176 c_parser_consume_token (parser
);
3177 value_loc
= c_parser_peek_token (parser
)->location
;
3178 enum_value
= c_parser_expr_no_commas (parser
, NULL
).value
;
3181 enum_value
= NULL_TREE
;
3182 enum_decl
= build_enumerator (decl_loc
, value_loc
,
3183 &the_enum
, enum_id
, enum_value
);
3185 decl_attributes (&TREE_PURPOSE (enum_decl
), enum_attrs
, 0);
3186 TREE_CHAIN (enum_decl
) = values
;
3189 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3191 comma_loc
= c_parser_peek_token (parser
)->location
;
3193 c_parser_consume_token (parser
);
3195 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3198 pedwarn_c90 (comma_loc
, OPT_Wpedantic
,
3199 "comma at end of enumerator list");
3200 c_parser_consume_token (parser
);
3205 c_parser_error (parser
, "expected %<,%> or %<}%>");
3206 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3207 values
= error_mark_node
;
3211 postfix_attrs
= c_parser_gnu_attributes (parser
);
3212 ret
.spec
= finish_enum (type
, nreverse (values
),
3214 chainon (attrs
, postfix_attrs
)));
3215 ret
.kind
= ctsk_tagdef
;
3216 ret
.expr
= NULL_TREE
;
3217 ret
.expr_const_operands
= true;
3218 timevar_pop (TV_PARSE_ENUM
);
3223 c_parser_error (parser
, "expected %<{%>");
3224 ret
.spec
= error_mark_node
;
3225 ret
.kind
= ctsk_tagref
;
3226 ret
.expr
= NULL_TREE
;
3227 ret
.expr_const_operands
= true;
3230 /* Attributes may only appear when the members are defined or in
3231 certain forward declarations (treat enum forward declarations in
3232 GNU C analogously to struct and union forward declarations in
3234 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3235 c_parser_error (parser
, "expected %<;%>");
3236 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
, have_std_attrs
,
3238 /* In ISO C, enumerated types can be referred to only if already
3240 if (pedantic
&& !COMPLETE_TYPE_P (ret
.spec
))
3243 pedwarn (enum_loc
, OPT_Wpedantic
,
3244 "ISO C forbids forward references to %<enum%> types");
3249 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3251 struct-or-union-specifier:
3252 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3253 identifier[opt] { struct-contents } gnu-attributes[opt]
3254 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3258 struct-declaration-list
3260 struct-declaration-list:
3261 struct-declaration ;
3262 struct-declaration-list struct-declaration ;
3269 struct-declaration-list struct-declaration
3271 struct-declaration-list:
3272 struct-declaration-list ;
3275 (Note that in the syntax here, unlike that in ISO C, the semicolons
3276 are included here rather than in struct-declaration, in order to
3277 describe the syntax with extra semicolons and missing semicolon at
3282 struct-declaration-list:
3283 @defs ( class-name )
3285 (Note this does not include a trailing semicolon, but can be
3286 followed by further declarations, and gets a pedwarn-if-pedantic
3287 when followed by a semicolon.) */
3289 static struct c_typespec
3290 c_parser_struct_or_union_specifier (c_parser
*parser
)
3292 struct c_typespec ret
;
3293 bool have_std_attrs
;
3294 tree std_attrs
= NULL_TREE
;
3296 tree ident
= NULL_TREE
;
3297 location_t struct_loc
;
3298 location_t ident_loc
= UNKNOWN_LOCATION
;
3299 enum tree_code code
;
3300 switch (c_parser_peek_token (parser
)->keyword
)
3311 struct_loc
= c_parser_peek_token (parser
)->location
;
3312 c_parser_consume_token (parser
);
3313 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3315 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3316 attrs
= c_parser_gnu_attributes (parser
);
3318 /* Set the location in case we create a decl now. */
3319 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3321 if (c_parser_next_token_is (parser
, CPP_NAME
))
3323 ident
= c_parser_peek_token (parser
)->value
;
3324 ident_loc
= c_parser_peek_token (parser
)->location
;
3325 struct_loc
= ident_loc
;
3326 c_parser_consume_token (parser
);
3328 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3330 /* Parse a struct or union definition. Start the scope of the
3331 tag before parsing components. */
3332 class c_struct_parse_info
*struct_info
;
3333 tree type
= start_struct (struct_loc
, code
, ident
, &struct_info
);
3335 /* We chain the components in reverse order, then put them in
3336 forward order at the end. Each struct-declaration may
3337 declare multiple components (comma-separated), so we must use
3338 chainon to join them, although when parsing each
3339 struct-declaration we can use TREE_CHAIN directly.
3341 The theory behind all this is that there will be more
3342 semicolon separated fields than comma separated fields, and
3343 so we'll be minimizing the number of node traversals required
3346 timevar_push (TV_PARSE_STRUCT
);
3347 contents
= NULL_TREE
;
3348 c_parser_consume_token (parser
);
3349 /* Handle the Objective-C @defs construct,
3350 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3351 if (c_parser_next_token_is_keyword (parser
, RID_AT_DEFS
))
3354 gcc_assert (c_dialect_objc ());
3355 c_parser_consume_token (parser
);
3356 matching_parens parens
;
3357 if (!parens
.require_open (parser
))
3359 if (c_parser_next_token_is (parser
, CPP_NAME
)
3360 && c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
)
3362 name
= c_parser_peek_token (parser
)->value
;
3363 c_parser_consume_token (parser
);
3367 c_parser_error (parser
, "expected class name");
3368 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
3371 parens
.skip_until_found_close (parser
);
3372 contents
= nreverse (objc_get_class_ivars (name
));
3375 /* Parse the struct-declarations and semicolons. Problems with
3376 semicolons are diagnosed here; empty structures are diagnosed
3381 /* Parse any stray semicolon. */
3382 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3384 location_t semicolon_loc
3385 = c_parser_peek_token (parser
)->location
;
3386 gcc_rich_location
richloc (semicolon_loc
);
3387 richloc
.add_fixit_remove ();
3388 pedwarn (&richloc
, OPT_Wpedantic
,
3389 "extra semicolon in struct or union specified");
3390 c_parser_consume_token (parser
);
3393 /* Stop if at the end of the struct or union contents. */
3394 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3396 c_parser_consume_token (parser
);
3399 /* Accept #pragmas at struct scope. */
3400 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
3402 c_parser_pragma (parser
, pragma_struct
, NULL
);
3405 /* Parse some comma-separated declarations, but not the
3406 trailing semicolon if any. */
3407 decls
= c_parser_struct_declaration (parser
);
3408 contents
= chainon (decls
, contents
);
3409 /* If no semicolon follows, either we have a parse error or
3410 are at the end of the struct or union and should
3412 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3413 c_parser_consume_token (parser
);
3416 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3417 pedwarn (c_parser_peek_token (parser
)->location
, 0,
3418 "no semicolon at end of struct or union");
3419 else if (parser
->error
3420 || !c_parser_next_token_starts_declspecs (parser
))
3422 c_parser_error (parser
, "expected %<;%>");
3423 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3427 /* If we come here, we have already emitted an error
3428 for an expected `;', identifier or `(', and we also
3429 recovered already. Go on with the next field. */
3432 postfix_attrs
= c_parser_gnu_attributes (parser
);
3433 ret
.spec
= finish_struct (struct_loc
, type
, nreverse (contents
),
3435 chainon (attrs
, postfix_attrs
)),
3437 ret
.kind
= ctsk_tagdef
;
3438 ret
.expr
= NULL_TREE
;
3439 ret
.expr_const_operands
= true;
3440 timevar_pop (TV_PARSE_STRUCT
);
3445 c_parser_error (parser
, "expected %<{%>");
3446 ret
.spec
= error_mark_node
;
3447 ret
.kind
= ctsk_tagref
;
3448 ret
.expr
= NULL_TREE
;
3449 ret
.expr_const_operands
= true;
3452 /* Attributes may only appear when the members are defined or in
3453 certain forward declarations. */
3454 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3455 c_parser_error (parser
, "expected %<;%>");
3456 /* ??? Existing practice is that GNU attributes are ignored after
3457 the struct or union keyword when not defining the members. */
3458 ret
= parser_xref_tag (ident_loc
, code
, ident
, have_std_attrs
, std_attrs
);
3462 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3463 *without* the trailing semicolon.
3466 attribute-specifier-sequence[opt] specifier-qualifier-list
3467 attribute-specifier-sequence[opt] struct-declarator-list
3468 static_assert-declaration-no-semi
3470 specifier-qualifier-list:
3471 type-specifier specifier-qualifier-list[opt]
3472 type-qualifier specifier-qualifier-list[opt]
3473 alignment-specifier specifier-qualifier-list[opt]
3474 gnu-attributes specifier-qualifier-list[opt]
3476 struct-declarator-list:
3478 struct-declarator-list , gnu-attributes[opt] struct-declarator
3481 declarator gnu-attributes[opt]
3482 declarator[opt] : constant-expression gnu-attributes[opt]
3487 __extension__ struct-declaration
3488 specifier-qualifier-list
3490 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3491 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3492 any expression without commas in the syntax (assignment
3493 expressions, not just conditional expressions); assignment
3494 expressions will be diagnosed as non-constant. */
3497 c_parser_struct_declaration (c_parser
*parser
)
3499 struct c_declspecs
*specs
;
3501 tree all_prefix_attrs
;
3503 location_t decl_loc
;
3504 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
3508 ext
= disable_extension_diagnostics ();
3509 c_parser_consume_token (parser
);
3510 decl
= c_parser_struct_declaration (parser
);
3511 restore_extension_diagnostics (ext
);
3514 if (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
3516 c_parser_static_assert_declaration_no_semi (parser
);
3519 specs
= build_null_declspecs ();
3520 decl_loc
= c_parser_peek_token (parser
)->location
;
3521 /* Strictly by the standard, we shouldn't allow _Alignas here,
3522 but it appears to have been intended to allow it there, so
3523 we're keeping it as it is until WG14 reaches a conclusion
3525 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3526 c_parser_declspecs (parser
, specs
, false, true, true,
3527 true, false, true, true, cla_nonabstract_decl
);
3530 if (!specs
->declspecs_seen_p
)
3532 c_parser_error (parser
, "expected specifier-qualifier-list");
3535 finish_declspecs (specs
);
3536 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3537 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3540 if (specs
->typespec_kind
== ctsk_none
)
3542 pedwarn (decl_loc
, OPT_Wpedantic
,
3543 "ISO C forbids member declarations with no members");
3544 shadow_tag_warned (specs
, pedantic
);
3549 /* Support for unnamed structs or unions as members of
3550 structs or unions (which is [a] useful and [b] supports
3554 ret
= grokfield (c_parser_peek_token (parser
)->location
,
3555 build_id_declarator (NULL_TREE
), specs
,
3558 decl_attributes (&ret
, attrs
, 0);
3563 /* Provide better error recovery. Note that a type name here is valid,
3564 and will be treated as a field name. */
3565 if (specs
->typespec_kind
== ctsk_tagdef
3566 && TREE_CODE (specs
->type
) != ENUMERAL_TYPE
3567 && c_parser_next_token_starts_declspecs (parser
)
3568 && !c_parser_next_token_is (parser
, CPP_NAME
))
3570 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
3571 parser
->error
= false;
3575 pending_xref_error ();
3576 prefix_attrs
= specs
->attrs
;
3577 all_prefix_attrs
= prefix_attrs
;
3578 specs
->attrs
= NULL_TREE
;
3582 /* Declaring one or more declarators or un-named bit-fields. */
3583 struct c_declarator
*declarator
;
3585 if (c_parser_next_token_is (parser
, CPP_COLON
))
3586 declarator
= build_id_declarator (NULL_TREE
);
3588 declarator
= c_parser_declarator (parser
,
3589 specs
->typespec_kind
!= ctsk_none
,
3590 C_DTR_NORMAL
, &dummy
);
3591 if (declarator
== NULL
)
3593 c_parser_skip_to_end_of_block_or_statement (parser
);
3596 if (c_parser_next_token_is (parser
, CPP_COLON
)
3597 || c_parser_next_token_is (parser
, CPP_COMMA
)
3598 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3599 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3600 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3602 tree postfix_attrs
= NULL_TREE
;
3603 tree width
= NULL_TREE
;
3605 if (c_parser_next_token_is (parser
, CPP_COLON
))
3607 c_parser_consume_token (parser
);
3608 width
= c_parser_expr_no_commas (parser
, NULL
).value
;
3610 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3611 postfix_attrs
= c_parser_gnu_attributes (parser
);
3612 d
= grokfield (c_parser_peek_token (parser
)->location
,
3613 declarator
, specs
, width
, &all_prefix_attrs
);
3614 decl_attributes (&d
, chainon (postfix_attrs
,
3615 all_prefix_attrs
), 0);
3616 DECL_CHAIN (d
) = decls
;
3618 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3619 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
3622 all_prefix_attrs
= prefix_attrs
;
3623 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3624 c_parser_consume_token (parser
);
3625 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3626 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3628 /* Semicolon consumed in caller. */
3633 c_parser_error (parser
, "expected %<,%>, %<;%> or %<}%>");
3639 c_parser_error (parser
,
3640 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3641 "%<__attribute__%>");
3648 /* Parse a typeof specifier (a GNU extension).
3651 typeof ( expression )
3652 typeof ( type-name )
3655 static struct c_typespec
3656 c_parser_typeof_specifier (c_parser
*parser
)
3658 struct c_typespec ret
;
3659 ret
.kind
= ctsk_typeof
;
3660 ret
.spec
= error_mark_node
;
3661 ret
.expr
= NULL_TREE
;
3662 ret
.expr_const_operands
= true;
3663 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TYPEOF
));
3664 c_parser_consume_token (parser
);
3665 c_inhibit_evaluation_warnings
++;
3667 matching_parens parens
;
3668 if (!parens
.require_open (parser
))
3670 c_inhibit_evaluation_warnings
--;
3674 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3676 struct c_type_name
*type
= c_parser_type_name (parser
);
3677 c_inhibit_evaluation_warnings
--;
3681 ret
.spec
= groktypename (type
, &ret
.expr
, &ret
.expr_const_operands
);
3682 pop_maybe_used (variably_modified_type_p (ret
.spec
, NULL_TREE
));
3688 location_t here
= c_parser_peek_token (parser
)->location
;
3689 struct c_expr expr
= c_parser_expression (parser
);
3690 c_inhibit_evaluation_warnings
--;
3692 if (TREE_CODE (expr
.value
) == COMPONENT_REF
3693 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
3694 error_at (here
, "%<typeof%> applied to a bit-field");
3695 mark_exp_read (expr
.value
);
3696 ret
.spec
= TREE_TYPE (expr
.value
);
3697 was_vm
= variably_modified_type_p (ret
.spec
, NULL_TREE
);
3698 /* This is returned with the type so that when the type is
3699 evaluated, this can be evaluated. */
3701 ret
.expr
= c_fully_fold (expr
.value
, false, &ret
.expr_const_operands
);
3702 pop_maybe_used (was_vm
);
3703 /* For use in macros such as those in <stdatomic.h>, remove all
3704 qualifiers from atomic types. (const can be an issue for more macros
3705 using typeof than just the <stdatomic.h> ones.) */
3706 if (ret
.spec
!= error_mark_node
&& TYPE_ATOMIC (ret
.spec
))
3707 ret
.spec
= c_build_qualified_type (ret
.spec
, TYPE_UNQUALIFIED
);
3709 parens
.skip_until_found_close (parser
);
3713 /* Parse an alignment-specifier.
3717 alignment-specifier:
3718 _Alignas ( type-name )
3719 _Alignas ( constant-expression )
3723 c_parser_alignas_specifier (c_parser
* parser
)
3725 tree ret
= error_mark_node
;
3726 location_t loc
= c_parser_peek_token (parser
)->location
;
3727 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
));
3728 c_parser_consume_token (parser
);
3730 pedwarn_c99 (loc
, OPT_Wpedantic
,
3731 "ISO C99 does not support %<_Alignas%>");
3733 pedwarn_c99 (loc
, OPT_Wpedantic
,
3734 "ISO C90 does not support %<_Alignas%>");
3735 matching_parens parens
;
3736 if (!parens
.require_open (parser
))
3738 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3740 struct c_type_name
*type
= c_parser_type_name (parser
);
3742 ret
= c_sizeof_or_alignof_type (loc
, groktypename (type
, NULL
, NULL
),
3746 ret
= c_parser_expr_no_commas (parser
, NULL
).value
;
3747 parens
.skip_until_found_close (parser
);
3751 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3752 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3753 a typedef name may be redeclared; otherwise it may not. KIND
3754 indicates which kind of declarator is wanted. Returns a valid
3755 declarator except in the case of a syntax error in which case NULL is
3756 returned. *SEEN_ID is set to true if an identifier being declared is
3757 seen; this is used to diagnose bad forms of abstract array declarators
3758 and to determine whether an identifier list is syntactically permitted.
3761 pointer[opt] direct-declarator
3765 ( gnu-attributes[opt] declarator )
3766 direct-declarator array-declarator
3767 direct-declarator ( parameter-type-list )
3768 direct-declarator ( identifier-list[opt] )
3771 * type-qualifier-list[opt]
3772 * type-qualifier-list[opt] pointer
3774 type-qualifier-list:
3777 type-qualifier-list type-qualifier
3778 type-qualifier-list gnu-attributes
3781 [ type-qualifier-list[opt] assignment-expression[opt] ]
3782 [ static type-qualifier-list[opt] assignment-expression ]
3783 [ type-qualifier-list static assignment-expression ]
3784 [ type-qualifier-list[opt] * ]
3786 parameter-type-list:
3788 parameter-list , ...
3791 parameter-declaration
3792 parameter-list , parameter-declaration
3794 parameter-declaration:
3795 declaration-specifiers declarator gnu-attributes[opt]
3796 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3800 identifier-list , identifier
3802 abstract-declarator:
3804 pointer[opt] direct-abstract-declarator
3806 direct-abstract-declarator:
3807 ( gnu-attributes[opt] abstract-declarator )
3808 direct-abstract-declarator[opt] array-declarator
3809 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3814 direct-declarator ( parameter-forward-declarations
3815 parameter-type-list[opt] )
3817 direct-abstract-declarator:
3818 direct-abstract-declarator[opt] ( parameter-forward-declarations
3819 parameter-type-list[opt] )
3821 parameter-forward-declarations:
3823 parameter-forward-declarations parameter-list ;
3825 The uses of gnu-attributes shown above are GNU extensions.
3827 Some forms of array declarator are not included in C99 in the
3828 syntax for abstract declarators; these are disallowed elsewhere.
3829 This may be a defect (DR#289).
3831 This function also accepts an omitted abstract declarator as being
3832 an abstract declarator, although not part of the formal syntax. */
3834 struct c_declarator
*
3835 c_parser_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3838 /* Parse any initial pointer part. */
3839 if (c_parser_next_token_is (parser
, CPP_MULT
))
3841 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
3842 struct c_declarator
*inner
;
3843 c_parser_consume_token (parser
);
3844 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
3845 false, false, true, false, cla_prefer_id
);
3846 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
3850 return make_pointer_declarator (quals_attrs
, inner
);
3852 /* Now we have a direct declarator, direct abstract declarator or
3853 nothing (which counts as a direct abstract declarator here). */
3854 return c_parser_direct_declarator (parser
, type_seen_p
, kind
, seen_id
);
3857 /* Parse a direct declarator or direct abstract declarator; arguments
3858 as c_parser_declarator. */
3860 static struct c_declarator
*
3861 c_parser_direct_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3864 /* The direct declarator must start with an identifier (possibly
3865 omitted) or a parenthesized declarator (possibly abstract). In
3866 an ordinary declarator, initial parentheses must start a
3867 parenthesized declarator. In an abstract declarator or parameter
3868 declarator, they could start a parenthesized declarator or a
3869 parameter list. To tell which, the open parenthesis and any
3870 following gnu-attributes must be read. If a declaration
3871 specifier or standard attributes follow, then it is a parameter
3872 list; if the specifier is a typedef name, there might be an
3873 ambiguity about redeclaring it, which is resolved in the
3874 direction of treating it as a typedef name. If a close
3875 parenthesis follows, it is also an empty parameter list, as the
3876 syntax does not permit empty abstract declarators. Otherwise, it
3877 is a parenthesized declarator (in which case the analysis may be
3878 repeated inside it, recursively).
3880 ??? There is an ambiguity in a parameter declaration "int
3881 (__attribute__((foo)) x)", where x is not a typedef name: it
3882 could be an abstract declarator for a function, or declare x with
3883 parentheses. The proper resolution of this ambiguity needs
3884 documenting. At present we follow an accident of the old
3885 parser's implementation, whereby the first parameter must have
3886 some declaration specifiers other than just gnu-attributes. Thus as
3887 a parameter declaration it is treated as a parenthesized
3888 parameter named x, and as an abstract declarator it is
3891 ??? Also following the old parser, gnu-attributes inside an empty
3892 parameter list are ignored, making it a list not yielding a
3893 prototype, rather than giving an error or making it have one
3894 parameter with implicit type int.
3896 ??? Also following the old parser, typedef names may be
3897 redeclared in declarators, but not Objective-C class names. */
3899 if (kind
!= C_DTR_ABSTRACT
3900 && c_parser_next_token_is (parser
, CPP_NAME
)
3902 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
3903 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
3904 || c_parser_peek_token (parser
)->id_kind
== C_ID_ID
))
3906 struct c_declarator
*inner
3907 = build_id_declarator (c_parser_peek_token (parser
)->value
);
3909 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3910 c_parser_consume_token (parser
);
3911 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3912 inner
->u
.id
.attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3913 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3916 if (kind
!= C_DTR_NORMAL
3917 && c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
3918 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
3920 struct c_declarator
*inner
= build_id_declarator (NULL_TREE
);
3921 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3922 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3925 /* Either we are at the end of an abstract declarator, or we have
3928 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3931 struct c_declarator
*inner
;
3932 c_parser_consume_token (parser
);
3933 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
3935 attrs
= c_parser_gnu_attributes (parser
);
3936 if (kind
!= C_DTR_NORMAL
3937 && (c_parser_next_token_starts_declspecs (parser
)
3939 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3940 || c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
)))
3942 struct c_arg_info
*args
3943 = c_parser_parms_declarator (parser
, kind
== C_DTR_NORMAL
,
3944 attrs
, have_gnu_attrs
);
3949 inner
= build_id_declarator (NULL_TREE
);
3951 && args
->types
!= error_mark_node
3952 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
3953 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3956 = c_parser_std_attribute_specifier_sequence (parser
);
3958 inner
= build_attrs_declarator (std_attrs
, inner
);
3960 inner
= build_function_declarator (args
, inner
);
3961 return c_parser_direct_declarator_inner (parser
, *seen_id
,
3965 /* A parenthesized declarator. */
3966 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
3967 if (inner
!= NULL
&& attrs
!= NULL
)
3968 inner
= build_attrs_declarator (attrs
, inner
);
3969 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
3971 c_parser_consume_token (parser
);
3975 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3979 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3986 if (kind
== C_DTR_NORMAL
)
3988 c_parser_error (parser
, "expected identifier or %<(%>");
3992 return build_id_declarator (NULL_TREE
);
3996 /* Parse part of a direct declarator or direct abstract declarator,
3997 given that some (in INNER) has already been parsed; ID_PRESENT is
3998 true if an identifier is present, false for an abstract
4001 static struct c_declarator
*
4002 c_parser_direct_declarator_inner (c_parser
*parser
, bool id_present
,
4003 struct c_declarator
*inner
)
4005 /* Parse a sequence of array declarators and parameter lists. */
4006 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4007 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4009 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
4010 struct c_declarator
*declarator
;
4011 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4014 struct c_expr dimen
;
4015 dimen
.value
= NULL_TREE
;
4016 dimen
.original_code
= ERROR_MARK
;
4017 dimen
.original_type
= NULL_TREE
;
4018 c_parser_consume_token (parser
);
4019 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4020 false, false, false, false, cla_prefer_id
);
4021 static_seen
= c_parser_next_token_is_keyword (parser
, RID_STATIC
);
4023 c_parser_consume_token (parser
);
4024 if (static_seen
&& !quals_attrs
->declspecs_seen_p
)
4025 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4026 false, false, false, false, cla_prefer_id
);
4027 if (!quals_attrs
->declspecs_seen_p
)
4029 /* If "static" is present, there must be an array dimension.
4030 Otherwise, there may be a dimension, "*", or no
4035 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4039 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4041 dimen
.value
= NULL_TREE
;
4044 else if (c_parser_next_token_is (parser
, CPP_MULT
))
4046 if (c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_SQUARE
)
4048 dimen
.value
= NULL_TREE
;
4050 c_parser_consume_token (parser
);
4055 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4061 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4064 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4065 c_parser_consume_token (parser
);
4068 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4073 dimen
= convert_lvalue_to_rvalue (brace_loc
, dimen
, true, true);
4074 declarator
= build_array_declarator (brace_loc
, dimen
.value
, quals_attrs
,
4075 static_seen
, star_seen
);
4076 if (declarator
== NULL
)
4078 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4081 = c_parser_std_attribute_specifier_sequence (parser
);
4083 inner
= build_attrs_declarator (std_attrs
, inner
);
4085 inner
= set_array_declarator_inner (declarator
, inner
);
4086 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4088 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4091 struct c_arg_info
*args
;
4092 c_parser_consume_token (parser
);
4093 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4095 attrs
= c_parser_gnu_attributes (parser
);
4096 args
= c_parser_parms_declarator (parser
, id_present
, attrs
,
4103 && args
->types
!= error_mark_node
4104 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4105 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4108 = c_parser_std_attribute_specifier_sequence (parser
);
4110 inner
= build_attrs_declarator (std_attrs
, inner
);
4112 inner
= build_function_declarator (args
, inner
);
4113 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4119 /* Parse a parameter list or identifier list, including the closing
4120 parenthesis but not the opening one. ATTRS are the gnu-attributes
4121 at the start of the list. ID_LIST_OK is true if an identifier list
4122 is acceptable; such a list must not have attributes at the start.
4123 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4124 attributes) were present (in which case standard attributes cannot
4127 static struct c_arg_info
*
4128 c_parser_parms_declarator (c_parser
*parser
, bool id_list_ok
, tree attrs
,
4129 bool have_gnu_attrs
)
4132 declare_parm_level ();
4133 /* If the list starts with an identifier, it is an identifier list.
4134 Otherwise, it is either a prototype list or an empty list. */
4137 && c_parser_next_token_is (parser
, CPP_NAME
)
4138 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4140 /* Look ahead to detect typos in type names. */
4141 && c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
4142 && c_parser_peek_2nd_token (parser
)->type
!= CPP_MULT
4143 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
4144 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_SQUARE
4145 && c_parser_peek_2nd_token (parser
)->type
!= CPP_KEYWORD
)
4147 tree list
= NULL_TREE
, *nextp
= &list
;
4148 while (c_parser_next_token_is (parser
, CPP_NAME
)
4149 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
4151 *nextp
= build_tree_list (NULL_TREE
,
4152 c_parser_peek_token (parser
)->value
);
4153 nextp
= & TREE_CHAIN (*nextp
);
4154 c_parser_consume_token (parser
);
4155 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
4157 c_parser_consume_token (parser
);
4158 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4160 c_parser_error (parser
, "expected identifier");
4164 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4166 struct c_arg_info
*ret
= build_arg_info ();
4168 c_parser_consume_token (parser
);
4174 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4182 struct c_arg_info
*ret
4183 = c_parser_parms_list_declarator (parser
, attrs
, NULL
, have_gnu_attrs
);
4189 /* Parse a parameter list (possibly empty), including the closing
4190 parenthesis but not the opening one. ATTRS are the gnu-attributes
4191 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4192 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4193 which means standard attributes cannot start the list. EXPR is
4194 NULL or an expression that needs to be evaluated for the side
4195 effects of array size expressions in the parameters. */
4197 static struct c_arg_info
*
4198 c_parser_parms_list_declarator (c_parser
*parser
, tree attrs
, tree expr
,
4199 bool have_gnu_attrs
)
4201 bool bad_parm
= false;
4203 /* ??? Following the old parser, forward parameter declarations may
4204 use abstract declarators, and if no real parameter declarations
4205 follow the forward declarations then this is not diagnosed. Also
4206 note as above that gnu-attributes are ignored as the only contents of
4207 the parentheses, or as the only contents after forward
4209 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4211 struct c_arg_info
*ret
= build_arg_info ();
4212 c_parser_consume_token (parser
);
4215 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4217 struct c_arg_info
*ret
= build_arg_info ();
4219 if (flag_allow_parameterless_variadic_functions
)
4221 /* F (...) is allowed. */
4222 ret
->types
= NULL_TREE
;
4226 /* Suppress -Wold-style-definition for this case. */
4227 ret
->types
= error_mark_node
;
4228 error_at (c_parser_peek_token (parser
)->location
,
4229 "ISO C requires a named argument before %<...%>");
4231 c_parser_consume_token (parser
);
4232 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4234 c_parser_consume_token (parser
);
4239 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4244 /* Nonempty list of parameters, either terminated with semicolon
4245 (forward declarations; recurse) or with close parenthesis (normal
4246 function) or with ", ... )" (variadic function). */
4249 /* Parse a parameter. */
4250 struct c_parm
*parm
= c_parser_parameter_declaration (parser
, attrs
,
4253 have_gnu_attrs
= false;
4257 push_parm_decl (parm
, &expr
);
4258 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4261 c_parser_consume_token (parser
);
4262 mark_forward_parm_decls ();
4263 bool new_have_gnu_attrs
4264 = c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
);
4265 new_attrs
= c_parser_gnu_attributes (parser
);
4266 return c_parser_parms_list_declarator (parser
, new_attrs
, expr
,
4267 new_have_gnu_attrs
);
4269 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4271 c_parser_consume_token (parser
);
4275 return get_parm_info (false, expr
);
4277 if (!c_parser_require (parser
, CPP_COMMA
,
4278 "expected %<;%>, %<,%> or %<)%>",
4279 UNKNOWN_LOCATION
, false))
4281 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4284 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4286 c_parser_consume_token (parser
);
4287 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4289 c_parser_consume_token (parser
);
4293 return get_parm_info (true, expr
);
4297 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4305 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4306 start of the declaration if it is the first parameter;
4307 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4310 static struct c_parm
*
4311 c_parser_parameter_declaration (c_parser
*parser
, tree attrs
,
4312 bool have_gnu_attrs
)
4314 struct c_declspecs
*specs
;
4315 struct c_declarator
*declarator
;
4317 tree postfix_attrs
= NULL_TREE
;
4320 /* Accept #pragmas between parameter declarations. */
4321 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
4322 c_parser_pragma (parser
, pragma_param
, NULL
);
4324 if (!c_parser_next_token_starts_declspecs (parser
)
4325 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4327 c_token
*token
= c_parser_peek_token (parser
);
4330 c_parser_set_source_position_from_token (token
);
4331 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
4333 auto_diagnostic_group d
;
4334 name_hint hint
= lookup_name_fuzzy (token
->value
,
4335 FUZZY_LOOKUP_TYPENAME
,
4337 if (const char *suggestion
= hint
.suggestion ())
4339 gcc_rich_location
richloc (token
->location
);
4340 richloc
.add_fixit_replace (suggestion
);
4342 "unknown type name %qE; did you mean %qs?",
4343 token
->value
, suggestion
);
4346 error_at (token
->location
, "unknown type name %qE", token
->value
);
4347 parser
->error
= true;
4349 /* ??? In some Objective-C cases '...' isn't applicable so there
4350 should be a different message. */
4352 c_parser_error (parser
,
4353 "expected declaration specifiers or %<...%>");
4354 c_parser_skip_to_end_of_parameter (parser
);
4358 location_t start_loc
= c_parser_peek_token (parser
)->location
;
4360 specs
= build_null_declspecs ();
4363 declspecs_add_attrs (input_location
, specs
, attrs
);
4366 c_parser_declspecs (parser
, specs
, true, true, true, true, false,
4367 !have_gnu_attrs
, true, cla_nonabstract_decl
);
4368 finish_declspecs (specs
);
4369 pending_xref_error ();
4370 prefix_attrs
= specs
->attrs
;
4371 specs
->attrs
= NULL_TREE
;
4372 declarator
= c_parser_declarator (parser
,
4373 specs
->typespec_kind
!= ctsk_none
,
4374 C_DTR_PARM
, &dummy
);
4375 if (declarator
== NULL
)
4377 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
4380 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4381 postfix_attrs
= c_parser_gnu_attributes (parser
);
4383 /* Generate a location for the parameter, ranging from the start of the
4384 initial token to the end of the final token.
4386 If we have a identifier, then use it for the caret location, e.g.
4388 extern int callee (int one, int (*two)(int, int), float three);
4389 ~~~~~~^~~~~~~~~~~~~~
4391 otherwise, reuse the start location for the caret location e.g.:
4393 extern int callee (int one, int (*)(int, int), float three);
4396 location_t end_loc
= parser
->last_token_location
;
4398 /* Find any cdk_id declarator; determine if we have an identifier. */
4399 c_declarator
*id_declarator
= declarator
;
4400 while (id_declarator
&& id_declarator
->kind
!= cdk_id
)
4401 id_declarator
= id_declarator
->declarator
;
4402 location_t caret_loc
= (id_declarator
->u
.id
.id
4403 ? id_declarator
->id_loc
4405 location_t param_loc
= make_location (caret_loc
, start_loc
, end_loc
);
4407 return build_c_parm (specs
, chainon (postfix_attrs
, prefix_attrs
),
4408 declarator
, param_loc
);
4411 /* Parse a string literal in an asm expression. It should not be
4412 translated, and wide string literals are an error although
4413 permitted by the syntax. This is a GNU extension.
4420 c_parser_asm_string_literal (c_parser
*parser
)
4423 int save_flag
= warn_overlength_strings
;
4424 warn_overlength_strings
= 0;
4425 str
= c_parser_string_literal (parser
, false, false).value
;
4426 warn_overlength_strings
= save_flag
;
4430 /* Parse a simple asm expression. This is used in restricted
4431 contexts, where a full expression with inputs and outputs does not
4432 make sense. This is a GNU extension.
4435 asm ( asm-string-literal )
4439 c_parser_simple_asm_expr (c_parser
*parser
)
4442 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
4443 c_parser_consume_token (parser
);
4444 matching_parens parens
;
4445 if (!parens
.require_open (parser
))
4447 str
= c_parser_asm_string_literal (parser
);
4448 if (!parens
.require_close (parser
))
4450 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4457 c_parser_gnu_attribute_any_word (c_parser
*parser
)
4459 tree attr_name
= NULL_TREE
;
4461 if (c_parser_next_token_is (parser
, CPP_KEYWORD
))
4463 /* ??? See comment above about what keywords are accepted here. */
4465 switch (c_parser_peek_token (parser
)->keyword
)
4496 case RID_TRANSACTION_ATOMIC
:
4497 case RID_TRANSACTION_CANCEL
:
4513 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4514 attr_name
= ridpointers
[(int) c_parser_peek_token (parser
)->keyword
];
4516 else if (c_parser_next_token_is (parser
, CPP_NAME
))
4517 attr_name
= c_parser_peek_token (parser
)->value
;
4522 /* Parse attribute arguments. This is a common form of syntax
4523 covering all currently valid GNU and standard attributes.
4525 gnu-attribute-arguments:
4527 identifier , nonempty-expr-list
4530 where the "identifier" must not be declared as a type. ??? Why not
4531 allow identifiers declared as types to start the arguments? */
4534 c_parser_attribute_arguments (c_parser
*parser
, bool takes_identifier
,
4535 bool require_string
, bool allow_empty_args
)
4537 vec
<tree
, va_gc
> *expr_list
;
4539 /* Parse the attribute contents. If they start with an
4540 identifier which is followed by a comma or close
4541 parenthesis, then the arguments start with that
4542 identifier; otherwise they are an expression list.
4543 In objective-c the identifier may be a classname. */
4544 if (c_parser_next_token_is (parser
, CPP_NAME
)
4545 && (c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4546 || (c_dialect_objc ()
4547 && c_parser_peek_token (parser
)->id_kind
4549 && ((c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
4550 || (c_parser_peek_2nd_token (parser
)->type
4551 == CPP_CLOSE_PAREN
))
4552 && (takes_identifier
4553 || (c_dialect_objc ()
4554 && c_parser_peek_token (parser
)->id_kind
4555 == C_ID_CLASSNAME
)))
4557 tree arg1
= c_parser_peek_token (parser
)->value
;
4558 c_parser_consume_token (parser
);
4559 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4560 attr_args
= build_tree_list (NULL_TREE
, arg1
);
4564 c_parser_consume_token (parser
);
4565 expr_list
= c_parser_expr_list (parser
, false, true,
4566 NULL
, NULL
, NULL
, NULL
);
4567 tree_list
= build_tree_list_vec (expr_list
);
4568 attr_args
= tree_cons (NULL_TREE
, arg1
, tree_list
);
4569 release_tree_vector (expr_list
);
4574 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4576 if (!allow_empty_args
)
4577 error_at (c_parser_peek_token (parser
)->location
,
4578 "parentheses must be omitted if "
4579 "attribute argument list is empty");
4580 attr_args
= NULL_TREE
;
4582 else if (require_string
)
4584 /* The only valid argument for this attribute is a string
4585 literal. Handle this specially here to avoid accepting
4586 string literals with excess parentheses. */
4587 tree string
= c_parser_string_literal (parser
, false, true).value
;
4588 attr_args
= build_tree_list (NULL_TREE
, string
);
4592 expr_list
= c_parser_expr_list (parser
, false, true,
4593 NULL
, NULL
, NULL
, NULL
);
4594 attr_args
= build_tree_list_vec (expr_list
);
4595 release_tree_vector (expr_list
);
4601 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4605 gnu-attributes gnu-attribute
4608 __attribute__ ( ( gnu-attribute-list ) )
4612 gnu-attribute_list , gnu-attrib
4617 any-word ( gnu-attribute-arguments )
4619 where "any-word" may be any identifier (including one declared as a
4620 type), a reserved word storage class specifier, type specifier or
4621 type qualifier. ??? This still leaves out most reserved keywords
4622 (following the old parser), shouldn't we include them?
4623 When EXPECT_COMMA is true, expect the attribute to be preceded
4624 by a comma and fail if it isn't.
4625 When EMPTY_OK is true, allow and consume any number of consecutive
4626 commas with no attributes in between. */
4629 c_parser_gnu_attribute (c_parser
*parser
, tree attrs
,
4630 bool expect_comma
= false, bool empty_ok
= true)
4632 bool comma_first
= c_parser_next_token_is (parser
, CPP_COMMA
);
4634 && !c_parser_next_token_is (parser
, CPP_NAME
)
4635 && !c_parser_next_token_is (parser
, CPP_KEYWORD
))
4638 while (c_parser_next_token_is (parser
, CPP_COMMA
))
4640 c_parser_consume_token (parser
);
4645 tree attr_name
= c_parser_gnu_attribute_any_word (parser
);
4646 if (attr_name
== NULL_TREE
)
4649 attr_name
= canonicalize_attr_name (attr_name
);
4650 c_parser_consume_token (parser
);
4653 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4655 if (expect_comma
&& !comma_first
)
4657 /* A comma is missing between the last attribute on the chain
4659 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4661 return error_mark_node
;
4663 attr
= build_tree_list (attr_name
, NULL_TREE
);
4664 /* Add this attribute to the list. */
4665 attrs
= chainon (attrs
, attr
);
4668 c_parser_consume_token (parser
);
4671 = c_parser_attribute_arguments (parser
,
4672 attribute_takes_identifier_p (attr_name
),
4675 attr
= build_tree_list (attr_name
, attr_args
);
4676 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4677 c_parser_consume_token (parser
);
4680 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4682 return error_mark_node
;
4685 if (expect_comma
&& !comma_first
)
4687 /* A comma is missing between the last attribute on the chain
4689 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4691 return error_mark_node
;
4694 /* Add this attribute to the list. */
4695 attrs
= chainon (attrs
, attr
);
4700 c_parser_gnu_attributes (c_parser
*parser
)
4702 tree attrs
= NULL_TREE
;
4703 while (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4705 bool save_translate_strings_p
= parser
->translate_strings_p
;
4706 parser
->translate_strings_p
= false;
4707 /* Consume the `__attribute__' keyword. */
4708 c_parser_consume_token (parser
);
4709 /* Look for the two `(' tokens. */
4710 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4712 parser
->translate_strings_p
= save_translate_strings_p
;
4715 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4717 parser
->translate_strings_p
= save_translate_strings_p
;
4718 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4721 /* Parse the attribute list. Require a comma between successive
4722 (possibly empty) attributes. */
4723 for (bool expect_comma
= false; ; expect_comma
= true)
4725 /* Parse a single attribute. */
4726 tree attr
= c_parser_gnu_attribute (parser
, attrs
, expect_comma
);
4727 if (attr
== error_mark_node
)
4734 /* Look for the two `)' tokens. */
4735 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4736 c_parser_consume_token (parser
);
4739 parser
->translate_strings_p
= save_translate_strings_p
;
4740 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4744 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4745 c_parser_consume_token (parser
);
4748 parser
->translate_strings_p
= save_translate_strings_p
;
4749 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4753 parser
->translate_strings_p
= save_translate_strings_p
;
4759 /* Parse an optional balanced token sequence.
4761 balanced-token-sequence:
4763 balanced-token-sequence balanced-token
4766 ( balanced-token-sequence[opt] )
4767 [ balanced-token-sequence[opt] ]
4768 { balanced-token-sequence[opt] }
4769 any token other than ()[]{}
4773 c_parser_balanced_token_sequence (c_parser
*parser
)
4777 c_token
*token
= c_parser_peek_token (parser
);
4778 switch (token
->type
)
4780 case CPP_OPEN_BRACE
:
4782 matching_braces braces
;
4783 braces
.consume_open (parser
);
4784 c_parser_balanced_token_sequence (parser
);
4785 braces
.require_close (parser
);
4789 case CPP_OPEN_PAREN
:
4791 matching_parens parens
;
4792 parens
.consume_open (parser
);
4793 c_parser_balanced_token_sequence (parser
);
4794 parens
.require_close (parser
);
4798 case CPP_OPEN_SQUARE
:
4799 c_parser_consume_token (parser
);
4800 c_parser_balanced_token_sequence (parser
);
4801 c_parser_require (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
4804 case CPP_CLOSE_BRACE
:
4805 case CPP_CLOSE_PAREN
:
4806 case CPP_CLOSE_SQUARE
:
4811 c_parser_consume_token (parser
);
4817 /* Parse standard (C2X) attributes (including GNU attributes in the
4820 attribute-specifier-sequence:
4821 attribute-specifier-sequence[opt] attribute-specifier
4823 attribute-specifier:
4824 [ [ attribute-list ] ]
4828 attribute-list, attribute[opt]
4831 attribute-token attribute-argument-clause[opt]
4835 attribute-prefixed-token
4840 attribute-prefixed-token:
4841 attribute-prefix :: identifier
4846 attribute-argument-clause:
4847 ( balanced-token-sequence[opt] )
4849 Keywords are accepted as identifiers for this purpose.
4853 c_parser_std_attribute (c_parser
*parser
, bool for_tm
)
4855 c_token
*token
= c_parser_peek_token (parser
);
4856 tree ns
, name
, attribute
;
4858 /* Parse the attribute-token. */
4859 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
4861 c_parser_error (parser
, "expected identifier");
4862 return error_mark_node
;
4864 name
= canonicalize_attr_name (token
->value
);
4865 c_parser_consume_token (parser
);
4866 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
4869 c_parser_consume_token (parser
);
4870 token
= c_parser_peek_token (parser
);
4871 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
4873 c_parser_error (parser
, "expected identifier");
4874 return error_mark_node
;
4876 name
= canonicalize_attr_name (token
->value
);
4877 c_parser_consume_token (parser
);
4881 attribute
= build_tree_list (build_tree_list (ns
, name
), NULL_TREE
);
4883 /* Parse the arguments, if any. */
4884 const attribute_spec
*as
= lookup_attribute_spec (TREE_PURPOSE (attribute
));
4885 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4888 location_t open_loc
= c_parser_peek_token (parser
)->location
;
4889 matching_parens parens
;
4890 parens
.consume_open (parser
);
4891 if ((as
&& as
->max_length
== 0)
4892 /* Special-case the transactional-memory attribute "outer",
4893 which is specially handled but not registered as an
4894 attribute, to avoid allowing arbitrary balanced token
4895 sequences as arguments. */
4896 || is_attribute_p ("outer", name
))
4898 error_at (open_loc
, "%qE attribute does not take any arguments", name
);
4899 parens
.skip_until_found_close (parser
);
4900 return error_mark_node
;
4904 bool takes_identifier
4906 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
4907 && attribute_takes_identifier_p (name
));
4910 && strcmp (IDENTIFIER_POINTER (name
), "deprecated") == 0);
4911 TREE_VALUE (attribute
)
4912 = c_parser_attribute_arguments (parser
, takes_identifier
,
4913 require_string
, false);
4916 c_parser_balanced_token_sequence (parser
);
4917 parens
.require_close (parser
);
4920 if (ns
== NULL_TREE
&& !for_tm
&& !as
&& !is_attribute_p ("nodiscard", name
))
4922 /* An attribute with standard syntax and no namespace specified
4923 is a constraint violation if it is not one of the known
4924 standard attributes (of which nodiscard is the only one
4925 without a handler in GCC). Diagnose it here with a pedwarn
4926 and then discard it to prevent a duplicate warning later. */
4927 pedwarn (input_location
, OPT_Wattributes
, "%qE attribute ignored",
4929 return error_mark_node
;
4935 c_parser_std_attribute_specifier (c_parser
*parser
, bool for_tm
)
4937 bool seen_deprecated
= false;
4938 bool seen_fallthrough
= false;
4939 bool seen_maybe_unused
= false;
4940 location_t loc
= c_parser_peek_token (parser
)->location
;
4941 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
4943 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
4945 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
4949 pedwarn_c11 (loc
, OPT_Wpedantic
,
4950 "ISO C does not support %<[[]]%> attributes before C2X");
4951 tree attributes
= NULL_TREE
;
4954 c_token
*token
= c_parser_peek_token (parser
);
4955 if (token
->type
== CPP_CLOSE_SQUARE
)
4957 if (token
->type
== CPP_COMMA
)
4959 c_parser_consume_token (parser
);
4962 tree attribute
= c_parser_std_attribute (parser
, for_tm
);
4963 if (attribute
!= error_mark_node
)
4965 bool duplicate
= false;
4966 tree name
= get_attribute_name (attribute
);
4967 tree ns
= get_attribute_namespace (attribute
);
4968 if (ns
== NULL_TREE
)
4970 /* Some standard attributes may appear at most once in
4971 each attribute list. Diagnose duplicates and remove
4972 them from the list to avoid subsequent diagnostics
4973 such as the more general one for multiple
4974 "fallthrough" attributes in the same place (including
4975 in separate attribute lists in the same attribute
4976 specifier sequence, which is not a constraint
4978 if (is_attribute_p ("deprecated", name
))
4980 if (seen_deprecated
)
4982 error ("attribute %<deprecated%> can appear at most "
4983 "once in an attribute-list");
4986 seen_deprecated
= true;
4988 else if (is_attribute_p ("fallthrough", name
))
4990 if (seen_fallthrough
)
4992 error ("attribute %<fallthrough%> can appear at most "
4993 "once in an attribute-list");
4996 seen_fallthrough
= true;
4998 else if (is_attribute_p ("maybe_unused", name
))
5000 if (seen_maybe_unused
)
5002 error ("attribute %<maybe_unused%> can appear at most "
5003 "once in an attribute-list");
5006 seen_maybe_unused
= true;
5011 TREE_CHAIN (attribute
) = attributes
;
5012 attributes
= attribute
;
5015 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5018 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5019 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5020 return nreverse (attributes
);
5023 /* Look past an optional balanced token sequence of raw look-ahead
5024 tokens starting with the *Nth token. *N is updated to point to the
5025 following token. Return true if such a sequence was found, false
5026 if the tokens parsed were not balanced. */
5029 c_parser_check_balanced_raw_token_sequence (c_parser
*parser
, unsigned int *n
)
5033 c_token
*token
= c_parser_peek_nth_token_raw (parser
, *n
);
5034 switch (token
->type
)
5036 case CPP_OPEN_BRACE
:
5039 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5041 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5042 if (token
->type
== CPP_CLOSE_BRACE
)
5052 case CPP_OPEN_PAREN
:
5055 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5057 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5058 if (token
->type
== CPP_CLOSE_PAREN
)
5068 case CPP_OPEN_SQUARE
:
5071 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5073 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5074 if (token
->type
== CPP_CLOSE_SQUARE
)
5084 case CPP_CLOSE_BRACE
:
5085 case CPP_CLOSE_PAREN
:
5086 case CPP_CLOSE_SQUARE
:
5097 /* Return whether standard attributes start with the Nth token. */
5100 c_parser_nth_token_starts_std_attributes (c_parser
*parser
, unsigned int n
)
5102 if (!(c_parser_peek_nth_token (parser
, n
)->type
== CPP_OPEN_SQUARE
5103 && c_parser_peek_nth_token (parser
, n
+ 1)->type
== CPP_OPEN_SQUARE
))
5105 /* In C, '[[' must start attributes. In Objective-C, we need to
5106 check whether '[[' is matched by ']]'. */
5107 if (!c_dialect_objc ())
5110 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
5112 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
5113 if (token
->type
!= CPP_CLOSE_SQUARE
)
5115 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
5116 return token
->type
== CPP_CLOSE_SQUARE
;
5120 c_parser_std_attribute_specifier_sequence (c_parser
*parser
)
5122 tree attributes
= NULL_TREE
;
5125 tree attrs
= c_parser_std_attribute_specifier (parser
, false);
5126 attributes
= chainon (attributes
, attrs
);
5128 while (c_parser_nth_token_starts_std_attributes (parser
, 1));
5132 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5133 says whether alignment specifiers are OK (only in cases that might
5134 be the type name of a compound literal).
5137 specifier-qualifier-list abstract-declarator[opt]
5140 struct c_type_name
*
5141 c_parser_type_name (c_parser
*parser
, bool alignas_ok
)
5143 struct c_declspecs
*specs
= build_null_declspecs ();
5144 struct c_declarator
*declarator
;
5145 struct c_type_name
*ret
;
5147 c_parser_declspecs (parser
, specs
, false, true, true, alignas_ok
, false,
5148 false, true, cla_prefer_type
);
5149 if (!specs
->declspecs_seen_p
)
5151 c_parser_error (parser
, "expected specifier-qualifier-list");
5154 if (specs
->type
!= error_mark_node
)
5156 pending_xref_error ();
5157 finish_declspecs (specs
);
5159 declarator
= c_parser_declarator (parser
,
5160 specs
->typespec_kind
!= ctsk_none
,
5161 C_DTR_ABSTRACT
, &dummy
);
5162 if (declarator
== NULL
)
5164 ret
= XOBNEW (&parser_obstack
, struct c_type_name
);
5166 ret
->declarator
= declarator
;
5170 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5173 assignment-expression
5174 { initializer-list }
5175 { initializer-list , }
5178 designation[opt] initializer
5179 initializer-list , designation[opt] initializer
5186 designator-list designator
5193 [ constant-expression ]
5205 [ constant-expression ... constant-expression ]
5207 Any expression without commas is accepted in the syntax for the
5208 constant-expressions, with non-constant expressions rejected later.
5210 This function is only used for top-level initializers; for nested
5211 ones, see c_parser_initval. */
5213 static struct c_expr
5214 c_parser_initializer (c_parser
*parser
)
5216 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
5217 return c_parser_braced_init (parser
, NULL_TREE
, false, NULL
);
5221 location_t loc
= c_parser_peek_token (parser
)->location
;
5222 ret
= c_parser_expr_no_commas (parser
, NULL
);
5223 if (TREE_CODE (ret
.value
) != STRING_CST
5224 && TREE_CODE (ret
.value
) != COMPOUND_LITERAL_EXPR
)
5225 ret
= convert_lvalue_to_rvalue (loc
, ret
, true, true);
5230 /* The location of the last comma within the current initializer list,
5231 or UNKNOWN_LOCATION if not within one. */
5233 location_t last_init_list_comma
;
5235 /* Parse a braced initializer list. TYPE is the type specified for a
5236 compound literal, and NULL_TREE for other initializers and for
5237 nested braced lists. NESTED_P is true for nested braced lists,
5238 false for the list of a compound literal or the list that is the
5239 top-level initializer in a declaration. */
5241 static struct c_expr
5242 c_parser_braced_init (c_parser
*parser
, tree type
, bool nested_p
,
5243 struct obstack
*outer_obstack
)
5246 struct obstack braced_init_obstack
;
5247 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
5248 gcc_obstack_init (&braced_init_obstack
);
5249 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
5250 matching_braces braces
;
5251 braces
.consume_open (parser
);
5254 finish_implicit_inits (brace_loc
, outer_obstack
);
5255 push_init_level (brace_loc
, 0, &braced_init_obstack
);
5258 really_start_incremental_init (type
);
5259 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5261 pedwarn (brace_loc
, OPT_Wpedantic
, "ISO C forbids empty initializer braces");
5265 /* Parse a non-empty initializer list, possibly with a trailing
5269 c_parser_initelt (parser
, &braced_init_obstack
);
5272 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5274 last_init_list_comma
= c_parser_peek_token (parser
)->location
;
5275 c_parser_consume_token (parser
);
5279 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5283 c_token
*next_tok
= c_parser_peek_token (parser
);
5284 if (next_tok
->type
!= CPP_CLOSE_BRACE
)
5287 ret
.original_code
= ERROR_MARK
;
5288 ret
.original_type
= NULL
;
5289 braces
.skip_until_found_close (parser
);
5290 pop_init_level (brace_loc
, 0, &braced_init_obstack
, last_init_list_comma
);
5291 obstack_free (&braced_init_obstack
, NULL
);
5294 location_t close_loc
= next_tok
->location
;
5295 c_parser_consume_token (parser
);
5296 ret
= pop_init_level (brace_loc
, 0, &braced_init_obstack
, close_loc
);
5297 obstack_free (&braced_init_obstack
, NULL
);
5298 set_c_expr_source_range (&ret
, brace_loc
, close_loc
);
5302 /* Parse a nested initializer, including designators. */
5305 c_parser_initelt (c_parser
*parser
, struct obstack
* braced_init_obstack
)
5307 /* Parse any designator or designator list. A single array
5308 designator may have the subsequent "=" omitted in GNU C, but a
5309 longer list or a structure member designator may not. */
5310 if (c_parser_next_token_is (parser
, CPP_NAME
)
5311 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
5313 /* Old-style structure member designator. */
5314 set_init_label (c_parser_peek_token (parser
)->location
,
5315 c_parser_peek_token (parser
)->value
,
5316 c_parser_peek_token (parser
)->location
,
5317 braced_init_obstack
);
5318 /* Use the colon as the error location. */
5319 pedwarn (c_parser_peek_2nd_token (parser
)->location
, OPT_Wpedantic
,
5320 "obsolete use of designated initializer with %<:%>");
5321 c_parser_consume_token (parser
);
5322 c_parser_consume_token (parser
);
5326 /* des_seen is 0 if there have been no designators, 1 if there
5327 has been a single array designator and 2 otherwise. */
5329 /* Location of a designator. */
5330 location_t des_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5331 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
5332 || c_parser_next_token_is (parser
, CPP_DOT
))
5334 int des_prev
= des_seen
;
5336 des_loc
= c_parser_peek_token (parser
)->location
;
5339 if (c_parser_next_token_is (parser
, CPP_DOT
))
5342 c_parser_consume_token (parser
);
5343 if (c_parser_next_token_is (parser
, CPP_NAME
))
5345 set_init_label (des_loc
, c_parser_peek_token (parser
)->value
,
5346 c_parser_peek_token (parser
)->location
,
5347 braced_init_obstack
);
5348 c_parser_consume_token (parser
);
5354 init
.original_code
= ERROR_MARK
;
5355 init
.original_type
= NULL
;
5356 c_parser_error (parser
, "expected identifier");
5357 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5358 process_init_element (input_location
, init
, false,
5359 braced_init_obstack
);
5366 location_t ellipsis_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5367 location_t array_index_loc
= UNKNOWN_LOCATION
;
5368 /* ??? Following the old parser, [ objc-receiver
5369 objc-message-args ] is accepted as an initializer,
5370 being distinguished from a designator by what follows
5371 the first assignment expression inside the square
5372 brackets, but after a first array designator a
5373 subsequent square bracket is for Objective-C taken to
5374 start an expression, using the obsolete form of
5375 designated initializer without '=', rather than
5376 possibly being a second level of designation: in LALR
5377 terms, the '[' is shifted rather than reducing
5378 designator to designator-list. */
5379 if (des_prev
== 1 && c_dialect_objc ())
5381 des_seen
= des_prev
;
5384 if (des_prev
== 0 && c_dialect_objc ())
5386 /* This might be an array designator or an
5387 Objective-C message expression. If the former,
5388 continue parsing here; if the latter, parse the
5389 remainder of the initializer given the starting
5390 primary-expression. ??? It might make sense to
5391 distinguish when des_prev == 1 as well; see
5392 previous comment. */
5394 struct c_expr mexpr
;
5395 c_parser_consume_token (parser
);
5396 if (c_parser_peek_token (parser
)->type
== CPP_NAME
5397 && ((c_parser_peek_token (parser
)->id_kind
5399 || (c_parser_peek_token (parser
)->id_kind
5400 == C_ID_CLASSNAME
)))
5402 /* Type name receiver. */
5403 tree id
= c_parser_peek_token (parser
)->value
;
5404 c_parser_consume_token (parser
);
5405 rec
= objc_get_class_reference (id
);
5406 goto parse_message_args
;
5408 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
5409 mark_exp_read (first
);
5410 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
)
5411 || c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5412 goto array_desig_after_first
;
5413 /* Expression receiver. So far only one part
5414 without commas has been parsed; there might be
5415 more of the expression. */
5417 while (c_parser_next_token_is (parser
, CPP_COMMA
))
5420 location_t comma_loc
, exp_loc
;
5421 comma_loc
= c_parser_peek_token (parser
)->location
;
5422 c_parser_consume_token (parser
);
5423 exp_loc
= c_parser_peek_token (parser
)->location
;
5424 next
= c_parser_expr_no_commas (parser
, NULL
);
5425 next
= convert_lvalue_to_rvalue (exp_loc
, next
,
5427 rec
= build_compound_expr (comma_loc
, rec
, next
.value
);
5430 /* Now parse the objc-message-args. */
5431 args
= c_parser_objc_message_args (parser
);
5432 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5435 = objc_build_message_expr (rec
, args
);
5436 mexpr
.original_code
= ERROR_MARK
;
5437 mexpr
.original_type
= NULL
;
5438 /* Now parse and process the remainder of the
5439 initializer, starting with this message
5440 expression as a primary-expression. */
5441 c_parser_initval (parser
, &mexpr
, braced_init_obstack
);
5444 c_parser_consume_token (parser
);
5445 array_index_loc
= c_parser_peek_token (parser
)->location
;
5446 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
5447 mark_exp_read (first
);
5448 array_desig_after_first
:
5449 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5451 ellipsis_loc
= c_parser_peek_token (parser
)->location
;
5452 c_parser_consume_token (parser
);
5453 second
= c_parser_expr_no_commas (parser
, NULL
).value
;
5454 mark_exp_read (second
);
5458 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5460 c_parser_consume_token (parser
);
5461 set_init_index (array_index_loc
, first
, second
,
5462 braced_init_obstack
);
5464 pedwarn (ellipsis_loc
, OPT_Wpedantic
,
5465 "ISO C forbids specifying range of elements to initialize");
5468 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5474 if (c_parser_next_token_is (parser
, CPP_EQ
))
5476 pedwarn_c90 (des_loc
, OPT_Wpedantic
,
5477 "ISO C90 forbids specifying subobject "
5479 c_parser_consume_token (parser
);
5484 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
5485 "obsolete use of designated initializer without %<=%>");
5490 init
.original_code
= ERROR_MARK
;
5491 init
.original_type
= NULL
;
5492 c_parser_error (parser
, "expected %<=%>");
5493 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5494 process_init_element (input_location
, init
, false,
5495 braced_init_obstack
);
5501 c_parser_initval (parser
, NULL
, braced_init_obstack
);
5504 /* Parse a nested initializer; as c_parser_initializer but parses
5505 initializers within braced lists, after any designators have been
5506 applied. If AFTER is not NULL then it is an Objective-C message
5507 expression which is the primary-expression starting the
5511 c_parser_initval (c_parser
*parser
, struct c_expr
*after
,
5512 struct obstack
* braced_init_obstack
)
5515 gcc_assert (!after
|| c_dialect_objc ());
5516 location_t loc
= c_parser_peek_token (parser
)->location
;
5518 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
) && !after
)
5519 init
= c_parser_braced_init (parser
, NULL_TREE
, true,
5520 braced_init_obstack
);
5523 init
= c_parser_expr_no_commas (parser
, after
);
5524 if (init
.value
!= NULL_TREE
5525 && TREE_CODE (init
.value
) != STRING_CST
5526 && TREE_CODE (init
.value
) != COMPOUND_LITERAL_EXPR
)
5527 init
= convert_lvalue_to_rvalue (loc
, init
, true, true);
5529 process_init_element (loc
, init
, false, braced_init_obstack
);
5532 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5533 C99 6.8.2, C11 6.8.2).
5536 { block-item-list[opt] }
5537 { label-declarations block-item-list }
5541 block-item-list block-item
5553 { label-declarations block-item-list }
5556 __extension__ nested-declaration
5557 nested-function-definition
5561 label-declarations label-declaration
5564 __label__ identifier-list ;
5566 Allowing the mixing of declarations and code is new in C99. The
5567 GNU syntax also permits (not shown above) labels at the end of
5568 compound statements, which yield an error. We don't allow labels
5569 on declarations; this might seem like a natural extension, but
5570 there would be a conflict between gnu-attributes on the label and
5571 prefix gnu-attributes on the declaration. ??? The syntax follows the
5572 old parser in requiring something after label declarations.
5573 Although they are erroneous if the labels declared aren't defined,
5574 is it useful for the syntax to be this way?
5595 cancellation-point-directive */
5598 c_parser_compound_statement (c_parser
*parser
)
5601 location_t brace_loc
;
5602 brace_loc
= c_parser_peek_token (parser
)->location
;
5603 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
5605 /* Ensure a scope is entered and left anyway to avoid confusion
5606 if we have just prepared to enter a function body. */
5607 stmt
= c_begin_compound_stmt (true);
5608 c_end_compound_stmt (brace_loc
, stmt
, true);
5609 return error_mark_node
;
5611 stmt
= c_begin_compound_stmt (true);
5612 c_parser_compound_statement_nostart (parser
);
5614 return c_end_compound_stmt (brace_loc
, stmt
, true);
5617 /* Parse a compound statement except for the opening brace. This is
5618 used for parsing both compound statements and statement expressions
5619 (which follow different paths to handling the opening). */
5622 c_parser_compound_statement_nostart (c_parser
*parser
)
5624 bool last_stmt
= false;
5625 bool last_label
= false;
5626 bool save_valid_for_pragma
= valid_location_for_stdc_pragma_p ();
5627 location_t label_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5628 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5630 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
5631 c_parser_consume_token (parser
);
5634 mark_valid_location_for_stdc_pragma (true);
5635 if (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5637 /* Read zero or more forward-declarations for labels that nested
5638 functions can jump to. */
5639 mark_valid_location_for_stdc_pragma (false);
5640 while (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5642 label_loc
= c_parser_peek_token (parser
)->location
;
5643 c_parser_consume_token (parser
);
5644 /* Any identifiers, including those declared as type names,
5649 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
5651 c_parser_error (parser
, "expected identifier");
5655 = declare_label (c_parser_peek_token (parser
)->value
);
5656 C_DECLARED_LABEL_FLAG (label
) = 1;
5657 add_stmt (build_stmt (label_loc
, DECL_EXPR
, label
));
5658 c_parser_consume_token (parser
);
5659 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5660 c_parser_consume_token (parser
);
5664 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
5666 pedwarn (label_loc
, OPT_Wpedantic
, "ISO C forbids label declarations");
5668 /* We must now have at least one statement, label or declaration. */
5669 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5671 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5672 c_parser_error (parser
, "expected declaration or statement");
5673 c_parser_consume_token (parser
);
5676 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_BRACE
))
5678 location_t loc
= c_parser_peek_token (parser
)->location
;
5679 loc
= expansion_point_location_if_in_system_header (loc
);
5680 /* Standard attributes may start a statement or a declaration. */
5682 = c_parser_nth_token_starts_std_attributes (parser
, 1);
5683 tree std_attrs
= NULL_TREE
;
5685 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5686 if (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5687 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5688 || (c_parser_next_token_is (parser
, CPP_NAME
)
5689 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5691 c_warn_unused_attributes (std_attrs
);
5692 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5693 label_loc
= c_parser_peek_2nd_token (parser
)->location
;
5695 label_loc
= c_parser_peek_token (parser
)->location
;
5698 mark_valid_location_for_stdc_pragma (false);
5699 c_parser_label (parser
);
5701 else if (!last_label
5702 && (c_parser_next_tokens_start_declaration (parser
)
5704 && c_parser_next_token_is (parser
, CPP_SEMICOLON
))))
5707 mark_valid_location_for_stdc_pragma (false);
5708 bool fallthru_attr_p
= false;
5709 c_parser_declaration_or_fndef (parser
, true, !have_std_attrs
,
5710 true, true, true, NULL
,
5711 vNULL
, have_std_attrs
, std_attrs
,
5712 NULL
, &fallthru_attr_p
);
5713 if (last_stmt
&& !fallthru_attr_p
)
5714 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5715 "ISO C90 forbids mixed declarations and code");
5716 last_stmt
= fallthru_attr_p
;
5718 else if (!last_label
5719 && c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
5721 /* __extension__ can start a declaration, but is also an
5722 unary operator that can start an expression. Consume all
5723 but the last of a possible series of __extension__ to
5724 determine which. If standard attributes have already
5725 been seen, it must start a statement, not a declaration,
5726 but standard attributes starting a declaration may appear
5727 after __extension__. */
5728 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
5729 && (c_parser_peek_2nd_token (parser
)->keyword
5731 c_parser_consume_token (parser
);
5733 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
5734 || c_parser_nth_token_starts_std_attributes (parser
, 2)))
5737 ext
= disable_extension_diagnostics ();
5738 c_parser_consume_token (parser
);
5740 mark_valid_location_for_stdc_pragma (false);
5741 c_parser_declaration_or_fndef (parser
, true, true, true, true,
5743 /* Following the old parser, __extension__ does not
5744 disable this diagnostic. */
5745 restore_extension_diagnostics (ext
);
5747 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5748 "ISO C90 forbids mixed declarations and code");
5754 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
5757 c_parser_error (parser
, "expected declaration or statement");
5758 /* External pragmas, and some omp pragmas, are not associated
5759 with regular c code, and so are not to be considered statements
5760 syntactically. This ensures that the user doesn't put them
5761 places that would turn into syntax errors if the directive
5763 if (c_parser_pragma (parser
,
5764 last_label
? pragma_stmt
: pragma_compound
,
5766 last_label
= false, last_stmt
= true;
5768 else if (c_parser_next_token_is (parser
, CPP_EOF
))
5770 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5771 c_parser_error (parser
, "expected declaration or statement");
5774 else if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
5776 if (parser
->in_if_block
)
5778 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5779 error_at (loc
, "expected %<}%> before %<else%>");
5784 error_at (loc
, "%<else%> without a previous %<if%>");
5785 c_parser_consume_token (parser
);
5792 c_warn_unused_attributes (std_attrs
);
5795 mark_valid_location_for_stdc_pragma (false);
5796 c_parser_statement_after_labels (parser
, NULL
);
5799 parser
->error
= false;
5802 error_at (label_loc
, "label at end of compound statement");
5803 c_parser_consume_token (parser
);
5804 /* Restore the value we started with. */
5805 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5808 /* Parse all consecutive labels, possibly preceded by standard
5809 attributes. In this context, a statement is required, not a
5810 declaration, so attributes must be followed by a statement that is
5811 not just a semicolon. */
5814 c_parser_all_labels (c_parser
*parser
)
5816 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
5818 tree std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5819 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5820 c_parser_error (parser
, "expected statement");
5822 c_warn_unused_attributes (std_attrs
);
5824 while (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5825 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5826 || (c_parser_next_token_is (parser
, CPP_NAME
)
5827 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5828 c_parser_label (parser
);
5831 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5834 identifier : gnu-attributes[opt]
5835 case constant-expression :
5841 case constant-expression ... constant-expression :
5843 The use of gnu-attributes on labels is a GNU extension. The syntax in
5844 GNU C accepts any expressions without commas, non-constant
5845 expressions being rejected later. Any standard
5846 attribute-specifier-sequence before the first label has been parsed
5847 in the caller, to distinguish statements from declarations. Any
5848 attribute-specifier-sequence after the label is parsed in this
5852 c_parser_label (c_parser
*parser
)
5854 location_t loc1
= c_parser_peek_token (parser
)->location
;
5855 tree label
= NULL_TREE
;
5857 /* Remember whether this case or a user-defined label is allowed to fall
5859 bool fallthrough_p
= c_parser_peek_token (parser
)->flags
& PREV_FALLTHROUGH
;
5861 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5864 c_parser_consume_token (parser
);
5865 exp1
= c_parser_expr_no_commas (parser
, NULL
).value
;
5866 if (c_parser_next_token_is (parser
, CPP_COLON
))
5868 c_parser_consume_token (parser
);
5869 label
= do_case (loc1
, exp1
, NULL_TREE
);
5871 else if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5873 c_parser_consume_token (parser
);
5874 exp2
= c_parser_expr_no_commas (parser
, NULL
).value
;
5875 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5876 label
= do_case (loc1
, exp1
, exp2
);
5879 c_parser_error (parser
, "expected %<:%> or %<...%>");
5881 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
5883 c_parser_consume_token (parser
);
5884 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5885 label
= do_case (loc1
, NULL_TREE
, NULL_TREE
);
5889 tree name
= c_parser_peek_token (parser
)->value
;
5892 location_t loc2
= c_parser_peek_token (parser
)->location
;
5893 gcc_assert (c_parser_next_token_is (parser
, CPP_NAME
));
5894 c_parser_consume_token (parser
);
5895 gcc_assert (c_parser_next_token_is (parser
, CPP_COLON
));
5896 c_parser_consume_token (parser
);
5897 attrs
= c_parser_gnu_attributes (parser
);
5898 tlab
= define_label (loc2
, name
);
5901 decl_attributes (&tlab
, attrs
, 0);
5902 label
= add_stmt (build_stmt (loc1
, LABEL_EXPR
, tlab
));
5907 if (TREE_CODE (label
) == LABEL_EXPR
)
5908 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label
)) = fallthrough_p
;
5910 FALLTHROUGH_LABEL_P (CASE_LABEL (label
)) = fallthrough_p
;
5912 /* Standard attributes are only allowed here if they start a
5913 statement, not a declaration (including the case of an
5914 attribute-declaration with only attributes). */
5916 = c_parser_nth_token_starts_std_attributes (parser
, 1);
5917 tree std_attrs
= NULL_TREE
;
5919 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5921 /* Allow '__attribute__((fallthrough));'. */
5923 && c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
5925 location_t loc
= c_parser_peek_token (parser
)->location
;
5926 tree attrs
= c_parser_gnu_attributes (parser
);
5927 if (attribute_fallthrough_p (attrs
))
5929 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5931 tree fn
= build_call_expr_internal_loc (loc
,
5937 warning_at (loc
, OPT_Wattributes
, "%<fallthrough%> attribute "
5938 "not followed by %<;%>");
5940 else if (attrs
!= NULL_TREE
)
5941 warning_at (loc
, OPT_Wattributes
, "only attribute %<fallthrough%>"
5942 " can be applied to a null statement");
5944 if (c_parser_next_tokens_start_declaration (parser
)
5946 && c_parser_next_token_is (parser
, CPP_SEMICOLON
)))
5948 error_at (c_parser_peek_token (parser
)->location
,
5949 "a label can only be part of a statement and "
5950 "a declaration is not a statement");
5951 c_parser_declaration_or_fndef (parser
, /*fndef_ok*/ false,
5952 /*static_assert_ok*/ true,
5953 /*empty_ok*/ true, /*nested*/ true,
5954 /*start_attr_ok*/ true, NULL
,
5955 vNULL
, have_std_attrs
, std_attrs
);
5958 /* Nonempty attributes on the following statement are ignored. */
5959 c_warn_unused_attributes (std_attrs
);
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
);
6140 switch (c_parser_peek_token (parser
)->type
)
6142 case CPP_OPEN_BRACE
:
6143 add_stmt (c_parser_compound_statement (parser
));
6146 switch (c_parser_peek_token (parser
)->keyword
)
6149 c_parser_if_statement (parser
, if_p
, chain
);
6152 c_parser_switch_statement (parser
, if_p
);
6155 c_parser_while_statement (parser
, false, 0, if_p
);
6158 c_parser_do_statement (parser
, 0, false);
6161 c_parser_for_statement (parser
, false, 0, if_p
);
6164 c_parser_consume_token (parser
);
6165 if (c_parser_next_token_is (parser
, CPP_NAME
))
6167 stmt
= c_finish_goto_label (loc
,
6168 c_parser_peek_token (parser
)->value
);
6169 c_parser_consume_token (parser
);
6171 else if (c_parser_next_token_is (parser
, CPP_MULT
))
6175 c_parser_consume_token (parser
);
6176 val
= c_parser_expression (parser
);
6177 val
= convert_lvalue_to_rvalue (loc
, val
, false, true);
6178 stmt
= c_finish_goto_ptr (loc
, val
.value
);
6181 c_parser_error (parser
, "expected identifier or %<*%>");
6182 goto expect_semicolon
;
6184 c_parser_consume_token (parser
);
6185 stmt
= c_finish_bc_stmt (loc
, &c_cont_label
, false);
6186 goto expect_semicolon
;
6188 c_parser_consume_token (parser
);
6189 stmt
= c_finish_bc_stmt (loc
, &c_break_label
, true);
6190 goto expect_semicolon
;
6192 c_parser_consume_token (parser
);
6193 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6195 stmt
= c_finish_return (loc
, NULL_TREE
, NULL_TREE
);
6196 c_parser_consume_token (parser
);
6200 location_t xloc
= c_parser_peek_token (parser
)->location
;
6201 struct c_expr expr
= c_parser_expression_conv (parser
);
6202 mark_exp_read (expr
.value
);
6203 stmt
= c_finish_return (EXPR_LOC_OR_LOC (expr
.value
, xloc
),
6204 expr
.value
, expr
.original_type
);
6205 goto expect_semicolon
;
6209 stmt
= c_parser_asm_statement (parser
);
6211 case RID_TRANSACTION_ATOMIC
:
6212 case RID_TRANSACTION_RELAXED
:
6213 stmt
= c_parser_transaction (parser
,
6214 c_parser_peek_token (parser
)->keyword
);
6216 case RID_TRANSACTION_CANCEL
:
6217 stmt
= c_parser_transaction_cancel (parser
);
6218 goto expect_semicolon
;
6220 gcc_assert (c_dialect_objc ());
6221 c_parser_consume_token (parser
);
6222 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6224 stmt
= objc_build_throw_stmt (loc
, NULL_TREE
);
6225 c_parser_consume_token (parser
);
6229 struct c_expr expr
= c_parser_expression (parser
);
6230 expr
= convert_lvalue_to_rvalue (loc
, expr
, false, false);
6231 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
6232 stmt
= objc_build_throw_stmt (loc
, expr
.value
);
6233 goto expect_semicolon
;
6237 gcc_assert (c_dialect_objc ());
6238 c_parser_objc_try_catch_finally_statement (parser
);
6240 case RID_AT_SYNCHRONIZED
:
6241 gcc_assert (c_dialect_objc ());
6242 c_parser_objc_synchronized_statement (parser
);
6246 /* Allow '__attribute__((fallthrough));'. */
6247 tree attrs
= c_parser_gnu_attributes (parser
);
6248 if (attribute_fallthrough_p (attrs
))
6250 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6252 tree fn
= build_call_expr_internal_loc (loc
,
6257 c_parser_consume_token (parser
);
6260 warning_at (loc
, OPT_Wattributes
,
6261 "%<fallthrough%> attribute not followed "
6264 else if (attrs
!= NULL_TREE
)
6265 warning_at (loc
, OPT_Wattributes
, "only attribute %<fallthrough%>"
6266 " can be applied to a null statement");
6274 c_parser_consume_token (parser
);
6276 case CPP_CLOSE_PAREN
:
6277 case CPP_CLOSE_SQUARE
:
6278 /* Avoid infinite loop in error recovery:
6279 c_parser_skip_until_found stops at a closing nesting
6280 delimiter without consuming it, but here we need to consume
6281 it to proceed further. */
6282 c_parser_error (parser
, "expected statement");
6283 c_parser_consume_token (parser
);
6286 c_parser_pragma (parser
, pragma_stmt
, if_p
);
6290 stmt
= c_finish_expr_stmt (loc
, c_parser_expression_conv (parser
).value
);
6292 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
6295 /* Two cases cannot and do not have line numbers associated: If stmt
6296 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6297 cannot hold line numbers. But that's OK because the statement
6298 will either be changed to a MODIFY_EXPR during gimplification of
6299 the statement expr, or discarded. If stmt was compound, but
6300 without new variables, we will have skipped the creation of a
6301 BIND and will have a bare STATEMENT_LIST. But that's OK because
6302 (recursively) all of the component statements should already have
6303 line numbers assigned. ??? Can we discard no-op statements
6305 if (EXPR_LOCATION (stmt
) == UNKNOWN_LOCATION
)
6306 protected_set_expr_location (stmt
, loc
);
6308 parser
->in_if_block
= in_if_block
;
6311 /* Parse the condition from an if, do, while or for statements. */
6314 c_parser_condition (c_parser
*parser
)
6316 location_t loc
= c_parser_peek_token (parser
)->location
;
6318 cond
= c_parser_expression_conv (parser
).value
;
6319 cond
= c_objc_common_truthvalue_conversion (loc
, cond
);
6320 cond
= c_fully_fold (cond
, false, NULL
);
6321 if (warn_sequence_point
)
6322 verify_sequence_points (cond
);
6326 /* Parse a parenthesized condition from an if, do or while statement.
6332 c_parser_paren_condition (c_parser
*parser
)
6335 matching_parens parens
;
6336 if (!parens
.require_open (parser
))
6337 return error_mark_node
;
6338 cond
= c_parser_condition (parser
);
6339 parens
.skip_until_found_close (parser
);
6343 /* Parse a statement which is a block in C99.
6345 IF_P is used to track whether there's a (possibly labeled) if statement
6346 which is not enclosed in braces and has an else clause. This is used to
6347 implement -Wparentheses. */
6350 c_parser_c99_block_statement (c_parser
*parser
, bool *if_p
,
6351 location_t
*loc_after_labels
)
6353 tree block
= c_begin_compound_stmt (flag_isoc99
);
6354 location_t loc
= c_parser_peek_token (parser
)->location
;
6355 c_parser_statement (parser
, if_p
, loc_after_labels
);
6356 return c_end_compound_stmt (loc
, block
, flag_isoc99
);
6359 /* Parse the body of an if statement. This is just parsing a
6360 statement but (a) it is a block in C99, (b) we track whether the
6361 body is an if statement for the sake of -Wparentheses warnings, (c)
6362 we handle an empty body specially for the sake of -Wempty-body
6363 warnings, and (d) we call parser_compound_statement directly
6364 because c_parser_statement_after_labels resets
6365 parser->in_if_block.
6367 IF_P is used to track whether there's a (possibly labeled) if statement
6368 which is not enclosed in braces and has an else clause. This is used to
6369 implement -Wparentheses. */
6372 c_parser_if_body (c_parser
*parser
, bool *if_p
,
6373 const token_indent_info
&if_tinfo
)
6375 tree block
= c_begin_compound_stmt (flag_isoc99
);
6376 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6377 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6378 token_indent_info body_tinfo
6379 = get_token_indent_info (c_parser_peek_token (parser
));
6381 c_parser_all_labels (parser
);
6382 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6384 location_t loc
= c_parser_peek_token (parser
)->location
;
6385 add_stmt (build_empty_stmt (loc
));
6386 c_parser_consume_token (parser
);
6387 if (!c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6388 warning_at (loc
, OPT_Wempty_body
,
6389 "suggest braces around empty body in an %<if%> statement");
6391 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6392 add_stmt (c_parser_compound_statement (parser
));
6395 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6396 c_parser_statement_after_labels (parser
, if_p
);
6399 token_indent_info next_tinfo
6400 = get_token_indent_info (c_parser_peek_token (parser
));
6401 warn_for_misleading_indentation (if_tinfo
, body_tinfo
, next_tinfo
);
6402 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6403 && next_tinfo
.type
!= CPP_SEMICOLON
)
6404 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6405 if_tinfo
.location
, RID_IF
);
6407 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6410 /* Parse the else body of an if statement. This is just parsing a
6411 statement but (a) it is a block in C99, (b) we handle an empty body
6412 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6413 of if-else-if conditions. */
6416 c_parser_else_body (c_parser
*parser
, const token_indent_info
&else_tinfo
,
6419 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6420 tree block
= c_begin_compound_stmt (flag_isoc99
);
6421 token_indent_info body_tinfo
6422 = get_token_indent_info (c_parser_peek_token (parser
));
6423 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6425 c_parser_all_labels (parser
);
6426 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6428 location_t loc
= c_parser_peek_token (parser
)->location
;
6431 "suggest braces around empty body in an %<else%> statement");
6432 add_stmt (build_empty_stmt (loc
));
6433 c_parser_consume_token (parser
);
6437 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6438 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6439 c_parser_statement_after_labels (parser
, NULL
, chain
);
6442 token_indent_info next_tinfo
6443 = get_token_indent_info (c_parser_peek_token (parser
));
6444 warn_for_misleading_indentation (else_tinfo
, body_tinfo
, next_tinfo
);
6445 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6446 && next_tinfo
.type
!= CPP_SEMICOLON
)
6447 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6448 else_tinfo
.location
, RID_ELSE
);
6450 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6453 /* We might need to reclassify any previously-lexed identifier, e.g.
6454 when we've left a for loop with an if-statement without else in the
6455 body - we might have used a wrong scope for the token. See PR67784. */
6458 c_parser_maybe_reclassify_token (c_parser
*parser
)
6460 if (c_parser_next_token_is (parser
, CPP_NAME
))
6462 c_token
*token
= c_parser_peek_token (parser
);
6464 if (token
->id_kind
!= C_ID_CLASSNAME
)
6466 tree decl
= lookup_name (token
->value
);
6468 token
->id_kind
= C_ID_ID
;
6471 if (TREE_CODE (decl
) == TYPE_DECL
)
6472 token
->id_kind
= C_ID_TYPENAME
;
6474 else if (c_dialect_objc ())
6476 tree objc_interface_decl
= objc_is_class_name (token
->value
);
6477 /* Objective-C class names are in the same namespace as
6478 variables and typedefs, and hence are shadowed by local
6480 if (objc_interface_decl
)
6482 token
->value
= objc_interface_decl
;
6483 token
->id_kind
= C_ID_CLASSNAME
;
6490 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6493 if ( expression ) statement
6494 if ( expression ) statement else statement
6496 CHAIN is a vector of if-else-if conditions.
6497 IF_P is used to track whether there's a (possibly labeled) if statement
6498 which is not enclosed in braces and has an else clause. This is used to
6499 implement -Wparentheses. */
6502 c_parser_if_statement (c_parser
*parser
, bool *if_p
, vec
<tree
> *chain
)
6507 bool nested_if
= false;
6508 tree first_body
, second_body
;
6511 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_IF
));
6512 token_indent_info if_tinfo
6513 = get_token_indent_info (c_parser_peek_token (parser
));
6514 c_parser_consume_token (parser
);
6515 block
= c_begin_compound_stmt (flag_isoc99
);
6516 loc
= c_parser_peek_token (parser
)->location
;
6517 cond
= c_parser_paren_condition (parser
);
6518 in_if_block
= parser
->in_if_block
;
6519 parser
->in_if_block
= true;
6520 first_body
= c_parser_if_body (parser
, &nested_if
, if_tinfo
);
6521 parser
->in_if_block
= in_if_block
;
6523 if (warn_duplicated_cond
)
6524 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond
), cond
, &chain
);
6526 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6528 token_indent_info else_tinfo
6529 = get_token_indent_info (c_parser_peek_token (parser
));
6530 c_parser_consume_token (parser
);
6531 if (warn_duplicated_cond
)
6533 if (c_parser_next_token_is_keyword (parser
, RID_IF
)
6536 /* We've got "if (COND) else if (COND2)". Start the
6537 condition chain and add COND as the first element. */
6538 chain
= new vec
<tree
> ();
6539 if (!CONSTANT_CLASS_P (cond
) && !TREE_SIDE_EFFECTS (cond
))
6540 chain
->safe_push (cond
);
6542 else if (!c_parser_next_token_is_keyword (parser
, RID_IF
))
6544 /* This is if-else without subsequent if. Zap the condition
6545 chain; we would have already warned at this point. */
6550 second_body
= c_parser_else_body (parser
, else_tinfo
, chain
);
6551 /* Set IF_P to true to indicate that this if statement has an
6552 else clause. This may trigger the Wparentheses warning
6553 below when we get back up to the parent if statement. */
6559 second_body
= NULL_TREE
;
6561 /* Diagnose an ambiguous else if if-then-else is nested inside
6564 warning_at (loc
, OPT_Wdangling_else
,
6565 "suggest explicit braces to avoid ambiguous %<else%>");
6567 if (warn_duplicated_cond
)
6569 /* This if statement does not have an else clause. We don't
6570 need the condition chain anymore. */
6575 c_finish_if_stmt (loc
, cond
, first_body
, second_body
);
6576 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6578 c_parser_maybe_reclassify_token (parser
);
6581 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6584 switch (expression) statement
6588 c_parser_switch_statement (c_parser
*parser
, bool *if_p
)
6591 tree block
, expr
, body
, save_break
;
6592 location_t switch_loc
= c_parser_peek_token (parser
)->location
;
6593 location_t switch_cond_loc
;
6594 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SWITCH
));
6595 c_parser_consume_token (parser
);
6596 block
= c_begin_compound_stmt (flag_isoc99
);
6597 bool explicit_cast_p
= false;
6598 matching_parens parens
;
6599 if (parens
.require_open (parser
))
6601 switch_cond_loc
= c_parser_peek_token (parser
)->location
;
6602 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
6603 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
6604 explicit_cast_p
= true;
6605 ce
= c_parser_expression (parser
);
6606 ce
= convert_lvalue_to_rvalue (switch_cond_loc
, ce
, true, false);
6608 /* ??? expr has no valid location? */
6609 parens
.skip_until_found_close (parser
);
6613 switch_cond_loc
= UNKNOWN_LOCATION
;
6614 expr
= error_mark_node
;
6615 ce
.original_type
= error_mark_node
;
6617 c_start_case (switch_loc
, switch_cond_loc
, expr
, explicit_cast_p
);
6618 save_break
= c_break_label
;
6619 c_break_label
= NULL_TREE
;
6620 location_t loc_after_labels
;
6621 bool open_brace_p
= c_parser_peek_token (parser
)->type
== CPP_OPEN_BRACE
;
6622 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6623 location_t next_loc
= c_parser_peek_token (parser
)->location
;
6624 if (!open_brace_p
&& c_parser_peek_token (parser
)->type
!= CPP_SEMICOLON
)
6625 warn_for_multistatement_macros (loc_after_labels
, next_loc
, switch_loc
,
6629 location_t here
= c_parser_peek_token (parser
)->location
;
6630 tree t
= build1 (LABEL_EXPR
, void_type_node
, c_break_label
);
6631 SET_EXPR_LOCATION (t
, here
);
6632 SWITCH_BREAK_LABEL_P (c_break_label
) = 1;
6633 append_to_statement_list_force (t
, &body
);
6635 c_finish_case (body
, ce
.original_type
);
6636 c_break_label
= save_break
;
6637 add_stmt (c_end_compound_stmt (switch_loc
, block
, flag_isoc99
));
6638 c_parser_maybe_reclassify_token (parser
);
6641 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6644 while (expression) statement
6646 IF_P is used to track whether there's a (possibly labeled) if statement
6647 which is not enclosed in braces and has an else clause. This is used to
6648 implement -Wparentheses. */
6651 c_parser_while_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6654 tree block
, cond
, body
, save_break
, save_cont
;
6656 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_WHILE
));
6657 token_indent_info while_tinfo
6658 = get_token_indent_info (c_parser_peek_token (parser
));
6659 c_parser_consume_token (parser
);
6660 block
= c_begin_compound_stmt (flag_isoc99
);
6661 loc
= c_parser_peek_token (parser
)->location
;
6662 cond
= c_parser_paren_condition (parser
);
6663 if (ivdep
&& cond
!= error_mark_node
)
6664 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6665 build_int_cst (integer_type_node
,
6666 annot_expr_ivdep_kind
),
6668 if (unroll
&& cond
!= error_mark_node
)
6669 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6670 build_int_cst (integer_type_node
,
6671 annot_expr_unroll_kind
),
6672 build_int_cst (integer_type_node
, unroll
));
6673 save_break
= c_break_label
;
6674 c_break_label
= NULL_TREE
;
6675 save_cont
= c_cont_label
;
6676 c_cont_label
= NULL_TREE
;
6678 token_indent_info body_tinfo
6679 = get_token_indent_info (c_parser_peek_token (parser
));
6681 location_t loc_after_labels
;
6682 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
6683 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6684 c_finish_loop (loc
, loc
, cond
, UNKNOWN_LOCATION
, NULL
, body
,
6685 c_break_label
, c_cont_label
, true);
6686 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6687 c_parser_maybe_reclassify_token (parser
);
6689 token_indent_info next_tinfo
6690 = get_token_indent_info (c_parser_peek_token (parser
));
6691 warn_for_misleading_indentation (while_tinfo
, body_tinfo
, next_tinfo
);
6693 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
6694 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
6695 while_tinfo
.location
, RID_WHILE
);
6697 c_break_label
= save_break
;
6698 c_cont_label
= save_cont
;
6701 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6704 do statement while ( expression ) ;
6708 c_parser_do_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
)
6710 tree block
, cond
, body
, save_break
, save_cont
, new_break
, new_cont
;
6712 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_DO
));
6713 c_parser_consume_token (parser
);
6714 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6715 warning_at (c_parser_peek_token (parser
)->location
,
6717 "suggest braces around empty body in %<do%> statement");
6718 block
= c_begin_compound_stmt (flag_isoc99
);
6719 loc
= c_parser_peek_token (parser
)->location
;
6720 save_break
= c_break_label
;
6721 c_break_label
= NULL_TREE
;
6722 save_cont
= c_cont_label
;
6723 c_cont_label
= NULL_TREE
;
6724 body
= c_parser_c99_block_statement (parser
, NULL
);
6725 c_parser_require_keyword (parser
, RID_WHILE
, "expected %<while%>");
6726 new_break
= c_break_label
;
6727 c_break_label
= save_break
;
6728 new_cont
= c_cont_label
;
6729 c_cont_label
= save_cont
;
6730 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
6731 cond
= c_parser_paren_condition (parser
);
6732 if (ivdep
&& cond
!= error_mark_node
)
6733 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6734 build_int_cst (integer_type_node
,
6735 annot_expr_ivdep_kind
),
6737 if (unroll
&& cond
!= error_mark_node
)
6738 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6739 build_int_cst (integer_type_node
,
6740 annot_expr_unroll_kind
),
6741 build_int_cst (integer_type_node
, unroll
));
6742 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
6743 c_parser_skip_to_end_of_block_or_statement (parser
);
6744 c_finish_loop (loc
, cond_loc
, cond
, UNKNOWN_LOCATION
, NULL
, body
,
6745 new_break
, new_cont
, false);
6746 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6749 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6752 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6753 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6755 The form with a declaration is new in C99.
6757 ??? In accordance with the old parser, the declaration may be a
6758 nested function, which is then rejected in check_for_loop_decls,
6759 but does it make any sense for this to be included in the grammar?
6760 Note in particular that the nested function does not include a
6761 trailing ';', whereas the "declaration" production includes one.
6762 Also, can we reject bad declarations earlier and cheaper than
6763 check_for_loop_decls?
6765 In Objective-C, there are two additional variants:
6768 for ( expression in expresssion ) statement
6769 for ( declaration in expression ) statement
6771 This is inconsistent with C, because the second variant is allowed
6772 even if c99 is not enabled.
6774 The rest of the comment documents these Objective-C foreach-statement.
6776 Here is the canonical example of the first variant:
6777 for (object in array) { do something with object }
6778 we call the first expression ("object") the "object_expression" and
6779 the second expression ("array") the "collection_expression".
6780 object_expression must be an lvalue of type "id" (a generic Objective-C
6781 object) because the loop works by assigning to object_expression the
6782 various objects from the collection_expression. collection_expression
6783 must evaluate to something of type "id" which responds to the method
6784 countByEnumeratingWithState:objects:count:.
6786 The canonical example of the second variant is:
6787 for (id object in array) { do something with object }
6788 which is completely equivalent to
6791 for (object in array) { do something with object }
6793 Note that initizializing 'object' in some way (eg, "for ((object =
6794 xxx) in array) { do something with object }") is possibly
6795 technically valid, but completely pointless as 'object' will be
6796 assigned to something else as soon as the loop starts. We should
6797 most likely reject it (TODO).
6799 The beginning of the Objective-C foreach-statement looks exactly
6800 like the beginning of the for-statement, and we can tell it is a
6801 foreach-statement only because the initial declaration or
6802 expression is terminated by 'in' instead of ';'.
6804 IF_P is used to track whether there's a (possibly labeled) if statement
6805 which is not enclosed in braces and has an else clause. This is used to
6806 implement -Wparentheses. */
6809 c_parser_for_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6812 tree block
, cond
, incr
, save_break
, save_cont
, body
;
6813 /* The following are only used when parsing an ObjC foreach statement. */
6814 tree object_expression
;
6815 /* Silence the bogus uninitialized warning. */
6816 tree collection_expression
= NULL
;
6817 location_t loc
= c_parser_peek_token (parser
)->location
;
6818 location_t for_loc
= loc
;
6819 location_t cond_loc
= UNKNOWN_LOCATION
;
6820 location_t incr_loc
= UNKNOWN_LOCATION
;
6821 bool is_foreach_statement
= false;
6822 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
6823 token_indent_info for_tinfo
6824 = get_token_indent_info (c_parser_peek_token (parser
));
6825 c_parser_consume_token (parser
);
6826 /* Open a compound statement in Objective-C as well, just in case this is
6827 as foreach expression. */
6828 block
= c_begin_compound_stmt (flag_isoc99
|| c_dialect_objc ());
6829 cond
= error_mark_node
;
6830 incr
= error_mark_node
;
6831 matching_parens parens
;
6832 if (parens
.require_open (parser
))
6834 /* Parse the initialization declaration or expression. */
6835 object_expression
= error_mark_node
;
6836 parser
->objc_could_be_foreach_context
= c_dialect_objc ();
6837 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6839 parser
->objc_could_be_foreach_context
= false;
6840 c_parser_consume_token (parser
);
6841 c_finish_expr_stmt (loc
, NULL_TREE
);
6843 else if (c_parser_next_tokens_start_declaration (parser
)
6844 || c_parser_nth_token_starts_std_attributes (parser
, 1))
6846 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
6847 &object_expression
, vNULL
);
6848 parser
->objc_could_be_foreach_context
= false;
6850 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6852 c_parser_consume_token (parser
);
6853 is_foreach_statement
= true;
6854 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6855 c_parser_error (parser
, "multiple iterating variables in "
6856 "fast enumeration");
6859 check_for_loop_decls (for_loc
, flag_isoc99
);
6861 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
6863 /* __extension__ can start a declaration, but is also an
6864 unary operator that can start an expression. Consume all
6865 but the last of a possible series of __extension__ to
6867 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
6868 && (c_parser_peek_2nd_token (parser
)->keyword
6870 c_parser_consume_token (parser
);
6871 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
6872 || c_parser_nth_token_starts_std_attributes (parser
, 2))
6875 ext
= disable_extension_diagnostics ();
6876 c_parser_consume_token (parser
);
6877 c_parser_declaration_or_fndef (parser
, true, true, true, true,
6878 true, &object_expression
, vNULL
);
6879 parser
->objc_could_be_foreach_context
= false;
6881 restore_extension_diagnostics (ext
);
6882 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6884 c_parser_consume_token (parser
);
6885 is_foreach_statement
= true;
6886 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6887 c_parser_error (parser
, "multiple iterating variables in "
6888 "fast enumeration");
6891 check_for_loop_decls (for_loc
, flag_isoc99
);
6901 tree init_expression
;
6902 ce
= c_parser_expression (parser
);
6903 init_expression
= ce
.value
;
6904 parser
->objc_could_be_foreach_context
= false;
6905 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6907 c_parser_consume_token (parser
);
6908 is_foreach_statement
= true;
6909 if (! lvalue_p (init_expression
))
6910 c_parser_error (parser
, "invalid iterating variable in "
6911 "fast enumeration");
6913 = c_fully_fold (init_expression
, false, NULL
);
6917 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6918 init_expression
= ce
.value
;
6919 c_finish_expr_stmt (loc
, init_expression
);
6920 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6925 /* Parse the loop condition. In the case of a foreach
6926 statement, there is no loop condition. */
6927 gcc_assert (!parser
->objc_could_be_foreach_context
);
6928 if (!is_foreach_statement
)
6930 cond_loc
= c_parser_peek_token (parser
)->location
;
6931 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6935 c_parser_error (parser
, "missing loop condition in loop "
6936 "with %<GCC ivdep%> pragma");
6937 cond
= error_mark_node
;
6941 c_parser_error (parser
, "missing loop condition in loop "
6942 "with %<GCC unroll%> pragma");
6943 cond
= error_mark_node
;
6947 c_parser_consume_token (parser
);
6953 cond
= c_parser_condition (parser
);
6954 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6957 if (ivdep
&& cond
!= error_mark_node
)
6958 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6959 build_int_cst (integer_type_node
,
6960 annot_expr_ivdep_kind
),
6962 if (unroll
&& cond
!= error_mark_node
)
6963 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6964 build_int_cst (integer_type_node
,
6965 annot_expr_unroll_kind
),
6966 build_int_cst (integer_type_node
, unroll
));
6968 /* Parse the increment expression (the third expression in a
6969 for-statement). In the case of a foreach-statement, this is
6970 the expression that follows the 'in'. */
6971 loc
= incr_loc
= c_parser_peek_token (parser
)->location
;
6972 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
6974 if (is_foreach_statement
)
6976 c_parser_error (parser
,
6977 "missing collection in fast enumeration");
6978 collection_expression
= error_mark_node
;
6981 incr
= c_process_expr_stmt (loc
, NULL_TREE
);
6985 if (is_foreach_statement
)
6986 collection_expression
6987 = c_fully_fold (c_parser_expression (parser
).value
, false, NULL
);
6990 struct c_expr ce
= c_parser_expression (parser
);
6991 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6992 incr
= c_process_expr_stmt (loc
, ce
.value
);
6995 parens
.skip_until_found_close (parser
);
6997 save_break
= c_break_label
;
6998 c_break_label
= NULL_TREE
;
6999 save_cont
= c_cont_label
;
7000 c_cont_label
= NULL_TREE
;
7002 token_indent_info body_tinfo
7003 = get_token_indent_info (c_parser_peek_token (parser
));
7005 location_t loc_after_labels
;
7006 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
7007 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
7009 if (is_foreach_statement
)
7010 objc_finish_foreach_loop (for_loc
, object_expression
,
7011 collection_expression
, body
, c_break_label
,
7014 c_finish_loop (for_loc
, cond_loc
, cond
, incr_loc
, incr
, body
,
7015 c_break_label
, c_cont_label
, true);
7016 add_stmt (c_end_compound_stmt (for_loc
, block
,
7017 flag_isoc99
|| c_dialect_objc ()));
7018 c_parser_maybe_reclassify_token (parser
);
7020 token_indent_info next_tinfo
7021 = get_token_indent_info (c_parser_peek_token (parser
));
7022 warn_for_misleading_indentation (for_tinfo
, body_tinfo
, next_tinfo
);
7024 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
7025 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
7026 for_tinfo
.location
, RID_FOR
);
7028 c_break_label
= save_break
;
7029 c_cont_label
= save_cont
;
7032 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7033 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7042 asm-qualifier-list asm-qualifier
7046 asm asm-qualifier-list[opt] ( asm-argument ) ;
7050 asm-string-literal : asm-operands[opt]
7051 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7052 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7054 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7057 The form with asm-goto-operands is valid if and only if the
7058 asm-qualifier-list contains goto, and is the only allowed form in that case.
7059 Duplicate asm-qualifiers are not allowed.
7061 The :: token is considered equivalent to two consecutive : tokens. */
7064 c_parser_asm_statement (c_parser
*parser
)
7066 tree str
, outputs
, inputs
, clobbers
, labels
, ret
;
7068 location_t asm_loc
= c_parser_peek_token (parser
)->location
;
7069 int section
, nsections
;
7071 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
7072 c_parser_consume_token (parser
);
7074 /* Handle the asm-qualifier-list. */
7075 location_t volatile_loc
= UNKNOWN_LOCATION
;
7076 location_t inline_loc
= UNKNOWN_LOCATION
;
7077 location_t goto_loc
= UNKNOWN_LOCATION
;
7080 c_token
*token
= c_parser_peek_token (parser
);
7081 location_t loc
= token
->location
;
7082 switch (token
->keyword
)
7087 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7088 inform (volatile_loc
, "first seen here");
7092 c_parser_consume_token (parser
);
7098 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7099 inform (inline_loc
, "first seen here");
7103 c_parser_consume_token (parser
);
7109 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7110 inform (goto_loc
, "first seen here");
7114 c_parser_consume_token (parser
);
7119 error_at (loc
, "%qE is not a valid %<asm%> qualifier", token
->value
);
7120 c_parser_consume_token (parser
);
7129 bool is_volatile
= (volatile_loc
!= UNKNOWN_LOCATION
);
7130 bool is_inline
= (inline_loc
!= UNKNOWN_LOCATION
);
7131 bool is_goto
= (goto_loc
!= UNKNOWN_LOCATION
);
7135 matching_parens parens
;
7136 if (!parens
.require_open (parser
))
7139 str
= c_parser_asm_string_literal (parser
);
7140 if (str
== NULL_TREE
)
7141 goto error_close_paren
;
7144 outputs
= NULL_TREE
;
7146 clobbers
= NULL_TREE
;
7149 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7152 /* Parse each colon-delimited section of operands. */
7153 nsections
= 3 + is_goto
;
7154 for (section
= 0; section
< nsections
; ++section
)
7156 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
7159 if (section
== nsections
)
7161 c_parser_error (parser
, "expected %<)%>");
7162 goto error_close_paren
;
7164 c_parser_consume_token (parser
);
7166 else if (!c_parser_require (parser
, CPP_COLON
,
7168 ? G_("expected %<:%>")
7169 : G_("expected %<:%> or %<)%>"),
7170 UNKNOWN_LOCATION
, is_goto
))
7171 goto error_close_paren
;
7173 /* Once past any colon, we're no longer a simple asm. */
7176 if ((!c_parser_next_token_is (parser
, CPP_COLON
)
7177 && !c_parser_next_token_is (parser
, CPP_SCOPE
)
7178 && !c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7183 /* For asm goto, we don't allow output operands, but reserve
7184 the slot for a future extension that does allow them. */
7186 outputs
= c_parser_asm_operands (parser
);
7189 inputs
= c_parser_asm_operands (parser
);
7192 clobbers
= c_parser_asm_clobbers (parser
);
7195 labels
= c_parser_asm_goto_operands (parser
);
7201 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7206 if (!parens
.require_close (parser
))
7208 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7212 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
7213 c_parser_skip_to_end_of_block_or_statement (parser
);
7215 ret
= build_asm_stmt (is_volatile
,
7216 build_asm_expr (asm_loc
, str
, outputs
, inputs
,
7217 clobbers
, labels
, simple
, is_inline
));
7223 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7227 /* Parse asm operands, a GNU extension.
7231 asm-operands , asm-operand
7234 asm-string-literal ( expression )
7235 [ identifier ] asm-string-literal ( expression )
7239 c_parser_asm_operands (c_parser
*parser
)
7241 tree list
= NULL_TREE
;
7246 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
7248 c_parser_consume_token (parser
);
7249 if (c_parser_next_token_is (parser
, CPP_NAME
))
7251 tree id
= c_parser_peek_token (parser
)->value
;
7252 c_parser_consume_token (parser
);
7253 name
= build_string (IDENTIFIER_LENGTH (id
),
7254 IDENTIFIER_POINTER (id
));
7258 c_parser_error (parser
, "expected identifier");
7259 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
7262 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
7267 str
= c_parser_asm_string_literal (parser
);
7268 if (str
== NULL_TREE
)
7270 matching_parens parens
;
7271 if (!parens
.require_open (parser
))
7273 expr
= c_parser_expression (parser
);
7274 mark_exp_read (expr
.value
);
7275 if (!parens
.require_close (parser
))
7277 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7280 list
= chainon (list
, build_tree_list (build_tree_list (name
, str
),
7282 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7283 c_parser_consume_token (parser
);
7290 /* Parse asm clobbers, a GNU extension.
7294 asm-clobbers , asm-string-literal
7298 c_parser_asm_clobbers (c_parser
*parser
)
7300 tree list
= NULL_TREE
;
7303 tree str
= c_parser_asm_string_literal (parser
);
7305 list
= tree_cons (NULL_TREE
, str
, list
);
7308 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7309 c_parser_consume_token (parser
);
7316 /* Parse asm goto labels, a GNU extension.
7320 asm-goto-operands , identifier
7324 c_parser_asm_goto_operands (c_parser
*parser
)
7326 tree list
= NULL_TREE
;
7331 if (c_parser_next_token_is (parser
, CPP_NAME
))
7333 c_token
*tok
= c_parser_peek_token (parser
);
7335 label
= lookup_label_for_goto (tok
->location
, name
);
7336 c_parser_consume_token (parser
);
7337 TREE_USED (label
) = 1;
7341 c_parser_error (parser
, "expected identifier");
7345 name
= build_string (IDENTIFIER_LENGTH (name
),
7346 IDENTIFIER_POINTER (name
));
7347 list
= tree_cons (name
, label
, list
);
7348 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7349 c_parser_consume_token (parser
);
7351 return nreverse (list
);
7355 /* Parse a possibly concatenated sequence of string literals.
7356 TRANSLATE says whether to translate them to the execution character
7357 set; WIDE_OK says whether any kind of prefixed string literal is
7358 permitted in this context. This code is based on that in
7362 c_parser_string_literal (c_parser
*parser
, bool translate
, bool wide_ok
)
7366 struct obstack str_ob
;
7367 struct obstack loc_ob
;
7368 cpp_string str
, istr
, *strs
;
7370 location_t loc
, last_tok_loc
;
7371 enum cpp_ttype type
;
7372 tree value
, string_tree
;
7374 tok
= c_parser_peek_token (parser
);
7375 loc
= tok
->location
;
7376 last_tok_loc
= linemap_resolve_location (line_table
, loc
,
7377 LRK_MACRO_DEFINITION_LOCATION
,
7386 case CPP_UTF8STRING
:
7387 string_tree
= tok
->value
;
7391 c_parser_error (parser
, "expected string literal");
7393 ret
.value
= NULL_TREE
;
7394 ret
.original_code
= ERROR_MARK
;
7395 ret
.original_type
= NULL_TREE
;
7399 /* Try to avoid the overhead of creating and destroying an obstack
7400 for the common case of just one string. */
7401 switch (c_parser_peek_2nd_token (parser
)->type
)
7404 c_parser_consume_token (parser
);
7405 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7406 str
.len
= TREE_STRING_LENGTH (string_tree
);
7415 case CPP_UTF8STRING
:
7416 gcc_obstack_init (&str_ob
);
7417 gcc_obstack_init (&loc_ob
);
7421 c_parser_consume_token (parser
);
7423 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7424 str
.len
= TREE_STRING_LENGTH (string_tree
);
7425 if (type
!= tok
->type
)
7427 if (type
== CPP_STRING
)
7429 else if (tok
->type
!= CPP_STRING
)
7430 error ("unsupported non-standard concatenation "
7431 "of string literals");
7433 obstack_grow (&str_ob
, &str
, sizeof (cpp_string
));
7434 obstack_grow (&loc_ob
, &last_tok_loc
, sizeof (location_t
));
7435 tok
= c_parser_peek_token (parser
);
7436 string_tree
= tok
->value
;
7438 = linemap_resolve_location (line_table
, tok
->location
,
7439 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
7441 while (tok
->type
== CPP_STRING
7442 || tok
->type
== CPP_WSTRING
7443 || tok
->type
== CPP_STRING16
7444 || tok
->type
== CPP_STRING32
7445 || tok
->type
== CPP_UTF8STRING
);
7446 strs
= (cpp_string
*) obstack_finish (&str_ob
);
7449 if (count
> 1 && !in_system_header_at (input_location
))
7450 warning (OPT_Wtraditional
,
7451 "traditional C rejects string constant concatenation");
7453 if ((type
== CPP_STRING
|| wide_ok
)
7455 ? cpp_interpret_string
: cpp_interpret_string_notranslate
)
7456 (parse_in
, strs
, count
, &istr
, type
)))
7458 value
= build_string (istr
.len
, (const char *) istr
.text
);
7459 free (CONST_CAST (unsigned char *, istr
.text
));
7462 location_t
*locs
= (location_t
*) obstack_finish (&loc_ob
);
7463 gcc_assert (g_string_concat_db
);
7464 g_string_concat_db
->record_string_concatenation (count
, locs
);
7469 if (type
!= CPP_STRING
&& !wide_ok
)
7471 error_at (loc
, "a wide string is invalid in this context");
7474 /* Callers cannot generally handle error_mark_node in this
7475 context, so return the empty string instead. An error has
7476 been issued, either above or from cpp_interpret_string. */
7481 case CPP_UTF8STRING
:
7482 value
= build_string (1, "");
7485 value
= build_string (TYPE_PRECISION (char16_type_node
)
7486 / TYPE_PRECISION (char_type_node
),
7487 "\0"); /* char16_t is 16 bits */
7490 value
= build_string (TYPE_PRECISION (char32_type_node
)
7491 / TYPE_PRECISION (char_type_node
),
7492 "\0\0\0"); /* char32_t is 32 bits */
7495 value
= build_string (TYPE_PRECISION (wchar_type_node
)
7496 / TYPE_PRECISION (char_type_node
),
7497 "\0\0\0"); /* widest supported wchar_t
7507 case CPP_UTF8STRING
:
7508 TREE_TYPE (value
) = char_array_type_node
;
7511 TREE_TYPE (value
) = char16_array_type_node
;
7514 TREE_TYPE (value
) = char32_array_type_node
;
7517 TREE_TYPE (value
) = wchar_array_type_node
;
7519 value
= fix_string_type (value
);
7523 obstack_free (&str_ob
, 0);
7524 obstack_free (&loc_ob
, 0);
7528 ret
.original_code
= STRING_CST
;
7529 ret
.original_type
= NULL_TREE
;
7530 set_c_expr_source_range (&ret
, get_range_from_loc (line_table
, loc
));
7534 /* Parse an expression other than a compound expression; that is, an
7535 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7536 AFTER is not NULL then it is an Objective-C message expression which
7537 is the primary-expression starting the expression as an initializer.
7539 assignment-expression:
7540 conditional-expression
7541 unary-expression assignment-operator assignment-expression
7543 assignment-operator: one of
7544 = *= /= %= += -= <<= >>= &= ^= |=
7546 In GNU C we accept any conditional expression on the LHS and
7547 diagnose the invalid lvalue rather than producing a syntax
7550 static struct c_expr
7551 c_parser_expr_no_commas (c_parser
*parser
, struct c_expr
*after
,
7552 tree omp_atomic_lhs
)
7554 struct c_expr lhs
, rhs
, ret
;
7555 enum tree_code code
;
7556 location_t op_location
, exp_location
;
7557 gcc_assert (!after
|| c_dialect_objc ());
7558 lhs
= c_parser_conditional_expression (parser
, after
, omp_atomic_lhs
);
7559 op_location
= c_parser_peek_token (parser
)->location
;
7560 switch (c_parser_peek_token (parser
)->type
)
7569 code
= TRUNC_DIV_EXPR
;
7572 code
= TRUNC_MOD_EXPR
;
7587 code
= BIT_AND_EXPR
;
7590 code
= BIT_XOR_EXPR
;
7593 code
= BIT_IOR_EXPR
;
7598 c_parser_consume_token (parser
);
7599 exp_location
= c_parser_peek_token (parser
)->location
;
7600 rhs
= c_parser_expr_no_commas (parser
, NULL
);
7601 rhs
= convert_lvalue_to_rvalue (exp_location
, rhs
, true, true);
7603 ret
.value
= build_modify_expr (op_location
, lhs
.value
, lhs
.original_type
,
7604 code
, exp_location
, rhs
.value
,
7606 set_c_expr_source_range (&ret
, lhs
.get_start (), rhs
.get_finish ());
7607 if (code
== NOP_EXPR
)
7608 ret
.original_code
= MODIFY_EXPR
;
7611 TREE_NO_WARNING (ret
.value
) = 1;
7612 ret
.original_code
= ERROR_MARK
;
7614 ret
.original_type
= NULL
;
7618 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7619 AFTER is not NULL then it is an Objective-C message expression which is
7620 the primary-expression starting the expression as an initializer.
7622 conditional-expression:
7623 logical-OR-expression
7624 logical-OR-expression ? expression : conditional-expression
7628 conditional-expression:
7629 logical-OR-expression ? : conditional-expression
7632 static struct c_expr
7633 c_parser_conditional_expression (c_parser
*parser
, struct c_expr
*after
,
7634 tree omp_atomic_lhs
)
7636 struct c_expr cond
, exp1
, exp2
, ret
;
7637 location_t start
, cond_loc
, colon_loc
;
7639 gcc_assert (!after
|| c_dialect_objc ());
7641 cond
= c_parser_binary_expression (parser
, after
, omp_atomic_lhs
);
7643 if (c_parser_next_token_is_not (parser
, CPP_QUERY
))
7645 if (cond
.value
!= error_mark_node
)
7646 start
= cond
.get_start ();
7648 start
= UNKNOWN_LOCATION
;
7649 cond_loc
= c_parser_peek_token (parser
)->location
;
7650 cond
= convert_lvalue_to_rvalue (cond_loc
, cond
, true, true);
7651 c_parser_consume_token (parser
);
7652 if (c_parser_next_token_is (parser
, CPP_COLON
))
7654 tree eptype
= NULL_TREE
;
7656 location_t middle_loc
= c_parser_peek_token (parser
)->location
;
7657 pedwarn (middle_loc
, OPT_Wpedantic
,
7658 "ISO C forbids omitting the middle term of a %<?:%> expression");
7659 if (TREE_CODE (cond
.value
) == EXCESS_PRECISION_EXPR
)
7661 eptype
= TREE_TYPE (cond
.value
);
7662 cond
.value
= TREE_OPERAND (cond
.value
, 0);
7664 tree e
= cond
.value
;
7665 while (TREE_CODE (e
) == COMPOUND_EXPR
)
7666 e
= TREE_OPERAND (e
, 1);
7667 warn_for_omitted_condop (middle_loc
, e
);
7668 /* Make sure first operand is calculated only once. */
7669 exp1
.value
= save_expr (default_conversion (cond
.value
));
7671 exp1
.value
= build1 (EXCESS_PRECISION_EXPR
, eptype
, exp1
.value
);
7672 exp1
.original_type
= NULL
;
7673 exp1
.src_range
= cond
.src_range
;
7674 cond
.value
= c_objc_common_truthvalue_conversion (cond_loc
, exp1
.value
);
7675 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_true_node
;
7680 = c_objc_common_truthvalue_conversion
7681 (cond_loc
, default_conversion (cond
.value
));
7682 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_false_node
;
7683 exp1
= c_parser_expression_conv (parser
);
7684 mark_exp_read (exp1
.value
);
7685 c_inhibit_evaluation_warnings
+=
7686 ((cond
.value
== truthvalue_true_node
)
7687 - (cond
.value
== truthvalue_false_node
));
7690 colon_loc
= c_parser_peek_token (parser
)->location
;
7691 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7693 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7695 ret
.original_code
= ERROR_MARK
;
7696 ret
.original_type
= NULL
;
7700 location_t exp2_loc
= c_parser_peek_token (parser
)->location
;
7701 exp2
= c_parser_conditional_expression (parser
, NULL
, NULL_TREE
);
7702 exp2
= convert_lvalue_to_rvalue (exp2_loc
, exp2
, true, true);
7704 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7705 location_t loc1
= make_location (exp1
.get_start (), exp1
.src_range
);
7706 location_t loc2
= make_location (exp2
.get_start (), exp2
.src_range
);
7707 ret
.value
= build_conditional_expr (colon_loc
, cond
.value
,
7708 cond
.original_code
== C_MAYBE_CONST_EXPR
,
7709 exp1
.value
, exp1
.original_type
, loc1
,
7710 exp2
.value
, exp2
.original_type
, loc2
);
7711 ret
.original_code
= ERROR_MARK
;
7712 if (exp1
.value
== error_mark_node
|| exp2
.value
== error_mark_node
)
7713 ret
.original_type
= NULL
;
7718 /* If both sides are enum type, the default conversion will have
7719 made the type of the result be an integer type. We want to
7720 remember the enum types we started with. */
7721 t1
= exp1
.original_type
? exp1
.original_type
: TREE_TYPE (exp1
.value
);
7722 t2
= exp2
.original_type
? exp2
.original_type
: TREE_TYPE (exp2
.value
);
7723 ret
.original_type
= ((t1
!= error_mark_node
7724 && t2
!= error_mark_node
7725 && (TYPE_MAIN_VARIANT (t1
)
7726 == TYPE_MAIN_VARIANT (t2
)))
7730 set_c_expr_source_range (&ret
, start
, exp2
.get_finish ());
7734 /* Parse a binary expression; that is, a logical-OR-expression (C90
7735 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7736 NULL then it is an Objective-C message expression which is the
7737 primary-expression starting the expression as an initializer.
7739 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7740 when it should be the unfolded lhs. In a valid OpenMP source,
7741 one of the operands of the toplevel binary expression must be equal
7742 to it. In that case, just return a build2 created binary operation
7743 rather than result of parser_build_binary_op.
7745 multiplicative-expression:
7747 multiplicative-expression * cast-expression
7748 multiplicative-expression / cast-expression
7749 multiplicative-expression % cast-expression
7751 additive-expression:
7752 multiplicative-expression
7753 additive-expression + multiplicative-expression
7754 additive-expression - multiplicative-expression
7758 shift-expression << additive-expression
7759 shift-expression >> additive-expression
7761 relational-expression:
7763 relational-expression < shift-expression
7764 relational-expression > shift-expression
7765 relational-expression <= shift-expression
7766 relational-expression >= shift-expression
7768 equality-expression:
7769 relational-expression
7770 equality-expression == relational-expression
7771 equality-expression != relational-expression
7775 AND-expression & equality-expression
7777 exclusive-OR-expression:
7779 exclusive-OR-expression ^ AND-expression
7781 inclusive-OR-expression:
7782 exclusive-OR-expression
7783 inclusive-OR-expression | exclusive-OR-expression
7785 logical-AND-expression:
7786 inclusive-OR-expression
7787 logical-AND-expression && inclusive-OR-expression
7789 logical-OR-expression:
7790 logical-AND-expression
7791 logical-OR-expression || logical-AND-expression
7794 static struct c_expr
7795 c_parser_binary_expression (c_parser
*parser
, struct c_expr
*after
,
7796 tree omp_atomic_lhs
)
7798 /* A binary expression is parsed using operator-precedence parsing,
7799 with the operands being cast expressions. All the binary
7800 operators are left-associative. Thus a binary expression is of
7803 E0 op1 E1 op2 E2 ...
7805 which we represent on a stack. On the stack, the precedence
7806 levels are strictly increasing. When a new operator is
7807 encountered of higher precedence than that at the top of the
7808 stack, it is pushed; its LHS is the top expression, and its RHS
7809 is everything parsed until it is popped. When a new operator is
7810 encountered with precedence less than or equal to that at the top
7811 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7812 by the result of the operation until the operator at the top of
7813 the stack has lower precedence than the new operator or there is
7814 only one element on the stack; then the top expression is the LHS
7815 of the new operator. In the case of logical AND and OR
7816 expressions, we also need to adjust c_inhibit_evaluation_warnings
7817 as appropriate when the operators are pushed and popped. */
7820 /* The expression at this stack level. */
7822 /* The precedence of the operator on its left, PREC_NONE at the
7823 bottom of the stack. */
7824 enum c_parser_prec prec
;
7825 /* The operation on its left. */
7827 /* The source location of this operation. */
7829 /* The sizeof argument if expr.original_code == SIZEOF_EXPR. */
7833 /* Location of the binary operator. */
7834 location_t binary_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
7837 switch (stack[sp].op) \
7839 case TRUTH_ANDIF_EXPR: \
7840 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7841 == truthvalue_false_node); \
7843 case TRUTH_ORIF_EXPR: \
7844 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7845 == truthvalue_true_node); \
7847 case TRUNC_DIV_EXPR: \
7848 if (stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7849 && stack[sp].expr.original_code == SIZEOF_EXPR) \
7851 tree type0 = stack[sp - 1].sizeof_arg; \
7852 tree type1 = stack[sp].sizeof_arg; \
7853 tree first_arg = type0; \
7854 if (!TYPE_P (type0)) \
7855 type0 = TREE_TYPE (type0); \
7856 if (!TYPE_P (type1)) \
7857 type1 = TREE_TYPE (type1); \
7858 if (POINTER_TYPE_P (type0) \
7859 && comptypes (TREE_TYPE (type0), type1) \
7860 && !(TREE_CODE (first_arg) == PARM_DECL \
7861 && C_ARRAY_PARAMETER (first_arg) \
7862 && warn_sizeof_array_argument)) \
7864 auto_diagnostic_group d; \
7865 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7866 "division %<sizeof (%T) / sizeof (%T)%> " \
7867 "does not compute the number of array " \
7870 if (DECL_P (first_arg)) \
7871 inform (DECL_SOURCE_LOCATION (first_arg), \
7872 "first %<sizeof%> operand was declared here"); \
7879 stack[sp - 1].expr \
7880 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7881 stack[sp - 1].expr, true, true); \
7883 = convert_lvalue_to_rvalue (stack[sp].loc, \
7884 stack[sp].expr, true, true); \
7885 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
7886 && c_parser_peek_token (parser)->type == CPP_SEMICOLON \
7887 && ((1 << stack[sp].prec) \
7888 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \
7889 | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \
7890 && stack[sp].op != TRUNC_MOD_EXPR \
7891 && stack[0].expr.value != error_mark_node \
7892 && stack[1].expr.value != error_mark_node \
7893 && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7894 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \
7895 stack[0].expr.value \
7896 = build2 (stack[1].op, TREE_TYPE (stack[0].expr.value), \
7897 stack[0].expr.value, stack[1].expr.value); \
7899 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7901 stack[sp - 1].expr, \
7905 gcc_assert (!after
|| c_dialect_objc ());
7906 stack
[0].loc
= c_parser_peek_token (parser
)->location
;
7907 stack
[0].expr
= c_parser_cast_expression (parser
, after
);
7908 stack
[0].prec
= PREC_NONE
;
7909 stack
[0].sizeof_arg
= c_last_sizeof_arg
;
7913 enum c_parser_prec oprec
;
7914 enum tree_code ocode
;
7915 source_range src_range
;
7918 switch (c_parser_peek_token (parser
)->type
)
7926 ocode
= TRUNC_DIV_EXPR
;
7930 ocode
= TRUNC_MOD_EXPR
;
7942 ocode
= LSHIFT_EXPR
;
7946 ocode
= RSHIFT_EXPR
;
7960 case CPP_GREATER_EQ
:
7973 oprec
= PREC_BITAND
;
7974 ocode
= BIT_AND_EXPR
;
7977 oprec
= PREC_BITXOR
;
7978 ocode
= BIT_XOR_EXPR
;
7982 ocode
= BIT_IOR_EXPR
;
7985 oprec
= PREC_LOGAND
;
7986 ocode
= TRUTH_ANDIF_EXPR
;
7990 ocode
= TRUTH_ORIF_EXPR
;
7993 /* Not a binary operator, so end of the binary
7997 binary_loc
= c_parser_peek_token (parser
)->location
;
7998 while (oprec
<= stack
[sp
].prec
)
8000 c_parser_consume_token (parser
);
8003 case TRUTH_ANDIF_EXPR
:
8004 src_range
= stack
[sp
].expr
.src_range
;
8006 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
8007 stack
[sp
].expr
, true, true);
8008 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
8009 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
8010 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
8011 == truthvalue_false_node
);
8012 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
8014 case TRUTH_ORIF_EXPR
:
8015 src_range
= stack
[sp
].expr
.src_range
;
8017 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
8018 stack
[sp
].expr
, true, true);
8019 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
8020 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
8021 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
8022 == truthvalue_true_node
);
8023 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
8029 stack
[sp
].loc
= binary_loc
;
8030 stack
[sp
].expr
= c_parser_cast_expression (parser
, NULL
);
8031 stack
[sp
].prec
= oprec
;
8032 stack
[sp
].op
= ocode
;
8033 stack
[sp
].sizeof_arg
= c_last_sizeof_arg
;
8038 return stack
[0].expr
;
8042 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8043 is not NULL then it is an Objective-C message expression which is the
8044 primary-expression starting the expression as an initializer.
8048 ( type-name ) unary-expression
8051 static struct c_expr
8052 c_parser_cast_expression (c_parser
*parser
, struct c_expr
*after
)
8054 location_t cast_loc
= c_parser_peek_token (parser
)->location
;
8055 gcc_assert (!after
|| c_dialect_objc ());
8057 return c_parser_postfix_expression_after_primary (parser
,
8059 /* If the expression begins with a parenthesized type name, it may
8060 be either a cast or a compound literal; we need to see whether
8061 the next character is '{' to tell the difference. If not, it is
8062 an unary expression. Full detection of unknown typenames here
8063 would require a 3-token lookahead. */
8064 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8065 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8067 struct c_type_name
*type_name
;
8070 matching_parens parens
;
8071 parens
.consume_open (parser
);
8072 type_name
= c_parser_type_name (parser
, true);
8073 parens
.skip_until_found_close (parser
);
8074 if (type_name
== NULL
)
8077 ret
.original_code
= ERROR_MARK
;
8078 ret
.original_type
= NULL
;
8082 /* Save casted types in the function's used types hash table. */
8083 used_types_insert (type_name
->specs
->type
);
8085 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8086 return c_parser_postfix_expression_after_paren_type (parser
, type_name
,
8088 if (type_name
->specs
->alignas_p
)
8089 error_at (type_name
->specs
->locations
[cdw_alignas
],
8090 "alignment specified for type name in cast");
8092 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
8093 expr
= c_parser_cast_expression (parser
, NULL
);
8094 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
8096 ret
.value
= c_cast_expr (cast_loc
, type_name
, expr
.value
);
8097 if (ret
.value
&& expr
.value
)
8098 set_c_expr_source_range (&ret
, cast_loc
, expr
.get_finish ());
8099 ret
.original_code
= ERROR_MARK
;
8100 ret
.original_type
= NULL
;
8104 return c_parser_unary_expression (parser
);
8107 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8113 unary-operator cast-expression
8114 sizeof unary-expression
8115 sizeof ( type-name )
8117 unary-operator: one of
8123 __alignof__ unary-expression
8124 __alignof__ ( type-name )
8127 (C11 permits _Alignof with type names only.)
8129 unary-operator: one of
8130 __extension__ __real__ __imag__
8132 Transactional Memory:
8135 transaction-expression
8137 In addition, the GNU syntax treats ++ and -- as unary operators, so
8138 they may be applied to cast expressions with errors for non-lvalues
8141 static struct c_expr
8142 c_parser_unary_expression (c_parser
*parser
)
8145 struct c_expr ret
, op
;
8146 location_t op_loc
= c_parser_peek_token (parser
)->location
;
8149 ret
.original_code
= ERROR_MARK
;
8150 ret
.original_type
= NULL
;
8151 switch (c_parser_peek_token (parser
)->type
)
8154 c_parser_consume_token (parser
);
8155 exp_loc
= c_parser_peek_token (parser
)->location
;
8156 op
= c_parser_cast_expression (parser
, NULL
);
8158 op
= default_function_array_read_conversion (exp_loc
, op
);
8159 return parser_build_unary_op (op_loc
, PREINCREMENT_EXPR
, op
);
8160 case CPP_MINUS_MINUS
:
8161 c_parser_consume_token (parser
);
8162 exp_loc
= c_parser_peek_token (parser
)->location
;
8163 op
= c_parser_cast_expression (parser
, NULL
);
8165 op
= default_function_array_read_conversion (exp_loc
, op
);
8166 return parser_build_unary_op (op_loc
, PREDECREMENT_EXPR
, op
);
8168 c_parser_consume_token (parser
);
8169 op
= c_parser_cast_expression (parser
, NULL
);
8170 mark_exp_read (op
.value
);
8171 return parser_build_unary_op (op_loc
, ADDR_EXPR
, op
);
8174 c_parser_consume_token (parser
);
8175 exp_loc
= c_parser_peek_token (parser
)->location
;
8176 op
= c_parser_cast_expression (parser
, NULL
);
8177 finish
= op
.get_finish ();
8178 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8179 location_t combined_loc
= make_location (op_loc
, op_loc
, finish
);
8180 ret
.value
= build_indirect_ref (combined_loc
, op
.value
, RO_UNARY_STAR
);
8181 ret
.src_range
.m_start
= op_loc
;
8182 ret
.src_range
.m_finish
= finish
;
8186 if (!c_dialect_objc () && !in_system_header_at (input_location
))
8189 "traditional C rejects the unary plus operator");
8190 c_parser_consume_token (parser
);
8191 exp_loc
= c_parser_peek_token (parser
)->location
;
8192 op
= c_parser_cast_expression (parser
, NULL
);
8193 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8194 return parser_build_unary_op (op_loc
, CONVERT_EXPR
, op
);
8196 c_parser_consume_token (parser
);
8197 exp_loc
= c_parser_peek_token (parser
)->location
;
8198 op
= c_parser_cast_expression (parser
, NULL
);
8199 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8200 return parser_build_unary_op (op_loc
, NEGATE_EXPR
, op
);
8202 c_parser_consume_token (parser
);
8203 exp_loc
= c_parser_peek_token (parser
)->location
;
8204 op
= c_parser_cast_expression (parser
, NULL
);
8205 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8206 return parser_build_unary_op (op_loc
, BIT_NOT_EXPR
, op
);
8208 c_parser_consume_token (parser
);
8209 exp_loc
= c_parser_peek_token (parser
)->location
;
8210 op
= c_parser_cast_expression (parser
, NULL
);
8211 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8212 return parser_build_unary_op (op_loc
, TRUTH_NOT_EXPR
, op
);
8214 /* Refer to the address of a label as a pointer. */
8215 c_parser_consume_token (parser
);
8216 if (c_parser_next_token_is (parser
, CPP_NAME
))
8218 ret
.value
= finish_label_address_expr
8219 (c_parser_peek_token (parser
)->value
, op_loc
);
8220 set_c_expr_source_range (&ret
, op_loc
,
8221 c_parser_peek_token (parser
)->get_finish ());
8222 c_parser_consume_token (parser
);
8226 c_parser_error (parser
, "expected identifier");
8231 switch (c_parser_peek_token (parser
)->keyword
)
8234 return c_parser_sizeof_expression (parser
);
8236 return c_parser_alignof_expression (parser
);
8237 case RID_BUILTIN_HAS_ATTRIBUTE
:
8238 return c_parser_has_attribute_expression (parser
);
8240 c_parser_consume_token (parser
);
8241 ext
= disable_extension_diagnostics ();
8242 ret
= c_parser_cast_expression (parser
, NULL
);
8243 restore_extension_diagnostics (ext
);
8246 c_parser_consume_token (parser
);
8247 exp_loc
= c_parser_peek_token (parser
)->location
;
8248 op
= c_parser_cast_expression (parser
, NULL
);
8249 op
= default_function_array_conversion (exp_loc
, op
);
8250 return parser_build_unary_op (op_loc
, REALPART_EXPR
, op
);
8252 c_parser_consume_token (parser
);
8253 exp_loc
= c_parser_peek_token (parser
)->location
;
8254 op
= c_parser_cast_expression (parser
, NULL
);
8255 op
= default_function_array_conversion (exp_loc
, op
);
8256 return parser_build_unary_op (op_loc
, IMAGPART_EXPR
, op
);
8257 case RID_TRANSACTION_ATOMIC
:
8258 case RID_TRANSACTION_RELAXED
:
8259 return c_parser_transaction_expression (parser
,
8260 c_parser_peek_token (parser
)->keyword
);
8262 return c_parser_postfix_expression (parser
);
8265 return c_parser_postfix_expression (parser
);
8269 /* Parse a sizeof expression. */
8271 static struct c_expr
8272 c_parser_sizeof_expression (c_parser
*parser
)
8275 struct c_expr result
;
8276 location_t expr_loc
;
8277 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SIZEOF
));
8280 location_t finish
= UNKNOWN_LOCATION
;
8282 start
= c_parser_peek_token (parser
)->location
;
8284 c_parser_consume_token (parser
);
8285 c_inhibit_evaluation_warnings
++;
8287 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8288 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8290 /* Either sizeof ( type-name ) or sizeof unary-expression
8291 starting with a compound literal. */
8292 struct c_type_name
*type_name
;
8293 matching_parens parens
;
8294 parens
.consume_open (parser
);
8295 expr_loc
= c_parser_peek_token (parser
)->location
;
8296 type_name
= c_parser_type_name (parser
, true);
8297 parens
.skip_until_found_close (parser
);
8298 finish
= parser
->tokens_buf
[0].location
;
8299 if (type_name
== NULL
)
8302 c_inhibit_evaluation_warnings
--;
8305 ret
.original_code
= ERROR_MARK
;
8306 ret
.original_type
= NULL
;
8309 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8311 expr
= c_parser_postfix_expression_after_paren_type (parser
,
8314 finish
= expr
.get_finish ();
8317 /* sizeof ( type-name ). */
8318 if (type_name
->specs
->alignas_p
)
8319 error_at (type_name
->specs
->locations
[cdw_alignas
],
8320 "alignment specified for type name in %<sizeof%>");
8321 c_inhibit_evaluation_warnings
--;
8323 result
= c_expr_sizeof_type (expr_loc
, type_name
);
8327 expr_loc
= c_parser_peek_token (parser
)->location
;
8328 expr
= c_parser_unary_expression (parser
);
8329 finish
= expr
.get_finish ();
8331 c_inhibit_evaluation_warnings
--;
8333 mark_exp_read (expr
.value
);
8334 if (TREE_CODE (expr
.value
) == COMPONENT_REF
8335 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
8336 error_at (expr_loc
, "%<sizeof%> applied to a bit-field");
8337 result
= c_expr_sizeof_expr (expr_loc
, expr
);
8339 if (finish
== UNKNOWN_LOCATION
)
8341 set_c_expr_source_range (&result
, start
, finish
);
8345 /* Parse an alignof expression. */
8347 static struct c_expr
8348 c_parser_alignof_expression (c_parser
*parser
)
8351 location_t start_loc
= c_parser_peek_token (parser
)->location
;
8353 tree alignof_spelling
= c_parser_peek_token (parser
)->value
;
8354 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNOF
));
8355 bool is_c11_alignof
= strcmp (IDENTIFIER_POINTER (alignof_spelling
),
8357 /* A diagnostic is not required for the use of this identifier in
8358 the implementation namespace; only diagnose it for the C11
8359 spelling because of existing code using the other spellings. */
8363 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C99 does not support %qE",
8366 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C90 does not support %qE",
8369 c_parser_consume_token (parser
);
8370 c_inhibit_evaluation_warnings
++;
8372 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8373 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8375 /* Either __alignof__ ( type-name ) or __alignof__
8376 unary-expression starting with a compound literal. */
8378 struct c_type_name
*type_name
;
8380 matching_parens parens
;
8381 parens
.consume_open (parser
);
8382 loc
= c_parser_peek_token (parser
)->location
;
8383 type_name
= c_parser_type_name (parser
, true);
8384 end_loc
= c_parser_peek_token (parser
)->location
;
8385 parens
.skip_until_found_close (parser
);
8386 if (type_name
== NULL
)
8389 c_inhibit_evaluation_warnings
--;
8392 ret
.original_code
= ERROR_MARK
;
8393 ret
.original_type
= NULL
;
8396 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8398 expr
= c_parser_postfix_expression_after_paren_type (parser
,
8403 /* alignof ( type-name ). */
8404 if (type_name
->specs
->alignas_p
)
8405 error_at (type_name
->specs
->locations
[cdw_alignas
],
8406 "alignment specified for type name in %qE",
8408 c_inhibit_evaluation_warnings
--;
8410 ret
.value
= c_sizeof_or_alignof_type (loc
, groktypename (type_name
,
8412 false, is_c11_alignof
, 1);
8413 ret
.original_code
= ERROR_MARK
;
8414 ret
.original_type
= NULL
;
8415 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
8421 expr
= c_parser_unary_expression (parser
);
8422 end_loc
= expr
.src_range
.m_finish
;
8424 mark_exp_read (expr
.value
);
8425 c_inhibit_evaluation_warnings
--;
8429 OPT_Wpedantic
, "ISO C does not allow %<%E (expression)%>",
8431 ret
.value
= c_alignof_expr (start_loc
, expr
.value
);
8432 ret
.original_code
= ERROR_MARK
;
8433 ret
.original_type
= NULL
;
8434 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
8439 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8442 static struct c_expr
8443 c_parser_has_attribute_expression (c_parser
*parser
)
8445 gcc_assert (c_parser_next_token_is_keyword (parser
,
8446 RID_BUILTIN_HAS_ATTRIBUTE
));
8447 c_parser_consume_token (parser
);
8449 c_inhibit_evaluation_warnings
++;
8451 matching_parens parens
;
8452 if (!parens
.require_open (parser
))
8454 c_inhibit_evaluation_warnings
--;
8457 struct c_expr result
;
8458 result
.set_error ();
8459 result
.original_code
= ERROR_MARK
;
8460 result
.original_type
= NULL
;
8464 /* Treat the type argument the same way as in typeof for the purposes
8465 of warnings. FIXME: Generalize this so the warning refers to
8466 __builtin_has_attribute rather than typeof. */
8469 /* The first operand: one of DECL, EXPR, or TYPE. */
8470 tree oper
= NULL_TREE
;
8471 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
8473 struct c_type_name
*tname
= c_parser_type_name (parser
);
8477 oper
= groktypename (tname
, NULL
, NULL
);
8478 pop_maybe_used (variably_modified_type_p (oper
, NULL_TREE
));
8483 struct c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
8484 c_inhibit_evaluation_warnings
--;
8486 if (cexpr
.value
!= error_mark_node
)
8488 mark_exp_read (cexpr
.value
);
8490 tree etype
= TREE_TYPE (oper
);
8491 bool was_vm
= variably_modified_type_p (etype
, NULL_TREE
);
8492 /* This is returned with the type so that when the type is
8493 evaluated, this can be evaluated. */
8495 oper
= c_fully_fold (oper
, false, NULL
);
8496 pop_maybe_used (was_vm
);
8500 struct c_expr result
;
8501 result
.original_code
= ERROR_MARK
;
8502 result
.original_type
= NULL
;
8504 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8506 /* Consume the closing parenthesis if that's the next token
8507 in the likely case the built-in was invoked with fewer
8508 than two arguments. */
8509 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8510 c_parser_consume_token (parser
);
8511 c_inhibit_evaluation_warnings
--;
8512 result
.set_error ();
8516 bool save_translate_strings_p
= parser
->translate_strings_p
;
8518 location_t atloc
= c_parser_peek_token (parser
)->location
;
8519 /* Parse a single attribute. Require no leading comma and do not
8520 allow empty attributes. */
8521 tree attr
= c_parser_gnu_attribute (parser
, NULL_TREE
, false, false);
8523 parser
->translate_strings_p
= save_translate_strings_p
;
8525 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8526 c_parser_consume_token (parser
);
8529 c_parser_error (parser
, "expected identifier");
8530 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8532 result
.set_error ();
8538 error_at (atloc
, "expected identifier");
8539 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8541 result
.set_error ();
8545 result
.original_code
= INTEGER_CST
;
8546 result
.original_type
= boolean_type_node
;
8548 if (has_attribute (atloc
, oper
, attr
, default_conversion
))
8549 result
.value
= boolean_true_node
;
8551 result
.value
= boolean_false_node
;
8556 /* Helper function to read arguments of builtins which are interfaces
8557 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8558 others. The name of the builtin is passed using BNAME parameter.
8559 Function returns true if there were no errors while parsing and
8560 stores the arguments in CEXPR_LIST. If it returns true,
8561 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8564 c_parser_get_builtin_args (c_parser
*parser
, const char *bname
,
8565 vec
<c_expr_t
, va_gc
> **ret_cexpr_list
,
8567 location_t
*out_close_paren_loc
)
8569 location_t loc
= c_parser_peek_token (parser
)->location
;
8570 vec
<c_expr_t
, va_gc
> *cexpr_list
;
8572 bool saved_force_folding_builtin_constant_p
;
8574 *ret_cexpr_list
= NULL
;
8575 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
8577 error_at (loc
, "cannot take address of %qs", bname
);
8581 c_parser_consume_token (parser
);
8583 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8585 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
8586 c_parser_consume_token (parser
);
8590 saved_force_folding_builtin_constant_p
8591 = force_folding_builtin_constant_p
;
8592 force_folding_builtin_constant_p
|= choose_expr_p
;
8593 expr
= c_parser_expr_no_commas (parser
, NULL
);
8594 force_folding_builtin_constant_p
8595 = saved_force_folding_builtin_constant_p
;
8596 vec_alloc (cexpr_list
, 1);
8597 vec_safe_push (cexpr_list
, expr
);
8598 while (c_parser_next_token_is (parser
, CPP_COMMA
))
8600 c_parser_consume_token (parser
);
8601 expr
= c_parser_expr_no_commas (parser
, NULL
);
8602 vec_safe_push (cexpr_list
, expr
);
8605 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
8606 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
8609 *ret_cexpr_list
= cexpr_list
;
8613 /* This represents a single generic-association. */
8615 struct c_generic_association
8617 /* The location of the starting token of the type. */
8618 location_t type_location
;
8619 /* The association's type, or NULL_TREE for 'default'. */
8621 /* The association's expression. */
8622 struct c_expr expression
;
8625 /* Parse a generic-selection. (C11 6.5.1.1).
8628 _Generic ( assignment-expression , generic-assoc-list )
8632 generic-assoc-list , generic-association
8634 generic-association:
8635 type-name : assignment-expression
8636 default : assignment-expression
8639 static struct c_expr
8640 c_parser_generic_selection (c_parser
*parser
)
8642 struct c_expr selector
, error_expr
;
8644 struct c_generic_association matched_assoc
;
8645 bool match_found
= false;
8646 location_t generic_loc
, selector_loc
;
8648 error_expr
.original_code
= ERROR_MARK
;
8649 error_expr
.original_type
= NULL
;
8650 error_expr
.set_error ();
8651 matched_assoc
.type_location
= UNKNOWN_LOCATION
;
8652 matched_assoc
.type
= NULL_TREE
;
8653 matched_assoc
.expression
= error_expr
;
8655 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_GENERIC
));
8656 generic_loc
= c_parser_peek_token (parser
)->location
;
8657 c_parser_consume_token (parser
);
8659 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
8660 "ISO C99 does not support %<_Generic%>");
8662 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
8663 "ISO C90 does not support %<_Generic%>");
8665 matching_parens parens
;
8666 if (!parens
.require_open (parser
))
8669 c_inhibit_evaluation_warnings
++;
8670 selector_loc
= c_parser_peek_token (parser
)->location
;
8671 selector
= c_parser_expr_no_commas (parser
, NULL
);
8672 selector
= default_function_array_conversion (selector_loc
, selector
);
8673 c_inhibit_evaluation_warnings
--;
8675 if (selector
.value
== error_mark_node
)
8677 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8680 selector_type
= TREE_TYPE (selector
.value
);
8681 /* In ISO C terms, rvalues (including the controlling expression of
8682 _Generic) do not have qualified types. */
8683 if (TREE_CODE (selector_type
) != ARRAY_TYPE
)
8684 selector_type
= TYPE_MAIN_VARIANT (selector_type
);
8685 /* In ISO C terms, _Noreturn is not part of the type of expressions
8686 such as &abort, but in GCC it is represented internally as a type
8688 if (FUNCTION_POINTER_TYPE_P (selector_type
)
8689 && TYPE_QUALS (TREE_TYPE (selector_type
)) != TYPE_UNQUALIFIED
)
8691 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type
)));
8693 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8695 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8699 auto_vec
<c_generic_association
> associations
;
8702 struct c_generic_association assoc
, *iter
;
8704 c_token
*token
= c_parser_peek_token (parser
);
8706 assoc
.type_location
= token
->location
;
8707 if (token
->type
== CPP_KEYWORD
&& token
->keyword
== RID_DEFAULT
)
8709 c_parser_consume_token (parser
);
8710 assoc
.type
= NULL_TREE
;
8714 struct c_type_name
*type_name
;
8716 type_name
= c_parser_type_name (parser
);
8717 if (type_name
== NULL
)
8719 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8722 assoc
.type
= groktypename (type_name
, NULL
, NULL
);
8723 if (assoc
.type
== error_mark_node
)
8725 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8729 if (TREE_CODE (assoc
.type
) == FUNCTION_TYPE
)
8730 error_at (assoc
.type_location
,
8731 "%<_Generic%> association has function type");
8732 else if (!COMPLETE_TYPE_P (assoc
.type
))
8733 error_at (assoc
.type_location
,
8734 "%<_Generic%> association has incomplete type");
8736 if (variably_modified_type_p (assoc
.type
, NULL_TREE
))
8737 error_at (assoc
.type_location
,
8738 "%<_Generic%> association has "
8739 "variable length type");
8742 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
8744 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8748 assoc
.expression
= c_parser_expr_no_commas (parser
, NULL
);
8749 if (assoc
.expression
.value
== error_mark_node
)
8751 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8755 for (ix
= 0; associations
.iterate (ix
, &iter
); ++ix
)
8757 if (assoc
.type
== NULL_TREE
)
8759 if (iter
->type
== NULL_TREE
)
8761 error_at (assoc
.type_location
,
8762 "duplicate %<default%> case in %<_Generic%>");
8763 inform (iter
->type_location
, "original %<default%> is here");
8766 else if (iter
->type
!= NULL_TREE
)
8768 if (comptypes (assoc
.type
, iter
->type
))
8770 error_at (assoc
.type_location
,
8771 "%<_Generic%> specifies two compatible types");
8772 inform (iter
->type_location
, "compatible type is here");
8777 if (assoc
.type
== NULL_TREE
)
8781 matched_assoc
= assoc
;
8785 else if (comptypes (assoc
.type
, selector_type
))
8787 if (!match_found
|| matched_assoc
.type
== NULL_TREE
)
8789 matched_assoc
= assoc
;
8794 error_at (assoc
.type_location
,
8795 "%<_Generic%> selector matches multiple associations");
8796 inform (matched_assoc
.type_location
,
8797 "other match is here");
8801 associations
.safe_push (assoc
);
8803 if (c_parser_peek_token (parser
)->type
!= CPP_COMMA
)
8805 c_parser_consume_token (parser
);
8808 if (!parens
.require_close (parser
))
8810 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8816 error_at (selector_loc
, "%<_Generic%> selector of type %qT is not "
8817 "compatible with any association",
8822 return matched_assoc
.expression
;
8825 /* Check the validity of a function pointer argument *EXPR (argument
8826 position POS) to __builtin_tgmath. Return the number of function
8827 arguments if possibly valid; return 0 having reported an error if
8831 check_tgmath_function (c_expr
*expr
, unsigned int pos
)
8833 tree type
= TREE_TYPE (expr
->value
);
8834 if (!FUNCTION_POINTER_TYPE_P (type
))
8836 error_at (expr
->get_location (),
8837 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8841 type
= TREE_TYPE (type
);
8842 if (!prototype_p (type
))
8844 error_at (expr
->get_location (),
8845 "argument %u of %<__builtin_tgmath%> is unprototyped", pos
);
8848 if (stdarg_p (type
))
8850 error_at (expr
->get_location (),
8851 "argument %u of %<__builtin_tgmath%> has variable arguments",
8855 unsigned int nargs
= 0;
8856 function_args_iterator iter
;
8858 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
8860 if (t
== void_type_node
)
8866 error_at (expr
->get_location (),
8867 "argument %u of %<__builtin_tgmath%> has no arguments", pos
);
8873 /* Ways in which a parameter or return value of a type-generic macro
8874 may vary between the different functions the macro may call. */
8875 enum tgmath_parm_kind
8877 tgmath_fixed
, tgmath_real
, tgmath_complex
8880 /* Helper function for c_parser_postfix_expression. Parse predefined
8883 static struct c_expr
8884 c_parser_predefined_identifier (c_parser
*parser
)
8886 location_t loc
= c_parser_peek_token (parser
)->location
;
8887 switch (c_parser_peek_token (parser
)->keyword
)
8889 case RID_FUNCTION_NAME
:
8890 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
8891 "identifier", "__FUNCTION__");
8893 case RID_PRETTY_FUNCTION_NAME
:
8894 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
8895 "identifier", "__PRETTY_FUNCTION__");
8897 case RID_C99_FUNCTION_NAME
:
8898 pedwarn_c90 (loc
, OPT_Wpedantic
, "ISO C90 does not support "
8899 "%<__func__%> predefined identifier");
8906 expr
.original_code
= ERROR_MARK
;
8907 expr
.original_type
= NULL
;
8908 expr
.value
= fname_decl (loc
, c_parser_peek_token (parser
)->keyword
,
8909 c_parser_peek_token (parser
)->value
);
8910 set_c_expr_source_range (&expr
, loc
, loc
);
8911 c_parser_consume_token (parser
);
8915 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8916 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8917 call c_parser_postfix_expression_after_paren_type on encountering them.
8921 postfix-expression [ expression ]
8922 postfix-expression ( argument-expression-list[opt] )
8923 postfix-expression . identifier
8924 postfix-expression -> identifier
8925 postfix-expression ++
8926 postfix-expression --
8927 ( type-name ) { initializer-list }
8928 ( type-name ) { initializer-list , }
8930 argument-expression-list:
8932 argument-expression-list , argument-expression
8945 (treated as a keyword in GNU C)
8948 ( compound-statement )
8949 __builtin_va_arg ( assignment-expression , type-name )
8950 __builtin_offsetof ( type-name , offsetof-member-designator )
8951 __builtin_choose_expr ( assignment-expression ,
8952 assignment-expression ,
8953 assignment-expression )
8954 __builtin_types_compatible_p ( type-name , type-name )
8955 __builtin_tgmath ( expr-list )
8956 __builtin_complex ( assignment-expression , assignment-expression )
8957 __builtin_shuffle ( assignment-expression , assignment-expression )
8958 __builtin_shuffle ( assignment-expression ,
8959 assignment-expression ,
8960 assignment-expression, )
8961 __builtin_convertvector ( assignment-expression , type-name )
8963 offsetof-member-designator:
8965 offsetof-member-designator . identifier
8966 offsetof-member-designator [ expression ]
8971 [ objc-receiver objc-message-args ]
8972 @selector ( objc-selector-arg )
8973 @protocol ( identifier )
8974 @encode ( type-name )
8976 Classname . identifier
8979 static struct c_expr
8980 c_parser_postfix_expression (c_parser
*parser
)
8982 struct c_expr expr
, e1
;
8983 struct c_type_name
*t1
, *t2
;
8984 location_t loc
= c_parser_peek_token (parser
)->location
;
8985 source_range tok_range
= c_parser_peek_token (parser
)->get_range ();
8986 expr
.original_code
= ERROR_MARK
;
8987 expr
.original_type
= NULL
;
8988 switch (c_parser_peek_token (parser
)->type
)
8991 expr
.value
= c_parser_peek_token (parser
)->value
;
8992 set_c_expr_source_range (&expr
, tok_range
);
8993 loc
= c_parser_peek_token (parser
)->location
;
8994 c_parser_consume_token (parser
);
8995 if (TREE_CODE (expr
.value
) == FIXED_CST
8996 && !targetm
.fixed_point_supported_p ())
8998 error_at (loc
, "fixed-point types not supported for this target");
9007 expr
.value
= c_parser_peek_token (parser
)->value
;
9008 /* For the purpose of warning when a pointer is compared with
9009 a zero character constant. */
9010 expr
.original_type
= char_type_node
;
9011 set_c_expr_source_range (&expr
, tok_range
);
9012 c_parser_consume_token (parser
);
9018 case CPP_UTF8STRING
:
9019 expr
= c_parser_string_literal (parser
, parser
->translate_strings_p
,
9022 case CPP_OBJC_STRING
:
9023 gcc_assert (c_dialect_objc ());
9025 = objc_build_string_object (c_parser_peek_token (parser
)->value
);
9026 set_c_expr_source_range (&expr
, tok_range
);
9027 c_parser_consume_token (parser
);
9030 switch (c_parser_peek_token (parser
)->id_kind
)
9034 tree id
= c_parser_peek_token (parser
)->value
;
9035 c_parser_consume_token (parser
);
9036 expr
.value
= build_external_ref (loc
, id
,
9037 (c_parser_peek_token (parser
)->type
9039 &expr
.original_type
);
9040 set_c_expr_source_range (&expr
, tok_range
);
9043 case C_ID_CLASSNAME
:
9045 /* Here we parse the Objective-C 2.0 Class.name dot
9047 tree class_name
= c_parser_peek_token (parser
)->value
;
9049 c_parser_consume_token (parser
);
9050 gcc_assert (c_dialect_objc ());
9051 if (!c_parser_require (parser
, CPP_DOT
, "expected %<.%>"))
9056 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9058 c_parser_error (parser
, "expected identifier");
9062 c_token
*component_tok
= c_parser_peek_token (parser
);
9063 component
= component_tok
->value
;
9064 location_t end_loc
= component_tok
->get_finish ();
9065 c_parser_consume_token (parser
);
9066 expr
.value
= objc_build_class_component_ref (class_name
,
9068 set_c_expr_source_range (&expr
, loc
, end_loc
);
9072 c_parser_error (parser
, "expected expression");
9077 case CPP_OPEN_PAREN
:
9078 /* A parenthesized expression, statement expression or compound
9080 if (c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_BRACE
)
9082 /* A statement expression. */
9084 location_t brace_loc
;
9085 c_parser_consume_token (parser
);
9086 brace_loc
= c_parser_peek_token (parser
)->location
;
9087 c_parser_consume_token (parser
);
9088 /* If we've not yet started the current function's statement list,
9089 or we're in the parameter scope of an old-style function
9090 declaration, statement expressions are not allowed. */
9091 if (!building_stmt_list_p () || old_style_parameter_scope ())
9093 error_at (loc
, "braced-group within expression allowed "
9094 "only inside a function");
9095 parser
->error
= true;
9096 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
9097 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9101 stmt
= c_begin_stmt_expr ();
9102 c_parser_compound_statement_nostart (parser
);
9103 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9104 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9106 pedwarn (loc
, OPT_Wpedantic
,
9107 "ISO C forbids braced-groups within expressions");
9108 expr
.value
= c_finish_stmt_expr (brace_loc
, stmt
);
9109 set_c_expr_source_range (&expr
, loc
, close_loc
);
9110 mark_exp_read (expr
.value
);
9114 /* A parenthesized expression. */
9115 location_t loc_open_paren
= c_parser_peek_token (parser
)->location
;
9116 c_parser_consume_token (parser
);
9117 expr
= c_parser_expression (parser
);
9118 if (TREE_CODE (expr
.value
) == MODIFY_EXPR
)
9119 TREE_NO_WARNING (expr
.value
) = 1;
9120 if (expr
.original_code
!= C_MAYBE_CONST_EXPR
9121 && expr
.original_code
!= SIZEOF_EXPR
)
9122 expr
.original_code
= ERROR_MARK
;
9123 /* Don't change EXPR.ORIGINAL_TYPE. */
9124 location_t loc_close_paren
= c_parser_peek_token (parser
)->location
;
9125 set_c_expr_source_range (&expr
, loc_open_paren
, loc_close_paren
);
9126 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9127 "expected %<)%>", loc_open_paren
);
9131 switch (c_parser_peek_token (parser
)->keyword
)
9133 case RID_FUNCTION_NAME
:
9134 case RID_PRETTY_FUNCTION_NAME
:
9135 case RID_C99_FUNCTION_NAME
:
9136 expr
= c_parser_predefined_identifier (parser
);
9140 location_t start_loc
= loc
;
9141 c_parser_consume_token (parser
);
9142 matching_parens parens
;
9143 if (!parens
.require_open (parser
))
9148 e1
= c_parser_expr_no_commas (parser
, NULL
);
9149 mark_exp_read (e1
.value
);
9150 e1
.value
= c_fully_fold (e1
.value
, false, NULL
);
9151 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9153 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9157 loc
= c_parser_peek_token (parser
)->location
;
9158 t1
= c_parser_type_name (parser
);
9159 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9160 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9168 tree type_expr
= NULL_TREE
;
9169 expr
.value
= c_build_va_arg (start_loc
, e1
.value
, loc
,
9170 groktypename (t1
, &type_expr
, NULL
));
9173 expr
.value
= build2 (C_MAYBE_CONST_EXPR
,
9174 TREE_TYPE (expr
.value
), type_expr
,
9176 C_MAYBE_CONST_EXPR_NON_CONST (expr
.value
) = true;
9178 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
9184 c_parser_consume_token (parser
);
9185 matching_parens parens
;
9186 if (!parens
.require_open (parser
))
9191 t1
= c_parser_type_name (parser
);
9193 parser
->error
= true;
9194 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9195 gcc_assert (parser
->error
);
9198 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9202 tree type
= groktypename (t1
, NULL
, NULL
);
9204 if (type
== error_mark_node
)
9205 offsetof_ref
= error_mark_node
;
9208 offsetof_ref
= build1 (INDIRECT_REF
, type
, null_pointer_node
);
9209 SET_EXPR_LOCATION (offsetof_ref
, loc
);
9211 /* Parse the second argument to __builtin_offsetof. We
9212 must have one identifier, and beyond that we want to
9213 accept sub structure and sub array references. */
9214 if (c_parser_next_token_is (parser
, CPP_NAME
))
9216 c_token
*comp_tok
= c_parser_peek_token (parser
);
9217 offsetof_ref
= build_component_ref
9218 (loc
, offsetof_ref
, comp_tok
->value
, comp_tok
->location
);
9219 c_parser_consume_token (parser
);
9220 while (c_parser_next_token_is (parser
, CPP_DOT
)
9221 || c_parser_next_token_is (parser
,
9223 || c_parser_next_token_is (parser
,
9226 if (c_parser_next_token_is (parser
, CPP_DEREF
))
9228 loc
= c_parser_peek_token (parser
)->location
;
9229 offsetof_ref
= build_array_ref (loc
,
9234 else if (c_parser_next_token_is (parser
, CPP_DOT
))
9237 c_parser_consume_token (parser
);
9238 if (c_parser_next_token_is_not (parser
,
9241 c_parser_error (parser
, "expected identifier");
9244 c_token
*comp_tok
= c_parser_peek_token (parser
);
9245 offsetof_ref
= build_component_ref
9246 (loc
, offsetof_ref
, comp_tok
->value
,
9247 comp_tok
->location
);
9248 c_parser_consume_token (parser
);
9254 loc
= c_parser_peek_token (parser
)->location
;
9255 c_parser_consume_token (parser
);
9256 ce
= c_parser_expression (parser
);
9257 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
9259 idx
= c_fully_fold (idx
, false, NULL
);
9260 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
9262 offsetof_ref
= build_array_ref (loc
, offsetof_ref
, idx
);
9267 c_parser_error (parser
, "expected identifier");
9268 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9269 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9271 expr
.value
= fold_offsetof (offsetof_ref
);
9272 set_c_expr_source_range (&expr
, loc
, end_loc
);
9275 case RID_CHOOSE_EXPR
:
9277 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9278 c_expr_t
*e1_p
, *e2_p
, *e3_p
;
9280 location_t close_paren_loc
;
9282 c_parser_consume_token (parser
);
9283 if (!c_parser_get_builtin_args (parser
,
9284 "__builtin_choose_expr",
9292 if (vec_safe_length (cexpr_list
) != 3)
9294 error_at (loc
, "wrong number of arguments to "
9295 "%<__builtin_choose_expr%>");
9300 e1_p
= &(*cexpr_list
)[0];
9301 e2_p
= &(*cexpr_list
)[1];
9302 e3_p
= &(*cexpr_list
)[2];
9305 mark_exp_read (e2_p
->value
);
9306 mark_exp_read (e3_p
->value
);
9307 if (TREE_CODE (c
) != INTEGER_CST
9308 || !INTEGRAL_TYPE_P (TREE_TYPE (c
)))
9310 "first argument to %<__builtin_choose_expr%> not"
9312 constant_expression_warning (c
);
9313 expr
= integer_zerop (c
) ? *e3_p
: *e2_p
;
9314 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9317 case RID_TYPES_COMPATIBLE_P
:
9319 c_parser_consume_token (parser
);
9320 matching_parens parens
;
9321 if (!parens
.require_open (parser
))
9326 t1
= c_parser_type_name (parser
);
9332 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9334 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9338 t2
= c_parser_type_name (parser
);
9344 location_t close_paren_loc
= c_parser_peek_token (parser
)->location
;
9345 parens
.skip_until_found_close (parser
);
9347 e1
= groktypename (t1
, NULL
, NULL
);
9348 e2
= groktypename (t2
, NULL
, NULL
);
9349 if (e1
== error_mark_node
|| e2
== error_mark_node
)
9355 e1
= TYPE_MAIN_VARIANT (e1
);
9356 e2
= TYPE_MAIN_VARIANT (e2
);
9359 = comptypes (e1
, e2
) ? integer_one_node
: integer_zero_node
;
9360 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9363 case RID_BUILTIN_TGMATH
:
9365 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9366 location_t close_paren_loc
;
9368 c_parser_consume_token (parser
);
9369 if (!c_parser_get_builtin_args (parser
,
9378 if (vec_safe_length (cexpr_list
) < 3)
9380 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9387 FOR_EACH_VEC_ELT (*cexpr_list
, i
, p
)
9388 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
9389 unsigned int nargs
= check_tgmath_function (&(*cexpr_list
)[0], 1);
9395 if (vec_safe_length (cexpr_list
) < nargs
)
9397 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9401 unsigned int num_functions
= vec_safe_length (cexpr_list
) - nargs
;
9402 if (num_functions
< 2)
9404 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9409 /* The first NUM_FUNCTIONS expressions are the function
9410 pointers. The remaining NARGS expressions are the
9411 arguments that are to be passed to one of those
9412 functions, chosen following <tgmath.h> rules. */
9413 for (unsigned int j
= 1; j
< num_functions
; j
++)
9415 unsigned int this_nargs
9416 = check_tgmath_function (&(*cexpr_list
)[j
], j
+ 1);
9417 if (this_nargs
== 0)
9422 if (this_nargs
!= nargs
)
9424 error_at ((*cexpr_list
)[j
].get_location (),
9425 "argument %u of %<__builtin_tgmath%> has "
9426 "wrong number of arguments", j
+ 1);
9432 /* The functions all have the same number of arguments.
9433 Determine whether arguments and return types vary in
9434 ways permitted for <tgmath.h> functions. */
9435 /* The first entry in each of these vectors is for the
9436 return type, subsequent entries for parameter
9438 auto_vec
<enum tgmath_parm_kind
> parm_kind (nargs
+ 1);
9439 auto_vec
<tree
> parm_first (nargs
+ 1);
9440 auto_vec
<bool> parm_complex (nargs
+ 1);
9441 auto_vec
<bool> parm_varies (nargs
+ 1);
9442 tree first_type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[0].value
));
9443 tree first_ret
= TYPE_MAIN_VARIANT (TREE_TYPE (first_type
));
9444 parm_first
.quick_push (first_ret
);
9445 parm_complex
.quick_push (TREE_CODE (first_ret
) == COMPLEX_TYPE
);
9446 parm_varies
.quick_push (false);
9447 function_args_iterator iter
;
9449 unsigned int argpos
;
9450 FOREACH_FUNCTION_ARGS (first_type
, t
, iter
)
9452 if (t
== void_type_node
)
9454 parm_first
.quick_push (TYPE_MAIN_VARIANT (t
));
9455 parm_complex
.quick_push (TREE_CODE (t
) == COMPLEX_TYPE
);
9456 parm_varies
.quick_push (false);
9458 for (unsigned int j
= 1; j
< num_functions
; j
++)
9460 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9461 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
9462 if (ret
!= parm_first
[0])
9464 parm_varies
[0] = true;
9465 if (!SCALAR_FLOAT_TYPE_P (parm_first
[0])
9466 && !COMPLEX_FLOAT_TYPE_P (parm_first
[0]))
9468 error_at ((*cexpr_list
)[0].get_location (),
9469 "invalid type-generic return type for "
9470 "argument %u of %<__builtin_tgmath%>",
9475 if (!SCALAR_FLOAT_TYPE_P (ret
)
9476 && !COMPLEX_FLOAT_TYPE_P (ret
))
9478 error_at ((*cexpr_list
)[j
].get_location (),
9479 "invalid type-generic return type for "
9480 "argument %u of %<__builtin_tgmath%>",
9486 if (TREE_CODE (ret
) == COMPLEX_TYPE
)
9487 parm_complex
[0] = true;
9489 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9491 if (t
== void_type_node
)
9493 t
= TYPE_MAIN_VARIANT (t
);
9494 if (t
!= parm_first
[argpos
])
9496 parm_varies
[argpos
] = true;
9497 if (!SCALAR_FLOAT_TYPE_P (parm_first
[argpos
])
9498 && !COMPLEX_FLOAT_TYPE_P (parm_first
[argpos
]))
9500 error_at ((*cexpr_list
)[0].get_location (),
9501 "invalid type-generic type for "
9502 "argument %u of argument %u of "
9503 "%<__builtin_tgmath%>", argpos
, 1);
9507 if (!SCALAR_FLOAT_TYPE_P (t
)
9508 && !COMPLEX_FLOAT_TYPE_P (t
))
9510 error_at ((*cexpr_list
)[j
].get_location (),
9511 "invalid type-generic type for "
9512 "argument %u of argument %u of "
9513 "%<__builtin_tgmath%>", argpos
, j
+ 1);
9518 if (TREE_CODE (t
) == COMPLEX_TYPE
)
9519 parm_complex
[argpos
] = true;
9523 enum tgmath_parm_kind max_variation
= tgmath_fixed
;
9524 for (unsigned int j
= 0; j
<= nargs
; j
++)
9526 enum tgmath_parm_kind this_kind
;
9529 if (parm_complex
[j
])
9530 max_variation
= this_kind
= tgmath_complex
;
9533 this_kind
= tgmath_real
;
9534 if (max_variation
!= tgmath_complex
)
9535 max_variation
= tgmath_real
;
9539 this_kind
= tgmath_fixed
;
9540 parm_kind
.quick_push (this_kind
);
9542 if (max_variation
== tgmath_fixed
)
9544 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
9545 "all have the same type");
9550 /* Identify a parameter (not the return type) that varies,
9551 including with complex types if any variation includes
9552 complex types; there must be at least one such
9554 unsigned int tgarg
= 0;
9555 for (unsigned int j
= 1; j
<= nargs
; j
++)
9556 if (parm_kind
[j
] == max_variation
)
9563 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
9564 "lack type-generic parameter");
9569 /* Determine the type of the relevant parameter for each
9571 auto_vec
<tree
> tg_type (num_functions
);
9572 for (unsigned int j
= 0; j
< num_functions
; j
++)
9574 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9576 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9578 if (argpos
== tgarg
)
9580 tg_type
.quick_push (TYPE_MAIN_VARIANT (t
));
9587 /* Verify that the corresponding types are different for
9588 all the listed functions. Also determine whether all
9589 the types are complex, whether all the types are
9590 standard or binary, and whether all the types are
9592 bool all_complex
= true;
9593 bool all_binary
= true;
9594 bool all_decimal
= true;
9595 hash_set
<tree
> tg_types
;
9596 FOR_EACH_VEC_ELT (tg_type
, i
, t
)
9598 if (TREE_CODE (t
) == COMPLEX_TYPE
)
9599 all_decimal
= false;
9602 all_complex
= false;
9603 if (DECIMAL_FLOAT_TYPE_P (t
))
9606 all_decimal
= false;
9608 if (tg_types
.add (t
))
9610 error_at ((*cexpr_list
)[i
].get_location (),
9611 "duplicate type-generic parameter type for "
9612 "function argument %u of %<__builtin_tgmath%>",
9619 /* Verify that other parameters and the return type whose
9620 types vary have their types varying in the correct
9622 for (unsigned int j
= 0; j
< num_functions
; j
++)
9624 tree exp_type
= tg_type
[j
];
9625 tree exp_real_type
= exp_type
;
9626 if (TREE_CODE (exp_type
) == COMPLEX_TYPE
)
9627 exp_real_type
= TREE_TYPE (exp_type
);
9628 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9629 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
9630 if ((parm_kind
[0] == tgmath_complex
&& ret
!= exp_type
)
9631 || (parm_kind
[0] == tgmath_real
&& ret
!= exp_real_type
))
9633 error_at ((*cexpr_list
)[j
].get_location (),
9634 "bad return type for function argument %u "
9635 "of %<__builtin_tgmath%>", j
+ 1);
9640 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9642 if (t
== void_type_node
)
9644 t
= TYPE_MAIN_VARIANT (t
);
9645 if ((parm_kind
[argpos
] == tgmath_complex
9647 || (parm_kind
[argpos
] == tgmath_real
9648 && t
!= exp_real_type
))
9650 error_at ((*cexpr_list
)[j
].get_location (),
9651 "bad type for argument %u of "
9652 "function argument %u of "
9653 "%<__builtin_tgmath%>", argpos
, j
+ 1);
9661 /* The functions listed are a valid set of functions for a
9662 <tgmath.h> macro to select between. Identify the
9663 matching function, if any. First, the argument types
9664 must be combined following <tgmath.h> rules. Integer
9665 types are treated as _Decimal64 if any type-generic
9666 argument is decimal, or if the only alternatives for
9667 type-generic arguments are of decimal types, and are
9668 otherwise treated as double (or _Complex double for
9669 complex integer types, or _Float64 or _Complex _Float64
9670 if all the return types are the same _FloatN or
9671 _FloatNx type). After that adjustment, types are
9672 combined following the usual arithmetic conversions.
9673 If the function only accepts complex arguments, a
9674 complex type is produced. */
9675 bool arg_complex
= all_complex
;
9676 bool arg_binary
= all_binary
;
9677 bool arg_int_decimal
= all_decimal
;
9678 for (unsigned int j
= 1; j
<= nargs
; j
++)
9680 if (parm_kind
[j
] == tgmath_fixed
)
9682 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9683 tree type
= TREE_TYPE (ce
->value
);
9684 if (!INTEGRAL_TYPE_P (type
)
9685 && !SCALAR_FLOAT_TYPE_P (type
)
9686 && TREE_CODE (type
) != COMPLEX_TYPE
)
9688 error_at (ce
->get_location (),
9689 "invalid type of argument %u of type-generic "
9694 if (DECIMAL_FLOAT_TYPE_P (type
))
9696 arg_int_decimal
= true;
9699 error_at (ce
->get_location (),
9700 "decimal floating-point argument %u to "
9701 "complex-only type-generic function", j
);
9705 else if (all_binary
)
9707 error_at (ce
->get_location (),
9708 "decimal floating-point argument %u to "
9709 "binary-only type-generic function", j
);
9713 else if (arg_complex
)
9715 error_at (ce
->get_location (),
9716 "both complex and decimal floating-point "
9717 "arguments to type-generic function");
9721 else if (arg_binary
)
9723 error_at (ce
->get_location (),
9724 "both binary and decimal floating-point "
9725 "arguments to type-generic function");
9730 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
9733 if (COMPLEX_FLOAT_TYPE_P (type
))
9737 error_at (ce
->get_location (),
9738 "complex argument %u to "
9739 "decimal-only type-generic function", j
);
9743 else if (arg_int_decimal
)
9745 error_at (ce
->get_location (),
9746 "both complex and decimal floating-point "
9747 "arguments to type-generic function");
9752 else if (SCALAR_FLOAT_TYPE_P (type
))
9757 error_at (ce
->get_location (),
9758 "binary argument %u to "
9759 "decimal-only type-generic function", j
);
9763 else if (arg_int_decimal
)
9765 error_at (ce
->get_location (),
9766 "both binary and decimal floating-point "
9767 "arguments to type-generic function");
9773 /* For a macro rounding its result to a narrower type, map
9774 integer types to _Float64 not double if the return type
9775 is a _FloatN or _FloatNx type. */
9776 bool arg_int_float64
= false;
9777 if (parm_kind
[0] == tgmath_fixed
9778 && SCALAR_FLOAT_TYPE_P (parm_first
[0])
9779 && float64_type_node
!= NULL_TREE
)
9780 for (unsigned int j
= 0; j
< NUM_FLOATN_NX_TYPES
; j
++)
9781 if (parm_first
[0] == FLOATN_TYPE_NODE (j
))
9783 arg_int_float64
= true;
9786 tree arg_real
= NULL_TREE
;
9787 for (unsigned int j
= 1; j
<= nargs
; j
++)
9789 if (parm_kind
[j
] == tgmath_fixed
)
9791 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9792 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (ce
->value
));
9793 if (TREE_CODE (type
) == COMPLEX_TYPE
)
9794 type
= TREE_TYPE (type
);
9795 if (INTEGRAL_TYPE_P (type
))
9796 type
= (arg_int_decimal
9797 ? dfloat64_type_node
9800 : double_type_node
);
9801 if (arg_real
== NULL_TREE
)
9804 arg_real
= common_type (arg_real
, type
);
9805 if (arg_real
== error_mark_node
)
9811 tree arg_type
= (arg_complex
9812 ? build_complex_type (arg_real
)
9815 /* Look for a function to call with type-generic parameter
9817 c_expr_t
*fn
= NULL
;
9818 for (unsigned int j
= 0; j
< num_functions
; j
++)
9820 if (tg_type
[j
] == arg_type
)
9822 fn
= &(*cexpr_list
)[j
];
9827 && parm_kind
[0] == tgmath_fixed
9828 && SCALAR_FLOAT_TYPE_P (parm_first
[0]))
9830 /* Presume this is a macro that rounds its result to a
9831 narrower type, and look for the first function with
9832 at least the range and precision of the argument
9834 for (unsigned int j
= 0; j
< num_functions
; j
++)
9837 != (TREE_CODE (tg_type
[j
]) == COMPLEX_TYPE
))
9839 tree real_tg_type
= (arg_complex
9840 ? TREE_TYPE (tg_type
[j
])
9842 if (DECIMAL_FLOAT_TYPE_P (arg_real
)
9843 != DECIMAL_FLOAT_TYPE_P (real_tg_type
))
9845 scalar_float_mode arg_mode
9846 = SCALAR_FLOAT_TYPE_MODE (arg_real
);
9847 scalar_float_mode tg_mode
9848 = SCALAR_FLOAT_TYPE_MODE (real_tg_type
);
9849 const real_format
*arg_fmt
= REAL_MODE_FORMAT (arg_mode
);
9850 const real_format
*tg_fmt
= REAL_MODE_FORMAT (tg_mode
);
9851 if (arg_fmt
->b
== tg_fmt
->b
9852 && arg_fmt
->p
<= tg_fmt
->p
9853 && arg_fmt
->emax
<= tg_fmt
->emax
9854 && (arg_fmt
->emin
- arg_fmt
->p
9855 >= tg_fmt
->emin
- tg_fmt
->p
))
9857 fn
= &(*cexpr_list
)[j
];
9864 error_at (loc
, "no matching function for type-generic call");
9869 /* Construct a call to FN. */
9870 vec
<tree
, va_gc
> *args
;
9871 vec_alloc (args
, nargs
);
9872 vec
<tree
, va_gc
> *origtypes
;
9873 vec_alloc (origtypes
, nargs
);
9874 auto_vec
<location_t
> arg_loc (nargs
);
9875 for (unsigned int j
= 0; j
< nargs
; j
++)
9877 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
];
9878 args
->quick_push (ce
->value
);
9879 arg_loc
.quick_push (ce
->get_location ());
9880 origtypes
->quick_push (ce
->original_type
);
9882 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fn
->value
,
9884 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9887 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN
:
9889 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9892 location_t close_paren_loc
;
9894 c_parser_consume_token (parser
);
9895 if (!c_parser_get_builtin_args (parser
,
9896 "__builtin_call_with_static_chain",
9903 if (vec_safe_length (cexpr_list
) != 2)
9905 error_at (loc
, "wrong number of arguments to "
9906 "%<__builtin_call_with_static_chain%>");
9911 expr
= (*cexpr_list
)[0];
9912 e2_p
= &(*cexpr_list
)[1];
9913 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
9914 chain_value
= e2_p
->value
;
9915 mark_exp_read (chain_value
);
9917 if (TREE_CODE (expr
.value
) != CALL_EXPR
)
9918 error_at (loc
, "first argument to "
9919 "%<__builtin_call_with_static_chain%> "
9920 "must be a call expression");
9921 else if (TREE_CODE (TREE_TYPE (chain_value
)) != POINTER_TYPE
)
9922 error_at (loc
, "second argument to "
9923 "%<__builtin_call_with_static_chain%> "
9924 "must be a pointer type");
9926 CALL_EXPR_STATIC_CHAIN (expr
.value
) = chain_value
;
9927 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9930 case RID_BUILTIN_COMPLEX
:
9932 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9933 c_expr_t
*e1_p
, *e2_p
;
9934 location_t close_paren_loc
;
9936 c_parser_consume_token (parser
);
9937 if (!c_parser_get_builtin_args (parser
,
9938 "__builtin_complex",
9946 if (vec_safe_length (cexpr_list
) != 2)
9948 error_at (loc
, "wrong number of arguments to "
9949 "%<__builtin_complex%>");
9954 e1_p
= &(*cexpr_list
)[0];
9955 e2_p
= &(*cexpr_list
)[1];
9957 *e1_p
= convert_lvalue_to_rvalue (loc
, *e1_p
, true, true);
9958 if (TREE_CODE (e1_p
->value
) == EXCESS_PRECISION_EXPR
)
9959 e1_p
->value
= convert (TREE_TYPE (e1_p
->value
),
9960 TREE_OPERAND (e1_p
->value
, 0));
9961 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
9962 if (TREE_CODE (e2_p
->value
) == EXCESS_PRECISION_EXPR
)
9963 e2_p
->value
= convert (TREE_TYPE (e2_p
->value
),
9964 TREE_OPERAND (e2_p
->value
, 0));
9965 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
9966 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
9967 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
))
9968 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
)))
9970 error_at (loc
, "%<__builtin_complex%> operand "
9971 "not of real binary floating-point type");
9975 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p
->value
))
9976 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p
->value
)))
9979 "%<__builtin_complex%> operands of different types");
9983 pedwarn_c90 (loc
, OPT_Wpedantic
,
9984 "ISO C90 does not support complex types");
9985 expr
.value
= build2_loc (loc
, COMPLEX_EXPR
,
9988 (TREE_TYPE (e1_p
->value
))),
9989 e1_p
->value
, e2_p
->value
);
9990 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9993 case RID_BUILTIN_SHUFFLE
:
9995 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9998 location_t close_paren_loc
;
10000 c_parser_consume_token (parser
);
10001 if (!c_parser_get_builtin_args (parser
,
10002 "__builtin_shuffle",
10003 &cexpr_list
, false,
10010 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
10011 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
10013 if (vec_safe_length (cexpr_list
) == 2)
10014 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10016 (*cexpr_list
)[1].value
);
10018 else if (vec_safe_length (cexpr_list
) == 3)
10019 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10020 (*cexpr_list
)[1].value
,
10021 (*cexpr_list
)[2].value
);
10024 error_at (loc
, "wrong number of arguments to "
10025 "%<__builtin_shuffle%>");
10028 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10031 case RID_BUILTIN_CONVERTVECTOR
:
10033 location_t start_loc
= loc
;
10034 c_parser_consume_token (parser
);
10035 matching_parens parens
;
10036 if (!parens
.require_open (parser
))
10041 e1
= c_parser_expr_no_commas (parser
, NULL
);
10042 mark_exp_read (e1
.value
);
10043 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10045 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10049 loc
= c_parser_peek_token (parser
)->location
;
10050 t1
= c_parser_type_name (parser
);
10051 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10052 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10058 tree type_expr
= NULL_TREE
;
10059 expr
.value
= c_build_vec_convert (start_loc
, e1
.value
, loc
,
10060 groktypename (t1
, &type_expr
,
10062 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10066 case RID_AT_SELECTOR
:
10068 gcc_assert (c_dialect_objc ());
10069 c_parser_consume_token (parser
);
10070 matching_parens parens
;
10071 if (!parens
.require_open (parser
))
10076 tree sel
= c_parser_objc_selector_arg (parser
);
10077 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10078 parens
.skip_until_found_close (parser
);
10079 expr
.value
= objc_build_selector_expr (loc
, sel
);
10080 set_c_expr_source_range (&expr
, loc
, close_loc
);
10083 case RID_AT_PROTOCOL
:
10085 gcc_assert (c_dialect_objc ());
10086 c_parser_consume_token (parser
);
10087 matching_parens parens
;
10088 if (!parens
.require_open (parser
))
10093 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10095 c_parser_error (parser
, "expected identifier");
10096 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10100 tree id
= c_parser_peek_token (parser
)->value
;
10101 c_parser_consume_token (parser
);
10102 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10103 parens
.skip_until_found_close (parser
);
10104 expr
.value
= objc_build_protocol_expr (id
);
10105 set_c_expr_source_range (&expr
, loc
, close_loc
);
10108 case RID_AT_ENCODE
:
10110 /* Extension to support C-structures in the archiver. */
10111 gcc_assert (c_dialect_objc ());
10112 c_parser_consume_token (parser
);
10113 matching_parens parens
;
10114 if (!parens
.require_open (parser
))
10119 t1
= c_parser_type_name (parser
);
10123 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10126 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10127 parens
.skip_until_found_close (parser
);
10128 tree type
= groktypename (t1
, NULL
, NULL
);
10129 expr
.value
= objc_build_encode_expr (type
);
10130 set_c_expr_source_range (&expr
, loc
, close_loc
);
10134 expr
= c_parser_generic_selection (parser
);
10137 c_parser_error (parser
, "expected expression");
10142 case CPP_OPEN_SQUARE
:
10143 if (c_dialect_objc ())
10145 tree receiver
, args
;
10146 c_parser_consume_token (parser
);
10147 receiver
= c_parser_objc_receiver (parser
);
10148 args
= c_parser_objc_message_args (parser
);
10149 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10150 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10152 expr
.value
= objc_build_message_expr (receiver
, args
);
10153 set_c_expr_source_range (&expr
, loc
, close_loc
);
10156 /* Else fall through to report error. */
10159 c_parser_error (parser
, "expected expression");
10164 return c_parser_postfix_expression_after_primary
10165 (parser
, EXPR_LOC_OR_LOC (expr
.value
, loc
), expr
);
10168 /* Parse a postfix expression after a parenthesized type name: the
10169 brace-enclosed initializer of a compound literal, possibly followed
10170 by some postfix operators. This is separate because it is not
10171 possible to tell until after the type name whether a cast
10172 expression has a cast or a compound literal, or whether the operand
10173 of sizeof is a parenthesized type name or starts with a compound
10174 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10175 location of the first token after the parentheses around the type
10178 static struct c_expr
10179 c_parser_postfix_expression_after_paren_type (c_parser
*parser
,
10180 struct c_type_name
*type_name
,
10181 location_t type_loc
)
10184 struct c_expr init
;
10186 struct c_expr expr
;
10187 location_t start_loc
;
10188 tree type_expr
= NULL_TREE
;
10189 bool type_expr_const
= true;
10190 check_compound_literal_type (type_loc
, type_name
);
10191 rich_location
richloc (line_table
, type_loc
);
10192 start_init (NULL_TREE
, NULL
, 0, &richloc
);
10193 type
= groktypename (type_name
, &type_expr
, &type_expr_const
);
10194 start_loc
= c_parser_peek_token (parser
)->location
;
10195 if (type
!= error_mark_node
&& C_TYPE_VARIABLE_SIZE (type
))
10197 error_at (type_loc
, "compound literal has variable size");
10198 type
= error_mark_node
;
10200 init
= c_parser_braced_init (parser
, type
, false, NULL
);
10202 maybe_warn_string_init (type_loc
, type
, init
);
10204 if (type
!= error_mark_node
10205 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type
))
10206 && current_function_decl
)
10208 error ("compound literal qualified by address-space qualifier");
10209 type
= error_mark_node
;
10212 pedwarn_c90 (start_loc
, OPT_Wpedantic
, "ISO C90 forbids compound literals");
10213 non_const
= ((init
.value
&& TREE_CODE (init
.value
) == CONSTRUCTOR
)
10214 ? CONSTRUCTOR_NON_CONST (init
.value
)
10215 : init
.original_code
== C_MAYBE_CONST_EXPR
);
10216 non_const
|= !type_expr_const
;
10217 unsigned int alignas_align
= 0;
10218 if (type
!= error_mark_node
10219 && type_name
->specs
->align_log
!= -1)
10221 alignas_align
= 1U << type_name
->specs
->align_log
;
10222 if (alignas_align
< min_align_of_type (type
))
10224 error_at (type_name
->specs
->locations
[cdw_alignas
],
10225 "%<_Alignas%> specifiers cannot reduce "
10226 "alignment of compound literal");
10230 expr
.value
= build_compound_literal (start_loc
, type
, init
.value
, non_const
,
10232 set_c_expr_source_range (&expr
, init
.src_range
);
10233 expr
.original_code
= ERROR_MARK
;
10234 expr
.original_type
= NULL
;
10235 if (type
!= error_mark_node
10236 && expr
.value
!= error_mark_node
10239 if (TREE_CODE (expr
.value
) == C_MAYBE_CONST_EXPR
)
10241 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr
.value
) == NULL_TREE
);
10242 C_MAYBE_CONST_EXPR_PRE (expr
.value
) = type_expr
;
10246 gcc_assert (!non_const
);
10247 expr
.value
= build2 (C_MAYBE_CONST_EXPR
, type
,
10248 type_expr
, expr
.value
);
10251 return c_parser_postfix_expression_after_primary (parser
, start_loc
, expr
);
10254 /* Callback function for sizeof_pointer_memaccess_warning to compare
10258 sizeof_ptr_memacc_comptypes (tree type1
, tree type2
)
10260 return comptypes (type1
, type2
) == 1;
10263 /* Warn for patterns where abs-like function appears to be used incorrectly,
10264 gracefully ignore any non-abs-like function. The warning location should
10265 be LOC. FNDECL is the declaration of called function, it must be a
10266 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10270 warn_for_abs (location_t loc
, tree fndecl
, tree arg
)
10272 /* Avoid warning in unreachable subexpressions. */
10273 if (c_inhibit_evaluation_warnings
)
10276 tree atype
= TREE_TYPE (arg
);
10278 /* Casts from pointers (and thus arrays and fndecls) will generate
10279 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10280 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10281 types and possibly other exotic types. */
10282 if (!INTEGRAL_TYPE_P (atype
)
10283 && !SCALAR_FLOAT_TYPE_P (atype
)
10284 && TREE_CODE (atype
) != COMPLEX_TYPE
)
10287 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
10292 case BUILT_IN_LABS
:
10293 case BUILT_IN_LLABS
:
10294 case BUILT_IN_IMAXABS
:
10295 if (!INTEGRAL_TYPE_P (atype
))
10297 if (SCALAR_FLOAT_TYPE_P (atype
))
10298 warning_at (loc
, OPT_Wabsolute_value
,
10299 "using integer absolute value function %qD when "
10300 "argument is of floating-point type %qT",
10302 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10303 warning_at (loc
, OPT_Wabsolute_value
,
10304 "using integer absolute value function %qD when "
10305 "argument is of complex type %qT", fndecl
, atype
);
10307 gcc_unreachable ();
10310 if (TYPE_UNSIGNED (atype
))
10311 warning_at (loc
, OPT_Wabsolute_value
,
10312 "taking the absolute value of unsigned type %qT "
10313 "has no effect", atype
);
10316 CASE_FLT_FN (BUILT_IN_FABS
):
10317 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS
):
10318 if (!SCALAR_FLOAT_TYPE_P (atype
)
10319 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype
)))
10321 if (INTEGRAL_TYPE_P (atype
))
10322 warning_at (loc
, OPT_Wabsolute_value
,
10323 "using floating-point absolute value function %qD "
10324 "when argument is of integer type %qT", fndecl
, atype
);
10325 else if (DECIMAL_FLOAT_TYPE_P (atype
))
10326 warning_at (loc
, OPT_Wabsolute_value
,
10327 "using floating-point absolute value function %qD "
10328 "when argument is of decimal floating-point type %qT",
10330 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10331 warning_at (loc
, OPT_Wabsolute_value
,
10332 "using floating-point absolute value function %qD when "
10333 "argument is of complex type %qT", fndecl
, atype
);
10335 gcc_unreachable ();
10340 CASE_FLT_FN (BUILT_IN_CABS
):
10341 if (TREE_CODE (atype
) != COMPLEX_TYPE
)
10343 if (INTEGRAL_TYPE_P (atype
))
10344 warning_at (loc
, OPT_Wabsolute_value
,
10345 "using complex absolute value function %qD when "
10346 "argument is of integer type %qT", fndecl
, atype
);
10347 else if (SCALAR_FLOAT_TYPE_P (atype
))
10348 warning_at (loc
, OPT_Wabsolute_value
,
10349 "using complex absolute value function %qD when "
10350 "argument is of floating-point type %qT",
10353 gcc_unreachable ();
10359 case BUILT_IN_FABSD32
:
10360 case BUILT_IN_FABSD64
:
10361 case BUILT_IN_FABSD128
:
10362 if (!DECIMAL_FLOAT_TYPE_P (atype
))
10364 if (INTEGRAL_TYPE_P (atype
))
10365 warning_at (loc
, OPT_Wabsolute_value
,
10366 "using decimal floating-point absolute value "
10367 "function %qD when argument is of integer type %qT",
10369 else if (SCALAR_FLOAT_TYPE_P (atype
))
10370 warning_at (loc
, OPT_Wabsolute_value
,
10371 "using decimal floating-point absolute value "
10372 "function %qD when argument is of floating-point "
10373 "type %qT", fndecl
, atype
);
10374 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10375 warning_at (loc
, OPT_Wabsolute_value
,
10376 "using decimal floating-point absolute value "
10377 "function %qD when argument is of complex type %qT",
10380 gcc_unreachable ();
10389 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl
)))
10392 tree ftype
= TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
10393 if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10395 gcc_assert (TREE_CODE (ftype
) == COMPLEX_TYPE
);
10396 atype
= TREE_TYPE (atype
);
10397 ftype
= TREE_TYPE (ftype
);
10400 if (TYPE_PRECISION (ftype
) < TYPE_PRECISION (atype
))
10401 warning_at (loc
, OPT_Wabsolute_value
,
10402 "absolute value function %qD given an argument of type %qT "
10403 "but has parameter of type %qT which may cause truncation "
10404 "of value", fndecl
, atype
, ftype
);
10408 /* Parse a postfix expression after the initial primary or compound
10409 literal; that is, parse a series of postfix operators.
10411 EXPR_LOC is the location of the primary expression. */
10413 static struct c_expr
10414 c_parser_postfix_expression_after_primary (c_parser
*parser
,
10415 location_t expr_loc
,
10416 struct c_expr expr
)
10418 struct c_expr orig_expr
;
10420 location_t sizeof_arg_loc
[3], comp_loc
;
10421 tree sizeof_arg
[3];
10422 unsigned int literal_zero_mask
;
10424 vec
<tree
, va_gc
> *exprlist
;
10425 vec
<tree
, va_gc
> *origtypes
= NULL
;
10426 vec
<location_t
> arg_loc
= vNULL
;
10432 location_t op_loc
= c_parser_peek_token (parser
)->location
;
10433 switch (c_parser_peek_token (parser
)->type
)
10435 case CPP_OPEN_SQUARE
:
10436 /* Array reference. */
10437 c_parser_consume_token (parser
);
10438 idx
= c_parser_expression (parser
).value
;
10439 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10441 start
= expr
.get_start ();
10442 finish
= parser
->tokens_buf
[0].location
;
10443 expr
.value
= build_array_ref (op_loc
, expr
.value
, idx
);
10444 set_c_expr_source_range (&expr
, start
, finish
);
10445 expr
.original_code
= ERROR_MARK
;
10446 expr
.original_type
= NULL
;
10448 case CPP_OPEN_PAREN
:
10449 /* Function call. */
10450 c_parser_consume_token (parser
);
10451 for (i
= 0; i
< 3; i
++)
10453 sizeof_arg
[i
] = NULL_TREE
;
10454 sizeof_arg_loc
[i
] = UNKNOWN_LOCATION
;
10456 literal_zero_mask
= 0;
10457 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10460 exprlist
= c_parser_expr_list (parser
, true, false, &origtypes
,
10461 sizeof_arg_loc
, sizeof_arg
,
10462 &arg_loc
, &literal_zero_mask
);
10463 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10466 mark_exp_read (expr
.value
);
10467 if (warn_sizeof_pointer_memaccess
)
10468 sizeof_pointer_memaccess_warning (sizeof_arg_loc
,
10469 expr
.value
, exprlist
,
10471 sizeof_ptr_memacc_comptypes
);
10472 if (TREE_CODE (expr
.value
) == FUNCTION_DECL
)
10474 if (fndecl_built_in_p (expr
.value
, BUILT_IN_MEMSET
)
10475 && vec_safe_length (exprlist
) == 3)
10477 tree arg0
= (*exprlist
)[0];
10478 tree arg2
= (*exprlist
)[2];
10479 warn_for_memset (expr_loc
, arg0
, arg2
, literal_zero_mask
);
10481 if (warn_absolute_value
10482 && fndecl_built_in_p (expr
.value
, BUILT_IN_NORMAL
)
10483 && vec_safe_length (exprlist
) == 1)
10484 warn_for_abs (expr_loc
, expr
.value
, (*exprlist
)[0]);
10487 start
= expr
.get_start ();
10488 finish
= parser
->tokens_buf
[0].get_finish ();
10490 = c_build_function_call_vec (expr_loc
, arg_loc
, expr
.value
,
10491 exprlist
, origtypes
);
10492 set_c_expr_source_range (&expr
, start
, finish
);
10494 expr
.original_code
= ERROR_MARK
;
10495 if (TREE_CODE (expr
.value
) == INTEGER_CST
10496 && TREE_CODE (orig_expr
.value
) == FUNCTION_DECL
10497 && fndecl_built_in_p (orig_expr
.value
, BUILT_IN_CONSTANT_P
))
10498 expr
.original_code
= C_MAYBE_CONST_EXPR
;
10499 expr
.original_type
= NULL
;
10502 release_tree_vector (exprlist
);
10503 release_tree_vector (origtypes
);
10505 arg_loc
.release ();
10508 /* Structure element reference. */
10509 c_parser_consume_token (parser
);
10510 expr
= default_function_array_conversion (expr_loc
, expr
);
10511 if (c_parser_next_token_is (parser
, CPP_NAME
))
10513 c_token
*comp_tok
= c_parser_peek_token (parser
);
10514 ident
= comp_tok
->value
;
10515 comp_loc
= comp_tok
->location
;
10519 c_parser_error (parser
, "expected identifier");
10521 expr
.original_code
= ERROR_MARK
;
10522 expr
.original_type
= NULL
;
10525 start
= expr
.get_start ();
10526 finish
= c_parser_peek_token (parser
)->get_finish ();
10527 c_parser_consume_token (parser
);
10528 expr
.value
= build_component_ref (op_loc
, expr
.value
, ident
,
10530 set_c_expr_source_range (&expr
, start
, finish
);
10531 expr
.original_code
= ERROR_MARK
;
10532 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
10533 expr
.original_type
= NULL
;
10536 /* Remember the original type of a bitfield. */
10537 tree field
= TREE_OPERAND (expr
.value
, 1);
10538 if (TREE_CODE (field
) != FIELD_DECL
)
10539 expr
.original_type
= NULL
;
10541 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
10545 /* Structure element reference. */
10546 c_parser_consume_token (parser
);
10547 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, false);
10548 if (c_parser_next_token_is (parser
, CPP_NAME
))
10550 c_token
*comp_tok
= c_parser_peek_token (parser
);
10551 ident
= comp_tok
->value
;
10552 comp_loc
= comp_tok
->location
;
10556 c_parser_error (parser
, "expected identifier");
10558 expr
.original_code
= ERROR_MARK
;
10559 expr
.original_type
= NULL
;
10562 start
= expr
.get_start ();
10563 finish
= c_parser_peek_token (parser
)->get_finish ();
10564 c_parser_consume_token (parser
);
10565 expr
.value
= build_component_ref (op_loc
,
10566 build_indirect_ref (op_loc
,
10570 set_c_expr_source_range (&expr
, start
, finish
);
10571 expr
.original_code
= ERROR_MARK
;
10572 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
10573 expr
.original_type
= NULL
;
10576 /* Remember the original type of a bitfield. */
10577 tree field
= TREE_OPERAND (expr
.value
, 1);
10578 if (TREE_CODE (field
) != FIELD_DECL
)
10579 expr
.original_type
= NULL
;
10581 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
10584 case CPP_PLUS_PLUS
:
10585 /* Postincrement. */
10586 start
= expr
.get_start ();
10587 finish
= c_parser_peek_token (parser
)->get_finish ();
10588 c_parser_consume_token (parser
);
10589 expr
= default_function_array_read_conversion (expr_loc
, expr
);
10590 expr
.value
= build_unary_op (op_loc
, POSTINCREMENT_EXPR
,
10591 expr
.value
, false);
10592 set_c_expr_source_range (&expr
, start
, finish
);
10593 expr
.original_code
= ERROR_MARK
;
10594 expr
.original_type
= NULL
;
10596 case CPP_MINUS_MINUS
:
10597 /* Postdecrement. */
10598 start
= expr
.get_start ();
10599 finish
= c_parser_peek_token (parser
)->get_finish ();
10600 c_parser_consume_token (parser
);
10601 expr
= default_function_array_read_conversion (expr_loc
, expr
);
10602 expr
.value
= build_unary_op (op_loc
, POSTDECREMENT_EXPR
,
10603 expr
.value
, false);
10604 set_c_expr_source_range (&expr
, start
, finish
);
10605 expr
.original_code
= ERROR_MARK
;
10606 expr
.original_type
= NULL
;
10614 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10617 assignment-expression
10618 expression , assignment-expression
10621 static struct c_expr
10622 c_parser_expression (c_parser
*parser
)
10624 location_t tloc
= c_parser_peek_token (parser
)->location
;
10625 struct c_expr expr
;
10626 expr
= c_parser_expr_no_commas (parser
, NULL
);
10627 if (c_parser_next_token_is (parser
, CPP_COMMA
))
10628 expr
= convert_lvalue_to_rvalue (tloc
, expr
, true, false);
10629 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10631 struct c_expr next
;
10633 location_t loc
= c_parser_peek_token (parser
)->location
;
10634 location_t expr_loc
;
10635 c_parser_consume_token (parser
);
10636 expr_loc
= c_parser_peek_token (parser
)->location
;
10637 lhsval
= expr
.value
;
10638 while (TREE_CODE (lhsval
) == COMPOUND_EXPR
)
10639 lhsval
= TREE_OPERAND (lhsval
, 1);
10640 if (DECL_P (lhsval
) || handled_component_p (lhsval
))
10641 mark_exp_read (lhsval
);
10642 next
= c_parser_expr_no_commas (parser
, NULL
);
10643 next
= convert_lvalue_to_rvalue (expr_loc
, next
, true, false);
10644 expr
.value
= build_compound_expr (loc
, expr
.value
, next
.value
);
10645 expr
.original_code
= COMPOUND_EXPR
;
10646 expr
.original_type
= next
.original_type
;
10651 /* Parse an expression and convert functions or arrays to pointers and
10652 lvalues to rvalues. */
10654 static struct c_expr
10655 c_parser_expression_conv (c_parser
*parser
)
10657 struct c_expr expr
;
10658 location_t loc
= c_parser_peek_token (parser
)->location
;
10659 expr
= c_parser_expression (parser
);
10660 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, false);
10664 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10665 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10668 c_parser_check_literal_zero (c_parser
*parser
, unsigned *literal_zero_mask
,
10671 if (idx
>= HOST_BITS_PER_INT
)
10674 c_token
*tok
= c_parser_peek_token (parser
);
10683 /* If a parameter is literal zero alone, remember it
10684 for -Wmemset-transposed-args warning. */
10685 if (integer_zerop (tok
->value
)
10686 && !TREE_OVERFLOW (tok
->value
)
10687 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
10688 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
10689 *literal_zero_mask
|= 1U << idx
;
10695 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10696 functions and arrays to pointers and lvalues to rvalues. If
10697 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10698 locations of function arguments into this vector.
10700 nonempty-expr-list:
10701 assignment-expression
10702 nonempty-expr-list , assignment-expression
10705 static vec
<tree
, va_gc
> *
10706 c_parser_expr_list (c_parser
*parser
, bool convert_p
, bool fold_p
,
10707 vec
<tree
, va_gc
> **p_orig_types
,
10708 location_t
*sizeof_arg_loc
, tree
*sizeof_arg
,
10709 vec
<location_t
> *locations
,
10710 unsigned int *literal_zero_mask
)
10712 vec
<tree
, va_gc
> *ret
;
10713 vec
<tree
, va_gc
> *orig_types
;
10714 struct c_expr expr
;
10715 unsigned int idx
= 0;
10717 ret
= make_tree_vector ();
10718 if (p_orig_types
== NULL
)
10721 orig_types
= make_tree_vector ();
10723 if (literal_zero_mask
)
10724 c_parser_check_literal_zero (parser
, literal_zero_mask
, 0);
10725 expr
= c_parser_expr_no_commas (parser
, NULL
);
10727 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true, true);
10729 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
10730 ret
->quick_push (expr
.value
);
10732 orig_types
->quick_push (expr
.original_type
);
10734 locations
->safe_push (expr
.get_location ());
10735 if (sizeof_arg
!= NULL
10736 && expr
.original_code
== SIZEOF_EXPR
)
10738 sizeof_arg
[0] = c_last_sizeof_arg
;
10739 sizeof_arg_loc
[0] = c_last_sizeof_loc
;
10741 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10743 c_parser_consume_token (parser
);
10744 if (literal_zero_mask
)
10745 c_parser_check_literal_zero (parser
, literal_zero_mask
, idx
+ 1);
10746 expr
= c_parser_expr_no_commas (parser
, NULL
);
10748 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true,
10751 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
10752 vec_safe_push (ret
, expr
.value
);
10754 vec_safe_push (orig_types
, expr
.original_type
);
10756 locations
->safe_push (expr
.get_location ());
10758 && sizeof_arg
!= NULL
10759 && expr
.original_code
== SIZEOF_EXPR
)
10761 sizeof_arg
[idx
] = c_last_sizeof_arg
;
10762 sizeof_arg_loc
[idx
] = c_last_sizeof_loc
;
10766 *p_orig_types
= orig_types
;
10770 /* Parse Objective-C-specific constructs. */
10772 /* Parse an objc-class-definition.
10774 objc-class-definition:
10775 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10776 objc-class-instance-variables[opt] objc-methodprotolist @end
10777 @implementation identifier objc-superclass[opt]
10778 objc-class-instance-variables[opt]
10779 @interface identifier ( identifier ) objc-protocol-refs[opt]
10780 objc-methodprotolist @end
10781 @interface identifier ( ) objc-protocol-refs[opt]
10782 objc-methodprotolist @end
10783 @implementation identifier ( identifier )
10788 "@interface identifier (" must start "@interface identifier (
10789 identifier ) ...": objc-methodprotolist in the first production may
10790 not start with a parenthesized identifier as a declarator of a data
10791 definition with no declaration specifiers if the objc-superclass,
10792 objc-protocol-refs and objc-class-instance-variables are omitted. */
10795 c_parser_objc_class_definition (c_parser
*parser
, tree attributes
)
10800 if (c_parser_next_token_is_keyword (parser
, RID_AT_INTERFACE
))
10802 else if (c_parser_next_token_is_keyword (parser
, RID_AT_IMPLEMENTATION
))
10805 gcc_unreachable ();
10807 c_parser_consume_token (parser
);
10808 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10810 c_parser_error (parser
, "expected identifier");
10813 id1
= c_parser_peek_token (parser
)->value
;
10814 c_parser_consume_token (parser
);
10815 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
10817 /* We have a category or class extension. */
10819 tree proto
= NULL_TREE
;
10820 matching_parens parens
;
10821 parens
.consume_open (parser
);
10822 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10824 if (iface_p
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10826 /* We have a class extension. */
10831 c_parser_error (parser
, "expected identifier or %<)%>");
10832 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10838 id2
= c_parser_peek_token (parser
)->value
;
10839 c_parser_consume_token (parser
);
10841 parens
.skip_until_found_close (parser
);
10844 objc_start_category_implementation (id1
, id2
);
10847 if (c_parser_next_token_is (parser
, CPP_LESS
))
10848 proto
= c_parser_objc_protocol_refs (parser
);
10849 objc_start_category_interface (id1
, id2
, proto
, attributes
);
10850 c_parser_objc_methodprotolist (parser
);
10851 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10852 objc_finish_interface ();
10855 if (c_parser_next_token_is (parser
, CPP_COLON
))
10857 c_parser_consume_token (parser
);
10858 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10860 c_parser_error (parser
, "expected identifier");
10863 superclass
= c_parser_peek_token (parser
)->value
;
10864 c_parser_consume_token (parser
);
10867 superclass
= NULL_TREE
;
10870 tree proto
= NULL_TREE
;
10871 if (c_parser_next_token_is (parser
, CPP_LESS
))
10872 proto
= c_parser_objc_protocol_refs (parser
);
10873 objc_start_class_interface (id1
, superclass
, proto
, attributes
);
10876 objc_start_class_implementation (id1
, superclass
);
10877 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
10878 c_parser_objc_class_instance_variables (parser
);
10881 objc_continue_interface ();
10882 c_parser_objc_methodprotolist (parser
);
10883 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10884 objc_finish_interface ();
10888 objc_continue_implementation ();
10893 /* Parse objc-class-instance-variables.
10895 objc-class-instance-variables:
10896 { objc-instance-variable-decl-list[opt] }
10898 objc-instance-variable-decl-list:
10899 objc-visibility-spec
10900 objc-instance-variable-decl ;
10902 objc-instance-variable-decl-list objc-visibility-spec
10903 objc-instance-variable-decl-list objc-instance-variable-decl ;
10904 objc-instance-variable-decl-list ;
10906 objc-visibility-spec:
10911 objc-instance-variable-decl:
10916 c_parser_objc_class_instance_variables (c_parser
*parser
)
10918 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
10919 c_parser_consume_token (parser
);
10920 while (c_parser_next_token_is_not (parser
, CPP_EOF
))
10923 /* Parse any stray semicolon. */
10924 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
10926 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
10927 "extra semicolon");
10928 c_parser_consume_token (parser
);
10931 /* Stop if at the end of the instance variables. */
10932 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
10934 c_parser_consume_token (parser
);
10937 /* Parse any objc-visibility-spec. */
10938 if (c_parser_next_token_is_keyword (parser
, RID_AT_PRIVATE
))
10940 c_parser_consume_token (parser
);
10941 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE
);
10944 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROTECTED
))
10946 c_parser_consume_token (parser
);
10947 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED
);
10950 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PUBLIC
))
10952 c_parser_consume_token (parser
);
10953 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC
);
10956 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PACKAGE
))
10958 c_parser_consume_token (parser
);
10959 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE
);
10962 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
10964 c_parser_pragma (parser
, pragma_external
, NULL
);
10968 /* Parse some comma-separated declarations. */
10969 decls
= c_parser_struct_declaration (parser
);
10972 /* There is a syntax error. We want to skip the offending
10973 tokens up to the next ';' (included) or '}'
10976 /* First, skip manually a ')' or ']'. This is because they
10977 reduce the nesting level, so c_parser_skip_until_found()
10978 wouldn't be able to skip past them. */
10979 c_token
*token
= c_parser_peek_token (parser
);
10980 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_CLOSE_SQUARE
)
10981 c_parser_consume_token (parser
);
10983 /* Then, do the standard skipping. */
10984 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
10986 /* We hopefully recovered. Start normal parsing again. */
10987 parser
->error
= false;
10992 /* Comma-separated instance variables are chained together
10993 in reverse order; add them one by one. */
10994 tree ivar
= nreverse (decls
);
10995 for (; ivar
; ivar
= DECL_CHAIN (ivar
))
10996 objc_add_instance_variable (copy_node (ivar
));
10998 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11002 /* Parse an objc-class-declaration.
11004 objc-class-declaration:
11005 @class identifier-list ;
11009 c_parser_objc_class_declaration (c_parser
*parser
)
11011 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_CLASS
));
11012 c_parser_consume_token (parser
);
11013 /* Any identifiers, including those declared as type names, are OK
11018 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11020 c_parser_error (parser
, "expected identifier");
11021 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11022 parser
->error
= false;
11025 id
= c_parser_peek_token (parser
)->value
;
11026 objc_declare_class (id
);
11027 c_parser_consume_token (parser
);
11028 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11029 c_parser_consume_token (parser
);
11033 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11036 /* Parse an objc-alias-declaration.
11038 objc-alias-declaration:
11039 @compatibility_alias identifier identifier ;
11043 c_parser_objc_alias_declaration (c_parser
*parser
)
11046 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_ALIAS
));
11047 c_parser_consume_token (parser
);
11048 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11050 c_parser_error (parser
, "expected identifier");
11051 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11054 id1
= c_parser_peek_token (parser
)->value
;
11055 c_parser_consume_token (parser
);
11056 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11058 c_parser_error (parser
, "expected identifier");
11059 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11062 id2
= c_parser_peek_token (parser
)->value
;
11063 c_parser_consume_token (parser
);
11064 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11065 objc_declare_alias (id1
, id2
);
11068 /* Parse an objc-protocol-definition.
11070 objc-protocol-definition:
11071 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11072 @protocol identifier-list ;
11074 "@protocol identifier ;" should be resolved as "@protocol
11075 identifier-list ;": objc-methodprotolist may not start with a
11076 semicolon in the first alternative if objc-protocol-refs are
11080 c_parser_objc_protocol_definition (c_parser
*parser
, tree attributes
)
11082 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROTOCOL
));
11084 c_parser_consume_token (parser
);
11085 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11087 c_parser_error (parser
, "expected identifier");
11090 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
11091 || c_parser_peek_2nd_token (parser
)->type
== CPP_SEMICOLON
)
11093 /* Any identifiers, including those declared as type names, are
11098 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11100 c_parser_error (parser
, "expected identifier");
11103 id
= c_parser_peek_token (parser
)->value
;
11104 objc_declare_protocol (id
, attributes
);
11105 c_parser_consume_token (parser
);
11106 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11107 c_parser_consume_token (parser
);
11111 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11115 tree id
= c_parser_peek_token (parser
)->value
;
11116 tree proto
= NULL_TREE
;
11117 c_parser_consume_token (parser
);
11118 if (c_parser_next_token_is (parser
, CPP_LESS
))
11119 proto
= c_parser_objc_protocol_refs (parser
);
11120 parser
->objc_pq_context
= true;
11121 objc_start_protocol (id
, proto
, attributes
);
11122 c_parser_objc_methodprotolist (parser
);
11123 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
11124 parser
->objc_pq_context
= false;
11125 objc_finish_interface ();
11129 /* Parse an objc-method-type.
11135 Return true if it is a class method (+) and false if it is
11136 an instance method (-).
11139 c_parser_objc_method_type (c_parser
*parser
)
11141 switch (c_parser_peek_token (parser
)->type
)
11144 c_parser_consume_token (parser
);
11147 c_parser_consume_token (parser
);
11150 gcc_unreachable ();
11154 /* Parse an objc-method-definition.
11156 objc-method-definition:
11157 objc-method-type objc-method-decl ;[opt] compound-statement
11161 c_parser_objc_method_definition (c_parser
*parser
)
11163 bool is_class_method
= c_parser_objc_method_type (parser
);
11164 tree decl
, attributes
= NULL_TREE
, expr
= NULL_TREE
;
11165 parser
->objc_pq_context
= true;
11166 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11168 if (decl
== error_mark_node
)
11169 return; /* Bail here. */
11171 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11173 c_parser_consume_token (parser
);
11174 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11175 "extra semicolon in method definition specified");
11178 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11180 c_parser_error (parser
, "expected %<{%>");
11184 parser
->objc_pq_context
= false;
11185 if (objc_start_method_definition (is_class_method
, decl
, attributes
, expr
))
11187 add_stmt (c_parser_compound_statement (parser
));
11188 objc_finish_method_definition (current_function_decl
);
11192 /* This code is executed when we find a method definition
11193 outside of an @implementation context (or invalid for other
11194 reasons). Parse the method (to keep going) but do not emit
11197 c_parser_compound_statement (parser
);
11201 /* Parse an objc-methodprotolist.
11203 objc-methodprotolist:
11205 objc-methodprotolist objc-methodproto
11206 objc-methodprotolist declaration
11207 objc-methodprotolist ;
11211 The declaration is a data definition, which may be missing
11212 declaration specifiers under the same rules and diagnostics as
11213 other data definitions outside functions, and the stray semicolon
11214 is diagnosed the same way as a stray semicolon outside a
11218 c_parser_objc_methodprotolist (c_parser
*parser
)
11222 /* The list is terminated by @end. */
11223 switch (c_parser_peek_token (parser
)->type
)
11225 case CPP_SEMICOLON
:
11226 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11227 "ISO C does not allow extra %<;%> outside of a function");
11228 c_parser_consume_token (parser
);
11232 c_parser_objc_methodproto (parser
);
11235 c_parser_pragma (parser
, pragma_external
, NULL
);
11240 if (c_parser_next_token_is_keyword (parser
, RID_AT_END
))
11242 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
))
11243 c_parser_objc_at_property_declaration (parser
);
11244 else if (c_parser_next_token_is_keyword (parser
, RID_AT_OPTIONAL
))
11246 objc_set_method_opt (true);
11247 c_parser_consume_token (parser
);
11249 else if (c_parser_next_token_is_keyword (parser
, RID_AT_REQUIRED
))
11251 objc_set_method_opt (false);
11252 c_parser_consume_token (parser
);
11255 c_parser_declaration_or_fndef (parser
, false, false, true,
11256 false, true, NULL
, vNULL
);
11262 /* Parse an objc-methodproto.
11265 objc-method-type objc-method-decl ;
11269 c_parser_objc_methodproto (c_parser
*parser
)
11271 bool is_class_method
= c_parser_objc_method_type (parser
);
11272 tree decl
, attributes
= NULL_TREE
;
11274 /* Remember protocol qualifiers in prototypes. */
11275 parser
->objc_pq_context
= true;
11276 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11278 /* Forget protocol qualifiers now. */
11279 parser
->objc_pq_context
= false;
11281 /* Do not allow the presence of attributes to hide an erroneous
11282 method implementation in the interface section. */
11283 if (!c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11285 c_parser_error (parser
, "expected %<;%>");
11289 if (decl
!= error_mark_node
)
11290 objc_add_method_declaration (is_class_method
, decl
, attributes
);
11292 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11295 /* If we are at a position that method attributes may be present, check that
11296 there are not any parsed already (a syntax error) and then collect any
11297 specified at the current location. Finally, if new attributes were present,
11298 check that the next token is legal ( ';' for decls and '{' for defs). */
11301 c_parser_objc_maybe_method_attributes (c_parser
* parser
, tree
* attributes
)
11306 c_parser_error (parser
,
11307 "method attributes must be specified at the end only");
11308 *attributes
= NULL_TREE
;
11312 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
11313 *attributes
= c_parser_gnu_attributes (parser
);
11315 /* If there were no attributes here, just report any earlier error. */
11316 if (*attributes
== NULL_TREE
|| bad
)
11319 /* If the attributes are followed by a ; or {, then just report any earlier
11321 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
11322 || c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11325 /* We've got attributes, but not at the end. */
11326 c_parser_error (parser
,
11327 "expected %<;%> or %<{%> after method attribute definition");
11331 /* Parse an objc-method-decl.
11334 ( objc-type-name ) objc-selector
11336 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11337 objc-keyword-selector objc-optparmlist
11340 objc-keyword-selector:
11342 objc-keyword-selector objc-keyword-decl
11345 objc-selector : ( objc-type-name ) identifier
11346 objc-selector : identifier
11347 : ( objc-type-name ) identifier
11351 objc-optparms objc-optellipsis
11355 objc-opt-parms , parameter-declaration
11363 c_parser_objc_method_decl (c_parser
*parser
, bool is_class_method
,
11364 tree
*attributes
, tree
*expr
)
11366 tree type
= NULL_TREE
;
11368 tree parms
= NULL_TREE
;
11369 bool ellipsis
= false;
11370 bool attr_err
= false;
11372 *attributes
= NULL_TREE
;
11373 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11375 matching_parens parens
;
11376 parens
.consume_open (parser
);
11377 type
= c_parser_objc_type_name (parser
);
11378 parens
.skip_until_found_close (parser
);
11380 sel
= c_parser_objc_selector (parser
);
11381 /* If there is no selector, or a colon follows, we have an
11382 objc-keyword-selector. If there is a selector, and a colon does
11383 not follow, that selector ends the objc-method-decl. */
11384 if (!sel
|| c_parser_next_token_is (parser
, CPP_COLON
))
11387 tree list
= NULL_TREE
;
11390 tree atype
= NULL_TREE
, id
, keyworddecl
;
11391 tree param_attr
= NULL_TREE
;
11392 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11394 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11396 c_parser_consume_token (parser
);
11397 atype
= c_parser_objc_type_name (parser
);
11398 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
11401 /* New ObjC allows attributes on method parameters. */
11402 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
11403 param_attr
= c_parser_gnu_attributes (parser
);
11404 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11406 c_parser_error (parser
, "expected identifier");
11407 return error_mark_node
;
11409 id
= c_parser_peek_token (parser
)->value
;
11410 c_parser_consume_token (parser
);
11411 keyworddecl
= objc_build_keyword_decl (tsel
, atype
, id
, param_attr
);
11412 list
= chainon (list
, keyworddecl
);
11413 tsel
= c_parser_objc_selector (parser
);
11414 if (!tsel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11418 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
11420 /* Parse the optional parameter list. Optional Objective-C
11421 method parameters follow the C syntax, and may include '...'
11422 to denote a variable number of arguments. */
11423 parms
= make_node (TREE_LIST
);
11424 while (c_parser_next_token_is (parser
, CPP_COMMA
))
11426 struct c_parm
*parm
;
11427 c_parser_consume_token (parser
);
11428 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
11431 c_parser_consume_token (parser
);
11432 attr_err
|= c_parser_objc_maybe_method_attributes
11433 (parser
, attributes
) ;
11436 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
11439 parms
= chainon (parms
,
11440 build_tree_list (NULL_TREE
, grokparm (parm
, expr
)));
11445 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
11449 c_parser_error (parser
, "objective-c method declaration is expected");
11450 return error_mark_node
;
11454 return error_mark_node
;
11456 return objc_build_method_signature (is_class_method
, type
, sel
, parms
, ellipsis
);
11459 /* Parse an objc-type-name.
11462 objc-type-qualifiers[opt] type-name
11463 objc-type-qualifiers[opt]
11465 objc-type-qualifiers:
11466 objc-type-qualifier
11467 objc-type-qualifiers objc-type-qualifier
11469 objc-type-qualifier: one of
11470 in out inout bycopy byref oneway
11474 c_parser_objc_type_name (c_parser
*parser
)
11476 tree quals
= NULL_TREE
;
11477 struct c_type_name
*type_name
= NULL
;
11478 tree type
= NULL_TREE
;
11481 c_token
*token
= c_parser_peek_token (parser
);
11482 if (token
->type
== CPP_KEYWORD
11483 && (token
->keyword
== RID_IN
11484 || token
->keyword
== RID_OUT
11485 || token
->keyword
== RID_INOUT
11486 || token
->keyword
== RID_BYCOPY
11487 || token
->keyword
== RID_BYREF
11488 || token
->keyword
== RID_ONEWAY
))
11490 quals
= chainon (build_tree_list (NULL_TREE
, token
->value
), quals
);
11491 c_parser_consume_token (parser
);
11496 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
11497 type_name
= c_parser_type_name (parser
);
11499 type
= groktypename (type_name
, NULL
, NULL
);
11501 /* If the type is unknown, and error has already been produced and
11502 we need to recover from the error. In that case, use NULL_TREE
11503 for the type, as if no type had been specified; this will use the
11504 default type ('id') which is good for error recovery. */
11505 if (type
== error_mark_node
)
11508 return build_tree_list (quals
, type
);
11511 /* Parse objc-protocol-refs.
11513 objc-protocol-refs:
11514 < identifier-list >
11518 c_parser_objc_protocol_refs (c_parser
*parser
)
11520 tree list
= NULL_TREE
;
11521 gcc_assert (c_parser_next_token_is (parser
, CPP_LESS
));
11522 c_parser_consume_token (parser
);
11523 /* Any identifiers, including those declared as type names, are OK
11528 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11530 c_parser_error (parser
, "expected identifier");
11533 id
= c_parser_peek_token (parser
)->value
;
11534 list
= chainon (list
, build_tree_list (NULL_TREE
, id
));
11535 c_parser_consume_token (parser
);
11536 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11537 c_parser_consume_token (parser
);
11541 c_parser_require (parser
, CPP_GREATER
, "expected %<>%>");
11545 /* Parse an objc-try-catch-finally-statement.
11547 objc-try-catch-finally-statement:
11548 @try compound-statement objc-catch-list[opt]
11549 @try compound-statement objc-catch-list[opt] @finally compound-statement
11552 @catch ( objc-catch-parameter-declaration ) compound-statement
11553 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11555 objc-catch-parameter-declaration:
11556 parameter-declaration
11559 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11561 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11562 for C++. Keep them in sync. */
11565 c_parser_objc_try_catch_finally_statement (c_parser
*parser
)
11567 location_t location
;
11570 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_TRY
));
11571 c_parser_consume_token (parser
);
11572 location
= c_parser_peek_token (parser
)->location
;
11573 objc_maybe_warn_exceptions (location
);
11574 stmt
= c_parser_compound_statement (parser
);
11575 objc_begin_try_stmt (location
, stmt
);
11577 while (c_parser_next_token_is_keyword (parser
, RID_AT_CATCH
))
11579 struct c_parm
*parm
;
11580 tree parameter_declaration
= error_mark_node
;
11581 bool seen_open_paren
= false;
11583 c_parser_consume_token (parser
);
11584 matching_parens parens
;
11585 if (!parens
.require_open (parser
))
11586 seen_open_paren
= true;
11587 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
11589 /* We have "@catch (...)" (where the '...' are literally
11590 what is in the code). Skip the '...'.
11591 parameter_declaration is set to NULL_TREE, and
11592 objc_being_catch_clauses() knows that that means
11594 c_parser_consume_token (parser
);
11595 parameter_declaration
= NULL_TREE
;
11599 /* We have "@catch (NSException *exception)" or something
11600 like that. Parse the parameter declaration. */
11601 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
11603 parameter_declaration
= error_mark_node
;
11605 parameter_declaration
= grokparm (parm
, NULL
);
11607 if (seen_open_paren
)
11608 parens
.require_close (parser
);
11611 /* If there was no open parenthesis, we are recovering from
11612 an error, and we are trying to figure out what mistake
11613 the user has made. */
11615 /* If there is an immediate closing parenthesis, the user
11616 probably forgot the opening one (ie, they typed "@catch
11617 NSException *e)". Parse the closing parenthesis and keep
11619 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
11620 c_parser_consume_token (parser
);
11622 /* If these is no immediate closing parenthesis, the user
11623 probably doesn't know that parenthesis are required at
11624 all (ie, they typed "@catch NSException *e"). So, just
11625 forget about the closing parenthesis and keep going. */
11627 objc_begin_catch_clause (parameter_declaration
);
11628 if (c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
11629 c_parser_compound_statement_nostart (parser
);
11630 objc_finish_catch_clause ();
11632 if (c_parser_next_token_is_keyword (parser
, RID_AT_FINALLY
))
11634 c_parser_consume_token (parser
);
11635 location
= c_parser_peek_token (parser
)->location
;
11636 stmt
= c_parser_compound_statement (parser
);
11637 objc_build_finally_clause (location
, stmt
);
11639 objc_finish_try_stmt ();
11642 /* Parse an objc-synchronized-statement.
11644 objc-synchronized-statement:
11645 @synchronized ( expression ) compound-statement
11649 c_parser_objc_synchronized_statement (c_parser
*parser
)
11653 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNCHRONIZED
));
11654 c_parser_consume_token (parser
);
11655 loc
= c_parser_peek_token (parser
)->location
;
11656 objc_maybe_warn_exceptions (loc
);
11657 matching_parens parens
;
11658 if (parens
.require_open (parser
))
11660 struct c_expr ce
= c_parser_expression (parser
);
11661 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
11663 expr
= c_fully_fold (expr
, false, NULL
);
11664 parens
.skip_until_found_close (parser
);
11667 expr
= error_mark_node
;
11668 stmt
= c_parser_compound_statement (parser
);
11669 objc_build_synchronized (loc
, expr
, stmt
);
11672 /* Parse an objc-selector; return NULL_TREE without an error if the
11673 next token is not an objc-selector.
11678 enum struct union if else while do for switch case default
11679 break continue return goto asm sizeof typeof __alignof
11680 unsigned long const short volatile signed restrict _Complex
11681 in out inout bycopy byref oneway int char float double void _Bool
11684 ??? Why this selection of keywords but not, for example, storage
11685 class specifiers? */
11688 c_parser_objc_selector (c_parser
*parser
)
11690 c_token
*token
= c_parser_peek_token (parser
);
11691 tree value
= token
->value
;
11692 if (token
->type
== CPP_NAME
)
11694 c_parser_consume_token (parser
);
11697 if (token
->type
!= CPP_KEYWORD
)
11699 switch (token
->keyword
)
11738 CASE_RID_FLOATN_NX
:
11742 case RID_AUTO_TYPE
:
11747 c_parser_consume_token (parser
);
11754 /* Parse an objc-selector-arg.
11758 objc-keywordname-list
11760 objc-keywordname-list:
11762 objc-keywordname-list objc-keywordname
11770 c_parser_objc_selector_arg (c_parser
*parser
)
11772 tree sel
= c_parser_objc_selector (parser
);
11773 tree list
= NULL_TREE
;
11774 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11778 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11780 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
11781 sel
= c_parser_objc_selector (parser
);
11782 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11788 /* Parse an objc-receiver.
11797 c_parser_objc_receiver (c_parser
*parser
)
11799 location_t loc
= c_parser_peek_token (parser
)->location
;
11801 if (c_parser_peek_token (parser
)->type
== CPP_NAME
11802 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
11803 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
11805 tree id
= c_parser_peek_token (parser
)->value
;
11806 c_parser_consume_token (parser
);
11807 return objc_get_class_reference (id
);
11809 struct c_expr ce
= c_parser_expression (parser
);
11810 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
11811 return c_fully_fold (ce
.value
, false, NULL
);
11814 /* Parse objc-message-args.
11818 objc-keywordarg-list
11820 objc-keywordarg-list:
11822 objc-keywordarg-list objc-keywordarg
11825 objc-selector : objc-keywordexpr
11830 c_parser_objc_message_args (c_parser
*parser
)
11832 tree sel
= c_parser_objc_selector (parser
);
11833 tree list
= NULL_TREE
;
11834 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11839 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11840 return error_mark_node
;
11841 keywordexpr
= c_parser_objc_keywordexpr (parser
);
11842 list
= chainon (list
, build_tree_list (sel
, keywordexpr
));
11843 sel
= c_parser_objc_selector (parser
);
11844 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11850 /* Parse an objc-keywordexpr.
11857 c_parser_objc_keywordexpr (c_parser
*parser
)
11860 vec
<tree
, va_gc
> *expr_list
= c_parser_expr_list (parser
, true, true,
11861 NULL
, NULL
, NULL
, NULL
);
11862 if (vec_safe_length (expr_list
) == 1)
11864 /* Just return the expression, remove a level of
11866 ret
= (*expr_list
)[0];
11870 /* We have a comma expression, we will collapse later. */
11871 ret
= build_tree_list_vec (expr_list
);
11873 release_tree_vector (expr_list
);
11877 /* A check, needed in several places, that ObjC interface, implementation or
11878 method definitions are not prefixed by incorrect items. */
11880 c_parser_objc_diagnose_bad_element_prefix (c_parser
*parser
,
11881 struct c_declspecs
*specs
)
11883 if (!specs
->declspecs_seen_p
|| specs
->non_sc_seen_p
11884 || specs
->typespec_kind
!= ctsk_none
)
11886 c_parser_error (parser
,
11887 "no type or storage class may be specified here,");
11888 c_parser_skip_to_end_of_block_or_statement (parser
);
11894 /* Parse an Objective-C @property declaration. The syntax is:
11896 objc-property-declaration:
11897 '@property' objc-property-attributes[opt] struct-declaration ;
11899 objc-property-attributes:
11900 '(' objc-property-attribute-list ')'
11902 objc-property-attribute-list:
11903 objc-property-attribute
11904 objc-property-attribute-list, objc-property-attribute
11906 objc-property-attribute
11907 'getter' = identifier
11908 'setter' = identifier
11917 @property NSString *name;
11918 @property (readonly) id object;
11919 @property (retain, nonatomic, getter=getTheName) id name;
11920 @property int a, b, c;
11922 PS: This function is identical to cp_parser_objc_at_propery_declaration
11923 for C++. Keep them in sync. */
11925 c_parser_objc_at_property_declaration (c_parser
*parser
)
11927 /* The following variables hold the attributes of the properties as
11928 parsed. They are 'false' or 'NULL_TREE' if the attribute was not
11929 seen. When we see an attribute, we set them to 'true' (if they
11930 are boolean properties) or to the identifier (if they have an
11931 argument, ie, for getter and setter). Note that here we only
11932 parse the list of attributes, check the syntax and accumulate the
11933 attributes that we find. objc_add_property_declaration() will
11934 then process the information. */
11935 bool property_assign
= false;
11936 bool property_copy
= false;
11937 tree property_getter_ident
= NULL_TREE
;
11938 bool property_nonatomic
= false;
11939 bool property_readonly
= false;
11940 bool property_readwrite
= false;
11941 bool property_retain
= false;
11942 tree property_setter_ident
= NULL_TREE
;
11944 /* 'properties' is the list of properties that we read. Usually a
11945 single one, but maybe more (eg, in "@property int a, b, c;" there
11950 loc
= c_parser_peek_token (parser
)->location
;
11951 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
));
11953 c_parser_consume_token (parser
); /* Eat '@property'. */
11955 /* Parse the optional attribute list... */
11956 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11958 matching_parens parens
;
11961 parens
.consume_open (parser
);
11963 /* Property attribute keywords are valid now. */
11964 parser
->objc_property_attr_context
= true;
11968 bool syntax_error
= false;
11969 c_token
*token
= c_parser_peek_token (parser
);
11972 if (token
->type
!= CPP_KEYWORD
)
11974 if (token
->type
== CPP_CLOSE_PAREN
)
11975 c_parser_error (parser
, "expected identifier");
11978 c_parser_consume_token (parser
);
11979 c_parser_error (parser
, "unknown property attribute");
11983 keyword
= token
->keyword
;
11984 c_parser_consume_token (parser
);
11987 case RID_ASSIGN
: property_assign
= true; break;
11988 case RID_COPY
: property_copy
= true; break;
11989 case RID_NONATOMIC
: property_nonatomic
= true; break;
11990 case RID_READONLY
: property_readonly
= true; break;
11991 case RID_READWRITE
: property_readwrite
= true; break;
11992 case RID_RETAIN
: property_retain
= true; break;
11996 if (c_parser_next_token_is_not (parser
, CPP_EQ
))
11998 if (keyword
== RID_GETTER
)
11999 c_parser_error (parser
,
12000 "missing %<=%> (after %<getter%> attribute)");
12002 c_parser_error (parser
,
12003 "missing %<=%> (after %<setter%> attribute)");
12004 syntax_error
= true;
12007 c_parser_consume_token (parser
); /* eat the = */
12008 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12010 c_parser_error (parser
, "expected identifier");
12011 syntax_error
= true;
12014 if (keyword
== RID_SETTER
)
12016 if (property_setter_ident
!= NULL_TREE
)
12017 c_parser_error (parser
, "the %<setter%> attribute may only be specified once");
12019 property_setter_ident
= c_parser_peek_token (parser
)->value
;
12020 c_parser_consume_token (parser
);
12021 if (c_parser_next_token_is_not (parser
, CPP_COLON
))
12022 c_parser_error (parser
, "setter name must terminate with %<:%>");
12024 c_parser_consume_token (parser
);
12028 if (property_getter_ident
!= NULL_TREE
)
12029 c_parser_error (parser
, "the %<getter%> attribute may only be specified once");
12031 property_getter_ident
= c_parser_peek_token (parser
)->value
;
12032 c_parser_consume_token (parser
);
12036 c_parser_error (parser
, "unknown property attribute");
12037 syntax_error
= true;
12044 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12045 c_parser_consume_token (parser
);
12049 parser
->objc_property_attr_context
= false;
12050 parens
.skip_until_found_close (parser
);
12052 /* ... and the property declaration(s). */
12053 properties
= c_parser_struct_declaration (parser
);
12055 if (properties
== error_mark_node
)
12057 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12058 parser
->error
= false;
12062 if (properties
== NULL_TREE
)
12063 c_parser_error (parser
, "expected identifier");
12066 /* Comma-separated properties are chained together in
12067 reverse order; add them one by one. */
12068 properties
= nreverse (properties
);
12070 for (; properties
; properties
= TREE_CHAIN (properties
))
12071 objc_add_property_declaration (loc
, copy_node (properties
),
12072 property_readonly
, property_readwrite
,
12073 property_assign
, property_retain
,
12074 property_copy
, property_nonatomic
,
12075 property_getter_ident
, property_setter_ident
);
12078 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12079 parser
->error
= false;
12082 /* Parse an Objective-C @synthesize declaration. The syntax is:
12084 objc-synthesize-declaration:
12085 @synthesize objc-synthesize-identifier-list ;
12087 objc-synthesize-identifier-list:
12088 objc-synthesize-identifier
12089 objc-synthesize-identifier-list, objc-synthesize-identifier
12091 objc-synthesize-identifier
12093 identifier = identifier
12096 @synthesize MyProperty;
12097 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12099 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12100 for C++. Keep them in sync.
12103 c_parser_objc_at_synthesize_declaration (c_parser
*parser
)
12105 tree list
= NULL_TREE
;
12107 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNTHESIZE
));
12108 loc
= c_parser_peek_token (parser
)->location
;
12110 c_parser_consume_token (parser
);
12113 tree property
, ivar
;
12114 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12116 c_parser_error (parser
, "expected identifier");
12117 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12118 /* Once we find the semicolon, we can resume normal parsing.
12119 We have to reset parser->error manually because
12120 c_parser_skip_until_found() won't reset it for us if the
12121 next token is precisely a semicolon. */
12122 parser
->error
= false;
12125 property
= c_parser_peek_token (parser
)->value
;
12126 c_parser_consume_token (parser
);
12127 if (c_parser_next_token_is (parser
, CPP_EQ
))
12129 c_parser_consume_token (parser
);
12130 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12132 c_parser_error (parser
, "expected identifier");
12133 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12134 parser
->error
= false;
12137 ivar
= c_parser_peek_token (parser
)->value
;
12138 c_parser_consume_token (parser
);
12142 list
= chainon (list
, build_tree_list (ivar
, property
));
12143 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12144 c_parser_consume_token (parser
);
12148 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12149 objc_add_synthesize_declaration (loc
, list
);
12152 /* Parse an Objective-C @dynamic declaration. The syntax is:
12154 objc-dynamic-declaration:
12155 @dynamic identifier-list ;
12158 @dynamic MyProperty;
12159 @dynamic MyProperty, AnotherProperty;
12161 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12162 for C++. Keep them in sync.
12165 c_parser_objc_at_dynamic_declaration (c_parser
*parser
)
12167 tree list
= NULL_TREE
;
12169 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_DYNAMIC
));
12170 loc
= c_parser_peek_token (parser
)->location
;
12172 c_parser_consume_token (parser
);
12176 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12178 c_parser_error (parser
, "expected identifier");
12179 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12180 parser
->error
= false;
12183 property
= c_parser_peek_token (parser
)->value
;
12184 list
= chainon (list
, build_tree_list (NULL_TREE
, property
));
12185 c_parser_consume_token (parser
);
12186 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12187 c_parser_consume_token (parser
);
12191 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12192 objc_add_dynamic_declaration (loc
, list
);
12196 /* Parse a pragma GCC ivdep. */
12199 c_parse_pragma_ivdep (c_parser
*parser
)
12201 c_parser_consume_pragma (parser
);
12202 c_parser_skip_to_pragma_eol (parser
);
12206 /* Parse a pragma GCC unroll. */
12208 static unsigned short
12209 c_parser_pragma_unroll (c_parser
*parser
)
12211 unsigned short unroll
;
12212 c_parser_consume_pragma (parser
);
12213 location_t location
= c_parser_peek_token (parser
)->location
;
12214 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
12215 mark_exp_read (expr
);
12216 expr
= c_fully_fold (expr
, false, NULL
);
12217 HOST_WIDE_INT lunroll
= 0;
12218 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
12219 || TREE_CODE (expr
) != INTEGER_CST
12220 || (lunroll
= tree_to_shwi (expr
)) < 0
12221 || lunroll
>= USHRT_MAX
)
12223 error_at (location
, "%<#pragma GCC unroll%> requires an"
12224 " assignment-expression that evaluates to a non-negative"
12225 " integral constant less than %u", USHRT_MAX
);
12230 unroll
= (unsigned short)lunroll
;
12235 c_parser_skip_to_pragma_eol (parser
);
12239 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12240 should be considered, statements. ALLOW_STMT is true if we're within
12241 the context of a function and such pragmas are to be allowed. Returns
12242 true if we actually parsed such a pragma. */
12245 c_parser_pragma (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
12248 const char *construct
= NULL
;
12250 id
= c_parser_peek_token (parser
)->pragma_kind
;
12251 gcc_assert (id
!= PRAGMA_NONE
);
12255 case PRAGMA_OACC_DECLARE
:
12256 c_parser_oacc_declare (parser
);
12259 case PRAGMA_OACC_ENTER_DATA
:
12260 if (context
!= pragma_compound
)
12262 construct
= "acc enter data";
12264 if (context
== pragma_stmt
)
12266 error_at (c_parser_peek_token (parser
)->location
,
12267 "%<#pragma %s%> may only be used in compound "
12268 "statements", construct
);
12269 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12274 c_parser_oacc_enter_exit_data (parser
, true);
12277 case PRAGMA_OACC_EXIT_DATA
:
12278 if (context
!= pragma_compound
)
12280 construct
= "acc exit data";
12283 c_parser_oacc_enter_exit_data (parser
, false);
12286 case PRAGMA_OACC_ROUTINE
:
12287 if (context
!= pragma_external
)
12289 error_at (c_parser_peek_token (parser
)->location
,
12290 "%<#pragma acc routine%> must be at file scope");
12291 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12294 c_parser_oacc_routine (parser
, context
);
12297 case PRAGMA_OACC_UPDATE
:
12298 if (context
!= pragma_compound
)
12300 construct
= "acc update";
12303 c_parser_oacc_update (parser
);
12306 case PRAGMA_OMP_BARRIER
:
12307 if (context
!= pragma_compound
)
12309 construct
= "omp barrier";
12312 c_parser_omp_barrier (parser
);
12315 case PRAGMA_OMP_DEPOBJ
:
12316 if (context
!= pragma_compound
)
12318 construct
= "omp depobj";
12321 c_parser_omp_depobj (parser
);
12324 case PRAGMA_OMP_FLUSH
:
12325 if (context
!= pragma_compound
)
12327 construct
= "omp flush";
12330 c_parser_omp_flush (parser
);
12333 case PRAGMA_OMP_TASKWAIT
:
12334 if (context
!= pragma_compound
)
12336 construct
= "omp taskwait";
12339 c_parser_omp_taskwait (parser
);
12342 case PRAGMA_OMP_TASKYIELD
:
12343 if (context
!= pragma_compound
)
12345 construct
= "omp taskyield";
12348 c_parser_omp_taskyield (parser
);
12351 case PRAGMA_OMP_CANCEL
:
12352 if (context
!= pragma_compound
)
12354 construct
= "omp cancel";
12357 c_parser_omp_cancel (parser
);
12360 case PRAGMA_OMP_CANCELLATION_POINT
:
12361 c_parser_omp_cancellation_point (parser
, context
);
12364 case PRAGMA_OMP_THREADPRIVATE
:
12365 c_parser_omp_threadprivate (parser
);
12368 case PRAGMA_OMP_TARGET
:
12369 return c_parser_omp_target (parser
, context
, if_p
);
12371 case PRAGMA_OMP_END_DECLARE_TARGET
:
12372 c_parser_omp_end_declare_target (parser
);
12375 case PRAGMA_OMP_SCAN
:
12376 error_at (c_parser_peek_token (parser
)->location
,
12377 "%<#pragma omp scan%> may only be used in "
12378 "a loop construct with %<inscan%> %<reduction%> clause");
12379 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12382 case PRAGMA_OMP_SECTION
:
12383 error_at (c_parser_peek_token (parser
)->location
,
12384 "%<#pragma omp section%> may only be used in "
12385 "%<#pragma omp sections%> construct");
12386 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12389 case PRAGMA_OMP_DECLARE
:
12390 c_parser_omp_declare (parser
, context
);
12393 case PRAGMA_OMP_REQUIRES
:
12394 c_parser_omp_requires (parser
);
12397 case PRAGMA_OMP_ORDERED
:
12398 return c_parser_omp_ordered (parser
, context
, if_p
);
12402 const bool ivdep
= c_parse_pragma_ivdep (parser
);
12403 unsigned short unroll
;
12404 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_UNROLL
)
12405 unroll
= c_parser_pragma_unroll (parser
);
12408 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12409 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12410 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12412 c_parser_error (parser
, "for, while or do statement expected");
12415 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12416 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12417 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12418 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12420 c_parser_do_statement (parser
, ivdep
, unroll
);
12424 case PRAGMA_UNROLL
:
12426 unsigned short unroll
= c_parser_pragma_unroll (parser
);
12428 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_IVDEP
)
12429 ivdep
= c_parse_pragma_ivdep (parser
);
12432 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12433 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12434 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12436 c_parser_error (parser
, "for, while or do statement expected");
12439 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12440 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12441 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12442 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12444 c_parser_do_statement (parser
, ivdep
, unroll
);
12448 case PRAGMA_GCC_PCH_PREPROCESS
:
12449 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
12450 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12453 case PRAGMA_OACC_WAIT
:
12454 if (context
!= pragma_compound
)
12456 construct
= "acc wait";
12459 /* FALL THROUGH. */
12462 if (id
< PRAGMA_FIRST_EXTERNAL
)
12464 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
12467 c_parser_error (parser
, "expected declaration specifiers");
12468 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12471 c_parser_omp_construct (parser
, if_p
);
12477 c_parser_consume_pragma (parser
);
12478 c_invoke_pragma_handler (id
);
12480 /* Skip to EOL, but suppress any error message. Those will have been
12481 generated by the handler routine through calling error, as opposed
12482 to calling c_parser_error. */
12483 parser
->error
= true;
12484 c_parser_skip_to_pragma_eol (parser
);
12489 /* The interface the pragma parsers have to the lexer. */
12492 pragma_lex (tree
*value
, location_t
*loc
)
12494 c_token
*tok
= c_parser_peek_token (the_parser
);
12495 enum cpp_ttype ret
= tok
->type
;
12497 *value
= tok
->value
;
12499 *loc
= tok
->location
;
12501 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
12503 else if (ret
== CPP_STRING
)
12504 *value
= c_parser_string_literal (the_parser
, false, false).value
;
12507 if (ret
== CPP_KEYWORD
)
12509 c_parser_consume_token (the_parser
);
12516 c_parser_pragma_pch_preprocess (c_parser
*parser
)
12520 parser
->lex_joined_string
= true;
12521 c_parser_consume_pragma (parser
);
12522 if (c_parser_next_token_is (parser
, CPP_STRING
))
12524 name
= c_parser_peek_token (parser
)->value
;
12525 c_parser_consume_token (parser
);
12528 c_parser_error (parser
, "expected string literal");
12529 c_parser_skip_to_pragma_eol (parser
);
12530 parser
->lex_joined_string
= false;
12533 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
12536 /* OpenACC and OpenMP parsing routines. */
12538 /* Returns name of the next clause.
12539 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12540 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12541 returned and the token is consumed. */
12543 static pragma_omp_clause
12544 c_parser_omp_clause_name (c_parser
*parser
)
12546 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
12548 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
12549 result
= PRAGMA_OACC_CLAUSE_AUTO
;
12550 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
12551 result
= PRAGMA_OMP_CLAUSE_IF
;
12552 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
12553 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
12554 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12555 result
= PRAGMA_OMP_CLAUSE_FOR
;
12556 else if (c_parser_next_token_is (parser
, CPP_NAME
))
12558 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
12563 if (!strcmp ("aligned", p
))
12564 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
12565 else if (!strcmp ("async", p
))
12566 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
12567 else if (!strcmp ("attach", p
))
12568 result
= PRAGMA_OACC_CLAUSE_ATTACH
;
12571 if (!strcmp ("bind", p
))
12572 result
= PRAGMA_OMP_CLAUSE_BIND
;
12575 if (!strcmp ("collapse", p
))
12576 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
12577 else if (!strcmp ("copy", p
))
12578 result
= PRAGMA_OACC_CLAUSE_COPY
;
12579 else if (!strcmp ("copyin", p
))
12580 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
12581 else if (!strcmp ("copyout", p
))
12582 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12583 else if (!strcmp ("copyprivate", p
))
12584 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
12585 else if (!strcmp ("create", p
))
12586 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12589 if (!strcmp ("defaultmap", p
))
12590 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
12591 else if (!strcmp ("delete", p
))
12592 result
= PRAGMA_OACC_CLAUSE_DELETE
;
12593 else if (!strcmp ("depend", p
))
12594 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
12595 else if (!strcmp ("detach", p
))
12596 result
= PRAGMA_OACC_CLAUSE_DETACH
;
12597 else if (!strcmp ("device", p
))
12598 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
12599 else if (!strcmp ("deviceptr", p
))
12600 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
12601 else if (!strcmp ("device_resident", p
))
12602 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
12603 else if (!strcmp ("device_type", p
))
12604 result
= PRAGMA_OMP_CLAUSE_DEVICE_TYPE
;
12605 else if (!strcmp ("dist_schedule", p
))
12606 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
12609 if (!strcmp ("final", p
))
12610 result
= PRAGMA_OMP_CLAUSE_FINAL
;
12611 else if (!strcmp ("finalize", p
))
12612 result
= PRAGMA_OACC_CLAUSE_FINALIZE
;
12613 else if (!strcmp ("firstprivate", p
))
12614 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
12615 else if (!strcmp ("from", p
))
12616 result
= PRAGMA_OMP_CLAUSE_FROM
;
12619 if (!strcmp ("gang", p
))
12620 result
= PRAGMA_OACC_CLAUSE_GANG
;
12621 else if (!strcmp ("grainsize", p
))
12622 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
12625 if (!strcmp ("hint", p
))
12626 result
= PRAGMA_OMP_CLAUSE_HINT
;
12627 else if (!strcmp ("host", p
))
12628 result
= PRAGMA_OACC_CLAUSE_HOST
;
12631 if (!strcmp ("if_present", p
))
12632 result
= PRAGMA_OACC_CLAUSE_IF_PRESENT
;
12633 else if (!strcmp ("in_reduction", p
))
12634 result
= PRAGMA_OMP_CLAUSE_IN_REDUCTION
;
12635 else if (!strcmp ("inbranch", p
))
12636 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
12637 else if (!strcmp ("independent", p
))
12638 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
12639 else if (!strcmp ("is_device_ptr", p
))
12640 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
12643 if (!strcmp ("lastprivate", p
))
12644 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
12645 else if (!strcmp ("linear", p
))
12646 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
12647 else if (!strcmp ("link", p
))
12648 result
= PRAGMA_OMP_CLAUSE_LINK
;
12651 if (!strcmp ("map", p
))
12652 result
= PRAGMA_OMP_CLAUSE_MAP
;
12653 else if (!strcmp ("mergeable", p
))
12654 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
12657 if (!strcmp ("no_create", p
))
12658 result
= PRAGMA_OACC_CLAUSE_NO_CREATE
;
12659 else if (!strcmp ("nogroup", p
))
12660 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
12661 else if (!strcmp ("nontemporal", p
))
12662 result
= PRAGMA_OMP_CLAUSE_NONTEMPORAL
;
12663 else if (!strcmp ("notinbranch", p
))
12664 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
12665 else if (!strcmp ("nowait", p
))
12666 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
12667 else if (!strcmp ("num_gangs", p
))
12668 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
12669 else if (!strcmp ("num_tasks", p
))
12670 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
12671 else if (!strcmp ("num_teams", p
))
12672 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
12673 else if (!strcmp ("num_threads", p
))
12674 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
12675 else if (!strcmp ("num_workers", p
))
12676 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
12679 if (!strcmp ("ordered", p
))
12680 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
12681 else if (!strcmp ("order", p
))
12682 result
= PRAGMA_OMP_CLAUSE_ORDER
;
12685 if (!strcmp ("parallel", p
))
12686 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
12687 else if (!strcmp ("present", p
))
12688 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
12689 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12691 else if (!strcmp ("present_or_copy", p
)
12692 || !strcmp ("pcopy", p
))
12693 result
= PRAGMA_OACC_CLAUSE_COPY
;
12694 else if (!strcmp ("present_or_copyin", p
)
12695 || !strcmp ("pcopyin", p
))
12696 result
= PRAGMA_OACC_CLAUSE_COPYIN
;
12697 else if (!strcmp ("present_or_copyout", p
)
12698 || !strcmp ("pcopyout", p
))
12699 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12700 else if (!strcmp ("present_or_create", p
)
12701 || !strcmp ("pcreate", p
))
12702 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12703 else if (!strcmp ("priority", p
))
12704 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
12705 else if (!strcmp ("private", p
))
12706 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
12707 else if (!strcmp ("proc_bind", p
))
12708 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
12711 if (!strcmp ("reduction", p
))
12712 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
12715 if (!strcmp ("safelen", p
))
12716 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
12717 else if (!strcmp ("schedule", p
))
12718 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
12719 else if (!strcmp ("sections", p
))
12720 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
12721 else if (!strcmp ("self", p
)) /* "self" is a synonym for "host". */
12722 result
= PRAGMA_OACC_CLAUSE_HOST
;
12723 else if (!strcmp ("seq", p
))
12724 result
= PRAGMA_OACC_CLAUSE_SEQ
;
12725 else if (!strcmp ("shared", p
))
12726 result
= PRAGMA_OMP_CLAUSE_SHARED
;
12727 else if (!strcmp ("simd", p
))
12728 result
= PRAGMA_OMP_CLAUSE_SIMD
;
12729 else if (!strcmp ("simdlen", p
))
12730 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
12733 if (!strcmp ("task_reduction", p
))
12734 result
= PRAGMA_OMP_CLAUSE_TASK_REDUCTION
;
12735 else if (!strcmp ("taskgroup", p
))
12736 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
12737 else if (!strcmp ("thread_limit", p
))
12738 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
12739 else if (!strcmp ("threads", p
))
12740 result
= PRAGMA_OMP_CLAUSE_THREADS
;
12741 else if (!strcmp ("tile", p
))
12742 result
= PRAGMA_OACC_CLAUSE_TILE
;
12743 else if (!strcmp ("to", p
))
12744 result
= PRAGMA_OMP_CLAUSE_TO
;
12747 if (!strcmp ("uniform", p
))
12748 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
12749 else if (!strcmp ("untied", p
))
12750 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
12751 else if (!strcmp ("use_device", p
))
12752 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
12753 else if (!strcmp ("use_device_addr", p
))
12754 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
;
12755 else if (!strcmp ("use_device_ptr", p
))
12756 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
12759 if (!strcmp ("vector", p
))
12760 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
12761 else if (!strcmp ("vector_length", p
))
12762 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
12765 if (!strcmp ("wait", p
))
12766 result
= PRAGMA_OACC_CLAUSE_WAIT
;
12767 else if (!strcmp ("worker", p
))
12768 result
= PRAGMA_OACC_CLAUSE_WORKER
;
12773 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
12774 c_parser_consume_token (parser
);
12779 /* Validate that a clause of the given type does not already exist. */
12782 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
12785 if (tree c
= omp_find_clause (clauses
, code
))
12786 error_at (OMP_CLAUSE_LOCATION (c
), "too many %qs clauses", name
);
12790 Parse wait clause or wait directive parameters. */
12793 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
12795 vec
<tree
, va_gc
> *args
;
12798 matching_parens parens
;
12799 if (!parens
.require_open (parser
))
12802 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
12803 args_tree
= build_tree_list_vec (args
);
12805 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
12807 tree targ
= TREE_VALUE (t
);
12809 if (targ
!= error_mark_node
)
12811 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
12813 c_parser_error (parser
, "expression must be integral");
12814 targ
= error_mark_node
;
12818 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
12820 OMP_CLAUSE_DECL (c
) = targ
;
12821 OMP_CLAUSE_CHAIN (c
) = list
;
12827 release_tree_vector (args
);
12828 parens
.require_close (parser
);
12832 /* OpenACC 2.0, OpenMP 2.5:
12835 variable-list , identifier
12837 If KIND is nonzero, create the appropriate node and install the
12838 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
12839 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
12841 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
12842 return the list created.
12844 The optional ALLOW_DEREF argument is true if list items can use the deref
12848 c_parser_omp_variable_list (c_parser
*parser
,
12849 location_t clause_loc
,
12850 enum omp_clause_code kind
, tree list
,
12851 bool allow_deref
= false)
12853 auto_vec
<c_token
> tokens
;
12854 unsigned int tokens_avail
= 0;
12859 bool array_section_p
= false;
12860 if (kind
== OMP_CLAUSE_DEPEND
)
12862 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
12863 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
12865 struct c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
12866 if (expr
.value
!= error_mark_node
)
12868 tree u
= build_omp_clause (clause_loc
, kind
);
12869 OMP_CLAUSE_DECL (u
) = expr
.value
;
12870 OMP_CLAUSE_CHAIN (u
) = list
;
12874 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
12877 c_parser_consume_token (parser
);
12882 tokens
.truncate (0);
12883 unsigned int nesting_depth
= 0;
12886 c_token
*token
= c_parser_peek_token (parser
);
12887 switch (token
->type
)
12890 case CPP_PRAGMA_EOL
:
12892 case CPP_OPEN_BRACE
:
12893 case CPP_OPEN_PAREN
:
12894 case CPP_OPEN_SQUARE
:
12897 case CPP_CLOSE_BRACE
:
12898 case CPP_CLOSE_PAREN
:
12899 case CPP_CLOSE_SQUARE
:
12900 if (nesting_depth
-- == 0)
12904 if (nesting_depth
== 0)
12909 tokens
.safe_push (*token
);
12910 c_parser_consume_token (parser
);
12916 /* Make sure nothing tries to read past the end of the tokens. */
12918 memset (&eof_token
, 0, sizeof (eof_token
));
12919 eof_token
.type
= CPP_EOF
;
12920 tokens
.safe_push (eof_token
);
12921 tokens
.safe_push (eof_token
);
12923 tokens_avail
= parser
->tokens_avail
;
12924 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
12925 parser
->tokens
= tokens
.address ();
12926 parser
->tokens_avail
= tokens
.length ();
12929 tree t
= NULL_TREE
;
12931 if (c_parser_next_token_is (parser
, CPP_NAME
)
12932 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
12934 t
= lookup_name (c_parser_peek_token (parser
)->value
);
12936 if (t
== NULL_TREE
)
12938 undeclared_variable (c_parser_peek_token (parser
)->location
,
12939 c_parser_peek_token (parser
)->value
);
12940 t
= error_mark_node
;
12943 c_parser_consume_token (parser
);
12945 else if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
12946 && (c_parser_peek_token (parser
)->keyword
== RID_FUNCTION_NAME
12947 || (c_parser_peek_token (parser
)->keyword
12948 == RID_PRETTY_FUNCTION_NAME
)
12949 || (c_parser_peek_token (parser
)->keyword
12950 == RID_C99_FUNCTION_NAME
)))
12951 t
= c_parser_predefined_identifier (parser
).value
;
12955 c_parser_error (parser
, "expected identifier");
12959 if (t
== error_mark_node
)
12961 else if (kind
!= 0)
12965 case OMP_CLAUSE__CACHE_
:
12966 /* The OpenACC cache directive explicitly only allows "array
12967 elements or subarrays". */
12968 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
12970 c_parser_error (parser
, "expected %<[%>");
12971 t
= error_mark_node
;
12975 case OMP_CLAUSE_MAP
:
12976 case OMP_CLAUSE_FROM
:
12977 case OMP_CLAUSE_TO
:
12978 while (c_parser_next_token_is (parser
, CPP_DOT
)
12980 && c_parser_next_token_is (parser
, CPP_DEREF
)))
12982 location_t op_loc
= c_parser_peek_token (parser
)->location
;
12983 if (c_parser_next_token_is (parser
, CPP_DEREF
))
12984 t
= build_simple_mem_ref (t
);
12985 c_parser_consume_token (parser
);
12986 if (!c_parser_next_token_is (parser
, CPP_NAME
))
12988 c_parser_error (parser
, "expected identifier");
12989 t
= error_mark_node
;
12993 c_token
*comp_tok
= c_parser_peek_token (parser
);
12994 tree ident
= comp_tok
->value
;
12995 location_t comp_loc
= comp_tok
->location
;
12996 c_parser_consume_token (parser
);
12997 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
);
13000 case OMP_CLAUSE_DEPEND
:
13001 case OMP_CLAUSE_REDUCTION
:
13002 case OMP_CLAUSE_IN_REDUCTION
:
13003 case OMP_CLAUSE_TASK_REDUCTION
:
13004 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
13006 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
13008 c_parser_consume_token (parser
);
13009 if (!c_parser_next_token_is (parser
, CPP_COLON
))
13011 location_t expr_loc
13012 = c_parser_peek_token (parser
)->location
;
13013 c_expr expr
= c_parser_expression (parser
);
13014 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13016 low_bound
= expr
.value
;
13018 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13019 length
= integer_one_node
;
13022 /* Look for `:'. */
13023 if (!c_parser_require (parser
, CPP_COLON
,
13026 t
= error_mark_node
;
13029 array_section_p
= true;
13030 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13032 location_t expr_loc
13033 = c_parser_peek_token (parser
)->location
;
13034 c_expr expr
= c_parser_expression (parser
);
13035 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13037 length
= expr
.value
;
13040 /* Look for the closing `]'. */
13041 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
13044 t
= error_mark_node
;
13048 t
= tree_cons (low_bound
, length
, t
);
13050 if (kind
== OMP_CLAUSE_DEPEND
13051 && t
!= error_mark_node
13052 && parser
->tokens_avail
!= 2)
13054 if (array_section_p
)
13056 error_at (c_parser_peek_token (parser
)->location
,
13057 "expected %<)%> or %<,%>");
13058 t
= error_mark_node
;
13062 parser
->tokens
= tokens
.address ();
13063 parser
->tokens_avail
= tokens
.length ();
13065 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
13066 if (t
!= error_mark_node
&& parser
->tokens_avail
!= 2)
13068 error_at (c_parser_peek_token (parser
)->location
,
13069 "expected %<)%> or %<,%>");
13070 t
= error_mark_node
;
13079 if (t
!= error_mark_node
)
13081 tree u
= build_omp_clause (clause_loc
, kind
);
13082 OMP_CLAUSE_DECL (u
) = t
;
13083 OMP_CLAUSE_CHAIN (u
) = list
;
13088 list
= tree_cons (t
, NULL_TREE
, list
);
13090 if (kind
== OMP_CLAUSE_DEPEND
)
13092 parser
->tokens
= &parser
->tokens_buf
[0];
13093 parser
->tokens_avail
= tokens_avail
;
13095 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
13098 c_parser_consume_token (parser
);
13105 /* Similarly, but expect leading and trailing parenthesis. This is a very
13106 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13107 argument is true if list items can use the deref (->) operator. */
13110 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
13111 tree list
, bool allow_deref
= false)
13113 /* The clauses location. */
13114 location_t loc
= c_parser_peek_token (parser
)->location
;
13116 matching_parens parens
;
13117 if (parens
.require_open (parser
))
13119 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
, allow_deref
);
13120 parens
.skip_until_found_close (parser
);
13126 copy ( variable-list )
13127 copyin ( variable-list )
13128 copyout ( variable-list )
13129 create ( variable-list )
13130 delete ( variable-list )
13131 present ( variable-list )
13134 no_create ( variable-list )
13135 attach ( variable-list )
13136 detach ( variable-list ) */
13139 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
13142 enum gomp_map_kind kind
;
13145 case PRAGMA_OACC_CLAUSE_ATTACH
:
13146 kind
= GOMP_MAP_ATTACH
;
13148 case PRAGMA_OACC_CLAUSE_COPY
:
13149 kind
= GOMP_MAP_TOFROM
;
13151 case PRAGMA_OACC_CLAUSE_COPYIN
:
13152 kind
= GOMP_MAP_TO
;
13154 case PRAGMA_OACC_CLAUSE_COPYOUT
:
13155 kind
= GOMP_MAP_FROM
;
13157 case PRAGMA_OACC_CLAUSE_CREATE
:
13158 kind
= GOMP_MAP_ALLOC
;
13160 case PRAGMA_OACC_CLAUSE_DELETE
:
13161 kind
= GOMP_MAP_RELEASE
;
13163 case PRAGMA_OACC_CLAUSE_DETACH
:
13164 kind
= GOMP_MAP_DETACH
;
13166 case PRAGMA_OACC_CLAUSE_DEVICE
:
13167 kind
= GOMP_MAP_FORCE_TO
;
13169 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
13170 kind
= GOMP_MAP_DEVICE_RESIDENT
;
13172 case PRAGMA_OACC_CLAUSE_HOST
:
13173 kind
= GOMP_MAP_FORCE_FROM
;
13175 case PRAGMA_OACC_CLAUSE_LINK
:
13176 kind
= GOMP_MAP_LINK
;
13178 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
13179 kind
= GOMP_MAP_IF_PRESENT
;
13181 case PRAGMA_OACC_CLAUSE_PRESENT
:
13182 kind
= GOMP_MAP_FORCE_PRESENT
;
13185 gcc_unreachable ();
13188 nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_MAP
, list
, true);
13190 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13191 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
13197 deviceptr ( variable-list ) */
13200 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
13202 location_t loc
= c_parser_peek_token (parser
)->location
;
13205 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13206 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13207 variable-list must only allow for pointer variables. */
13208 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
13209 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
13211 tree v
= TREE_PURPOSE (t
);
13213 /* FIXME diagnostics: Ideally we should keep individual
13214 locations for all the variables in the var list to make the
13215 following errors more precise. Perhaps
13216 c_parser_omp_var_list_parens() should construct a list of
13217 locations to go along with the var list. */
13219 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
13220 error_at (loc
, "%qD is not a variable", v
);
13221 else if (TREE_TYPE (v
) == error_mark_node
)
13223 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
13224 error_at (loc
, "%qD is not a pointer variable", v
);
13226 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
13227 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
13228 OMP_CLAUSE_DECL (u
) = v
;
13229 OMP_CLAUSE_CHAIN (u
) = list
;
13236 /* OpenACC 2.0, OpenMP 3.0:
13237 collapse ( constant-expression ) */
13240 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
13242 tree c
, num
= error_mark_node
;
13246 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
13247 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
13249 loc
= c_parser_peek_token (parser
)->location
;
13250 matching_parens parens
;
13251 if (parens
.require_open (parser
))
13253 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
13254 parens
.skip_until_found_close (parser
);
13256 if (num
== error_mark_node
)
13258 mark_exp_read (num
);
13259 num
= c_fully_fold (num
, false, NULL
);
13260 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
13261 || !tree_fits_shwi_p (num
)
13262 || (n
= tree_to_shwi (num
)) <= 0
13266 "collapse argument needs positive constant integer expression");
13269 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
13270 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
13271 OMP_CLAUSE_CHAIN (c
) = list
;
13276 copyin ( variable-list ) */
13279 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
13281 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
13285 copyprivate ( variable-list ) */
13288 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
13290 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
13294 default ( none | shared )
13297 default ( none | present ) */
13300 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
13302 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
13303 location_t loc
= c_parser_peek_token (parser
)->location
;
13306 matching_parens parens
;
13307 if (!parens
.require_open (parser
))
13309 if (c_parser_next_token_is (parser
, CPP_NAME
))
13311 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13316 if (strcmp ("none", p
) != 0)
13318 kind
= OMP_CLAUSE_DEFAULT_NONE
;
13322 if (strcmp ("present", p
) != 0 || !is_oacc
)
13324 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
13328 if (strcmp ("shared", p
) != 0 || is_oacc
)
13330 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
13337 c_parser_consume_token (parser
);
13343 c_parser_error (parser
, "expected %<none%> or %<present%>");
13345 c_parser_error (parser
, "expected %<none%> or %<shared%>");
13347 parens
.skip_until_found_close (parser
);
13349 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
13352 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
13353 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
13354 OMP_CLAUSE_CHAIN (c
) = list
;
13355 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
13361 firstprivate ( variable-list ) */
13364 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
13366 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
13370 final ( expression ) */
13373 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
13375 location_t loc
= c_parser_peek_token (parser
)->location
;
13376 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13378 matching_parens parens
;
13380 if (!parens
.require_open (parser
))
13381 t
= error_mark_node
;
13384 location_t eloc
= c_parser_peek_token (parser
)->location
;
13385 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13386 t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
13387 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
13388 t
= c_fully_fold (t
, false, NULL
);
13389 parens
.skip_until_found_close (parser
);
13392 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
13394 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
13395 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
13396 OMP_CLAUSE_CHAIN (c
) = list
;
13400 c_parser_error (parser
, "expected %<(%>");
13405 /* OpenACC, OpenMP 2.5:
13409 if ( directive-name-modifier : expression )
13411 directive-name-modifier:
13412 parallel | task | taskloop | target data | target | target update
13413 | target enter data | target exit data
13416 directive-name-modifier:
13417 ... | simd | cancel */
13420 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
13422 location_t location
= c_parser_peek_token (parser
)->location
;
13423 enum tree_code if_modifier
= ERROR_MARK
;
13425 matching_parens parens
;
13426 if (!parens
.require_open (parser
))
13429 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
13431 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13433 if (strcmp (p
, "cancel") == 0)
13434 if_modifier
= VOID_CST
;
13435 else if (strcmp (p
, "parallel") == 0)
13436 if_modifier
= OMP_PARALLEL
;
13437 else if (strcmp (p
, "simd") == 0)
13438 if_modifier
= OMP_SIMD
;
13439 else if (strcmp (p
, "task") == 0)
13440 if_modifier
= OMP_TASK
;
13441 else if (strcmp (p
, "taskloop") == 0)
13442 if_modifier
= OMP_TASKLOOP
;
13443 else if (strcmp (p
, "target") == 0)
13445 if_modifier
= OMP_TARGET
;
13446 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
13448 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
13449 if (strcmp ("data", p
) == 0)
13450 if_modifier
= OMP_TARGET_DATA
;
13451 else if (strcmp ("update", p
) == 0)
13452 if_modifier
= OMP_TARGET_UPDATE
;
13453 else if (strcmp ("enter", p
) == 0)
13454 if_modifier
= OMP_TARGET_ENTER_DATA
;
13455 else if (strcmp ("exit", p
) == 0)
13456 if_modifier
= OMP_TARGET_EXIT_DATA
;
13457 if (if_modifier
!= OMP_TARGET
)
13460 c_parser_consume_token (parser
);
13464 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
13465 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
13467 if_modifier
= ERROR_MARK
;
13469 if (if_modifier
== OMP_TARGET_ENTER_DATA
13470 || if_modifier
== OMP_TARGET_EXIT_DATA
)
13472 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
13474 p
= IDENTIFIER_POINTER
13475 (c_parser_peek_2nd_token (parser
)->value
);
13476 if (strcmp ("data", p
) == 0)
13480 c_parser_consume_token (parser
);
13484 = c_parser_peek_2nd_token (parser
)->location
;
13485 error_at (loc
, "expected %<data%>");
13486 if_modifier
= ERROR_MARK
;
13491 if (if_modifier
!= ERROR_MARK
)
13493 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13495 c_parser_consume_token (parser
);
13496 c_parser_consume_token (parser
);
13502 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
13503 error_at (loc
, "expected %<:%>");
13505 if_modifier
= ERROR_MARK
;
13510 location_t loc
= c_parser_peek_token (parser
)->location
;
13511 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13512 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
13513 tree t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
), c
;
13514 t
= c_fully_fold (t
, false, NULL
);
13515 parens
.skip_until_found_close (parser
);
13517 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
13518 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
13520 if (if_modifier
!= ERROR_MARK
13521 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
13523 const char *p
= NULL
;
13524 switch (if_modifier
)
13526 case VOID_CST
: p
= "cancel"; break;
13527 case OMP_PARALLEL
: p
= "parallel"; break;
13528 case OMP_SIMD
: p
= "simd"; break;
13529 case OMP_TASK
: p
= "task"; break;
13530 case OMP_TASKLOOP
: p
= "taskloop"; break;
13531 case OMP_TARGET_DATA
: p
= "target data"; break;
13532 case OMP_TARGET
: p
= "target"; break;
13533 case OMP_TARGET_UPDATE
: p
= "target update"; break;
13534 case OMP_TARGET_ENTER_DATA
: p
= "target enter data"; break;
13535 case OMP_TARGET_EXIT_DATA
: p
= "target exit data"; break;
13536 default: gcc_unreachable ();
13538 error_at (location
, "too many %<if%> clauses with %qs modifier",
13542 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
13545 error_at (location
, "too many %<if%> clauses");
13547 error_at (location
, "too many %<if%> clauses without modifier");
13550 else if (if_modifier
== ERROR_MARK
13551 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
13553 error_at (location
, "if any %<if%> clause has modifier, then all "
13554 "%<if%> clauses have to use modifier");
13559 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
13560 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
13561 OMP_CLAUSE_IF_EXPR (c
) = t
;
13562 OMP_CLAUSE_CHAIN (c
) = list
;
13567 lastprivate ( variable-list )
13570 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13573 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
13575 /* The clauses location. */
13576 location_t loc
= c_parser_peek_token (parser
)->location
;
13578 if (c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
13580 bool conditional
= false;
13581 if (c_parser_next_token_is (parser
, CPP_NAME
)
13582 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13585 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13586 if (strcmp (p
, "conditional") == 0)
13588 conditional
= true;
13589 c_parser_consume_token (parser
);
13590 c_parser_consume_token (parser
);
13593 tree nlist
= c_parser_omp_variable_list (parser
, loc
,
13594 OMP_CLAUSE_LASTPRIVATE
, list
);
13595 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
13597 for (tree c
= nlist
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13598 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 1;
13608 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13612 /* FIXME: Should we allow duplicates? */
13613 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
13615 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
13616 OMP_CLAUSE_MERGEABLE
);
13617 OMP_CLAUSE_CHAIN (c
) = list
;
13626 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13629 location_t loc
= c_parser_peek_token (parser
)->location
;
13631 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
13633 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
13634 OMP_CLAUSE_CHAIN (c
) = list
;
13639 num_threads ( expression ) */
13642 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
13644 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
13645 matching_parens parens
;
13646 if (parens
.require_open (parser
))
13648 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13649 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13650 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13651 tree c
, t
= expr
.value
;
13652 t
= c_fully_fold (t
, false, NULL
);
13654 parens
.skip_until_found_close (parser
);
13656 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13658 c_parser_error (parser
, "expected integer expression");
13662 /* Attempt to statically determine when the number isn't positive. */
13663 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13664 build_int_cst (TREE_TYPE (t
), 0));
13665 protected_set_expr_location (c
, expr_loc
);
13666 if (c
== boolean_true_node
)
13668 warning_at (expr_loc
, 0,
13669 "%<num_threads%> value must be positive");
13670 t
= integer_one_node
;
13673 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
13675 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
13676 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
13677 OMP_CLAUSE_CHAIN (c
) = list
;
13685 num_tasks ( expression ) */
13688 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
13690 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
13691 matching_parens parens
;
13692 if (parens
.require_open (parser
))
13694 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13695 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13696 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13697 tree c
, t
= expr
.value
;
13698 t
= c_fully_fold (t
, false, NULL
);
13700 parens
.skip_until_found_close (parser
);
13702 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13704 c_parser_error (parser
, "expected integer expression");
13708 /* Attempt to statically determine when the number isn't positive. */
13709 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13710 build_int_cst (TREE_TYPE (t
), 0));
13711 if (CAN_HAVE_LOCATION_P (c
))
13712 SET_EXPR_LOCATION (c
, expr_loc
);
13713 if (c
== boolean_true_node
)
13715 warning_at (expr_loc
, 0, "%<num_tasks%> value must be positive");
13716 t
= integer_one_node
;
13719 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
13721 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
13722 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
13723 OMP_CLAUSE_CHAIN (c
) = list
;
13731 grainsize ( expression ) */
13734 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
13736 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
13737 matching_parens parens
;
13738 if (parens
.require_open (parser
))
13740 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13741 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13742 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13743 tree c
, t
= expr
.value
;
13744 t
= c_fully_fold (t
, false, NULL
);
13746 parens
.skip_until_found_close (parser
);
13748 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13750 c_parser_error (parser
, "expected integer expression");
13754 /* Attempt to statically determine when the number isn't positive. */
13755 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13756 build_int_cst (TREE_TYPE (t
), 0));
13757 if (CAN_HAVE_LOCATION_P (c
))
13758 SET_EXPR_LOCATION (c
, expr_loc
);
13759 if (c
== boolean_true_node
)
13761 warning_at (expr_loc
, 0, "%<grainsize%> value must be positive");
13762 t
= integer_one_node
;
13765 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
13767 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
13768 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
13769 OMP_CLAUSE_CHAIN (c
) = list
;
13777 priority ( expression ) */
13780 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
13782 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
13783 matching_parens parens
;
13784 if (parens
.require_open (parser
))
13786 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13787 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13788 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13789 tree c
, t
= expr
.value
;
13790 t
= c_fully_fold (t
, false, NULL
);
13792 parens
.skip_until_found_close (parser
);
13794 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13796 c_parser_error (parser
, "expected integer expression");
13800 /* Attempt to statically determine when the number isn't
13802 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
13803 build_int_cst (TREE_TYPE (t
), 0));
13804 if (CAN_HAVE_LOCATION_P (c
))
13805 SET_EXPR_LOCATION (c
, expr_loc
);
13806 if (c
== boolean_true_node
)
13808 warning_at (expr_loc
, 0, "%<priority%> value must be non-negative");
13809 t
= integer_one_node
;
13812 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
13814 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
13815 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
13816 OMP_CLAUSE_CHAIN (c
) = list
;
13824 hint ( expression ) */
13827 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
13829 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
13830 matching_parens parens
;
13831 if (parens
.require_open (parser
))
13833 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13834 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13835 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13836 tree c
, t
= expr
.value
;
13837 t
= c_fully_fold (t
, false, NULL
);
13839 parens
.skip_until_found_close (parser
);
13841 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
13842 || TREE_CODE (t
) != INTEGER_CST
)
13844 c_parser_error (parser
, "expected constant integer expression");
13848 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
13850 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
13851 OMP_CLAUSE_HINT_EXPR (c
) = t
;
13852 OMP_CLAUSE_CHAIN (c
) = list
;
13860 defaultmap ( tofrom : scalar )
13863 defaultmap ( implicit-behavior [ : variable-category ] ) */
13866 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
13868 location_t loc
= c_parser_peek_token (parser
)->location
;
13871 enum omp_clause_defaultmap_kind behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
13872 enum omp_clause_defaultmap_kind category
13873 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
13875 matching_parens parens
;
13876 if (!parens
.require_open (parser
))
13878 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
13880 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
13883 c_parser_error (parser
, "expected %<alloc%>, %<to%>, %<from%>, "
13884 "%<tofrom%>, %<firstprivate%>, %<none%> "
13889 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13894 if (strcmp ("alloc", p
) == 0)
13895 behavior
= OMP_CLAUSE_DEFAULTMAP_ALLOC
;
13897 goto invalid_behavior
;
13901 if (strcmp ("default", p
) == 0)
13902 behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
13904 goto invalid_behavior
;
13908 if (strcmp ("firstprivate", p
) == 0)
13909 behavior
= OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
13910 else if (strcmp ("from", p
) == 0)
13911 behavior
= OMP_CLAUSE_DEFAULTMAP_FROM
;
13913 goto invalid_behavior
;
13917 if (strcmp ("none", p
) == 0)
13918 behavior
= OMP_CLAUSE_DEFAULTMAP_NONE
;
13920 goto invalid_behavior
;
13924 if (strcmp ("tofrom", p
) == 0)
13925 behavior
= OMP_CLAUSE_DEFAULTMAP_TOFROM
;
13926 else if (strcmp ("to", p
) == 0)
13927 behavior
= OMP_CLAUSE_DEFAULTMAP_TO
;
13929 goto invalid_behavior
;
13933 goto invalid_behavior
;
13935 c_parser_consume_token (parser
);
13937 if (!c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
13939 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
13941 if (!c_parser_next_token_is (parser
, CPP_NAME
))
13944 c_parser_error (parser
, "expected %<scalar%>, %<aggregate%> or "
13948 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13952 if (strcmp ("aggregate", p
) == 0)
13953 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
;
13955 goto invalid_category
;
13959 if (strcmp ("pointer", p
) == 0)
13960 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
;
13962 goto invalid_category
;
13966 if (strcmp ("scalar", p
) == 0)
13967 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
;
13969 goto invalid_category
;
13973 goto invalid_category
;
13976 c_parser_consume_token (parser
);
13978 parens
.skip_until_found_close (parser
);
13980 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
13981 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEFAULTMAP
13982 && (category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
13983 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
) == category
13984 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
13985 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)))
13987 enum omp_clause_defaultmap_kind cat
= category
;
13988 location_t loc
= OMP_CLAUSE_LOCATION (c
);
13989 if (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
13990 cat
= OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
);
13994 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
13997 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
14000 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
14003 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
14007 gcc_unreachable ();
14010 error_at (loc
, "too many %<defaultmap%> clauses with %qs category",
14013 error_at (loc
, "too many %<defaultmap%> clauses with unspecified "
14018 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
14019 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c
, behavior
, category
);
14020 OMP_CLAUSE_CHAIN (c
) = list
;
14024 parens
.skip_until_found_close (parser
);
14029 use_device ( variable-list )
14032 use_device_ptr ( variable-list ) */
14035 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
14037 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
14042 use_device_addr ( variable-list ) */
14045 c_parser_omp_clause_use_device_addr (c_parser
*parser
, tree list
)
14047 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_ADDR
,
14052 is_device_ptr ( variable-list ) */
14055 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
14057 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
14061 num_gangs ( expression )
14062 num_workers ( expression )
14063 vector_length ( expression ) */
14066 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
14069 location_t loc
= c_parser_peek_token (parser
)->location
;
14071 matching_parens parens
;
14072 if (!parens
.require_open (parser
))
14075 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14076 c_expr expr
= c_parser_expression (parser
);
14077 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14078 tree c
, t
= expr
.value
;
14079 t
= c_fully_fold (t
, false, NULL
);
14081 parens
.skip_until_found_close (parser
);
14083 if (t
== error_mark_node
)
14085 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14087 error_at (expr_loc
, "%qs expression must be integral",
14088 omp_clause_code_name
[code
]);
14092 /* Attempt to statically determine when the number isn't positive. */
14093 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14094 build_int_cst (TREE_TYPE (t
), 0));
14095 protected_set_expr_location (c
, expr_loc
);
14096 if (c
== boolean_true_node
)
14098 warning_at (expr_loc
, 0,
14099 "%qs value must be positive",
14100 omp_clause_code_name
[code
]);
14101 t
= integer_one_node
;
14104 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14106 c
= build_omp_clause (loc
, code
);
14107 OMP_CLAUSE_OPERAND (c
, 0) = t
;
14108 OMP_CLAUSE_CHAIN (c
) = list
;
14114 gang [( gang-arg-list )]
14115 worker [( [num:] int-expr )]
14116 vector [( [length:] int-expr )]
14118 where gang-arg is one of:
14123 and size-expr may be:
14130 c_parser_oacc_shape_clause (c_parser
*parser
, location_t loc
,
14131 omp_clause_code kind
,
14132 const char *str
, tree list
)
14134 const char *id
= "num";
14135 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
14137 if (kind
== OMP_CLAUSE_VECTOR
)
14140 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14142 c_parser_consume_token (parser
);
14146 c_token
*next
= c_parser_peek_token (parser
);
14149 /* Gang static argument. */
14150 if (kind
== OMP_CLAUSE_GANG
14151 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
14153 c_parser_consume_token (parser
);
14155 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14156 goto cleanup_error
;
14159 if (ops
[idx
] != NULL_TREE
)
14161 c_parser_error (parser
, "too many %<static%> arguments");
14162 goto cleanup_error
;
14165 /* Check for the '*' argument. */
14166 if (c_parser_next_token_is (parser
, CPP_MULT
)
14167 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14168 || c_parser_peek_2nd_token (parser
)->type
14169 == CPP_CLOSE_PAREN
))
14171 c_parser_consume_token (parser
);
14172 ops
[idx
] = integer_minus_one_node
;
14174 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14176 c_parser_consume_token (parser
);
14183 /* Worker num: argument and vector length: arguments. */
14184 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14185 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
14186 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14188 c_parser_consume_token (parser
); /* id */
14189 c_parser_consume_token (parser
); /* ':' */
14192 /* Now collect the actual argument. */
14193 if (ops
[idx
] != NULL_TREE
)
14195 c_parser_error (parser
, "unexpected argument");
14196 goto cleanup_error
;
14199 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14200 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14201 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14202 tree expr
= cexpr
.value
;
14203 if (expr
== error_mark_node
)
14204 goto cleanup_error
;
14206 expr
= c_fully_fold (expr
, false, NULL
);
14208 /* Attempt to statically determine when the number isn't a
14209 positive integer. */
14211 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
14213 c_parser_error (parser
, "expected integer expression");
14217 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
14218 build_int_cst (TREE_TYPE (expr
), 0));
14219 if (c
== boolean_true_node
)
14221 warning_at (loc
, 0,
14222 "%qs value must be positive", str
);
14223 expr
= integer_one_node
;
14228 if (kind
== OMP_CLAUSE_GANG
14229 && c_parser_next_token_is (parser
, CPP_COMMA
))
14231 c_parser_consume_token (parser
);
14238 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14239 goto cleanup_error
;
14242 check_no_duplicate_clause (list
, kind
, str
);
14244 c
= build_omp_clause (loc
, kind
);
14247 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
14249 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
14250 OMP_CLAUSE_CHAIN (c
) = list
;
14255 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14267 c_parser_oacc_simple_clause (location_t loc
, enum omp_clause_code code
,
14270 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14272 tree c
= build_omp_clause (loc
, code
);
14273 OMP_CLAUSE_CHAIN (c
) = list
;
14279 async [( int-expr )] */
14282 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
14285 location_t loc
= c_parser_peek_token (parser
)->location
;
14287 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14289 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14291 c_parser_consume_token (parser
);
14293 t
= c_parser_expression (parser
).value
;
14294 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14295 c_parser_error (parser
, "expected integer expression");
14296 else if (t
== error_mark_node
14297 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14301 t
= c_fully_fold (t
, false, NULL
);
14303 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
14305 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
14306 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
14307 OMP_CLAUSE_CHAIN (c
) = list
;
14314 tile ( size-expr-list ) */
14317 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
14319 tree c
, expr
= error_mark_node
;
14321 tree tile
= NULL_TREE
;
14323 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
14324 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
14326 loc
= c_parser_peek_token (parser
)->location
;
14327 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
14332 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
14335 if (c_parser_next_token_is (parser
, CPP_MULT
)
14336 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14337 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
14339 c_parser_consume_token (parser
);
14340 expr
= integer_zero_node
;
14344 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14345 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14346 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14347 expr
= cexpr
.value
;
14349 if (expr
== error_mark_node
)
14351 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
14356 expr
= c_fully_fold (expr
, false, NULL
);
14358 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
14359 || !tree_fits_shwi_p (expr
)
14360 || tree_to_shwi (expr
) <= 0)
14362 error_at (expr_loc
, "%<tile%> argument needs positive"
14363 " integral constant");
14364 expr
= integer_zero_node
;
14368 tile
= tree_cons (NULL_TREE
, expr
, tile
);
14370 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
14372 /* Consume the trailing ')'. */
14373 c_parser_consume_token (parser
);
14375 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
14376 tile
= nreverse (tile
);
14377 OMP_CLAUSE_TILE_LIST (c
) = tile
;
14378 OMP_CLAUSE_CHAIN (c
) = list
;
14383 wait [( int-expr-list )] */
14386 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
14388 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14390 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14391 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
14394 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
14396 OMP_CLAUSE_DECL (c
) = build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14397 OMP_CLAUSE_CHAIN (c
) = list
;
14406 order ( concurrent ) */
14409 c_parser_omp_clause_order (c_parser
*parser
, tree list
)
14411 location_t loc
= c_parser_peek_token (parser
)->location
;
14415 matching_parens parens
;
14416 if (!parens
.require_open (parser
))
14418 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14420 c_parser_error (parser
, "expected %<concurrent%>");
14423 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14424 if (strcmp (p
, "concurrent") != 0)
14426 c_parser_error (parser
, "expected %<concurrent%>");
14429 c_parser_consume_token (parser
);
14430 parens
.skip_until_found_close (parser
);
14431 /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */
14432 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDER
);
14433 OMP_CLAUSE_CHAIN (c
) = list
;
14437 parens
.skip_until_found_close (parser
);
14443 bind ( teams | parallel | thread ) */
14446 c_parser_omp_clause_bind (c_parser
*parser
, tree list
)
14448 location_t loc
= c_parser_peek_token (parser
)->location
;
14451 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
14453 matching_parens parens
;
14454 if (!parens
.require_open (parser
))
14456 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14459 c_parser_error (parser
,
14460 "expected %<teams%>, %<parallel%> or %<thread%>");
14461 parens
.skip_until_found_close (parser
);
14464 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14465 if (strcmp (p
, "teams") == 0)
14466 kind
= OMP_CLAUSE_BIND_TEAMS
;
14467 else if (strcmp (p
, "parallel") == 0)
14468 kind
= OMP_CLAUSE_BIND_PARALLEL
;
14469 else if (strcmp (p
, "thread") != 0)
14471 c_parser_consume_token (parser
);
14472 parens
.skip_until_found_close (parser
);
14473 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14474 c
= build_omp_clause (loc
, OMP_CLAUSE_BIND
);
14475 OMP_CLAUSE_BIND_KIND (c
) = kind
;
14476 OMP_CLAUSE_CHAIN (c
) = list
;
14485 ordered ( constant-expression ) */
14488 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
14490 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
14492 tree c
, num
= NULL_TREE
;
14494 location_t loc
= c_parser_peek_token (parser
)->location
;
14495 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14497 matching_parens parens
;
14498 parens
.consume_open (parser
);
14499 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
14500 parens
.skip_until_found_close (parser
);
14502 if (num
== error_mark_node
)
14506 mark_exp_read (num
);
14507 num
= c_fully_fold (num
, false, NULL
);
14508 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
14509 || !tree_fits_shwi_p (num
)
14510 || (n
= tree_to_shwi (num
)) <= 0
14513 error_at (loc
, "ordered argument needs positive "
14514 "constant integer expression");
14518 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
14519 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
14520 OMP_CLAUSE_CHAIN (c
) = list
;
14525 private ( variable-list ) */
14528 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
14530 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
14534 reduction ( reduction-operator : variable-list )
14536 reduction-operator:
14537 One of: + * - & ^ | && ||
14541 reduction-operator:
14542 One of: + * - & ^ | && || max min
14546 reduction-operator:
14547 One of: + * - & ^ | && ||
14551 reduction ( reduction-modifier, reduction-operator : variable-list )
14552 in_reduction ( reduction-operator : variable-list )
14553 task_reduction ( reduction-operator : variable-list ) */
14556 c_parser_omp_clause_reduction (c_parser
*parser
, enum omp_clause_code kind
,
14557 bool is_omp
, tree list
)
14559 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14560 matching_parens parens
;
14561 if (parens
.require_open (parser
))
14564 bool inscan
= false;
14565 enum tree_code code
= ERROR_MARK
;
14566 tree reduc_id
= NULL_TREE
;
14568 if (kind
== OMP_CLAUSE_REDUCTION
&& is_omp
)
14570 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
14571 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
14573 c_parser_consume_token (parser
);
14574 c_parser_consume_token (parser
);
14576 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14577 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
14580 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14581 if (strcmp (p
, "task") == 0)
14583 else if (strcmp (p
, "inscan") == 0)
14585 if (task
|| inscan
)
14587 c_parser_consume_token (parser
);
14588 c_parser_consume_token (parser
);
14593 switch (c_parser_peek_token (parser
)->type
)
14605 code
= BIT_AND_EXPR
;
14608 code
= BIT_XOR_EXPR
;
14611 code
= BIT_IOR_EXPR
;
14614 code
= TRUTH_ANDIF_EXPR
;
14617 code
= TRUTH_ORIF_EXPR
;
14622 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14623 if (strcmp (p
, "min") == 0)
14628 if (strcmp (p
, "max") == 0)
14633 reduc_id
= c_parser_peek_token (parser
)->value
;
14637 c_parser_error (parser
,
14638 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
14639 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
14640 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14643 c_parser_consume_token (parser
);
14644 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
14645 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14649 nl
= c_parser_omp_variable_list (parser
, clause_loc
, kind
, list
);
14650 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
14652 tree d
= OMP_CLAUSE_DECL (c
), type
;
14653 if (TREE_CODE (d
) != TREE_LIST
)
14654 type
= TREE_TYPE (d
);
14659 for (t
= d
; TREE_CODE (t
) == TREE_LIST
; t
= TREE_CHAIN (t
))
14661 type
= TREE_TYPE (t
);
14664 if (TREE_CODE (type
) != POINTER_TYPE
14665 && TREE_CODE (type
) != ARRAY_TYPE
)
14667 type
= TREE_TYPE (type
);
14671 while (TREE_CODE (type
) == ARRAY_TYPE
)
14672 type
= TREE_TYPE (type
);
14673 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
14675 OMP_CLAUSE_REDUCTION_TASK (c
) = 1;
14677 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 1;
14678 if (code
== ERROR_MARK
14679 || !(INTEGRAL_TYPE_P (type
)
14680 || TREE_CODE (type
) == REAL_TYPE
14681 || TREE_CODE (type
) == COMPLEX_TYPE
))
14682 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
14683 = c_omp_reduction_lookup (reduc_id
,
14684 TYPE_MAIN_VARIANT (type
));
14689 parens
.skip_until_found_close (parser
);
14695 schedule ( schedule-kind )
14696 schedule ( schedule-kind , expression )
14699 static | dynamic | guided | runtime | auto
14702 schedule ( schedule-modifier : schedule-kind )
14703 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
14711 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
14714 location_t loc
= c_parser_peek_token (parser
)->location
;
14715 int modifiers
= 0, nmodifiers
= 0;
14717 matching_parens parens
;
14718 if (!parens
.require_open (parser
))
14721 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
14723 while (c_parser_next_token_is (parser
, CPP_NAME
))
14725 tree kind
= c_parser_peek_token (parser
)->value
;
14726 const char *p
= IDENTIFIER_POINTER (kind
);
14727 if (strcmp ("simd", p
) == 0)
14728 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
14729 else if (strcmp ("monotonic", p
) == 0)
14730 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
14731 else if (strcmp ("nonmonotonic", p
) == 0)
14732 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
14735 c_parser_consume_token (parser
);
14736 if (nmodifiers
++ == 0
14737 && c_parser_next_token_is (parser
, CPP_COMMA
))
14738 c_parser_consume_token (parser
);
14741 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
14746 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
14747 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
14748 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
14749 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
14751 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
14756 if (c_parser_next_token_is (parser
, CPP_NAME
))
14758 tree kind
= c_parser_peek_token (parser
)->value
;
14759 const char *p
= IDENTIFIER_POINTER (kind
);
14764 if (strcmp ("dynamic", p
) != 0)
14766 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
14770 if (strcmp ("guided", p
) != 0)
14772 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
14776 if (strcmp ("runtime", p
) != 0)
14778 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
14785 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
14786 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
14787 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
14788 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
14792 c_parser_consume_token (parser
);
14793 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14796 c_parser_consume_token (parser
);
14798 here
= c_parser_peek_token (parser
)->location
;
14799 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14800 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
14802 t
= c_fully_fold (t
, false, NULL
);
14804 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
14805 error_at (here
, "schedule %<runtime%> does not take "
14806 "a %<chunk_size%> parameter");
14807 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
14809 "schedule %<auto%> does not take "
14810 "a %<chunk_size%> parameter");
14811 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
)
14813 /* Attempt to statically determine when the number isn't
14815 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
14816 build_int_cst (TREE_TYPE (t
), 0));
14817 protected_set_expr_location (s
, loc
);
14818 if (s
== boolean_true_node
)
14820 warning_at (loc
, 0,
14821 "chunk size value must be positive");
14822 t
= integer_one_node
;
14824 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
14827 c_parser_error (parser
, "expected integer expression");
14829 parens
.skip_until_found_close (parser
);
14832 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
14833 "expected %<,%> or %<)%>");
14835 OMP_CLAUSE_SCHEDULE_KIND (c
)
14836 = (enum omp_clause_schedule_kind
)
14837 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
14839 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
14840 OMP_CLAUSE_CHAIN (c
) = list
;
14844 c_parser_error (parser
, "invalid schedule kind");
14845 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14850 shared ( variable-list ) */
14853 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
14855 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
14862 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
14866 /* FIXME: Should we allow duplicates? */
14867 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
14869 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
14870 OMP_CLAUSE_UNTIED
);
14871 OMP_CLAUSE_CHAIN (c
) = list
;
14881 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
14882 enum omp_clause_code code
, tree list
)
14884 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14886 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
14887 OMP_CLAUSE_CHAIN (c
) = list
;
14899 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
14900 enum omp_clause_code code
, tree list
)
14902 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
14903 OMP_CLAUSE_CHAIN (c
) = list
;
14912 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
14914 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
14915 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
14916 OMP_CLAUSE_NOGROUP
);
14917 OMP_CLAUSE_CHAIN (c
) = list
;
14926 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
14927 enum omp_clause_code code
, tree list
)
14929 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14930 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
14931 OMP_CLAUSE_CHAIN (c
) = list
;
14936 num_teams ( expression ) */
14939 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
14941 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
14942 matching_parens parens
;
14943 if (parens
.require_open (parser
))
14945 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14946 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14947 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14948 tree c
, t
= expr
.value
;
14949 t
= c_fully_fold (t
, false, NULL
);
14951 parens
.skip_until_found_close (parser
);
14953 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14955 c_parser_error (parser
, "expected integer expression");
14959 /* Attempt to statically determine when the number isn't positive. */
14960 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14961 build_int_cst (TREE_TYPE (t
), 0));
14962 protected_set_expr_location (c
, expr_loc
);
14963 if (c
== boolean_true_node
)
14965 warning_at (expr_loc
, 0, "%<num_teams%> value must be positive");
14966 t
= integer_one_node
;
14969 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
14971 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
14972 OMP_CLAUSE_NUM_TEAMS_EXPR (c
) = t
;
14973 OMP_CLAUSE_CHAIN (c
) = list
;
14981 thread_limit ( expression ) */
14984 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
14986 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
14987 matching_parens parens
;
14988 if (parens
.require_open (parser
))
14990 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14991 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14992 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14993 tree c
, t
= expr
.value
;
14994 t
= c_fully_fold (t
, false, NULL
);
14996 parens
.skip_until_found_close (parser
);
14998 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15000 c_parser_error (parser
, "expected integer expression");
15004 /* Attempt to statically determine when the number isn't positive. */
15005 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
15006 build_int_cst (TREE_TYPE (t
), 0));
15007 protected_set_expr_location (c
, expr_loc
);
15008 if (c
== boolean_true_node
)
15010 warning_at (expr_loc
, 0, "%<thread_limit%> value must be positive");
15011 t
= integer_one_node
;
15014 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
15017 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
15018 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
15019 OMP_CLAUSE_CHAIN (c
) = list
;
15027 aligned ( variable-list )
15028 aligned ( variable-list : constant-expression ) */
15031 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
15033 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15036 matching_parens parens
;
15037 if (!parens
.require_open (parser
))
15040 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15041 OMP_CLAUSE_ALIGNED
, list
);
15043 if (c_parser_next_token_is (parser
, CPP_COLON
))
15045 c_parser_consume_token (parser
);
15046 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15047 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15048 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15049 tree alignment
= expr
.value
;
15050 alignment
= c_fully_fold (alignment
, false, NULL
);
15051 if (TREE_CODE (alignment
) != INTEGER_CST
15052 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
15053 || tree_int_cst_sgn (alignment
) != 1)
15055 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
15056 "be positive constant integer expression");
15057 alignment
= NULL_TREE
;
15060 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15061 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
15064 parens
.skip_until_found_close (parser
);
15069 linear ( variable-list )
15070 linear ( variable-list : expression )
15073 linear ( modifier ( variable-list ) )
15074 linear ( modifier ( variable-list ) : expression ) */
15077 c_parser_omp_clause_linear (c_parser
*parser
, tree list
)
15079 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15081 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15083 matching_parens parens
;
15084 if (!parens
.require_open (parser
))
15087 if (c_parser_next_token_is (parser
, CPP_NAME
))
15089 c_token
*tok
= c_parser_peek_token (parser
);
15090 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15091 if (strcmp ("val", p
) == 0)
15092 kind
= OMP_CLAUSE_LINEAR_VAL
;
15093 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
15094 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15095 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15097 c_parser_consume_token (parser
);
15098 c_parser_consume_token (parser
);
15102 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15103 OMP_CLAUSE_LINEAR
, list
);
15105 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15106 parens
.skip_until_found_close (parser
);
15108 if (c_parser_next_token_is (parser
, CPP_COLON
))
15110 c_parser_consume_token (parser
);
15111 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15112 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15113 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15115 step
= c_fully_fold (step
, false, NULL
);
15116 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
15118 error_at (clause_loc
, "%<linear%> clause step expression must "
15120 step
= integer_one_node
;
15125 step
= integer_one_node
;
15127 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15129 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
15130 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
15133 parens
.skip_until_found_close (parser
);
15138 nontemporal ( variable-list ) */
15141 c_parser_omp_clause_nontemporal (c_parser
*parser
, tree list
)
15143 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_NONTEMPORAL
, list
);
15147 safelen ( constant-expression ) */
15150 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
15152 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15155 matching_parens parens
;
15156 if (!parens
.require_open (parser
))
15159 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15160 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15161 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15163 t
= c_fully_fold (t
, false, NULL
);
15164 if (TREE_CODE (t
) != INTEGER_CST
15165 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
15166 || tree_int_cst_sgn (t
) != 1)
15168 error_at (clause_loc
, "%<safelen%> clause expression must "
15169 "be positive constant integer expression");
15173 parens
.skip_until_found_close (parser
);
15174 if (t
== NULL_TREE
|| t
== error_mark_node
)
15177 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
15179 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
15180 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
15181 OMP_CLAUSE_CHAIN (c
) = list
;
15186 simdlen ( constant-expression ) */
15189 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
15191 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15194 matching_parens parens
;
15195 if (!parens
.require_open (parser
))
15198 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15199 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15200 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15202 t
= c_fully_fold (t
, false, NULL
);
15203 if (TREE_CODE (t
) != INTEGER_CST
15204 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
15205 || tree_int_cst_sgn (t
) != 1)
15207 error_at (clause_loc
, "%<simdlen%> clause expression must "
15208 "be positive constant integer expression");
15212 parens
.skip_until_found_close (parser
);
15213 if (t
== NULL_TREE
|| t
== error_mark_node
)
15216 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
15218 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
15219 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
15220 OMP_CLAUSE_CHAIN (c
) = list
;
15226 identifier [+/- integer]
15227 vec , identifier [+/- integer]
15231 c_parser_omp_clause_depend_sink (c_parser
*parser
, location_t clause_loc
,
15235 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
15236 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
15238 c_parser_error (parser
, "expected identifier");
15242 while (c_parser_next_token_is (parser
, CPP_NAME
)
15243 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
15245 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
15246 tree addend
= NULL
;
15248 if (t
== NULL_TREE
)
15250 undeclared_variable (c_parser_peek_token (parser
)->location
,
15251 c_parser_peek_token (parser
)->value
);
15252 t
= error_mark_node
;
15255 c_parser_consume_token (parser
);
15258 if (c_parser_next_token_is (parser
, CPP_MINUS
))
15260 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
15262 addend
= integer_zero_node
;
15264 goto add_to_vector
;
15266 c_parser_consume_token (parser
);
15268 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
15270 c_parser_error (parser
, "expected integer");
15274 addend
= c_parser_peek_token (parser
)->value
;
15275 if (TREE_CODE (addend
) != INTEGER_CST
)
15277 c_parser_error (parser
, "expected integer");
15280 c_parser_consume_token (parser
);
15283 if (t
!= error_mark_node
)
15285 vec
= tree_cons (addend
, t
, vec
);
15287 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec
) = 1;
15290 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
15293 c_parser_consume_token (parser
);
15296 if (vec
== NULL_TREE
)
15299 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
15300 OMP_CLAUSE_DEPEND_KIND (u
) = OMP_CLAUSE_DEPEND_SINK
;
15301 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
15302 OMP_CLAUSE_CHAIN (u
) = list
;
15307 iterators ( iterators-definition )
15309 iterators-definition:
15311 iterator-specifier , iterators-definition
15313 iterator-specifier:
15314 identifier = range-specification
15315 iterator-type identifier = range-specification
15317 range-specification:
15319 begin : end : step */
15322 c_parser_omp_iterators (c_parser
*parser
)
15324 tree ret
= NULL_TREE
, *last
= &ret
;
15325 c_parser_consume_token (parser
);
15329 matching_parens parens
;
15330 if (!parens
.require_open (parser
))
15331 return error_mark_node
;
15335 tree iter_type
= NULL_TREE
, type_expr
= NULL_TREE
;
15336 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
15338 struct c_type_name
*type
= c_parser_type_name (parser
);
15340 iter_type
= groktypename (type
, &type_expr
, NULL
);
15342 if (iter_type
== NULL_TREE
)
15343 iter_type
= integer_type_node
;
15345 location_t loc
= c_parser_peek_token (parser
)->location
;
15346 if (!c_parser_next_token_is (parser
, CPP_NAME
))
15348 c_parser_error (parser
, "expected identifier");
15352 tree id
= c_parser_peek_token (parser
)->value
;
15353 c_parser_consume_token (parser
);
15355 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
15358 location_t eloc
= c_parser_peek_token (parser
)->location
;
15359 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15360 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15361 tree begin
= expr
.value
;
15363 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15366 eloc
= c_parser_peek_token (parser
)->location
;
15367 expr
= c_parser_expr_no_commas (parser
, NULL
);
15368 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15369 tree end
= expr
.value
;
15371 tree step
= integer_one_node
;
15372 if (c_parser_next_token_is (parser
, CPP_COLON
))
15374 c_parser_consume_token (parser
);
15375 eloc
= c_parser_peek_token (parser
)->location
;
15376 expr
= c_parser_expr_no_commas (parser
, NULL
);
15377 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15381 tree iter_var
= build_decl (loc
, VAR_DECL
, id
, iter_type
);
15382 DECL_ARTIFICIAL (iter_var
) = 1;
15383 DECL_CONTEXT (iter_var
) = current_function_decl
;
15384 pushdecl (iter_var
);
15386 *last
= make_tree_vec (6);
15387 TREE_VEC_ELT (*last
, 0) = iter_var
;
15388 TREE_VEC_ELT (*last
, 1) = begin
;
15389 TREE_VEC_ELT (*last
, 2) = end
;
15390 TREE_VEC_ELT (*last
, 3) = step
;
15391 last
= &TREE_CHAIN (*last
);
15393 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15395 c_parser_consume_token (parser
);
15402 parens
.skip_until_found_close (parser
);
15403 return ret
? ret
: error_mark_node
;
15407 depend ( depend-kind: variable-list )
15415 depend ( sink : vec )
15418 depend ( depend-modifier , depend-kind: variable-list )
15421 in | out | inout | mutexinoutset | depobj
15424 iterator ( iterators-definition ) */
15427 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
15429 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15430 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_LAST
;
15431 tree nl
, c
, iterators
= NULL_TREE
;
15433 matching_parens parens
;
15434 if (!parens
.require_open (parser
))
15439 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
15442 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15443 if (strcmp ("iterator", p
) == 0 && iterators
== NULL_TREE
)
15445 iterators
= c_parser_omp_iterators (parser
);
15446 c_parser_require (parser
, CPP_COMMA
, "expected %<,%>");
15449 if (strcmp ("in", p
) == 0)
15450 kind
= OMP_CLAUSE_DEPEND_IN
;
15451 else if (strcmp ("inout", p
) == 0)
15452 kind
= OMP_CLAUSE_DEPEND_INOUT
;
15453 else if (strcmp ("mutexinoutset", p
) == 0)
15454 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
15455 else if (strcmp ("out", p
) == 0)
15456 kind
= OMP_CLAUSE_DEPEND_OUT
;
15457 else if (strcmp ("depobj", p
) == 0)
15458 kind
= OMP_CLAUSE_DEPEND_DEPOBJ
;
15459 else if (strcmp ("sink", p
) == 0)
15460 kind
= OMP_CLAUSE_DEPEND_SINK
;
15461 else if (strcmp ("source", p
) == 0)
15462 kind
= OMP_CLAUSE_DEPEND_SOURCE
;
15469 c_parser_consume_token (parser
);
15472 && (kind
== OMP_CLAUSE_DEPEND_SOURCE
|| kind
== OMP_CLAUSE_DEPEND_SINK
))
15475 error_at (clause_loc
, "%<iterator%> modifier incompatible with %qs",
15476 kind
== OMP_CLAUSE_DEPEND_SOURCE
? "source" : "sink");
15477 iterators
= NULL_TREE
;
15480 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
15482 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
15483 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
15484 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
15485 OMP_CLAUSE_CHAIN (c
) = list
;
15486 parens
.skip_until_found_close (parser
);
15490 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15493 if (kind
== OMP_CLAUSE_DEPEND_SINK
)
15494 nl
= c_parser_omp_clause_depend_sink (parser
, clause_loc
, list
);
15497 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15498 OMP_CLAUSE_DEPEND
, list
);
15502 tree block
= pop_scope ();
15503 if (iterators
== error_mark_node
)
15504 iterators
= NULL_TREE
;
15506 TREE_VEC_ELT (iterators
, 5) = block
;
15509 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15511 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
15513 OMP_CLAUSE_DECL (c
)
15514 = build_tree_list (iterators
, OMP_CLAUSE_DECL (c
));
15518 parens
.skip_until_found_close (parser
);
15522 c_parser_error (parser
, "invalid depend kind");
15524 parens
.skip_until_found_close (parser
);
15531 map ( map-kind: variable-list )
15532 map ( variable-list )
15535 alloc | to | from | tofrom
15539 alloc | to | from | tofrom | release | delete
15541 map ( always [,] map-kind: variable-list ) */
15544 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
15546 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15547 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
15549 enum c_id_kind always_id_kind
= C_ID_NONE
;
15550 location_t always_loc
= UNKNOWN_LOCATION
;
15551 tree always_id
= NULL_TREE
;
15554 matching_parens parens
;
15555 if (!parens
.require_open (parser
))
15558 if (c_parser_next_token_is (parser
, CPP_NAME
))
15560 c_token
*tok
= c_parser_peek_token (parser
);
15561 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15562 always_id_kind
= tok
->id_kind
;
15563 always_loc
= tok
->location
;
15564 always_id
= tok
->value
;
15565 if (strcmp ("always", p
) == 0)
15567 c_token
*sectok
= c_parser_peek_2nd_token (parser
);
15568 if (sectok
->type
== CPP_COMMA
)
15570 c_parser_consume_token (parser
);
15571 c_parser_consume_token (parser
);
15574 else if (sectok
->type
== CPP_NAME
)
15576 p
= IDENTIFIER_POINTER (sectok
->value
);
15577 if (strcmp ("alloc", p
) == 0
15578 || strcmp ("to", p
) == 0
15579 || strcmp ("from", p
) == 0
15580 || strcmp ("tofrom", p
) == 0
15581 || strcmp ("release", p
) == 0
15582 || strcmp ("delete", p
) == 0)
15584 c_parser_consume_token (parser
);
15591 if (c_parser_next_token_is (parser
, CPP_NAME
)
15592 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
15594 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15595 if (strcmp ("alloc", p
) == 0)
15596 kind
= GOMP_MAP_ALLOC
;
15597 else if (strcmp ("to", p
) == 0)
15598 kind
= always
? GOMP_MAP_ALWAYS_TO
: GOMP_MAP_TO
;
15599 else if (strcmp ("from", p
) == 0)
15600 kind
= always
? GOMP_MAP_ALWAYS_FROM
: GOMP_MAP_FROM
;
15601 else if (strcmp ("tofrom", p
) == 0)
15602 kind
= always
? GOMP_MAP_ALWAYS_TOFROM
: GOMP_MAP_TOFROM
;
15603 else if (strcmp ("release", p
) == 0)
15604 kind
= GOMP_MAP_RELEASE
;
15605 else if (strcmp ("delete", p
) == 0)
15606 kind
= GOMP_MAP_DELETE
;
15609 c_parser_error (parser
, "invalid map kind");
15610 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15614 c_parser_consume_token (parser
);
15615 c_parser_consume_token (parser
);
15619 if (always_id_kind
!= C_ID_ID
)
15621 c_parser_error (parser
, "expected identifier");
15622 parens
.skip_until_found_close (parser
);
15626 tree t
= lookup_name (always_id
);
15627 if (t
== NULL_TREE
)
15629 undeclared_variable (always_loc
, always_id
);
15630 t
= error_mark_node
;
15632 if (t
!= error_mark_node
)
15634 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_MAP
);
15635 OMP_CLAUSE_DECL (u
) = t
;
15636 OMP_CLAUSE_CHAIN (u
) = list
;
15637 OMP_CLAUSE_SET_MAP_KIND (u
, kind
);
15642 parens
.skip_until_found_close (parser
);
15647 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
);
15649 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15650 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
15652 parens
.skip_until_found_close (parser
);
15657 device ( expression ) */
15660 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
15662 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15663 matching_parens parens
;
15664 if (parens
.require_open (parser
))
15666 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15667 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15668 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15669 tree c
, t
= expr
.value
;
15670 t
= c_fully_fold (t
, false, NULL
);
15672 parens
.skip_until_found_close (parser
);
15674 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15676 c_parser_error (parser
, "expected integer expression");
15680 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
15682 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
15683 OMP_CLAUSE_DEVICE_ID (c
) = t
;
15684 OMP_CLAUSE_CHAIN (c
) = list
;
15692 dist_schedule ( static )
15693 dist_schedule ( static , expression ) */
15696 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
15698 tree c
, t
= NULL_TREE
;
15699 location_t loc
= c_parser_peek_token (parser
)->location
;
15701 matching_parens parens
;
15702 if (!parens
.require_open (parser
))
15705 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
15707 c_parser_error (parser
, "invalid dist_schedule kind");
15708 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15713 c_parser_consume_token (parser
);
15714 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15716 c_parser_consume_token (parser
);
15718 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15719 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15720 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15722 t
= c_fully_fold (t
, false, NULL
);
15723 parens
.skip_until_found_close (parser
);
15726 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15727 "expected %<,%> or %<)%>");
15729 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
15730 "dist_schedule"); */
15731 if (omp_find_clause (list
, OMP_CLAUSE_DIST_SCHEDULE
))
15732 warning_at (loc
, 0, "too many %qs clauses", "dist_schedule");
15733 if (t
== error_mark_node
)
15736 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
15737 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
15738 OMP_CLAUSE_CHAIN (c
) = list
;
15743 proc_bind ( proc-bind-kind )
15746 master | close | spread */
15749 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
15751 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15752 enum omp_clause_proc_bind_kind kind
;
15755 matching_parens parens
;
15756 if (!parens
.require_open (parser
))
15759 if (c_parser_next_token_is (parser
, CPP_NAME
))
15761 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15762 if (strcmp ("master", p
) == 0)
15763 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
15764 else if (strcmp ("close", p
) == 0)
15765 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
15766 else if (strcmp ("spread", p
) == 0)
15767 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
15774 check_no_duplicate_clause (list
, OMP_CLAUSE_PROC_BIND
, "proc_bind");
15775 c_parser_consume_token (parser
);
15776 parens
.skip_until_found_close (parser
);
15777 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
15778 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
15779 OMP_CLAUSE_CHAIN (c
) = list
;
15783 c_parser_error (parser
, "invalid proc_bind kind");
15784 parens
.skip_until_found_close (parser
);
15789 device_type ( host | nohost | any ) */
15792 c_parser_omp_clause_device_type (c_parser
*parser
, tree list
)
15794 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15795 enum omp_clause_device_type_kind kind
;
15798 matching_parens parens
;
15799 if (!parens
.require_open (parser
))
15802 if (c_parser_next_token_is (parser
, CPP_NAME
))
15804 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15805 if (strcmp ("host", p
) == 0)
15806 kind
= OMP_CLAUSE_DEVICE_TYPE_HOST
;
15807 else if (strcmp ("nohost", p
) == 0)
15808 kind
= OMP_CLAUSE_DEVICE_TYPE_NOHOST
;
15809 else if (strcmp ("any", p
) == 0)
15810 kind
= OMP_CLAUSE_DEVICE_TYPE_ANY
;
15817 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
15819 c_parser_consume_token (parser
);
15820 parens
.skip_until_found_close (parser
);
15821 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE_TYPE
);
15822 OMP_CLAUSE_DEVICE_TYPE_KIND (c
) = kind
;
15823 OMP_CLAUSE_CHAIN (c
) = list
;
15827 c_parser_error (parser
, "expected %<host%>, %<nohost%> or %<any%>");
15828 parens
.skip_until_found_close (parser
);
15833 to ( variable-list ) */
15836 c_parser_omp_clause_to (c_parser
*parser
, tree list
)
15838 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO
, list
);
15842 from ( variable-list ) */
15845 c_parser_omp_clause_from (c_parser
*parser
, tree list
)
15847 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FROM
, list
);
15851 uniform ( variable-list ) */
15854 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
15856 /* The clauses location. */
15857 location_t loc
= c_parser_peek_token (parser
)->location
;
15859 matching_parens parens
;
15860 if (parens
.require_open (parser
))
15862 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
15864 parens
.skip_until_found_close (parser
);
15869 /* Parse all OpenACC clauses. The set clauses allowed by the directive
15870 is a bitmask in MASK. Return the list of clauses found. */
15873 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
15874 const char *where
, bool finish_p
= true)
15876 tree clauses
= NULL
;
15879 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
15882 pragma_omp_clause c_kind
;
15883 const char *c_name
;
15884 tree prev
= clauses
;
15886 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
15887 c_parser_consume_token (parser
);
15889 here
= c_parser_peek_token (parser
)->location
;
15890 c_kind
= c_parser_omp_clause_name (parser
);
15894 case PRAGMA_OACC_CLAUSE_ASYNC
:
15895 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
15898 case PRAGMA_OACC_CLAUSE_AUTO
:
15899 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_AUTO
,
15903 case PRAGMA_OACC_CLAUSE_ATTACH
:
15904 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15907 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
15908 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
15909 c_name
= "collapse";
15911 case PRAGMA_OACC_CLAUSE_COPY
:
15912 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15915 case PRAGMA_OACC_CLAUSE_COPYIN
:
15916 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15919 case PRAGMA_OACC_CLAUSE_COPYOUT
:
15920 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15921 c_name
= "copyout";
15923 case PRAGMA_OACC_CLAUSE_CREATE
:
15924 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15927 case PRAGMA_OACC_CLAUSE_DELETE
:
15928 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15931 case PRAGMA_OMP_CLAUSE_DEFAULT
:
15932 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
15933 c_name
= "default";
15935 case PRAGMA_OACC_CLAUSE_DETACH
:
15936 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15939 case PRAGMA_OACC_CLAUSE_DEVICE
:
15940 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15943 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
15944 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
15945 c_name
= "deviceptr";
15947 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
15948 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15949 c_name
= "device_resident";
15951 case PRAGMA_OACC_CLAUSE_FINALIZE
:
15952 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_FINALIZE
,
15954 c_name
= "finalize";
15956 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
15957 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
15958 c_name
= "firstprivate";
15960 case PRAGMA_OACC_CLAUSE_GANG
:
15962 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_GANG
,
15965 case PRAGMA_OACC_CLAUSE_HOST
:
15966 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15969 case PRAGMA_OACC_CLAUSE_IF
:
15970 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
15973 case PRAGMA_OACC_CLAUSE_IF_PRESENT
:
15974 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_IF_PRESENT
,
15976 c_name
= "if_present";
15978 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
15979 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_INDEPENDENT
,
15981 c_name
= "independent";
15983 case PRAGMA_OACC_CLAUSE_LINK
:
15984 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15987 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
15988 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15989 c_name
= "no_create";
15991 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
15992 clauses
= c_parser_oacc_single_int_clause (parser
,
15993 OMP_CLAUSE_NUM_GANGS
,
15995 c_name
= "num_gangs";
15997 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
15998 clauses
= c_parser_oacc_single_int_clause (parser
,
15999 OMP_CLAUSE_NUM_WORKERS
,
16001 c_name
= "num_workers";
16003 case PRAGMA_OACC_CLAUSE_PRESENT
:
16004 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16005 c_name
= "present";
16007 case PRAGMA_OACC_CLAUSE_PRIVATE
:
16008 clauses
= c_parser_omp_clause_private (parser
, clauses
);
16009 c_name
= "private";
16011 case PRAGMA_OACC_CLAUSE_REDUCTION
:
16013 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
16015 c_name
= "reduction";
16017 case PRAGMA_OACC_CLAUSE_SEQ
:
16018 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_SEQ
,
16022 case PRAGMA_OACC_CLAUSE_TILE
:
16023 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
16026 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
16027 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
16028 c_name
= "use_device";
16030 case PRAGMA_OACC_CLAUSE_VECTOR
:
16032 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_VECTOR
,
16035 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
16036 clauses
= c_parser_oacc_single_int_clause (parser
,
16037 OMP_CLAUSE_VECTOR_LENGTH
,
16039 c_name
= "vector_length";
16041 case PRAGMA_OACC_CLAUSE_WAIT
:
16042 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
16045 case PRAGMA_OACC_CLAUSE_WORKER
:
16047 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_WORKER
,
16051 c_parser_error (parser
, "expected %<#pragma acc%> clause");
16057 if (((mask
>> c_kind
) & 1) == 0)
16059 /* Remove the invalid clause(s) from the list to avoid
16060 confusing the rest of the compiler. */
16062 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
16067 c_parser_skip_to_pragma_eol (parser
);
16070 return c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16075 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16076 is a bitmask in MASK. Return the list of clauses found.
16077 FINISH_P set if c_finish_omp_clauses should be called.
16078 NESTED non-zero if clauses should be terminated by closing paren instead
16079 of end of pragma. If it is 2, additionally commas are required in between
16083 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
16084 const char *where
, bool finish_p
= true,
16087 tree clauses
= NULL
;
16090 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
16093 pragma_omp_clause c_kind
;
16094 const char *c_name
;
16095 tree prev
= clauses
;
16097 if (nested
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
16102 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16103 c_parser_consume_token (parser
);
16104 else if (nested
== 2)
16105 error_at (c_parser_peek_token (parser
)->location
,
16106 "clauses in %<simd%> trait should be separated "
16110 here
= c_parser_peek_token (parser
)->location
;
16111 c_kind
= c_parser_omp_clause_name (parser
);
16115 case PRAGMA_OMP_CLAUSE_BIND
:
16116 clauses
= c_parser_omp_clause_bind (parser
, clauses
);
16119 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
16120 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
16121 c_name
= "collapse";
16123 case PRAGMA_OMP_CLAUSE_COPYIN
:
16124 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
16127 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
16128 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
16129 c_name
= "copyprivate";
16131 case PRAGMA_OMP_CLAUSE_DEFAULT
:
16132 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
16133 c_name
= "default";
16135 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
16136 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
16137 c_name
= "firstprivate";
16139 case PRAGMA_OMP_CLAUSE_FINAL
:
16140 clauses
= c_parser_omp_clause_final (parser
, clauses
);
16143 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
16144 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
16145 c_name
= "grainsize";
16147 case PRAGMA_OMP_CLAUSE_HINT
:
16148 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
16151 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
16152 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
16153 c_name
= "defaultmap";
16155 case PRAGMA_OMP_CLAUSE_IF
:
16156 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
16159 case PRAGMA_OMP_CLAUSE_IN_REDUCTION
:
16161 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_IN_REDUCTION
,
16163 c_name
= "in_reduction";
16165 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
16166 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
16167 c_name
= "lastprivate";
16169 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
16170 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
16171 c_name
= "mergeable";
16173 case PRAGMA_OMP_CLAUSE_NOWAIT
:
16174 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
16177 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
16178 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
16179 c_name
= "num_tasks";
16181 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
16182 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
16183 c_name
= "num_threads";
16185 case PRAGMA_OMP_CLAUSE_ORDER
:
16186 clauses
= c_parser_omp_clause_order (parser
, clauses
);
16189 case PRAGMA_OMP_CLAUSE_ORDERED
:
16190 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
16191 c_name
= "ordered";
16193 case PRAGMA_OMP_CLAUSE_PRIORITY
:
16194 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
16195 c_name
= "priority";
16197 case PRAGMA_OMP_CLAUSE_PRIVATE
:
16198 clauses
= c_parser_omp_clause_private (parser
, clauses
);
16199 c_name
= "private";
16201 case PRAGMA_OMP_CLAUSE_REDUCTION
:
16203 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
16205 c_name
= "reduction";
16207 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
16208 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
16209 c_name
= "schedule";
16211 case PRAGMA_OMP_CLAUSE_SHARED
:
16212 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
16215 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION
:
16217 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_TASK_REDUCTION
,
16219 c_name
= "task_reduction";
16221 case PRAGMA_OMP_CLAUSE_UNTIED
:
16222 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
16225 case PRAGMA_OMP_CLAUSE_INBRANCH
:
16226 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
16228 c_name
= "inbranch";
16230 case PRAGMA_OMP_CLAUSE_NONTEMPORAL
:
16231 clauses
= c_parser_omp_clause_nontemporal (parser
, clauses
);
16232 c_name
= "nontemporal";
16234 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
16235 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
16237 c_name
= "notinbranch";
16239 case PRAGMA_OMP_CLAUSE_PARALLEL
:
16241 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
16243 c_name
= "parallel";
16247 error_at (here
, "%qs must be the first clause of %qs",
16252 case PRAGMA_OMP_CLAUSE_FOR
:
16254 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
16258 goto clause_not_first
;
16260 case PRAGMA_OMP_CLAUSE_SECTIONS
:
16262 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
16264 c_name
= "sections";
16266 goto clause_not_first
;
16268 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
16270 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
16272 c_name
= "taskgroup";
16274 goto clause_not_first
;
16276 case PRAGMA_OMP_CLAUSE_LINK
:
16278 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
16281 case PRAGMA_OMP_CLAUSE_TO
:
16282 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
16284 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO_DECLARE
,
16287 clauses
= c_parser_omp_clause_to (parser
, clauses
);
16290 case PRAGMA_OMP_CLAUSE_FROM
:
16291 clauses
= c_parser_omp_clause_from (parser
, clauses
);
16294 case PRAGMA_OMP_CLAUSE_UNIFORM
:
16295 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
16296 c_name
= "uniform";
16298 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
16299 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
16300 c_name
= "num_teams";
16302 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
16303 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
16304 c_name
= "thread_limit";
16306 case PRAGMA_OMP_CLAUSE_ALIGNED
:
16307 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
16308 c_name
= "aligned";
16310 case PRAGMA_OMP_CLAUSE_LINEAR
:
16311 clauses
= c_parser_omp_clause_linear (parser
, clauses
);
16314 case PRAGMA_OMP_CLAUSE_DEPEND
:
16315 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
16318 case PRAGMA_OMP_CLAUSE_MAP
:
16319 clauses
= c_parser_omp_clause_map (parser
, clauses
);
16322 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
16323 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
16324 c_name
= "use_device_ptr";
16326 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
:
16327 clauses
= c_parser_omp_clause_use_device_addr (parser
, clauses
);
16328 c_name
= "use_device_addr";
16330 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
16331 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
16332 c_name
= "is_device_ptr";
16334 case PRAGMA_OMP_CLAUSE_DEVICE
:
16335 clauses
= c_parser_omp_clause_device (parser
, clauses
);
16338 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
16339 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
16340 c_name
= "dist_schedule";
16342 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
16343 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
16344 c_name
= "proc_bind";
16346 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE
:
16347 clauses
= c_parser_omp_clause_device_type (parser
, clauses
);
16348 c_name
= "device_type";
16350 case PRAGMA_OMP_CLAUSE_SAFELEN
:
16351 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
16352 c_name
= "safelen";
16354 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
16355 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
16356 c_name
= "simdlen";
16358 case PRAGMA_OMP_CLAUSE_NOGROUP
:
16359 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
16360 c_name
= "nogroup";
16362 case PRAGMA_OMP_CLAUSE_THREADS
:
16364 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
16366 c_name
= "threads";
16368 case PRAGMA_OMP_CLAUSE_SIMD
:
16370 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
16375 c_parser_error (parser
, "expected %<#pragma omp%> clause");
16381 if (((mask
>> c_kind
) & 1) == 0)
16383 /* Remove the invalid clause(s) from the list to avoid
16384 confusing the rest of the compiler. */
16386 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
16392 c_parser_skip_to_pragma_eol (parser
);
16396 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
16397 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
16398 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
16404 /* OpenACC 2.0, OpenMP 2.5:
16408 In practice, we're also interested in adding the statement to an
16409 outer node. So it is convenient if we work around the fact that
16410 c_parser_statement calls add_stmt. */
16413 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
16415 tree stmt
= push_stmt_list ();
16416 c_parser_statement (parser
, if_p
);
16417 return pop_stmt_list (stmt
);
16421 # pragma acc cache (variable-list) new-line
16423 LOC is the location of the #pragma token.
16427 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
16429 tree stmt
, clauses
;
16431 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE__CACHE_
, NULL
);
16432 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16434 c_parser_skip_to_pragma_eol (parser
);
16436 stmt
= make_node (OACC_CACHE
);
16437 TREE_TYPE (stmt
) = void_type_node
;
16438 OACC_CACHE_CLAUSES (stmt
) = clauses
;
16439 SET_EXPR_LOCATION (stmt
, loc
);
16446 # pragma acc data oacc-data-clause[optseq] new-line
16449 LOC is the location of the #pragma token.
16452 #define OACC_DATA_CLAUSE_MASK \
16453 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16454 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16455 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16456 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16457 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16458 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16459 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16460 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16461 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16464 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
16466 tree stmt
, clauses
, block
;
16468 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
16469 "#pragma acc data");
16471 block
= c_begin_omp_parallel ();
16472 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
16474 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
16480 # pragma acc declare oacc-data-clause[optseq] new-line
16483 #define OACC_DECLARE_CLAUSE_MASK \
16484 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16485 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16486 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16487 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16488 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16489 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
16490 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
16491 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16494 c_parser_oacc_declare (c_parser
*parser
)
16496 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
16497 tree clauses
, stmt
, t
, decl
;
16499 bool error
= false;
16501 c_parser_consume_pragma (parser
);
16503 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
16504 "#pragma acc declare");
16507 error_at (pragma_loc
,
16508 "no valid clauses specified in %<#pragma acc declare%>");
16512 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
16514 location_t loc
= OMP_CLAUSE_LOCATION (t
);
16515 decl
= OMP_CLAUSE_DECL (t
);
16516 if (!DECL_P (decl
))
16518 error_at (loc
, "array section in %<#pragma acc declare%>");
16523 switch (OMP_CLAUSE_MAP_KIND (t
))
16525 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
16526 case GOMP_MAP_ALLOC
:
16528 case GOMP_MAP_FORCE_DEVICEPTR
:
16529 case GOMP_MAP_DEVICE_RESIDENT
:
16532 case GOMP_MAP_LINK
:
16533 if (!global_bindings_p ()
16534 && (TREE_STATIC (decl
)
16535 || !DECL_EXTERNAL (decl
)))
16538 "%qD must be a global variable in "
16539 "%<#pragma acc declare link%>",
16547 if (global_bindings_p ())
16549 error_at (loc
, "invalid OpenACC clause at file scope");
16553 if (DECL_EXTERNAL (decl
))
16556 "invalid use of %<extern%> variable %qD "
16557 "in %<#pragma acc declare%>", decl
);
16561 else if (TREE_PUBLIC (decl
))
16564 "invalid use of %<global%> variable %qD "
16565 "in %<#pragma acc declare%>", decl
);
16572 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
16573 || lookup_attribute ("omp declare target link",
16574 DECL_ATTRIBUTES (decl
)))
16576 error_at (loc
, "variable %qD used more than once with "
16577 "%<#pragma acc declare%>", decl
);
16586 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
16587 id
= get_identifier ("omp declare target link");
16589 id
= get_identifier ("omp declare target");
16591 DECL_ATTRIBUTES (decl
)
16592 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
16594 if (global_bindings_p ())
16596 symtab_node
*node
= symtab_node::get (decl
);
16599 node
->offloadable
= 1;
16600 if (ENABLE_OFFLOADING
)
16602 g
->have_offload
= true;
16603 if (is_a
<varpool_node
*> (node
))
16604 vec_safe_push (offload_vars
, decl
);
16611 if (error
|| global_bindings_p ())
16614 stmt
= make_node (OACC_DECLARE
);
16615 TREE_TYPE (stmt
) = void_type_node
;
16616 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
16617 SET_EXPR_LOCATION (stmt
, pragma_loc
);
16625 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
16629 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
16632 LOC is the location of the #pragma token.
16635 #define OACC_ENTER_DATA_CLAUSE_MASK \
16636 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16641 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16643 #define OACC_EXIT_DATA_CLAUSE_MASK \
16644 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16645 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16646 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16647 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
16648 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
16649 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
16650 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16653 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
16655 location_t loc
= c_parser_peek_token (parser
)->location
;
16656 tree clauses
, stmt
;
16657 const char *p
= "";
16659 c_parser_consume_pragma (parser
);
16661 if (c_parser_next_token_is (parser
, CPP_NAME
))
16663 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16664 c_parser_consume_token (parser
);
16667 if (strcmp (p
, "data") != 0)
16669 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
16670 enter
? "enter" : "exit");
16671 parser
->error
= true;
16672 c_parser_skip_to_pragma_eol (parser
);
16677 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
16678 "#pragma acc enter data");
16680 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
16681 "#pragma acc exit data");
16683 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
16685 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
16686 enter
? "enter" : "exit");
16690 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
16691 TREE_TYPE (stmt
) = void_type_node
;
16692 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
16693 SET_EXPR_LOCATION (stmt
, loc
);
16699 # pragma acc host_data oacc-data-clause[optseq] new-line
16703 #define OACC_HOST_DATA_CLAUSE_MASK \
16704 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) )
16707 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
16709 tree stmt
, clauses
, block
;
16711 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
16712 "#pragma acc host_data");
16714 block
= c_begin_omp_parallel ();
16715 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
16716 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
16723 # pragma acc loop oacc-loop-clause[optseq] new-line
16726 LOC is the location of the #pragma token.
16729 #define OACC_LOOP_CLAUSE_MASK \
16730 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
16731 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16732 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16733 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
16737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
16738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
16739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
16741 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
16742 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
16744 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
16746 strcat (p_name
, " loop");
16747 mask
|= OACC_LOOP_CLAUSE_MASK
;
16749 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
16753 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
16755 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC
);
16757 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16760 tree block
= c_begin_compound_stmt (true);
16761 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
16763 block
= c_end_compound_stmt (loc
, block
, true);
16770 # pragma acc kernels oacc-kernels-clause[optseq] new-line
16775 # pragma acc parallel oacc-parallel-clause[optseq] new-line
16780 # pragma acc serial oacc-serial-clause[optseq] new-line
16783 LOC is the location of the #pragma token.
16786 #define OACC_KERNELS_CLAUSE_MASK \
16787 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16788 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16789 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16790 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16791 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16792 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16793 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16794 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16795 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16796 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16797 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16798 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16799 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16800 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16801 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16803 #define OACC_PARALLEL_CLAUSE_MASK \
16804 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16805 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16806 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16807 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16808 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16809 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16815 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
16816 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16817 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16818 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16819 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16820 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16821 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16823 #define OACC_SERIAL_CLAUSE_MASK \
16824 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16825 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16827 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16828 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16829 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16830 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16831 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16832 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16833 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16834 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16835 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
16836 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16837 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16838 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16841 c_parser_oacc_compute (location_t loc
, c_parser
*parser
,
16842 enum pragma_kind p_kind
, char *p_name
, bool *if_p
)
16844 omp_clause_mask mask
;
16845 enum tree_code code
;
16848 case PRAGMA_OACC_KERNELS
:
16849 strcat (p_name
, " kernels");
16850 mask
= OACC_KERNELS_CLAUSE_MASK
;
16851 code
= OACC_KERNELS
;
16853 case PRAGMA_OACC_PARALLEL
:
16854 strcat (p_name
, " parallel");
16855 mask
= OACC_PARALLEL_CLAUSE_MASK
;
16856 code
= OACC_PARALLEL
;
16858 case PRAGMA_OACC_SERIAL
:
16859 strcat (p_name
, " serial");
16860 mask
= OACC_SERIAL_CLAUSE_MASK
;
16861 code
= OACC_SERIAL
;
16864 gcc_unreachable ();
16867 if (c_parser_next_token_is (parser
, CPP_NAME
))
16869 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16870 if (strcmp (p
, "loop") == 0)
16872 c_parser_consume_token (parser
);
16873 tree block
= c_begin_omp_parallel ();
16875 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
16876 return c_finish_omp_construct (loc
, code
, block
, clauses
);
16880 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
);
16882 tree block
= c_begin_omp_parallel ();
16883 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
16885 return c_finish_omp_construct (loc
, code
, block
, clauses
);
16889 # pragma acc routine oacc-routine-clause[optseq] new-line
16890 function-definition
16892 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
16895 #define OACC_ROUTINE_CLAUSE_MASK \
16896 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16897 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16898 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16899 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) )
16901 /* Parse an OpenACC routine directive. For named directives, we apply
16902 immediately to the named function. For unnamed ones we then parse
16903 a declaration or definition, which must be for a function. */
16906 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
16908 gcc_checking_assert (context
== pragma_external
);
16910 oacc_routine_data data
;
16911 data
.error_seen
= false;
16912 data
.fndecl_seen
= false;
16913 data
.clauses
= NULL_TREE
;
16914 data
.loc
= c_parser_peek_token (parser
)->location
;
16916 c_parser_consume_pragma (parser
);
16918 /* Look for optional '( name )'. */
16919 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
16921 c_parser_consume_token (parser
); /* '(' */
16923 tree decl
= NULL_TREE
;
16924 c_token
*name_token
= c_parser_peek_token (parser
);
16925 location_t name_loc
= name_token
->location
;
16926 if (name_token
->type
== CPP_NAME
16927 && (name_token
->id_kind
== C_ID_ID
16928 || name_token
->id_kind
== C_ID_TYPENAME
))
16930 decl
= lookup_name (name_token
->value
);
16932 error_at (name_loc
,
16933 "%qE has not been declared", name_token
->value
);
16934 c_parser_consume_token (parser
);
16937 c_parser_error (parser
, "expected function name");
16940 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
16942 c_parser_skip_to_pragma_eol (parser
, false);
16947 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
16948 "#pragma acc routine");
16949 /* The clauses are in reverse order; fix that to make later diagnostic
16950 emission easier. */
16951 data
.clauses
= nreverse (data
.clauses
);
16953 if (TREE_CODE (decl
) != FUNCTION_DECL
)
16955 error_at (name_loc
, "%qD does not refer to a function", decl
);
16959 c_finish_oacc_routine (&data
, decl
, false);
16961 else /* No optional '( name )'. */
16964 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
16965 "#pragma acc routine");
16966 /* The clauses are in reverse order; fix that to make later diagnostic
16967 emission easier. */
16968 data
.clauses
= nreverse (data
.clauses
);
16970 /* Emit a helpful diagnostic if there's another pragma following this
16971 one. Also don't allow a static assertion declaration, as in the
16972 following we'll just parse a *single* "declaration or function
16973 definition", and the static assertion counts an one. */
16974 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
16975 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
16977 error_at (data
.loc
,
16978 "%<#pragma acc routine%> not immediately followed by"
16979 " function declaration or definition");
16980 /* ..., and then just keep going. */
16984 /* We only have to consider the pragma_external case here. */
16985 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
16986 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
16988 int ext
= disable_extension_diagnostics ();
16990 c_parser_consume_token (parser
);
16991 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
16992 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
16993 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
16994 NULL
, vNULL
, false, NULL
, &data
);
16995 restore_extension_diagnostics (ext
);
16998 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
16999 NULL
, vNULL
, false, NULL
, &data
);
17003 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17004 IS_DEFN is true if we're applying it to the definition. */
17007 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
17010 /* Keep going if we're in error reporting mode. */
17011 if (data
->error_seen
17012 || fndecl
== error_mark_node
)
17015 if (data
->fndecl_seen
)
17017 error_at (data
->loc
,
17018 "%<#pragma acc routine%> not immediately followed by"
17019 " a single function declaration or definition");
17020 data
->error_seen
= true;
17023 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
17025 error_at (data
->loc
,
17026 "%<#pragma acc routine%> not immediately followed by"
17027 " function declaration or definition");
17028 data
->error_seen
= true;
17033 = oacc_verify_routine_clauses (fndecl
, &data
->clauses
, data
->loc
,
17034 "#pragma acc routine");
17035 if (compatible
< 0)
17037 data
->error_seen
= true;
17040 if (compatible
> 0)
17045 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
17047 error_at (data
->loc
,
17049 ? G_("%<#pragma acc routine%> must be applied before use")
17050 : G_("%<#pragma acc routine%> must be applied before"
17052 data
->error_seen
= true;
17056 /* Set the routine's level of parallelism. */
17057 tree dims
= oacc_build_routine_dims (data
->clauses
);
17058 oacc_replace_fn_attrib (fndecl
, dims
);
17060 /* Add an "omp declare target" attribute. */
17061 DECL_ATTRIBUTES (fndecl
)
17062 = tree_cons (get_identifier ("omp declare target"),
17063 data
->clauses
, DECL_ATTRIBUTES (fndecl
));
17066 /* Remember that we've used this "#pragma acc routine". */
17067 data
->fndecl_seen
= true;
17071 # pragma acc update oacc-update-clause[optseq] new-line
17074 #define OACC_UPDATE_CLAUSE_MASK \
17075 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17076 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17077 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17078 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17079 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
17080 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17083 c_parser_oacc_update (c_parser
*parser
)
17085 location_t loc
= c_parser_peek_token (parser
)->location
;
17087 c_parser_consume_pragma (parser
);
17089 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
17090 "#pragma acc update");
17091 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
17094 "%<#pragma acc update%> must contain at least one "
17095 "%<device%> or %<host%> or %<self%> clause");
17102 tree stmt
= make_node (OACC_UPDATE
);
17103 TREE_TYPE (stmt
) = void_type_node
;
17104 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
17105 SET_EXPR_LOCATION (stmt
, loc
);
17110 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
17112 LOC is the location of the #pragma token.
17115 #define OACC_WAIT_CLAUSE_MASK \
17116 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
17119 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
17121 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
17123 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
17124 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
17126 strcpy (p_name
, " wait");
17127 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
17128 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
17135 # pragma omp atomic new-line
17139 x binop= expr | x++ | ++x | x-- | --x
17141 +, *, -, /, &, ^, |, <<, >>
17143 where x is an lvalue expression with scalar type.
17146 # pragma omp atomic new-line
17149 # pragma omp atomic read new-line
17152 # pragma omp atomic write new-line
17155 # pragma omp atomic update new-line
17158 # pragma omp atomic capture new-line
17161 # pragma omp atomic capture new-line
17169 expression-stmt | x = x binop expr
17171 v = expression-stmt
17173 { v = x; update-stmt; } | { update-stmt; v = x; }
17177 expression-stmt | x = x binop expr | x = expr binop x
17181 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
17183 where x and v are lvalue expressions with scalar type.
17185 LOC is the location of the #pragma token. */
17188 c_parser_omp_atomic (location_t loc
, c_parser
*parser
)
17190 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
;
17191 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
17192 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
17193 enum tree_code code
= ERROR_MARK
, opcode
= NOP_EXPR
;
17194 enum omp_memory_order memory_order
= OMP_MEMORY_ORDER_UNSPECIFIED
;
17195 struct c_expr expr
;
17197 bool structured_block
= false;
17198 bool swapped
= false;
17201 tree clauses
= NULL_TREE
;
17203 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17205 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
17206 c_parser_consume_token (parser
);
17210 if (c_parser_next_token_is (parser
, CPP_NAME
))
17213 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17214 location_t cloc
= c_parser_peek_token (parser
)->location
;
17215 enum tree_code new_code
= ERROR_MARK
;
17216 enum omp_memory_order new_memory_order
17217 = OMP_MEMORY_ORDER_UNSPECIFIED
;
17219 if (!strcmp (p
, "read"))
17220 new_code
= OMP_ATOMIC_READ
;
17221 else if (!strcmp (p
, "write"))
17222 new_code
= NOP_EXPR
;
17223 else if (!strcmp (p
, "update"))
17224 new_code
= OMP_ATOMIC
;
17225 else if (!strcmp (p
, "capture"))
17226 new_code
= OMP_ATOMIC_CAPTURE_NEW
;
17227 else if (!strcmp (p
, "seq_cst"))
17228 new_memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17229 else if (!strcmp (p
, "acq_rel"))
17230 new_memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
17231 else if (!strcmp (p
, "release"))
17232 new_memory_order
= OMP_MEMORY_ORDER_RELEASE
;
17233 else if (!strcmp (p
, "acquire"))
17234 new_memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
17235 else if (!strcmp (p
, "relaxed"))
17236 new_memory_order
= OMP_MEMORY_ORDER_RELAXED
;
17237 else if (!strcmp (p
, "hint"))
17239 c_parser_consume_token (parser
);
17240 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
17246 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
17247 "%<capture%>, %<seq_cst%>, %<acq_rel%>, "
17248 "%<release%>, %<relaxed%> or %<hint%> clause");
17252 if (new_code
!= ERROR_MARK
)
17254 if (code
!= ERROR_MARK
)
17255 error_at (cloc
, "too many atomic clauses");
17259 else if (new_memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
17261 if (memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
17262 error_at (cloc
, "too many memory order clauses");
17264 memory_order
= new_memory_order
;
17266 c_parser_consume_token (parser
);
17272 c_parser_skip_to_pragma_eol (parser
);
17274 if (code
== ERROR_MARK
)
17276 if (memory_order
== OMP_MEMORY_ORDER_UNSPECIFIED
)
17279 = (enum omp_requires
) (omp_requires_mask
17280 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
);
17281 switch ((enum omp_memory_order
)
17282 (omp_requires_mask
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
))
17284 case OMP_MEMORY_ORDER_UNSPECIFIED
:
17285 case OMP_MEMORY_ORDER_RELAXED
:
17286 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
17288 case OMP_MEMORY_ORDER_SEQ_CST
:
17289 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17291 case OMP_MEMORY_ORDER_ACQ_REL
:
17294 case OMP_ATOMIC_READ
:
17295 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
17297 case NOP_EXPR
: /* atomic write */
17299 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
17302 memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
17307 gcc_unreachable ();
17313 case OMP_ATOMIC_READ
:
17314 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
17315 || memory_order
== OMP_MEMORY_ORDER_RELEASE
)
17317 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
17318 "%<acq_rel%> or %<release%> clauses");
17319 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17322 case NOP_EXPR
: /* atomic write */
17323 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
17324 || memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
17326 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
17327 "%<acq_rel%> or %<acquire%> clauses");
17328 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17332 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
17333 || memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
17335 error_at (loc
, "%<#pragma omp atomic update%> incompatible with "
17336 "%<acq_rel%> or %<acquire%> clauses");
17337 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17346 case OMP_ATOMIC_READ
:
17347 case NOP_EXPR
: /* atomic write */
17348 v
= c_parser_cast_expression (parser
, NULL
).value
;
17349 non_lvalue_p
= !lvalue_p (v
);
17350 v
= c_fully_fold (v
, false, NULL
, true);
17351 if (v
== error_mark_node
)
17354 v
= non_lvalue (v
);
17355 loc
= c_parser_peek_token (parser
)->location
;
17356 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
17358 if (code
== NOP_EXPR
)
17360 lhs
= c_parser_expression (parser
).value
;
17361 lhs
= c_fully_fold (lhs
, false, NULL
);
17362 if (lhs
== error_mark_node
)
17367 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
17368 non_lvalue_p
= !lvalue_p (lhs
);
17369 lhs
= c_fully_fold (lhs
, false, NULL
, true);
17370 if (lhs
== error_mark_node
)
17373 lhs
= non_lvalue (lhs
);
17375 if (code
== NOP_EXPR
)
17377 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
17385 case OMP_ATOMIC_CAPTURE_NEW
:
17386 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
17388 c_parser_consume_token (parser
);
17389 structured_block
= true;
17393 v
= c_parser_cast_expression (parser
, NULL
).value
;
17394 non_lvalue_p
= !lvalue_p (v
);
17395 v
= c_fully_fold (v
, false, NULL
, true);
17396 if (v
== error_mark_node
)
17399 v
= non_lvalue (v
);
17400 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
17408 /* For structured_block case we don't know yet whether
17409 old or new x should be captured. */
17411 eloc
= c_parser_peek_token (parser
)->location
;
17412 expr
= c_parser_cast_expression (parser
, NULL
);
17414 expr
= default_function_array_conversion (eloc
, expr
);
17415 unfolded_lhs
= expr
.value
;
17416 lhs
= c_fully_fold (lhs
, false, NULL
, true);
17418 switch (TREE_CODE (lhs
))
17422 c_parser_skip_to_end_of_block_or_statement (parser
);
17423 if (structured_block
)
17425 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
17426 c_parser_consume_token (parser
);
17427 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
17429 c_parser_skip_to_end_of_block_or_statement (parser
);
17430 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
17431 c_parser_consume_token (parser
);
17436 case POSTINCREMENT_EXPR
:
17437 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
17438 code
= OMP_ATOMIC_CAPTURE_OLD
;
17440 case PREINCREMENT_EXPR
:
17441 lhs
= TREE_OPERAND (lhs
, 0);
17442 unfolded_lhs
= NULL_TREE
;
17443 opcode
= PLUS_EXPR
;
17444 rhs
= integer_one_node
;
17447 case POSTDECREMENT_EXPR
:
17448 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
17449 code
= OMP_ATOMIC_CAPTURE_OLD
;
17451 case PREDECREMENT_EXPR
:
17452 lhs
= TREE_OPERAND (lhs
, 0);
17453 unfolded_lhs
= NULL_TREE
;
17454 opcode
= MINUS_EXPR
;
17455 rhs
= integer_one_node
;
17458 case COMPOUND_EXPR
:
17459 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
17460 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
17461 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
17462 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
17463 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
17464 (TREE_OPERAND (lhs
, 1), 0), 0)))
17466 /* Undo effects of boolean_increment for post {in,de}crement. */
17467 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
17470 if (TREE_CODE (lhs
) == MODIFY_EXPR
17471 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs
, 0))) == BOOLEAN_TYPE
)
17473 /* Undo effects of boolean_increment. */
17474 if (integer_onep (TREE_OPERAND (lhs
, 1)))
17476 /* This is pre or post increment. */
17477 rhs
= TREE_OPERAND (lhs
, 1);
17478 lhs
= TREE_OPERAND (lhs
, 0);
17479 unfolded_lhs
= NULL_TREE
;
17481 if (code
== OMP_ATOMIC_CAPTURE_NEW
17482 && !structured_block
17483 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
17484 code
= OMP_ATOMIC_CAPTURE_OLD
;
17487 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
17488 && TREE_OPERAND (lhs
, 0)
17489 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
17491 /* This is pre or post decrement. */
17492 rhs
= TREE_OPERAND (lhs
, 1);
17493 lhs
= TREE_OPERAND (lhs
, 0);
17494 unfolded_lhs
= NULL_TREE
;
17496 if (code
== OMP_ATOMIC_CAPTURE_NEW
17497 && !structured_block
17498 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
17499 code
= OMP_ATOMIC_CAPTURE_OLD
;
17505 if (!lvalue_p (unfolded_lhs
))
17506 lhs
= non_lvalue (lhs
);
17507 switch (c_parser_peek_token (parser
)->type
)
17510 opcode
= MULT_EXPR
;
17513 opcode
= TRUNC_DIV_EXPR
;
17516 opcode
= PLUS_EXPR
;
17519 opcode
= MINUS_EXPR
;
17521 case CPP_LSHIFT_EQ
:
17522 opcode
= LSHIFT_EXPR
;
17524 case CPP_RSHIFT_EQ
:
17525 opcode
= RSHIFT_EXPR
;
17528 opcode
= BIT_AND_EXPR
;
17531 opcode
= BIT_IOR_EXPR
;
17534 opcode
= BIT_XOR_EXPR
;
17537 c_parser_consume_token (parser
);
17538 eloc
= c_parser_peek_token (parser
)->location
;
17539 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
17541 switch (TREE_CODE (rhs1
))
17544 case TRUNC_DIV_EXPR
:
17553 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
17555 opcode
= TREE_CODE (rhs1
);
17556 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
17558 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
17562 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
17564 opcode
= TREE_CODE (rhs1
);
17565 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
17567 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
17569 swapped
= !commutative_tree_code (opcode
);
17578 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
17580 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
17582 code
= OMP_ATOMIC_CAPTURE_OLD
;
17585 expr
= default_function_array_read_conversion (eloc
, expr
);
17586 unfolded_lhs1
= expr
.value
;
17587 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
17589 c_parser_consume_token (parser
);
17592 if (structured_block
)
17595 expr
= default_function_array_read_conversion (eloc
, expr
);
17596 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
17601 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
17604 c_parser_error (parser
,
17605 "invalid operator for %<#pragma omp atomic%>");
17609 /* Arrange to pass the location of the assignment operator to
17610 c_finish_omp_atomic. */
17611 loc
= c_parser_peek_token (parser
)->location
;
17612 c_parser_consume_token (parser
);
17613 eloc
= c_parser_peek_token (parser
)->location
;
17614 expr
= c_parser_expression (parser
);
17615 expr
= default_function_array_read_conversion (eloc
, expr
);
17617 rhs
= c_fully_fold (rhs
, false, NULL
, true);
17621 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
17623 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
17625 v
= c_parser_cast_expression (parser
, NULL
).value
;
17626 non_lvalue_p
= !lvalue_p (v
);
17627 v
= c_fully_fold (v
, false, NULL
, true);
17628 if (v
== error_mark_node
)
17631 v
= non_lvalue (v
);
17632 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
17634 eloc
= c_parser_peek_token (parser
)->location
;
17635 expr
= c_parser_cast_expression (parser
, NULL
);
17637 expr
= default_function_array_read_conversion (eloc
, expr
);
17638 unfolded_lhs1
= expr
.value
;
17639 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
17640 if (lhs1
== error_mark_node
)
17642 if (!lvalue_p (unfolded_lhs1
))
17643 lhs1
= non_lvalue (lhs1
);
17645 if (structured_block
)
17647 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
17648 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
17651 if (unfolded_lhs
&& unfolded_lhs1
17652 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
17654 error ("%<#pragma omp atomic capture%> uses two different "
17655 "expressions for memory");
17656 stmt
= error_mark_node
;
17659 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
,
17660 swapped
, memory_order
);
17661 if (stmt
!= error_mark_node
)
17664 if (!structured_block
)
17665 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
17670 # pragma omp barrier new-line
17674 c_parser_omp_barrier (c_parser
*parser
)
17676 location_t loc
= c_parser_peek_token (parser
)->location
;
17677 c_parser_consume_pragma (parser
);
17678 c_parser_skip_to_pragma_eol (parser
);
17680 c_finish_omp_barrier (loc
);
17684 # pragma omp critical [(name)] new-line
17688 # pragma omp critical [(name) [hint(expression)]] new-line
17690 LOC is the location of the #pragma itself. */
17692 #define OMP_CRITICAL_CLAUSE_MASK \
17693 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
17696 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
17698 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
17700 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17702 c_parser_consume_token (parser
);
17703 if (c_parser_next_token_is (parser
, CPP_NAME
))
17705 name
= c_parser_peek_token (parser
)->value
;
17706 c_parser_consume_token (parser
);
17707 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
17710 c_parser_error (parser
, "expected identifier");
17712 if (c_parser_next_token_is (parser
, CPP_COMMA
)
17713 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
17714 c_parser_consume_token (parser
);
17716 clauses
= c_parser_omp_all_clauses (parser
,
17717 OMP_CRITICAL_CLAUSE_MASK
,
17718 "#pragma omp critical");
17722 if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17723 c_parser_error (parser
, "expected %<(%> or end of line");
17724 c_parser_skip_to_pragma_eol (parser
);
17727 stmt
= c_parser_omp_structured_block (parser
, if_p
);
17728 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
17732 # pragma omp depobj ( depobj ) depobj-clause new-line
17735 depend (dependence-type : locator)
17737 update (dependence-type)
17746 c_parser_omp_depobj (c_parser
*parser
)
17748 location_t loc
= c_parser_peek_token (parser
)->location
;
17749 c_parser_consume_pragma (parser
);
17750 matching_parens parens
;
17751 if (!parens
.require_open (parser
))
17753 c_parser_skip_to_pragma_eol (parser
);
17757 tree depobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
17758 if (depobj
!= error_mark_node
)
17760 if (!lvalue_p (depobj
))
17762 error_at (EXPR_LOC_OR_LOC (depobj
, loc
),
17763 "%<depobj%> expression is not lvalue expression");
17764 depobj
= error_mark_node
;
17768 tree addr
= build_unary_op (EXPR_LOC_OR_LOC (depobj
, loc
), ADDR_EXPR
,
17770 if (addr
== error_mark_node
)
17771 depobj
= error_mark_node
;
17773 depobj
= build_indirect_ref (EXPR_LOC_OR_LOC (depobj
, loc
),
17774 addr
, RO_UNARY_STAR
);
17778 parens
.skip_until_found_close (parser
);
17779 tree clause
= NULL_TREE
;
17780 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_SOURCE
;
17781 location_t c_loc
= c_parser_peek_token (parser
)->location
;
17782 if (c_parser_next_token_is (parser
, CPP_NAME
))
17784 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17786 c_parser_consume_token (parser
);
17787 if (!strcmp ("depend", p
))
17789 clause
= c_parser_omp_clause_depend (parser
, NULL_TREE
);
17790 clause
= c_finish_omp_clauses (clause
, C_ORT_OMP
);
17792 clause
= error_mark_node
;
17794 else if (!strcmp ("destroy", p
))
17795 kind
= OMP_CLAUSE_DEPEND_LAST
;
17796 else if (!strcmp ("update", p
))
17798 matching_parens c_parens
;
17799 if (c_parens
.require_open (parser
))
17801 location_t c2_loc
= c_parser_peek_token (parser
)->location
;
17802 if (c_parser_next_token_is (parser
, CPP_NAME
))
17805 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17807 c_parser_consume_token (parser
);
17808 if (!strcmp ("in", p2
))
17809 kind
= OMP_CLAUSE_DEPEND_IN
;
17810 else if (!strcmp ("out", p2
))
17811 kind
= OMP_CLAUSE_DEPEND_OUT
;
17812 else if (!strcmp ("inout", p2
))
17813 kind
= OMP_CLAUSE_DEPEND_INOUT
;
17814 else if (!strcmp ("mutexinoutset", p2
))
17815 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
17817 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
17819 clause
= error_mark_node
;
17820 error_at (c2_loc
, "expected %<in%>, %<out%>, %<inout%> or "
17821 "%<mutexinoutset%>");
17823 c_parens
.skip_until_found_close (parser
);
17826 clause
= error_mark_node
;
17829 if (!clause
&& kind
== OMP_CLAUSE_DEPEND_SOURCE
)
17831 clause
= error_mark_node
;
17832 error_at (c_loc
, "expected %<depend%>, %<destroy%> or %<update%> clause");
17834 c_parser_skip_to_pragma_eol (parser
);
17836 c_finish_omp_depobj (loc
, depobj
, kind
, clause
);
17841 # pragma omp flush flush-vars[opt] new-line
17847 # pragma omp flush memory-order-clause new-line */
17850 c_parser_omp_flush (c_parser
*parser
)
17852 location_t loc
= c_parser_peek_token (parser
)->location
;
17853 c_parser_consume_pragma (parser
);
17854 enum memmodel mo
= MEMMODEL_LAST
;
17855 if (c_parser_next_token_is (parser
, CPP_NAME
))
17858 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17860 if (!strcmp (p
, "acq_rel"))
17861 mo
= MEMMODEL_ACQ_REL
;
17862 else if (!strcmp (p
, "release"))
17863 mo
= MEMMODEL_RELEASE
;
17864 else if (!strcmp (p
, "acquire"))
17865 mo
= MEMMODEL_ACQUIRE
;
17867 error_at (c_parser_peek_token (parser
)->location
,
17868 "expected %<acq_rel%>, %<release%> or %<acquire%>");
17869 c_parser_consume_token (parser
);
17871 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17873 if (mo
!= MEMMODEL_LAST
)
17874 error_at (c_parser_peek_token (parser
)->location
,
17875 "%<flush%> list specified together with memory order "
17877 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
17879 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17880 c_parser_error (parser
, "expected %<(%> or end of line");
17881 c_parser_skip_to_pragma_eol (parser
);
17883 c_finish_omp_flush (loc
, mo
);
17889 { structured-block scan-directive structured-block } */
17892 c_parser_omp_scan_loop_body (c_parser
*parser
, bool open_brace_parsed
)
17896 tree clauses
= NULL_TREE
;
17898 loc
= c_parser_peek_token (parser
)->location
;
17899 if (!open_brace_parsed
17900 && !c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
17902 /* Avoid skipping until the end of the block. */
17903 parser
->error
= false;
17907 substmt
= c_parser_omp_structured_block (parser
, NULL
);
17908 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, NULL_TREE
);
17909 SET_EXPR_LOCATION (substmt
, loc
);
17910 add_stmt (substmt
);
17912 loc
= c_parser_peek_token (parser
)->location
;
17913 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SCAN
)
17915 enum omp_clause_code clause
= OMP_CLAUSE_ERROR
;
17917 c_parser_consume_pragma (parser
);
17919 if (c_parser_next_token_is (parser
, CPP_NAME
))
17922 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17923 if (strcmp (p
, "inclusive") == 0)
17924 clause
= OMP_CLAUSE_INCLUSIVE
;
17925 else if (strcmp (p
, "exclusive") == 0)
17926 clause
= OMP_CLAUSE_EXCLUSIVE
;
17928 if (clause
!= OMP_CLAUSE_ERROR
)
17930 c_parser_consume_token (parser
);
17931 clauses
= c_parser_omp_var_list_parens (parser
, clause
, NULL_TREE
);
17934 c_parser_error (parser
, "expected %<inclusive%> or "
17935 "%<exclusive%> clause");
17936 c_parser_skip_to_pragma_eol (parser
);
17939 error ("expected %<#pragma omp scan%>");
17941 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
17942 substmt
= c_parser_omp_structured_block (parser
, NULL
);
17943 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, clauses
);
17944 SET_EXPR_LOCATION (substmt
, loc
);
17945 add_stmt (substmt
);
17947 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
17951 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
17952 The real trick here is to determine the loop control variable early
17953 so that we can push a new decl if necessary to make it private.
17954 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
17958 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
17959 tree clauses
, tree
*cclauses
, bool *if_p
)
17961 tree decl
, cond
, incr
, save_break
, save_cont
, body
, init
, stmt
, cl
;
17962 tree declv
, condv
, incrv
, initv
, ret
= NULL_TREE
;
17963 tree pre_body
= NULL_TREE
, this_pre_body
;
17964 tree ordered_cl
= NULL_TREE
;
17965 bool fail
= false, open_brace_parsed
= false;
17966 int i
, collapse
= 1, ordered
= 0, count
, nbraces
= 0;
17967 location_t for_loc
;
17968 bool tiling
= false;
17969 bool inscan
= false;
17970 vec
<tree
, va_gc
> *for_block
= make_tree_vector ();
17972 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
17973 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
17974 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
17975 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
17978 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
17980 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
17981 && OMP_CLAUSE_ORDERED_EXPR (cl
))
17984 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
17986 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_REDUCTION
17987 && OMP_CLAUSE_REDUCTION_INSCAN (cl
)
17988 && (code
== OMP_SIMD
|| code
== OMP_FOR
))
17991 if (ordered
&& ordered
< collapse
)
17993 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
17994 "%<ordered%> clause parameter is less than %<collapse%>");
17995 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
17996 = build_int_cst (NULL_TREE
, collapse
);
17997 ordered
= collapse
;
18001 for (tree
*pc
= &clauses
; *pc
; )
18002 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LINEAR
)
18004 error_at (OMP_CLAUSE_LOCATION (*pc
),
18005 "%<linear%> clause may not be specified together "
18006 "with %<ordered%> clause with a parameter");
18007 *pc
= OMP_CLAUSE_CHAIN (*pc
);
18010 pc
= &OMP_CLAUSE_CHAIN (*pc
);
18013 gcc_assert (tiling
|| (collapse
>= 1 && ordered
>= 0));
18014 count
= ordered
? ordered
: collapse
;
18016 declv
= make_tree_vec (count
);
18017 initv
= make_tree_vec (count
);
18018 condv
= make_tree_vec (count
);
18019 incrv
= make_tree_vec (count
);
18021 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
))
18023 c_parser_error (parser
, "for statement expected");
18026 for_loc
= c_parser_peek_token (parser
)->location
;
18027 c_parser_consume_token (parser
);
18029 for (i
= 0; i
< count
; i
++)
18031 int bracecount
= 0;
18033 matching_parens parens
;
18034 if (!parens
.require_open (parser
))
18037 /* Parse the initialization declaration or expression. */
18038 if (c_parser_next_tokens_start_declaration (parser
))
18041 vec_safe_push (for_block
, c_begin_compound_stmt (true));
18042 this_pre_body
= push_stmt_list ();
18043 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
18047 this_pre_body
= pop_stmt_list (this_pre_body
);
18051 pre_body
= push_stmt_list ();
18053 add_stmt (this_pre_body
);
18054 pre_body
= pop_stmt_list (pre_body
);
18057 pre_body
= this_pre_body
;
18059 decl
= check_for_loop_decls (for_loc
, flag_isoc99
);
18062 if (DECL_INITIAL (decl
) == error_mark_node
)
18063 decl
= error_mark_node
;
18066 else if (c_parser_next_token_is (parser
, CPP_NAME
)
18067 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
18069 struct c_expr decl_exp
;
18070 struct c_expr init_exp
;
18071 location_t init_loc
;
18073 decl_exp
= c_parser_postfix_expression (parser
);
18074 decl
= decl_exp
.value
;
18076 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
18078 init_loc
= c_parser_peek_token (parser
)->location
;
18079 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
18080 init_exp
= default_function_array_read_conversion (init_loc
,
18082 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
18083 NOP_EXPR
, init_loc
, init_exp
.value
,
18084 init_exp
.original_type
);
18085 init
= c_process_expr_stmt (init_loc
, init
);
18087 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
18092 c_parser_error (parser
,
18093 "expected iteration declaration or initialization");
18094 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
18100 /* Parse the loop condition. */
18102 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
18104 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
18105 struct c_expr cond_expr
18106 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
18108 cond
= cond_expr
.value
;
18109 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
18110 if (COMPARISON_CLASS_P (cond
))
18112 tree op0
= TREE_OPERAND (cond
, 0), op1
= TREE_OPERAND (cond
, 1);
18113 op0
= c_fully_fold (op0
, false, NULL
);
18114 op1
= c_fully_fold (op1
, false, NULL
);
18115 TREE_OPERAND (cond
, 0) = op0
;
18116 TREE_OPERAND (cond
, 1) = op1
;
18118 switch (cond_expr
.original_code
)
18126 if (code
!= OACC_LOOP
)
18130 /* Can't be cond = error_mark_node, because we want to preserve
18131 the location until c_finish_omp_for. */
18132 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
18135 protected_set_expr_location (cond
, cond_loc
);
18137 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
18139 /* Parse the increment expression. */
18141 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
18143 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
18145 incr
= c_process_expr_stmt (incr_loc
,
18146 c_parser_expression (parser
).value
);
18148 parens
.skip_until_found_close (parser
);
18150 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
18154 TREE_VEC_ELT (declv
, i
) = decl
;
18155 TREE_VEC_ELT (initv
, i
) = init
;
18156 TREE_VEC_ELT (condv
, i
) = cond
;
18157 TREE_VEC_ELT (incrv
, i
) = incr
;
18161 if (i
== count
- 1)
18164 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
18165 in between the collapsed for loops to be still considered perfectly
18166 nested. Hopefully the final version clarifies this.
18167 For now handle (multiple) {'s and empty statements. */
18170 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
18172 c_parser_consume_token (parser
);
18175 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
18177 c_parser_consume_token (parser
);
18180 else if (bracecount
18181 && c_parser_next_token_is (parser
, CPP_SEMICOLON
))
18182 c_parser_consume_token (parser
);
18185 c_parser_error (parser
, "not enough perfectly nested loops");
18188 open_brace_parsed
= true;
18198 nbraces
+= bracecount
;
18204 save_break
= c_break_label
;
18205 c_break_label
= size_one_node
;
18206 save_cont
= c_cont_label
;
18207 c_cont_label
= NULL_TREE
;
18208 body
= push_stmt_list ();
18211 c_parser_omp_scan_loop_body (parser
, open_brace_parsed
);
18212 else if (open_brace_parsed
)
18214 location_t here
= c_parser_peek_token (parser
)->location
;
18215 stmt
= c_begin_compound_stmt (true);
18216 c_parser_compound_statement_nostart (parser
);
18217 add_stmt (c_end_compound_stmt (here
, stmt
, true));
18220 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
18223 tree t
= build1 (LABEL_EXPR
, void_type_node
, c_cont_label
);
18224 SET_EXPR_LOCATION (t
, loc
);
18228 body
= pop_stmt_list (body
);
18229 c_break_label
= save_break
;
18230 c_cont_label
= save_cont
;
18234 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18236 c_parser_consume_token (parser
);
18239 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
18240 c_parser_consume_token (parser
);
18243 c_parser_error (parser
, "collapsed loops not perfectly nested");
18246 location_t here
= c_parser_peek_token (parser
)->location
;
18247 stmt
= c_begin_compound_stmt (true);
18249 c_parser_compound_statement_nostart (parser
);
18250 body
= c_end_compound_stmt (here
, stmt
, true);
18257 /* Only bother calling c_finish_omp_for if we haven't already generated
18258 an error from the initialization parsing. */
18261 stmt
= c_finish_omp_for (loc
, code
, declv
, NULL
, initv
, condv
,
18262 incrv
, body
, pre_body
, true);
18264 /* Check for iterators appearing in lb, b or incr expressions. */
18265 if (stmt
&& !c_omp_check_loop_iv (stmt
, declv
, NULL
))
18272 if (cclauses
!= NULL
18273 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
18276 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
18277 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
18278 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
18279 c
= &OMP_CLAUSE_CHAIN (*c
);
18282 for (i
= 0; i
< count
; i
++)
18283 if (TREE_VEC_ELT (declv
, i
) == OMP_CLAUSE_DECL (*c
))
18286 c
= &OMP_CLAUSE_CHAIN (*c
);
18287 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
18290 "iteration variable %qD should not be firstprivate",
18291 OMP_CLAUSE_DECL (*c
));
18292 *c
= OMP_CLAUSE_CHAIN (*c
);
18296 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
18298 *c
= OMP_CLAUSE_CHAIN (*c
);
18299 if (code
== OMP_SIMD
)
18301 OMP_CLAUSE_CHAIN (l
)
18302 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
18303 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
18307 OMP_CLAUSE_CHAIN (l
) = clauses
;
18313 OMP_FOR_CLAUSES (stmt
) = clauses
;
18318 while (!for_block
->is_empty ())
18320 /* FIXME diagnostics: LOC below should be the actual location of
18321 this particular for block. We need to build a list of
18322 locations to go along with FOR_BLOCK. */
18323 stmt
= c_end_compound_stmt (loc
, for_block
->pop (), true);
18326 release_tree_vector (for_block
);
18330 /* Helper function for OpenMP parsing, split clauses and call
18331 finish_omp_clauses on each of the set of clauses afterwards. */
18334 omp_split_clauses (location_t loc
, enum tree_code code
,
18335 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
18338 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
18339 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
18341 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
], C_ORT_OMP
);
18345 #pragma omp loop loop-clause[optseq] new-line
18348 LOC is the location of the #pragma token.
18351 #define OMP_LOOP_CLAUSE_MASK \
18352 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18354 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18355 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18356 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
18357 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18360 c_parser_omp_loop (location_t loc
, c_parser
*parser
,
18361 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18364 tree block
, clauses
, ret
;
18366 strcat (p_name
, " loop");
18367 mask
|= OMP_LOOP_CLAUSE_MASK
;
18369 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18372 omp_split_clauses (loc
, OMP_LOOP
, mask
, clauses
, cclauses
);
18373 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_LOOP
];
18376 block
= c_begin_compound_stmt (true);
18377 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_LOOP
, clauses
, cclauses
, if_p
);
18378 block
= c_end_compound_stmt (loc
, block
, true);
18385 #pragma omp simd simd-clause[optseq] new-line
18388 LOC is the location of the #pragma token.
18391 #define OMP_SIMD_CLAUSE_MASK \
18392 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
18393 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
18394 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18395 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
18396 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18397 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18398 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18399 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18400 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18401 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
18402 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18405 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
18406 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18409 tree block
, clauses
, ret
;
18411 strcat (p_name
, " simd");
18412 mask
|= OMP_SIMD_CLAUSE_MASK
;
18414 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18417 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
18418 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
18419 tree c
= omp_find_clause (cclauses
[C_OMP_CLAUSE_SPLIT_FOR
],
18420 OMP_CLAUSE_ORDERED
);
18421 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
18423 error_at (OMP_CLAUSE_LOCATION (c
),
18424 "%<ordered%> clause with parameter may not be specified "
18425 "on %qs construct", p_name
);
18426 OMP_CLAUSE_ORDERED_EXPR (c
) = NULL_TREE
;
18430 block
= c_begin_compound_stmt (true);
18431 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
18432 block
= c_end_compound_stmt (loc
, block
, true);
18439 #pragma omp for for-clause[optseq] new-line
18443 #pragma omp for simd for-simd-clause[optseq] new-line
18446 LOC is the location of the #pragma token.
18449 #define OMP_FOR_CLAUSE_MASK \
18450 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18451 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18452 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18453 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18454 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18455 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
18456 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
18457 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18458 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
18459 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18462 c_parser_omp_for (location_t loc
, c_parser
*parser
,
18463 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18466 tree block
, clauses
, ret
;
18468 strcat (p_name
, " for");
18469 mask
|= OMP_FOR_CLAUSE_MASK
;
18470 /* parallel for{, simd} disallows nowait clause, but for
18471 target {teams distribute ,}parallel for{, simd} it should be accepted. */
18472 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
18473 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
18474 /* Composite distribute parallel for{, simd} disallows ordered clause. */
18475 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
18476 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
18478 if (c_parser_next_token_is (parser
, CPP_NAME
))
18480 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18482 if (strcmp (p
, "simd") == 0)
18484 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18485 if (cclauses
== NULL
)
18486 cclauses
= cclauses_buf
;
18488 c_parser_consume_token (parser
);
18489 if (!flag_openmp
) /* flag_openmp_simd */
18490 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
18492 block
= c_begin_compound_stmt (true);
18493 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
18494 block
= c_end_compound_stmt (loc
, block
, true);
18495 if (ret
== NULL_TREE
)
18497 ret
= make_node (OMP_FOR
);
18498 TREE_TYPE (ret
) = void_type_node
;
18499 OMP_FOR_BODY (ret
) = block
;
18500 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
18501 SET_EXPR_LOCATION (ret
, loc
);
18506 if (!flag_openmp
) /* flag_openmp_simd */
18508 c_parser_skip_to_pragma_eol (parser
, false);
18512 /* Composite distribute parallel for disallows linear clause. */
18513 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
18514 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
18516 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18519 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
18520 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
18523 block
= c_begin_compound_stmt (true);
18524 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
18525 block
= c_end_compound_stmt (loc
, block
, true);
18531 static tree
c_parser_omp_taskloop (location_t
, c_parser
*, char *,
18532 omp_clause_mask
, tree
*, bool *);
18535 # pragma omp master new-line
18538 LOC is the location of the #pragma token.
18542 c_parser_omp_master (location_t loc
, c_parser
*parser
,
18543 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18546 tree block
, clauses
, ret
;
18548 strcat (p_name
, " master");
18550 if (c_parser_next_token_is (parser
, CPP_NAME
))
18552 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18554 if (strcmp (p
, "taskloop") == 0)
18556 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18557 if (cclauses
== NULL
)
18558 cclauses
= cclauses_buf
;
18560 c_parser_consume_token (parser
);
18561 if (!flag_openmp
) /* flag_openmp_simd */
18562 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
18564 block
= c_begin_compound_stmt (true);
18565 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
18567 block
= c_end_compound_stmt (loc
, block
, true);
18568 if (ret
== NULL_TREE
)
18570 ret
= c_finish_omp_master (loc
, block
);
18574 if (!flag_openmp
) /* flag_openmp_simd */
18576 c_parser_skip_to_pragma_eol (parser
, false);
18582 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, false);
18583 omp_split_clauses (loc
, OMP_MASTER
, mask
, clauses
, cclauses
);
18586 c_parser_skip_to_pragma_eol (parser
);
18588 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
18593 # pragma omp ordered new-line
18597 # pragma omp ordered ordered-clauses new-line
18600 # pragma omp ordered depend-clauses new-line */
18602 #define OMP_ORDERED_CLAUSE_MASK \
18603 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
18604 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
18606 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
18607 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
18610 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
18613 location_t loc
= c_parser_peek_token (parser
)->location
;
18614 c_parser_consume_pragma (parser
);
18616 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
18618 c_parser_error (parser
, "expected declaration specifiers");
18619 c_parser_skip_to_pragma_eol (parser
, false);
18623 if (c_parser_next_token_is (parser
, CPP_NAME
))
18625 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18627 if (!strcmp ("depend", p
))
18629 if (!flag_openmp
) /* flag_openmp_simd */
18631 c_parser_skip_to_pragma_eol (parser
, false);
18634 if (context
== pragma_stmt
)
18637 "%<#pragma omp ordered%> with %<depend%> clause may "
18638 "only be used in compound statements");
18639 c_parser_skip_to_pragma_eol (parser
, false);
18644 = c_parser_omp_all_clauses (parser
,
18645 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
18646 "#pragma omp ordered");
18647 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
18652 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
18653 "#pragma omp ordered");
18655 if (!flag_openmp
/* flag_openmp_simd */
18656 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
18659 c_finish_omp_ordered (loc
, clauses
,
18660 c_parser_omp_structured_block (parser
, if_p
));
18667 { section-sequence }
18670 section-directive[opt] structured-block
18671 section-sequence section-directive structured-block
18673 SECTIONS_LOC is the location of the #pragma omp sections. */
18676 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
18678 tree stmt
, substmt
;
18679 bool error_suppress
= false;
18682 loc
= c_parser_peek_token (parser
)->location
;
18683 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
18685 /* Avoid skipping until the end of the block. */
18686 parser
->error
= false;
18690 stmt
= push_stmt_list ();
18692 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
)
18694 substmt
= c_parser_omp_structured_block (parser
, NULL
);
18695 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
18696 SET_EXPR_LOCATION (substmt
, loc
);
18697 add_stmt (substmt
);
18702 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18704 if (c_parser_next_token_is (parser
, CPP_EOF
))
18707 loc
= c_parser_peek_token (parser
)->location
;
18708 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
18710 c_parser_consume_pragma (parser
);
18711 c_parser_skip_to_pragma_eol (parser
);
18712 error_suppress
= false;
18714 else if (!error_suppress
)
18716 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
18717 error_suppress
= true;
18720 substmt
= c_parser_omp_structured_block (parser
, NULL
);
18721 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
18722 SET_EXPR_LOCATION (substmt
, loc
);
18723 add_stmt (substmt
);
18725 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
18726 "expected %<#pragma omp section%> or %<}%>");
18728 substmt
= pop_stmt_list (stmt
);
18730 stmt
= make_node (OMP_SECTIONS
);
18731 SET_EXPR_LOCATION (stmt
, sections_loc
);
18732 TREE_TYPE (stmt
) = void_type_node
;
18733 OMP_SECTIONS_BODY (stmt
) = substmt
;
18735 return add_stmt (stmt
);
18739 # pragma omp sections sections-clause[optseq] newline
18742 LOC is the location of the #pragma token.
18745 #define OMP_SECTIONS_CLAUSE_MASK \
18746 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18749 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18750 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18753 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
18754 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
18756 tree block
, clauses
, ret
;
18758 strcat (p_name
, " sections");
18759 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
18761 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
18763 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18766 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
18767 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
18770 block
= c_begin_compound_stmt (true);
18771 ret
= c_parser_omp_sections_scope (loc
, parser
);
18773 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
18774 block
= c_end_compound_stmt (loc
, block
, true);
18781 # pragma omp parallel parallel-clause[optseq] new-line
18783 # pragma omp parallel for parallel-for-clause[optseq] new-line
18785 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
18789 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
18792 LOC is the location of the #pragma token.
18795 #define OMP_PARALLEL_CLAUSE_MASK \
18796 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18797 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18798 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18799 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18800 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18801 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
18802 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
18804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
18807 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
18808 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18811 tree stmt
, clauses
, block
;
18813 strcat (p_name
, " parallel");
18814 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
18815 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
18816 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
18817 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
18818 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
18820 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
18822 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18823 if (cclauses
== NULL
)
18824 cclauses
= cclauses_buf
;
18826 c_parser_consume_token (parser
);
18827 if (!flag_openmp
) /* flag_openmp_simd */
18828 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
18829 block
= c_begin_omp_parallel ();
18830 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
18832 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
18834 if (ret
== NULL_TREE
)
18836 OMP_PARALLEL_COMBINED (stmt
) = 1;
18839 /* When combined with distribute, parallel has to be followed by for.
18840 #pragma omp target parallel is allowed though. */
18842 && (mask
& (OMP_CLAUSE_MASK_1
18843 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
18845 error_at (loc
, "expected %<for%> after %qs", p_name
);
18846 c_parser_skip_to_pragma_eol (parser
);
18849 else if (c_parser_next_token_is (parser
, CPP_NAME
))
18851 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18852 if (cclauses
== NULL
&& strcmp (p
, "master") == 0)
18854 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18855 cclauses
= cclauses_buf
;
18857 c_parser_consume_token (parser
);
18858 if (!flag_openmp
) /* flag_openmp_simd */
18859 return c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
18861 block
= c_begin_omp_parallel ();
18862 tree ret
= c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
18864 stmt
= c_finish_omp_parallel (loc
,
18865 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
18867 OMP_PARALLEL_COMBINED (stmt
) = 1;
18872 else if (strcmp (p
, "loop") == 0)
18874 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18875 if (cclauses
== NULL
)
18876 cclauses
= cclauses_buf
;
18878 c_parser_consume_token (parser
);
18879 if (!flag_openmp
) /* flag_openmp_simd */
18880 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
18882 block
= c_begin_omp_parallel ();
18883 tree ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
18886 = c_finish_omp_parallel (loc
,
18887 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
18889 if (ret
== NULL_TREE
)
18891 OMP_PARALLEL_COMBINED (stmt
) = 1;
18894 else if (!flag_openmp
) /* flag_openmp_simd */
18896 c_parser_skip_to_pragma_eol (parser
, false);
18899 else if (cclauses
== NULL
&& strcmp (p
, "sections") == 0)
18901 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18902 cclauses
= cclauses_buf
;
18904 c_parser_consume_token (parser
);
18905 block
= c_begin_omp_parallel ();
18906 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
18907 stmt
= c_finish_omp_parallel (loc
,
18908 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
18910 OMP_PARALLEL_COMBINED (stmt
) = 1;
18914 else if (!flag_openmp
) /* flag_openmp_simd */
18916 c_parser_skip_to_pragma_eol (parser
, false);
18920 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18923 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
18924 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
18927 block
= c_begin_omp_parallel ();
18928 c_parser_statement (parser
, if_p
);
18929 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
18935 # pragma omp single single-clause[optseq] new-line
18938 LOC is the location of the #pragma.
18941 #define OMP_SINGLE_CLAUSE_MASK \
18942 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18943 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18944 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
18945 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18948 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
18950 tree stmt
= make_node (OMP_SINGLE
);
18951 SET_EXPR_LOCATION (stmt
, loc
);
18952 TREE_TYPE (stmt
) = void_type_node
;
18954 OMP_SINGLE_CLAUSES (stmt
)
18955 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
18956 "#pragma omp single");
18957 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
18959 return add_stmt (stmt
);
18963 # pragma omp task task-clause[optseq] new-line
18965 LOC is the location of the #pragma.
18968 #define OMP_TASK_CLAUSE_MASK \
18969 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18970 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
18971 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18972 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18973 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18974 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18975 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
18976 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
18977 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
18978 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
18979 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
18982 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
18984 tree clauses
, block
;
18986 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
18987 "#pragma omp task");
18989 block
= c_begin_omp_task ();
18990 c_parser_statement (parser
, if_p
);
18991 return c_finish_omp_task (loc
, clauses
, block
);
18995 # pragma omp taskwait new-line
18998 # pragma omp taskwait taskwait-clause[optseq] new-line
19001 #define OMP_TASKWAIT_CLAUSE_MASK \
19002 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19005 c_parser_omp_taskwait (c_parser
*parser
)
19007 location_t loc
= c_parser_peek_token (parser
)->location
;
19008 c_parser_consume_pragma (parser
);
19011 = c_parser_omp_all_clauses (parser
, OMP_TASKWAIT_CLAUSE_MASK
,
19012 "#pragma omp taskwait");
19016 tree stmt
= make_node (OMP_TASK
);
19017 TREE_TYPE (stmt
) = void_node
;
19018 OMP_TASK_CLAUSES (stmt
) = clauses
;
19019 OMP_TASK_BODY (stmt
) = NULL_TREE
;
19020 SET_EXPR_LOCATION (stmt
, loc
);
19024 c_finish_omp_taskwait (loc
);
19028 # pragma omp taskyield new-line
19032 c_parser_omp_taskyield (c_parser
*parser
)
19034 location_t loc
= c_parser_peek_token (parser
)->location
;
19035 c_parser_consume_pragma (parser
);
19036 c_parser_skip_to_pragma_eol (parser
);
19038 c_finish_omp_taskyield (loc
);
19042 # pragma omp taskgroup new-line
19045 # pragma omp taskgroup taskgroup-clause[optseq] new-line
19048 #define OMP_TASKGROUP_CLAUSE_MASK \
19049 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
19052 c_parser_omp_taskgroup (location_t loc
, c_parser
*parser
, bool *if_p
)
19054 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_TASKGROUP_CLAUSE_MASK
,
19055 "#pragma omp taskgroup");
19057 tree body
= c_parser_omp_structured_block (parser
, if_p
);
19058 return c_finish_omp_taskgroup (loc
, body
, clauses
);
19062 # pragma omp cancel cancel-clause[optseq] new-line
19064 LOC is the location of the #pragma.
19067 #define OMP_CANCEL_CLAUSE_MASK \
19068 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19069 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19070 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19071 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
19072 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
19075 c_parser_omp_cancel (c_parser
*parser
)
19077 location_t loc
= c_parser_peek_token (parser
)->location
;
19079 c_parser_consume_pragma (parser
);
19080 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
19081 "#pragma omp cancel");
19083 c_finish_omp_cancel (loc
, clauses
);
19087 # pragma omp cancellation point cancelpt-clause[optseq] new-line
19089 LOC is the location of the #pragma.
19092 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
19093 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19094 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19095 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19096 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
19099 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
19101 location_t loc
= c_parser_peek_token (parser
)->location
;
19103 bool point_seen
= false;
19105 c_parser_consume_pragma (parser
);
19106 if (c_parser_next_token_is (parser
, CPP_NAME
))
19108 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19109 if (strcmp (p
, "point") == 0)
19111 c_parser_consume_token (parser
);
19117 c_parser_error (parser
, "expected %<point%>");
19118 c_parser_skip_to_pragma_eol (parser
);
19122 if (context
!= pragma_compound
)
19124 if (context
== pragma_stmt
)
19126 "%<#pragma %s%> may only be used in compound statements",
19127 "omp cancellation point");
19129 c_parser_error (parser
, "expected declaration specifiers");
19130 c_parser_skip_to_pragma_eol (parser
, false);
19135 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
19136 "#pragma omp cancellation point");
19138 c_finish_omp_cancellation_point (loc
, clauses
);
19142 #pragma omp distribute distribute-clause[optseq] new-line
19145 #define OMP_DISTRIBUTE_CLAUSE_MASK \
19146 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19147 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19148 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19149 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
19150 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
19153 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
19154 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19157 tree clauses
, block
, ret
;
19159 strcat (p_name
, " distribute");
19160 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
19162 if (c_parser_next_token_is (parser
, CPP_NAME
))
19164 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19166 bool parallel
= false;
19168 if (strcmp (p
, "simd") == 0)
19171 parallel
= strcmp (p
, "parallel") == 0;
19172 if (parallel
|| simd
)
19174 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19175 if (cclauses
== NULL
)
19176 cclauses
= cclauses_buf
;
19177 c_parser_consume_token (parser
);
19178 if (!flag_openmp
) /* flag_openmp_simd */
19181 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
19184 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
19187 block
= c_begin_compound_stmt (true);
19189 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
19192 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
19194 block
= c_end_compound_stmt (loc
, block
, true);
19197 ret
= make_node (OMP_DISTRIBUTE
);
19198 TREE_TYPE (ret
) = void_type_node
;
19199 OMP_FOR_BODY (ret
) = block
;
19200 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
19201 SET_EXPR_LOCATION (ret
, loc
);
19206 if (!flag_openmp
) /* flag_openmp_simd */
19208 c_parser_skip_to_pragma_eol (parser
, false);
19212 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19215 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
19216 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
19219 block
= c_begin_compound_stmt (true);
19220 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
19222 block
= c_end_compound_stmt (loc
, block
, true);
19229 # pragma omp teams teams-clause[optseq] new-line
19230 structured-block */
19232 #define OMP_TEAMS_CLAUSE_MASK \
19233 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19234 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19235 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
19236 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19237 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
19238 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
19239 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
19242 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
19243 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19246 tree clauses
, block
, ret
;
19248 strcat (p_name
, " teams");
19249 mask
|= OMP_TEAMS_CLAUSE_MASK
;
19251 if (c_parser_next_token_is (parser
, CPP_NAME
))
19253 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19254 if (strcmp (p
, "distribute") == 0)
19256 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19257 if (cclauses
== NULL
)
19258 cclauses
= cclauses_buf
;
19260 c_parser_consume_token (parser
);
19261 if (!flag_openmp
) /* flag_openmp_simd */
19262 return c_parser_omp_distribute (loc
, parser
, p_name
, mask
,
19264 block
= c_begin_omp_parallel ();
19265 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
19267 block
= c_end_compound_stmt (loc
, block
, true);
19270 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19271 ret
= make_node (OMP_TEAMS
);
19272 TREE_TYPE (ret
) = void_type_node
;
19273 OMP_TEAMS_CLAUSES (ret
) = clauses
;
19274 OMP_TEAMS_BODY (ret
) = block
;
19275 OMP_TEAMS_COMBINED (ret
) = 1;
19276 SET_EXPR_LOCATION (ret
, loc
);
19277 return add_stmt (ret
);
19279 else if (strcmp (p
, "loop") == 0)
19281 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19282 if (cclauses
== NULL
)
19283 cclauses
= cclauses_buf
;
19285 c_parser_consume_token (parser
);
19286 if (!flag_openmp
) /* flag_openmp_simd */
19287 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
19289 block
= c_begin_omp_parallel ();
19290 ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
19291 block
= c_end_compound_stmt (loc
, block
, true);
19294 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19295 ret
= make_node (OMP_TEAMS
);
19296 TREE_TYPE (ret
) = void_type_node
;
19297 OMP_TEAMS_CLAUSES (ret
) = clauses
;
19298 OMP_TEAMS_BODY (ret
) = block
;
19299 OMP_TEAMS_COMBINED (ret
) = 1;
19300 SET_EXPR_LOCATION (ret
, loc
);
19301 return add_stmt (ret
);
19304 if (!flag_openmp
) /* flag_openmp_simd */
19306 c_parser_skip_to_pragma_eol (parser
, false);
19310 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19313 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
19314 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19317 tree stmt
= make_node (OMP_TEAMS
);
19318 TREE_TYPE (stmt
) = void_type_node
;
19319 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
19320 block
= c_begin_omp_parallel ();
19321 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19322 OMP_TEAMS_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
19323 SET_EXPR_LOCATION (stmt
, loc
);
19325 return add_stmt (stmt
);
19329 # pragma omp target data target-data-clause[optseq] new-line
19330 structured-block */
19332 #define OMP_TARGET_DATA_CLAUSE_MASK \
19333 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19334 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19335 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19336 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
19337 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
19340 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
19343 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
19344 "#pragma omp target data");
19346 for (tree
*pc
= &clauses
; *pc
;)
19348 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
19349 switch (OMP_CLAUSE_MAP_KIND (*pc
))
19352 case GOMP_MAP_ALWAYS_TO
:
19353 case GOMP_MAP_FROM
:
19354 case GOMP_MAP_ALWAYS_FROM
:
19355 case GOMP_MAP_TOFROM
:
19356 case GOMP_MAP_ALWAYS_TOFROM
:
19357 case GOMP_MAP_ALLOC
:
19360 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19361 case GOMP_MAP_ALWAYS_POINTER
:
19365 error_at (OMP_CLAUSE_LOCATION (*pc
),
19366 "%<#pragma omp target data%> with map-type other "
19367 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19368 "on %<map%> clause");
19369 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19372 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
19373 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
19375 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19382 "%<#pragma omp target data%> must contain at least "
19383 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
19388 tree stmt
= make_node (OMP_TARGET_DATA
);
19389 TREE_TYPE (stmt
) = void_type_node
;
19390 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
19391 keep_next_level ();
19392 tree block
= c_begin_compound_stmt (true);
19393 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19394 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
19396 SET_EXPR_LOCATION (stmt
, loc
);
19397 return add_stmt (stmt
);
19401 # pragma omp target update target-update-clause[optseq] new-line */
19403 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
19404 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
19405 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
19406 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19407 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19408 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19409 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19412 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
19413 enum pragma_context context
)
19415 if (context
== pragma_stmt
)
19417 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
19418 "omp target update");
19419 c_parser_skip_to_pragma_eol (parser
, false);
19424 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
19425 "#pragma omp target update");
19426 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
19427 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
19430 "%<#pragma omp target update%> must contain at least one "
19431 "%<from%> or %<to%> clauses");
19435 tree stmt
= make_node (OMP_TARGET_UPDATE
);
19436 TREE_TYPE (stmt
) = void_type_node
;
19437 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
19438 SET_EXPR_LOCATION (stmt
, loc
);
19444 # pragma omp target enter data target-data-clause[optseq] new-line */
19446 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
19447 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19448 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19449 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19450 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19451 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19454 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
19455 enum pragma_context context
)
19457 bool data_seen
= false;
19458 if (c_parser_next_token_is (parser
, CPP_NAME
))
19460 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19461 if (strcmp (p
, "data") == 0)
19463 c_parser_consume_token (parser
);
19469 c_parser_error (parser
, "expected %<data%>");
19470 c_parser_skip_to_pragma_eol (parser
);
19474 if (context
== pragma_stmt
)
19476 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
19477 "omp target enter data");
19478 c_parser_skip_to_pragma_eol (parser
, false);
19483 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
19484 "#pragma omp target enter data");
19486 for (tree
*pc
= &clauses
; *pc
;)
19488 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
19489 switch (OMP_CLAUSE_MAP_KIND (*pc
))
19492 case GOMP_MAP_ALWAYS_TO
:
19493 case GOMP_MAP_ALLOC
:
19496 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19497 case GOMP_MAP_ALWAYS_POINTER
:
19501 error_at (OMP_CLAUSE_LOCATION (*pc
),
19502 "%<#pragma omp target enter data%> with map-type other "
19503 "than %<to%> or %<alloc%> on %<map%> clause");
19504 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19507 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19514 "%<#pragma omp target enter data%> must contain at least "
19515 "one %<map%> clause");
19519 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
19520 TREE_TYPE (stmt
) = void_type_node
;
19521 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
19522 SET_EXPR_LOCATION (stmt
, loc
);
19528 # pragma omp target exit data target-data-clause[optseq] new-line */
19530 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
19531 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19532 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19533 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19534 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19535 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19538 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
19539 enum pragma_context context
)
19541 bool data_seen
= false;
19542 if (c_parser_next_token_is (parser
, CPP_NAME
))
19544 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19545 if (strcmp (p
, "data") == 0)
19547 c_parser_consume_token (parser
);
19553 c_parser_error (parser
, "expected %<data%>");
19554 c_parser_skip_to_pragma_eol (parser
);
19558 if (context
== pragma_stmt
)
19560 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
19561 "omp target exit data");
19562 c_parser_skip_to_pragma_eol (parser
, false);
19567 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
19568 "#pragma omp target exit data");
19571 for (tree
*pc
= &clauses
; *pc
;)
19573 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
19574 switch (OMP_CLAUSE_MAP_KIND (*pc
))
19576 case GOMP_MAP_FROM
:
19577 case GOMP_MAP_ALWAYS_FROM
:
19578 case GOMP_MAP_RELEASE
:
19579 case GOMP_MAP_DELETE
:
19582 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19583 case GOMP_MAP_ALWAYS_POINTER
:
19587 error_at (OMP_CLAUSE_LOCATION (*pc
),
19588 "%<#pragma omp target exit data%> with map-type other "
19589 "than %<from%>, %<release%> or %<delete%> on %<map%>"
19591 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19594 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19601 "%<#pragma omp target exit data%> must contain at least one "
19606 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
19607 TREE_TYPE (stmt
) = void_type_node
;
19608 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
19609 SET_EXPR_LOCATION (stmt
, loc
);
19615 # pragma omp target target-clause[optseq] new-line
19616 structured-block */
19618 #define OMP_TARGET_CLAUSE_MASK \
19619 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19620 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19621 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19622 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19623 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19624 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19625 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19626 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
19627 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
19630 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
19632 location_t loc
= c_parser_peek_token (parser
)->location
;
19633 c_parser_consume_pragma (parser
);
19634 tree
*pc
= NULL
, stmt
, block
;
19636 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
19638 c_parser_error (parser
, "expected declaration specifiers");
19639 c_parser_skip_to_pragma_eol (parser
);
19645 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
19647 if (c_parser_next_token_is (parser
, CPP_NAME
))
19649 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19650 enum tree_code ccode
= ERROR_MARK
;
19652 if (strcmp (p
, "teams") == 0)
19654 else if (strcmp (p
, "parallel") == 0)
19655 ccode
= OMP_PARALLEL
;
19656 else if (strcmp (p
, "simd") == 0)
19658 if (ccode
!= ERROR_MARK
)
19660 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
19661 char p_name
[sizeof ("#pragma omp target teams distribute "
19662 "parallel for simd")];
19664 c_parser_consume_token (parser
);
19665 strcpy (p_name
, "#pragma omp target");
19666 if (!flag_openmp
) /* flag_openmp_simd */
19672 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
19673 OMP_TARGET_CLAUSE_MASK
,
19677 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
19678 OMP_TARGET_CLAUSE_MASK
,
19682 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
19683 OMP_TARGET_CLAUSE_MASK
,
19687 gcc_unreachable ();
19689 return stmt
!= NULL_TREE
;
19691 keep_next_level ();
19692 tree block
= c_begin_compound_stmt (true), ret
;
19696 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
19697 OMP_TARGET_CLAUSE_MASK
, cclauses
,
19701 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
19702 OMP_TARGET_CLAUSE_MASK
, cclauses
,
19706 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
19707 OMP_TARGET_CLAUSE_MASK
, cclauses
,
19711 gcc_unreachable ();
19713 block
= c_end_compound_stmt (loc
, block
, true);
19714 if (ret
== NULL_TREE
)
19716 if (ccode
== OMP_TEAMS
)
19718 /* For combined target teams, ensure the num_teams and
19719 thread_limit clause expressions are evaluated on the host,
19720 before entering the target construct. */
19722 for (c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19723 c
; c
= OMP_CLAUSE_CHAIN (c
))
19724 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
19725 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
19726 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, 0)) != INTEGER_CST
)
19728 tree expr
= OMP_CLAUSE_OPERAND (c
, 0);
19729 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
19730 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
19731 expr
, NULL_TREE
, NULL_TREE
);
19733 OMP_CLAUSE_OPERAND (c
, 0) = expr
;
19734 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
19735 OMP_CLAUSE_FIRSTPRIVATE
);
19736 OMP_CLAUSE_DECL (tc
) = tmp
;
19737 OMP_CLAUSE_CHAIN (tc
)
19738 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
19739 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
19742 tree stmt
= make_node (OMP_TARGET
);
19743 TREE_TYPE (stmt
) = void_type_node
;
19744 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
19745 OMP_TARGET_BODY (stmt
) = block
;
19746 OMP_TARGET_COMBINED (stmt
) = 1;
19747 SET_EXPR_LOCATION (stmt
, loc
);
19749 pc
= &OMP_TARGET_CLAUSES (stmt
);
19750 goto check_clauses
;
19752 else if (!flag_openmp
) /* flag_openmp_simd */
19754 c_parser_skip_to_pragma_eol (parser
, false);
19757 else if (strcmp (p
, "data") == 0)
19759 c_parser_consume_token (parser
);
19760 c_parser_omp_target_data (loc
, parser
, if_p
);
19763 else if (strcmp (p
, "enter") == 0)
19765 c_parser_consume_token (parser
);
19766 c_parser_omp_target_enter_data (loc
, parser
, context
);
19769 else if (strcmp (p
, "exit") == 0)
19771 c_parser_consume_token (parser
);
19772 c_parser_omp_target_exit_data (loc
, parser
, context
);
19775 else if (strcmp (p
, "update") == 0)
19777 c_parser_consume_token (parser
);
19778 return c_parser_omp_target_update (loc
, parser
, context
);
19781 if (!flag_openmp
) /* flag_openmp_simd */
19783 c_parser_skip_to_pragma_eol (parser
, false);
19787 stmt
= make_node (OMP_TARGET
);
19788 TREE_TYPE (stmt
) = void_type_node
;
19790 OMP_TARGET_CLAUSES (stmt
)
19791 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
19792 "#pragma omp target");
19793 pc
= &OMP_TARGET_CLAUSES (stmt
);
19794 keep_next_level ();
19795 block
= c_begin_compound_stmt (true);
19796 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19797 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
19799 SET_EXPR_LOCATION (stmt
, loc
);
19805 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
19806 switch (OMP_CLAUSE_MAP_KIND (*pc
))
19809 case GOMP_MAP_ALWAYS_TO
:
19810 case GOMP_MAP_FROM
:
19811 case GOMP_MAP_ALWAYS_FROM
:
19812 case GOMP_MAP_TOFROM
:
19813 case GOMP_MAP_ALWAYS_TOFROM
:
19814 case GOMP_MAP_ALLOC
:
19815 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19816 case GOMP_MAP_ALWAYS_POINTER
:
19819 error_at (OMP_CLAUSE_LOCATION (*pc
),
19820 "%<#pragma omp target%> with map-type other "
19821 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19822 "on %<map%> clause");
19823 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19826 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19832 # pragma omp declare simd declare-simd-clauses[optseq] new-line
19835 # pragma omp declare variant (identifier) match(context-selector) new-line
19838 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
19839 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19840 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19841 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19842 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
19843 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
19844 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
19847 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
19849 c_token
*token
= c_parser_peek_token (parser
);
19850 gcc_assert (token
->type
== CPP_NAME
);
19851 tree kind
= token
->value
;
19852 gcc_assert (strcmp (IDENTIFIER_POINTER (kind
), "simd") == 0
19853 || strcmp (IDENTIFIER_POINTER (kind
), "variant") == 0);
19855 auto_vec
<c_token
> clauses
;
19856 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19858 c_token
*token
= c_parser_peek_token (parser
);
19859 if (token
->type
== CPP_EOF
)
19861 c_parser_skip_to_pragma_eol (parser
);
19864 clauses
.safe_push (*token
);
19865 c_parser_consume_token (parser
);
19867 clauses
.safe_push (*c_parser_peek_token (parser
));
19868 c_parser_skip_to_pragma_eol (parser
);
19870 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
19872 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_DECLARE
19873 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
19874 || c_parser_peek_2nd_token (parser
)->value
!= kind
)
19876 error ("%<#pragma omp declare %s%> must be followed by "
19877 "function declaration or definition or another "
19878 "%<#pragma omp declare %s%>",
19879 IDENTIFIER_POINTER (kind
), IDENTIFIER_POINTER (kind
));
19882 c_parser_consume_pragma (parser
);
19883 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19885 c_token
*token
= c_parser_peek_token (parser
);
19886 if (token
->type
== CPP_EOF
)
19888 c_parser_skip_to_pragma_eol (parser
);
19891 clauses
.safe_push (*token
);
19892 c_parser_consume_token (parser
);
19894 clauses
.safe_push (*c_parser_peek_token (parser
));
19895 c_parser_skip_to_pragma_eol (parser
);
19898 /* Make sure nothing tries to read past the end of the tokens. */
19900 memset (&eof_token
, 0, sizeof (eof_token
));
19901 eof_token
.type
= CPP_EOF
;
19902 clauses
.safe_push (eof_token
);
19903 clauses
.safe_push (eof_token
);
19907 case pragma_external
:
19908 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19909 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
19911 int ext
= disable_extension_diagnostics ();
19913 c_parser_consume_token (parser
);
19914 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19915 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
19916 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
19918 restore_extension_diagnostics (ext
);
19921 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
19924 case pragma_struct
:
19927 error ("%<#pragma omp declare %s%> must be followed by "
19928 "function declaration or definition",
19929 IDENTIFIER_POINTER (kind
));
19931 case pragma_compound
:
19932 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19933 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
19935 int ext
= disable_extension_diagnostics ();
19937 c_parser_consume_token (parser
);
19938 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19939 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
19940 if (c_parser_next_tokens_start_declaration (parser
))
19942 c_parser_declaration_or_fndef (parser
, true, true, true, true,
19943 true, NULL
, clauses
);
19944 restore_extension_diagnostics (ext
);
19947 restore_extension_diagnostics (ext
);
19949 else if (c_parser_next_tokens_start_declaration (parser
))
19951 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
19955 error ("%<#pragma omp declare %s%> must be followed by "
19956 "function declaration or definition",
19957 IDENTIFIER_POINTER (kind
));
19960 gcc_unreachable ();
19964 static const char *const omp_construct_selectors
[] = {
19965 "simd", "target", "teams", "parallel", "for", NULL
};
19966 static const char *const omp_device_selectors
[] = {
19967 "kind", "isa", "arch", NULL
};
19968 static const char *const omp_implementation_selectors
[] = {
19969 "vendor", "extension", "atomic_default_mem_order", "unified_address",
19970 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL
};
19971 static const char *const omp_user_selectors
[] = {
19972 "condition", NULL
};
19977 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
19980 score(score-expression) */
19983 c_parser_omp_context_selector (c_parser
*parser
, tree set
, tree parms
)
19985 tree ret
= NULL_TREE
;
19989 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19990 || c_parser_next_token_is (parser
, CPP_NAME
))
19991 selector
= c_parser_peek_token (parser
)->value
;
19994 c_parser_error (parser
, "expected trait selector name");
19995 return error_mark_node
;
19998 tree properties
= NULL_TREE
;
19999 const char *const *selectors
= NULL
;
20000 bool allow_score
= true;
20001 bool allow_user
= false;
20002 int property_limit
= 0;
20003 enum { CTX_PROPERTY_NONE
, CTX_PROPERTY_USER
, CTX_PROPERTY_NAME_LIST
,
20004 CTX_PROPERTY_ID
, CTX_PROPERTY_EXPR
,
20005 CTX_PROPERTY_SIMD
} property_kind
= CTX_PROPERTY_NONE
;
20006 switch (IDENTIFIER_POINTER (set
)[0])
20008 case 'c': /* construct */
20009 selectors
= omp_construct_selectors
;
20010 allow_score
= false;
20011 property_limit
= 1;
20012 property_kind
= CTX_PROPERTY_SIMD
;
20014 case 'd': /* device */
20015 selectors
= omp_device_selectors
;
20016 allow_score
= false;
20018 property_limit
= 3;
20019 property_kind
= CTX_PROPERTY_NAME_LIST
;
20021 case 'i': /* implementation */
20022 selectors
= omp_implementation_selectors
;
20024 property_limit
= 3;
20025 property_kind
= CTX_PROPERTY_NAME_LIST
;
20027 case 'u': /* user */
20028 selectors
= omp_user_selectors
;
20029 property_limit
= 1;
20030 property_kind
= CTX_PROPERTY_EXPR
;
20033 gcc_unreachable ();
20035 for (int i
= 0; ; i
++)
20037 if (selectors
[i
] == NULL
)
20041 property_kind
= CTX_PROPERTY_USER
;
20046 error_at (c_parser_peek_token (parser
)->location
,
20047 "selector %qs not allowed for context selector "
20048 "set %qs", IDENTIFIER_POINTER (selector
),
20049 IDENTIFIER_POINTER (set
));
20050 c_parser_consume_token (parser
);
20051 return error_mark_node
;
20054 if (i
== property_limit
)
20055 property_kind
= CTX_PROPERTY_NONE
;
20056 if (strcmp (selectors
[i
], IDENTIFIER_POINTER (selector
)) == 0)
20059 if (property_kind
== CTX_PROPERTY_NAME_LIST
20060 && IDENTIFIER_POINTER (set
)[0] == 'i'
20061 && strcmp (IDENTIFIER_POINTER (selector
),
20062 "atomic_default_mem_order") == 0)
20063 property_kind
= CTX_PROPERTY_ID
;
20065 c_parser_consume_token (parser
);
20067 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
20069 if (property_kind
== CTX_PROPERTY_NONE
)
20071 error_at (c_parser_peek_token (parser
)->location
,
20072 "selector %qs does not accept any properties",
20073 IDENTIFIER_POINTER (selector
));
20074 return error_mark_node
;
20077 matching_parens parens
;
20078 parens
.require_open (parser
);
20080 c_token
*token
= c_parser_peek_token (parser
);
20082 && c_parser_next_token_is (parser
, CPP_NAME
)
20083 && strcmp (IDENTIFIER_POINTER (token
->value
), "score") == 0
20084 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
20086 c_parser_consume_token (parser
);
20088 matching_parens parens2
;
20089 parens2
.require_open (parser
);
20090 tree score
= c_parser_expr_no_commas (parser
, NULL
).value
;
20091 parens2
.skip_until_found_close (parser
);
20092 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
20093 if (score
!= error_mark_node
)
20095 mark_exp_read (score
);
20096 score
= c_fully_fold (score
, false, NULL
);
20097 if (!INTEGRAL_TYPE_P (TREE_TYPE (score
))
20098 || TREE_CODE (score
) != INTEGER_CST
)
20099 error_at (token
->location
, "score argument must be "
20100 "constant integer expression");
20101 else if (tree_int_cst_sgn (score
) < 0)
20102 error_at (token
->location
, "score argument must be "
20105 properties
= tree_cons (get_identifier (" score"),
20106 score
, properties
);
20108 token
= c_parser_peek_token (parser
);
20111 switch (property_kind
)
20114 case CTX_PROPERTY_USER
:
20117 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
20118 if (TREE_CODE (t
) == STRING_CST
)
20119 properties
= tree_cons (NULL_TREE
, t
, properties
);
20120 else if (t
!= error_mark_node
)
20123 t
= c_fully_fold (t
, false, NULL
);
20124 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
20125 || !tree_fits_shwi_p (t
))
20126 error_at (token
->location
, "property must be "
20127 "constant integer expression or string "
20130 properties
= tree_cons (NULL_TREE
, t
, properties
);
20133 return error_mark_node
;
20135 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20136 c_parser_consume_token (parser
);
20142 case CTX_PROPERTY_ID
:
20143 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20144 || c_parser_next_token_is (parser
, CPP_NAME
))
20146 tree prop
= c_parser_peek_token (parser
)->value
;
20147 c_parser_consume_token (parser
);
20148 properties
= tree_cons (prop
, NULL_TREE
, properties
);
20152 c_parser_error (parser
, "expected identifier");
20153 return error_mark_node
;
20156 case CTX_PROPERTY_NAME_LIST
:
20159 tree prop
= NULL_TREE
, value
= NULL_TREE
;
20160 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20161 || c_parser_next_token_is (parser
, CPP_NAME
))
20163 prop
= c_parser_peek_token (parser
)->value
;
20164 c_parser_consume_token (parser
);
20166 else if (c_parser_next_token_is (parser
, CPP_STRING
))
20167 value
= c_parser_string_literal (parser
, false,
20171 c_parser_error (parser
, "expected identifier or "
20173 return error_mark_node
;
20176 properties
= tree_cons (prop
, value
, properties
);
20178 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20179 c_parser_consume_token (parser
);
20185 case CTX_PROPERTY_EXPR
:
20186 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
20187 if (t
!= error_mark_node
)
20190 t
= c_fully_fold (t
, false, NULL
);
20191 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
20192 || !tree_fits_shwi_p (t
))
20193 error_at (token
->location
, "property must be "
20194 "constant integer expression");
20196 properties
= tree_cons (NULL_TREE
, t
, properties
);
20199 return error_mark_node
;
20201 case CTX_PROPERTY_SIMD
:
20202 if (parms
== NULL_TREE
)
20204 error_at (token
->location
, "properties for %<simd%> "
20205 "selector may not be specified in "
20206 "%<metadirective%>");
20207 return error_mark_node
;
20210 c
= c_parser_omp_all_clauses (parser
,
20211 OMP_DECLARE_SIMD_CLAUSE_MASK
,
20213 c
= c_omp_declare_simd_clauses_to_numbers (parms
20215 ? NULL_TREE
: parms
,
20220 gcc_unreachable ();
20223 parens
.skip_until_found_close (parser
);
20224 properties
= nreverse (properties
);
20226 else if (property_kind
== CTX_PROPERTY_NAME_LIST
20227 || property_kind
== CTX_PROPERTY_ID
20228 || property_kind
== CTX_PROPERTY_EXPR
)
20230 c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>");
20231 return error_mark_node
;
20234 ret
= tree_cons (selector
, properties
, ret
);
20236 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20237 c_parser_consume_token (parser
);
20243 return nreverse (ret
);
20248 trait-set-selector[,trait-set-selector[,...]]
20250 trait-set-selector:
20251 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
20253 trait-set-selector-name:
20260 c_parser_omp_context_selector_specification (c_parser
*parser
, tree parms
)
20262 tree ret
= NULL_TREE
;
20265 const char *setp
= "";
20266 if (c_parser_next_token_is (parser
, CPP_NAME
))
20267 setp
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20271 if (strcmp (setp
, "construct") == 0)
20275 if (strcmp (setp
, "device") == 0)
20279 if (strcmp (setp
, "implementation") == 0)
20283 if (strcmp (setp
, "user") == 0)
20291 c_parser_error (parser
, "expected %<construct%>, %<device%>, "
20292 "%<implementation%> or %<user%>");
20293 return error_mark_node
;
20296 tree set
= c_parser_peek_token (parser
)->value
;
20297 c_parser_consume_token (parser
);
20299 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
20300 return error_mark_node
;
20302 matching_braces braces
;
20303 if (!braces
.require_open (parser
))
20304 return error_mark_node
;
20306 tree selectors
= c_parser_omp_context_selector (parser
, set
, parms
);
20307 if (selectors
== error_mark_node
)
20308 ret
= error_mark_node
;
20309 else if (ret
!= error_mark_node
)
20310 ret
= tree_cons (set
, selectors
, ret
);
20312 braces
.skip_until_found_close (parser
);
20314 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20315 c_parser_consume_token (parser
);
20321 if (ret
== error_mark_node
)
20323 return nreverse (ret
);
20326 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
20327 that into "omp declare variant base" attribute. */
20330 c_finish_omp_declare_variant (c_parser
*parser
, tree fndecl
, tree parms
)
20332 matching_parens parens
;
20333 if (!parens
.require_open (parser
))
20336 c_parser_skip_to_pragma_eol (parser
, false);
20340 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
20341 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
20343 c_parser_error (parser
, "expected identifier");
20347 c_token
*token
= c_parser_peek_token (parser
);
20348 tree variant
= lookup_name (token
->value
);
20350 if (variant
== NULL_TREE
)
20352 undeclared_variable (token
->location
, token
->value
);
20353 variant
= error_mark_node
;
20356 c_parser_consume_token (parser
);
20358 parens
.require_close (parser
);
20360 const char *clause
= "";
20361 location_t match_loc
= c_parser_peek_token (parser
)->location
;
20362 if (c_parser_next_token_is (parser
, CPP_NAME
))
20363 clause
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20364 if (strcmp (clause
, "match"))
20366 c_parser_error (parser
, "expected %<match%>");
20370 c_parser_consume_token (parser
);
20372 if (!parens
.require_open (parser
))
20375 if (parms
== NULL_TREE
)
20376 parms
= error_mark_node
;
20378 tree ctx
= c_parser_omp_context_selector_specification (parser
, parms
);
20379 if (ctx
== error_mark_node
)
20381 ctx
= c_omp_check_context_selector (match_loc
, ctx
);
20382 if (ctx
!= error_mark_node
&& variant
!= error_mark_node
)
20384 if (TREE_CODE (variant
) != FUNCTION_DECL
)
20386 error_at (token
->location
, "variant %qD is not a function", variant
);
20387 variant
= error_mark_node
;
20389 else if (omp_get_context_selector (ctx
, "construct", "simd") == NULL_TREE
20390 && !comptypes (TREE_TYPE (fndecl
), TREE_TYPE (variant
)))
20392 error_at (token
->location
, "variant %qD and base %qD have "
20393 "incompatible types", variant
, fndecl
);
20394 variant
= error_mark_node
;
20396 else if (fndecl_built_in_p (variant
)
20397 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
20398 "__builtin_", strlen ("__builtin_")) == 0
20399 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
20400 "__sync_", strlen ("__sync_")) == 0
20401 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
20402 "__atomic_", strlen ("__atomic_")) == 0))
20404 error_at (token
->location
, "variant %qD is a built-in", variant
);
20405 variant
= error_mark_node
;
20407 if (variant
!= error_mark_node
)
20409 C_DECL_USED (variant
) = 1;
20410 tree construct
= omp_get_context_selector (ctx
, "construct", NULL
);
20411 c_omp_mark_declare_variant (match_loc
, variant
, construct
);
20412 if (omp_context_selector_matches (ctx
))
20415 = tree_cons (get_identifier ("omp declare variant base"),
20416 build_tree_list (variant
, ctx
),
20417 DECL_ATTRIBUTES (fndecl
));
20418 DECL_ATTRIBUTES (fndecl
) = attr
;
20423 parens
.require_close (parser
);
20424 c_parser_skip_to_pragma_eol (parser
);
20427 /* Finalize #pragma omp declare simd or #pragma omp declare variant
20428 clauses after FNDECL has been parsed, and put that into "omp declare simd"
20429 or "omp declare variant base" attribute. */
20432 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
20433 vec
<c_token
> clauses
)
20435 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
20436 indicates error has been reported and CPP_PRAGMA that
20437 c_finish_omp_declare_simd has already processed the tokens. */
20438 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
20440 const char *kind
= "simd";
20441 if (clauses
.exists ()
20442 && (clauses
[0].type
== CPP_NAME
|| clauses
[0].type
== CPP_PRAGMA
))
20443 kind
= IDENTIFIER_POINTER (clauses
[0].value
);
20444 gcc_assert (strcmp (kind
, "simd") == 0 || strcmp (kind
, "variant") == 0);
20445 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
20447 error ("%<#pragma omp declare %s%> not immediately followed by "
20448 "a function declaration or definition", kind
);
20449 clauses
[0].type
= CPP_EOF
;
20452 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
20454 error_at (DECL_SOURCE_LOCATION (fndecl
),
20455 "%<#pragma omp declare %s%> not immediately followed by "
20456 "a single function declaration or definition", kind
);
20457 clauses
[0].type
= CPP_EOF
;
20461 if (parms
== NULL_TREE
)
20462 parms
= DECL_ARGUMENTS (fndecl
);
20464 unsigned int tokens_avail
= parser
->tokens_avail
;
20465 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
20467 parser
->tokens
= clauses
.address ();
20468 parser
->tokens_avail
= clauses
.length ();
20470 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
20471 while (parser
->tokens_avail
> 3)
20473 c_token
*token
= c_parser_peek_token (parser
);
20474 gcc_assert (token
->type
== CPP_NAME
20475 && strcmp (IDENTIFIER_POINTER (token
->value
), kind
) == 0);
20476 c_parser_consume_token (parser
);
20477 parser
->in_pragma
= true;
20479 if (strcmp (kind
, "simd") == 0)
20482 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
20483 "#pragma omp declare simd");
20484 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
20485 if (c
!= NULL_TREE
)
20486 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
20487 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
20488 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
20489 DECL_ATTRIBUTES (fndecl
) = c
;
20493 gcc_assert (strcmp (kind
, "variant") == 0);
20494 c_finish_omp_declare_variant (parser
, fndecl
, parms
);
20498 parser
->tokens
= &parser
->tokens_buf
[0];
20499 parser
->tokens_avail
= tokens_avail
;
20500 if (clauses
.exists ())
20501 clauses
[0].type
= CPP_PRAGMA
;
20506 # pragma omp declare target new-line
20507 declarations and definitions
20508 # pragma omp end declare target new-line
20511 # pragma omp declare target ( extended-list ) new-line
20513 # pragma omp declare target declare-target-clauses[seq] new-line */
20515 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
20516 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
20517 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
20518 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
20521 c_parser_omp_declare_target (c_parser
*parser
)
20523 tree clauses
= NULL_TREE
;
20524 int device_type
= 0;
20525 bool only_device_type
= true;
20526 if (c_parser_next_token_is (parser
, CPP_NAME
))
20527 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
20528 "#pragma omp declare target");
20529 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
20531 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO_DECLARE
,
20533 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
20534 c_parser_skip_to_pragma_eol (parser
);
20538 c_parser_skip_to_pragma_eol (parser
);
20539 current_omp_declare_target_attribute
++;
20542 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
20543 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
20544 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
20545 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
20547 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
20549 tree t
= OMP_CLAUSE_DECL (c
), id
;
20550 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
20551 tree at2
= lookup_attribute ("omp declare target link",
20552 DECL_ATTRIBUTES (t
));
20553 only_device_type
= false;
20554 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
20556 id
= get_identifier ("omp declare target link");
20557 std::swap (at1
, at2
);
20560 id
= get_identifier ("omp declare target");
20563 error_at (OMP_CLAUSE_LOCATION (c
),
20564 "%qD specified both in declare target %<link%> and %<to%>"
20570 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
20571 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
20574 symtab_node
*node
= symtab_node::get (t
);
20577 node
->offloadable
= 1;
20578 if (ENABLE_OFFLOADING
)
20580 g
->have_offload
= true;
20581 if (is_a
<varpool_node
*> (node
))
20582 vec_safe_push (offload_vars
, t
);
20586 if (TREE_CODE (t
) != FUNCTION_DECL
)
20588 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_HOST
) != 0)
20590 tree at3
= lookup_attribute ("omp declare target host",
20591 DECL_ATTRIBUTES (t
));
20592 if (at3
== NULL_TREE
)
20594 id
= get_identifier ("omp declare target host");
20595 DECL_ATTRIBUTES (t
)
20596 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
20599 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_NOHOST
) != 0)
20601 tree at3
= lookup_attribute ("omp declare target nohost",
20602 DECL_ATTRIBUTES (t
));
20603 if (at3
== NULL_TREE
)
20605 id
= get_identifier ("omp declare target nohost");
20606 DECL_ATTRIBUTES (t
)
20607 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
20611 if (device_type
&& only_device_type
)
20612 warning_at (OMP_CLAUSE_LOCATION (clauses
), 0,
20613 "directive with only %<device_type%> clauses ignored");
20617 c_parser_omp_end_declare_target (c_parser
*parser
)
20619 location_t loc
= c_parser_peek_token (parser
)->location
;
20620 c_parser_consume_pragma (parser
);
20621 if (c_parser_next_token_is (parser
, CPP_NAME
)
20622 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
20625 c_parser_consume_token (parser
);
20626 if (c_parser_next_token_is (parser
, CPP_NAME
)
20627 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
20629 c_parser_consume_token (parser
);
20632 c_parser_error (parser
, "expected %<target%>");
20633 c_parser_skip_to_pragma_eol (parser
);
20639 c_parser_error (parser
, "expected %<declare%>");
20640 c_parser_skip_to_pragma_eol (parser
);
20643 c_parser_skip_to_pragma_eol (parser
);
20644 if (!current_omp_declare_target_attribute
)
20645 error_at (loc
, "%<#pragma omp end declare target%> without corresponding "
20646 "%<#pragma omp declare target%>");
20648 current_omp_declare_target_attribute
--;
20653 #pragma omp declare reduction (reduction-id : typename-list : expression) \
20654 initializer-clause[opt] new-line
20656 initializer-clause:
20657 initializer (omp_priv = initializer)
20658 initializer (function-name (argument-list)) */
20661 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
20663 unsigned int tokens_avail
= 0, i
;
20664 vec
<tree
> types
= vNULL
;
20665 vec
<c_token
> clauses
= vNULL
;
20666 enum tree_code reduc_code
= ERROR_MARK
;
20667 tree reduc_id
= NULL_TREE
;
20669 location_t rloc
= c_parser_peek_token (parser
)->location
;
20671 if (context
== pragma_struct
|| context
== pragma_param
)
20673 error ("%<#pragma omp declare reduction%> not at file or block scope");
20677 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
20680 switch (c_parser_peek_token (parser
)->type
)
20683 reduc_code
= PLUS_EXPR
;
20686 reduc_code
= MULT_EXPR
;
20689 reduc_code
= MINUS_EXPR
;
20692 reduc_code
= BIT_AND_EXPR
;
20695 reduc_code
= BIT_XOR_EXPR
;
20698 reduc_code
= BIT_IOR_EXPR
;
20701 reduc_code
= TRUTH_ANDIF_EXPR
;
20704 reduc_code
= TRUTH_ORIF_EXPR
;
20708 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20709 if (strcmp (p
, "min") == 0)
20711 reduc_code
= MIN_EXPR
;
20714 if (strcmp (p
, "max") == 0)
20716 reduc_code
= MAX_EXPR
;
20719 reduc_id
= c_parser_peek_token (parser
)->value
;
20722 c_parser_error (parser
,
20723 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
20724 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
20728 tree orig_reduc_id
, reduc_decl
;
20729 orig_reduc_id
= reduc_id
;
20730 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
20731 reduc_decl
= c_omp_reduction_decl (reduc_id
);
20732 c_parser_consume_token (parser
);
20734 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
20739 location_t loc
= c_parser_peek_token (parser
)->location
;
20740 struct c_type_name
*ctype
= c_parser_type_name (parser
);
20743 type
= groktypename (ctype
, NULL
, NULL
);
20744 if (type
== error_mark_node
)
20746 else if ((INTEGRAL_TYPE_P (type
)
20747 || TREE_CODE (type
) == REAL_TYPE
20748 || TREE_CODE (type
) == COMPLEX_TYPE
)
20749 && orig_reduc_id
== NULL_TREE
)
20750 error_at (loc
, "predeclared arithmetic type in "
20751 "%<#pragma omp declare reduction%>");
20752 else if (TREE_CODE (type
) == FUNCTION_TYPE
20753 || TREE_CODE (type
) == ARRAY_TYPE
)
20754 error_at (loc
, "function or array type in "
20755 "%<#pragma omp declare reduction%>");
20756 else if (TYPE_ATOMIC (type
))
20757 error_at (loc
, "%<_Atomic%> qualified type in "
20758 "%<#pragma omp declare reduction%>");
20759 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
20760 error_at (loc
, "const, volatile or restrict qualified type in "
20761 "%<#pragma omp declare reduction%>");
20765 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
20766 if (comptypes (TREE_PURPOSE (t
), type
))
20768 error_at (loc
, "redeclaration of %qs "
20769 "%<#pragma omp declare reduction%> for "
20771 IDENTIFIER_POINTER (reduc_id
)
20772 + sizeof ("omp declare reduction ") - 1,
20775 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
20777 error_at (ploc
, "previous %<#pragma omp declare "
20781 if (t
== NULL_TREE
)
20782 types
.safe_push (type
);
20784 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20785 c_parser_consume_token (parser
);
20793 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
20794 || types
.is_empty ())
20797 clauses
.release ();
20801 c_token
*token
= c_parser_peek_token (parser
);
20802 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
20804 c_parser_consume_token (parser
);
20806 c_parser_skip_to_pragma_eol (parser
);
20810 if (types
.length () > 1)
20812 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
20814 c_token
*token
= c_parser_peek_token (parser
);
20815 if (token
->type
== CPP_EOF
)
20817 clauses
.safe_push (*token
);
20818 c_parser_consume_token (parser
);
20820 clauses
.safe_push (*c_parser_peek_token (parser
));
20821 c_parser_skip_to_pragma_eol (parser
);
20823 /* Make sure nothing tries to read past the end of the tokens. */
20825 memset (&eof_token
, 0, sizeof (eof_token
));
20826 eof_token
.type
= CPP_EOF
;
20827 clauses
.safe_push (eof_token
);
20828 clauses
.safe_push (eof_token
);
20831 int errs
= errorcount
;
20832 FOR_EACH_VEC_ELT (types
, i
, type
)
20834 tokens_avail
= parser
->tokens_avail
;
20835 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
20836 if (!clauses
.is_empty ())
20838 parser
->tokens
= clauses
.address ();
20839 parser
->tokens_avail
= clauses
.length ();
20840 parser
->in_pragma
= true;
20843 bool nested
= current_function_decl
!= NULL_TREE
;
20845 c_push_function_context ();
20846 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
20847 reduc_id
, default_function_type
);
20848 current_function_decl
= fndecl
;
20849 allocate_struct_function (fndecl
, true);
20851 tree stmt
= push_stmt_list ();
20852 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
20853 warn about these. */
20854 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20855 get_identifier ("omp_out"), type
);
20856 DECL_ARTIFICIAL (omp_out
) = 1;
20857 DECL_CONTEXT (omp_out
) = fndecl
;
20858 pushdecl (omp_out
);
20859 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20860 get_identifier ("omp_in"), type
);
20861 DECL_ARTIFICIAL (omp_in
) = 1;
20862 DECL_CONTEXT (omp_in
) = fndecl
;
20864 struct c_expr combiner
= c_parser_expression (parser
);
20865 struct c_expr initializer
;
20866 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
20868 initializer
.set_error ();
20869 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
20871 else if (c_parser_next_token_is (parser
, CPP_NAME
)
20872 && strcmp (IDENTIFIER_POINTER
20873 (c_parser_peek_token (parser
)->value
),
20874 "initializer") == 0)
20876 c_parser_consume_token (parser
);
20879 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20880 get_identifier ("omp_priv"), type
);
20881 DECL_ARTIFICIAL (omp_priv
) = 1;
20882 DECL_INITIAL (omp_priv
) = error_mark_node
;
20883 DECL_CONTEXT (omp_priv
) = fndecl
;
20884 pushdecl (omp_priv
);
20885 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20886 get_identifier ("omp_orig"), type
);
20887 DECL_ARTIFICIAL (omp_orig
) = 1;
20888 DECL_CONTEXT (omp_orig
) = fndecl
;
20889 pushdecl (omp_orig
);
20890 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
20892 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
20894 c_parser_error (parser
, "expected %<omp_priv%> or "
20898 else if (strcmp (IDENTIFIER_POINTER
20899 (c_parser_peek_token (parser
)->value
),
20902 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
20903 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
20905 c_parser_error (parser
, "expected function-name %<(%>");
20909 initializer
= c_parser_postfix_expression (parser
);
20910 if (initializer
.value
20911 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
20914 tree c
= initializer
.value
;
20915 for (j
= 0; j
< call_expr_nargs (c
); j
++)
20917 tree a
= CALL_EXPR_ARG (c
, j
);
20919 if (TREE_CODE (a
) == ADDR_EXPR
20920 && TREE_OPERAND (a
, 0) == omp_priv
)
20923 if (j
== call_expr_nargs (c
))
20924 error ("one of the initializer call arguments should be "
20930 c_parser_consume_token (parser
);
20931 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
20935 tree st
= push_stmt_list ();
20936 location_t loc
= c_parser_peek_token (parser
)->location
;
20937 rich_location
richloc (line_table
, loc
);
20938 start_init (omp_priv
, NULL_TREE
, 0, &richloc
);
20939 struct c_expr init
= c_parser_initializer (parser
);
20941 finish_decl (omp_priv
, loc
, init
.value
,
20942 init
.original_type
, NULL_TREE
);
20943 pop_stmt_list (st
);
20947 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
20953 c_parser_skip_to_pragma_eol (parser
);
20955 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
20956 DECL_INITIAL (reduc_decl
));
20957 DECL_INITIAL (reduc_decl
) = t
;
20958 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
20959 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
20960 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
20961 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
20962 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
20963 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
20966 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
20967 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
20968 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
20969 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
20970 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
20971 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
20972 walk_tree (&DECL_INITIAL (omp_priv
),
20973 c_check_omp_declare_reduction_r
,
20974 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
20978 pop_stmt_list (stmt
);
20980 if (cfun
->language
!= NULL
)
20982 ggc_free (cfun
->language
);
20983 cfun
->language
= NULL
;
20986 current_function_decl
= NULL_TREE
;
20988 c_pop_function_context ();
20990 if (!clauses
.is_empty ())
20992 parser
->tokens
= &parser
->tokens_buf
[0];
20993 parser
->tokens_avail
= tokens_avail
;
20997 if (errs
!= errorcount
)
21001 clauses
.release ();
21007 #pragma omp declare simd declare-simd-clauses[optseq] new-line
21008 #pragma omp declare reduction (reduction-id : typename-list : expression) \
21009 initializer-clause[opt] new-line
21010 #pragma omp declare target new-line
21013 #pragma omp declare variant (identifier) match (context-selector) */
21016 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
21018 c_parser_consume_pragma (parser
);
21019 if (c_parser_next_token_is (parser
, CPP_NAME
))
21021 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21022 if (strcmp (p
, "simd") == 0)
21024 /* c_parser_consume_token (parser); done in
21025 c_parser_omp_declare_simd. */
21026 c_parser_omp_declare_simd (parser
, context
);
21029 if (strcmp (p
, "reduction") == 0)
21031 c_parser_consume_token (parser
);
21032 c_parser_omp_declare_reduction (parser
, context
);
21035 if (!flag_openmp
) /* flag_openmp_simd */
21037 c_parser_skip_to_pragma_eol (parser
, false);
21040 if (strcmp (p
, "target") == 0)
21042 c_parser_consume_token (parser
);
21043 c_parser_omp_declare_target (parser
);
21046 if (strcmp (p
, "variant") == 0)
21048 /* c_parser_consume_token (parser); done in
21049 c_parser_omp_declare_simd. */
21050 c_parser_omp_declare_simd (parser
, context
);
21055 c_parser_error (parser
, "expected %<simd%>, %<reduction%>, "
21056 "%<target%> or %<variant%>");
21057 c_parser_skip_to_pragma_eol (parser
);
21061 #pragma omp requires clauses[optseq] new-line */
21064 c_parser_omp_requires (c_parser
*parser
)
21067 enum omp_requires new_req
= (enum omp_requires
) 0;
21069 c_parser_consume_pragma (parser
);
21071 location_t loc
= c_parser_peek_token (parser
)->location
;
21072 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21074 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
21075 c_parser_consume_token (parser
);
21079 if (c_parser_next_token_is (parser
, CPP_NAME
))
21082 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21083 location_t cloc
= c_parser_peek_token (parser
)->location
;
21084 enum omp_requires this_req
= (enum omp_requires
) 0;
21086 if (!strcmp (p
, "unified_address"))
21087 this_req
= OMP_REQUIRES_UNIFIED_ADDRESS
;
21088 else if (!strcmp (p
, "unified_shared_memory"))
21089 this_req
= OMP_REQUIRES_UNIFIED_SHARED_MEMORY
;
21090 else if (!strcmp (p
, "dynamic_allocators"))
21091 this_req
= OMP_REQUIRES_DYNAMIC_ALLOCATORS
;
21092 else if (!strcmp (p
, "reverse_offload"))
21093 this_req
= OMP_REQUIRES_REVERSE_OFFLOAD
;
21094 else if (!strcmp (p
, "atomic_default_mem_order"))
21096 c_parser_consume_token (parser
);
21098 matching_parens parens
;
21099 if (parens
.require_open (parser
))
21101 if (c_parser_next_token_is (parser
, CPP_NAME
))
21103 tree v
= c_parser_peek_token (parser
)->value
;
21104 p
= IDENTIFIER_POINTER (v
);
21106 if (!strcmp (p
, "seq_cst"))
21108 = (enum omp_requires
) OMP_MEMORY_ORDER_SEQ_CST
;
21109 else if (!strcmp (p
, "relaxed"))
21111 = (enum omp_requires
) OMP_MEMORY_ORDER_RELAXED
;
21112 else if (!strcmp (p
, "acq_rel"))
21114 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQ_REL
;
21118 error_at (c_parser_peek_token (parser
)->location
,
21119 "expected %<seq_cst%>, %<relaxed%> or "
21121 if (c_parser_peek_2nd_token (parser
)->type
21122 == CPP_CLOSE_PAREN
)
21123 c_parser_consume_token (parser
);
21126 c_parser_consume_token (parser
);
21128 parens
.skip_until_found_close (parser
);
21131 c_parser_skip_to_pragma_eol (parser
, false);
21139 error_at (cloc
, "expected %<unified_address%>, "
21140 "%<unified_shared_memory%>, "
21141 "%<dynamic_allocators%>, "
21142 "%<reverse_offload%> "
21143 "or %<atomic_default_mem_order%> clause");
21144 c_parser_skip_to_pragma_eol (parser
, false);
21148 sorry_at (cloc
, "%qs clause on %<requires%> directive not "
21149 "supported yet", p
);
21151 c_parser_consume_token (parser
);
21154 if ((this_req
& ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
21156 if ((this_req
& new_req
) != 0)
21157 error_at (cloc
, "too many %qs clauses", p
);
21158 if (this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
21159 && (omp_requires_mask
& OMP_REQUIRES_TARGET_USED
) != 0)
21160 error_at (cloc
, "%qs clause used lexically after first "
21161 "target construct or offloading API", p
);
21163 else if ((new_req
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
21165 error_at (cloc
, "too many %qs clauses",
21166 "atomic_default_mem_order");
21167 this_req
= (enum omp_requires
) 0;
21169 else if ((omp_requires_mask
21170 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
21172 error_at (cloc
, "more than one %<atomic_default_mem_order%>"
21173 " clause in a single compilation unit");
21175 = (enum omp_requires
)
21177 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
);
21179 else if ((omp_requires_mask
21180 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
) != 0)
21181 error_at (cloc
, "%<atomic_default_mem_order%> clause used "
21182 "lexically after first %<atomic%> construct "
21183 "without memory order clause");
21184 new_req
= (enum omp_requires
) (new_req
| this_req
);
21186 = (enum omp_requires
) (omp_requires_mask
| this_req
);
21192 c_parser_skip_to_pragma_eol (parser
);
21195 error_at (loc
, "%<pragma omp requires%> requires at least one clause");
21198 /* Helper function for c_parser_omp_taskloop.
21199 Disallow zero sized or potentially zero sized task reductions. */
21202 c_finish_taskloop_clauses (tree clauses
)
21204 tree
*pc
= &clauses
;
21205 for (tree c
= clauses
; c
; c
= *pc
)
21207 bool remove
= false;
21208 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
21210 tree type
= strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
21211 if (integer_zerop (TYPE_SIZE_UNIT (type
)))
21213 error_at (OMP_CLAUSE_LOCATION (c
),
21214 "zero sized type %qT in %<reduction%> clause", type
);
21217 else if (TREE_CODE (TYPE_SIZE_UNIT (type
)) != INTEGER_CST
)
21219 error_at (OMP_CLAUSE_LOCATION (c
),
21220 "variable sized type %qT in %<reduction%> clause",
21226 *pc
= OMP_CLAUSE_CHAIN (c
);
21228 pc
= &OMP_CLAUSE_CHAIN (c
);
21234 #pragma omp taskloop taskloop-clause[optseq] new-line
21237 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
21240 #define OMP_TASKLOOP_CLAUSE_MASK \
21241 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21242 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21243 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21244 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
21245 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
21246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
21247 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
21248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
21249 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
21250 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21251 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
21252 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
21253 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
21254 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
21255 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21256 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
21259 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
21260 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
21263 tree clauses
, block
, ret
;
21265 strcat (p_name
, " taskloop");
21266 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
21267 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
21269 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
)) != 0)
21270 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_IN_REDUCTION
);
21272 if (c_parser_next_token_is (parser
, CPP_NAME
))
21274 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21276 if (strcmp (p
, "simd") == 0)
21278 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
21279 if (cclauses
== NULL
)
21280 cclauses
= cclauses_buf
;
21281 c_parser_consume_token (parser
);
21282 if (!flag_openmp
) /* flag_openmp_simd */
21283 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
21285 block
= c_begin_compound_stmt (true);
21286 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
21287 block
= c_end_compound_stmt (loc
, block
, true);
21290 ret
= make_node (OMP_TASKLOOP
);
21291 TREE_TYPE (ret
) = void_type_node
;
21292 OMP_FOR_BODY (ret
) = block
;
21293 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
21294 OMP_FOR_CLAUSES (ret
)
21295 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret
));
21296 SET_EXPR_LOCATION (ret
, loc
);
21301 if (!flag_openmp
) /* flag_openmp_simd */
21303 c_parser_skip_to_pragma_eol (parser
, false);
21307 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
21310 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
21311 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
21314 clauses
= c_finish_taskloop_clauses (clauses
);
21315 block
= c_begin_compound_stmt (true);
21316 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
21317 block
= c_end_compound_stmt (loc
, block
, true);
21323 /* Main entry point to parsing most OpenMP pragmas. */
21326 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
21328 enum pragma_kind p_kind
;
21331 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
21332 omp_clause_mask
mask (0);
21334 loc
= c_parser_peek_token (parser
)->location
;
21335 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
21336 c_parser_consume_pragma (parser
);
21340 case PRAGMA_OACC_ATOMIC
:
21341 c_parser_omp_atomic (loc
, parser
);
21343 case PRAGMA_OACC_CACHE
:
21344 strcpy (p_name
, "#pragma acc");
21345 stmt
= c_parser_oacc_cache (loc
, parser
);
21347 case PRAGMA_OACC_DATA
:
21348 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
21350 case PRAGMA_OACC_HOST_DATA
:
21351 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
21353 case PRAGMA_OACC_KERNELS
:
21354 case PRAGMA_OACC_PARALLEL
:
21355 case PRAGMA_OACC_SERIAL
:
21356 strcpy (p_name
, "#pragma acc");
21357 stmt
= c_parser_oacc_compute (loc
, parser
, p_kind
, p_name
, if_p
);
21359 case PRAGMA_OACC_LOOP
:
21360 strcpy (p_name
, "#pragma acc");
21361 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21363 case PRAGMA_OACC_WAIT
:
21364 strcpy (p_name
, "#pragma wait");
21365 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
21367 case PRAGMA_OMP_ATOMIC
:
21368 c_parser_omp_atomic (loc
, parser
);
21370 case PRAGMA_OMP_CRITICAL
:
21371 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
21373 case PRAGMA_OMP_DISTRIBUTE
:
21374 strcpy (p_name
, "#pragma omp");
21375 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21377 case PRAGMA_OMP_FOR
:
21378 strcpy (p_name
, "#pragma omp");
21379 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21381 case PRAGMA_OMP_LOOP
:
21382 strcpy (p_name
, "#pragma omp");
21383 stmt
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21385 case PRAGMA_OMP_MASTER
:
21386 strcpy (p_name
, "#pragma omp");
21387 stmt
= c_parser_omp_master (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21389 case PRAGMA_OMP_PARALLEL
:
21390 strcpy (p_name
, "#pragma omp");
21391 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21393 case PRAGMA_OMP_SECTIONS
:
21394 strcpy (p_name
, "#pragma omp");
21395 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
21397 case PRAGMA_OMP_SIMD
:
21398 strcpy (p_name
, "#pragma omp");
21399 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21401 case PRAGMA_OMP_SINGLE
:
21402 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
21404 case PRAGMA_OMP_TASK
:
21405 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
21407 case PRAGMA_OMP_TASKGROUP
:
21408 stmt
= c_parser_omp_taskgroup (loc
, parser
, if_p
);
21410 case PRAGMA_OMP_TASKLOOP
:
21411 strcpy (p_name
, "#pragma omp");
21412 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21414 case PRAGMA_OMP_TEAMS
:
21415 strcpy (p_name
, "#pragma omp");
21416 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21419 gcc_unreachable ();
21423 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
21428 # pragma omp threadprivate (variable-list) */
21431 c_parser_omp_threadprivate (c_parser
*parser
)
21436 c_parser_consume_pragma (parser
);
21437 loc
= c_parser_peek_token (parser
)->location
;
21438 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
21440 /* Mark every variable in VARS to be assigned thread local storage. */
21441 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
21443 tree v
= TREE_PURPOSE (t
);
21445 /* FIXME diagnostics: Ideally we should keep individual
21446 locations for all the variables in the var list to make the
21447 following errors more precise. Perhaps
21448 c_parser_omp_var_list_parens() should construct a list of
21449 locations to go along with the var list. */
21451 /* If V had already been marked threadprivate, it doesn't matter
21452 whether it had been used prior to this point. */
21454 error_at (loc
, "%qD is not a variable", v
);
21455 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
21456 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
21457 else if (! is_global_var (v
))
21458 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
21459 else if (TREE_TYPE (v
) == error_mark_node
)
21461 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
21462 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
21465 if (! DECL_THREAD_LOCAL_P (v
))
21467 set_decl_tls_model (v
, decl_default_tls_model (v
));
21468 /* If rtl has been already set for this var, call
21469 make_decl_rtl once again, so that encode_section_info
21470 has a chance to look at the new decl flags. */
21471 if (DECL_RTL_SET_P (v
))
21474 C_DECL_THREADPRIVATE_P (v
) = 1;
21478 c_parser_skip_to_pragma_eol (parser
);
21481 /* Parse a transaction attribute (GCC Extension).
21483 transaction-attribute:
21485 attribute-specifier
21489 c_parser_transaction_attributes (c_parser
*parser
)
21491 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
21492 return c_parser_gnu_attributes (parser
);
21494 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
21496 return c_parser_std_attribute_specifier (parser
, true);
21499 /* Parse a __transaction_atomic or __transaction_relaxed statement
21502 transaction-statement:
21503 __transaction_atomic transaction-attribute[opt] compound-statement
21504 __transaction_relaxed compound-statement
21506 Note that the only valid attribute is: "outer".
21510 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
21512 unsigned int old_in
= parser
->in_transaction
;
21513 unsigned int this_in
= 1, new_in
;
21514 location_t loc
= c_parser_peek_token (parser
)->location
;
21517 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
21518 || keyword
== RID_TRANSACTION_RELAXED
)
21519 && c_parser_next_token_is_keyword (parser
, keyword
));
21520 c_parser_consume_token (parser
);
21522 if (keyword
== RID_TRANSACTION_RELAXED
)
21523 this_in
|= TM_STMT_ATTR_RELAXED
;
21526 attrs
= c_parser_transaction_attributes (parser
);
21528 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
21531 /* Keep track if we're in the lexical scope of an outer transaction. */
21532 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
21534 parser
->in_transaction
= new_in
;
21535 stmt
= c_parser_compound_statement (parser
);
21536 parser
->in_transaction
= old_in
;
21539 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
21541 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
21542 "%<__transaction_atomic%> without transactional memory support enabled"
21543 : "%<__transaction_relaxed %> "
21544 "without transactional memory support enabled"));
21549 /* Parse a __transaction_atomic or __transaction_relaxed expression
21552 transaction-expression:
21553 __transaction_atomic ( expression )
21554 __transaction_relaxed ( expression )
21557 static struct c_expr
21558 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
21561 unsigned int old_in
= parser
->in_transaction
;
21562 unsigned int this_in
= 1;
21563 location_t loc
= c_parser_peek_token (parser
)->location
;
21566 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
21567 || keyword
== RID_TRANSACTION_RELAXED
)
21568 && c_parser_next_token_is_keyword (parser
, keyword
));
21569 c_parser_consume_token (parser
);
21571 if (keyword
== RID_TRANSACTION_RELAXED
)
21572 this_in
|= TM_STMT_ATTR_RELAXED
;
21575 attrs
= c_parser_transaction_attributes (parser
);
21577 this_in
|= parse_tm_stmt_attr (attrs
, 0);
21580 parser
->in_transaction
= this_in
;
21581 matching_parens parens
;
21582 if (parens
.require_open (parser
))
21584 tree expr
= c_parser_expression (parser
).value
;
21585 ret
.original_type
= TREE_TYPE (expr
);
21586 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
21587 if (this_in
& TM_STMT_ATTR_RELAXED
)
21588 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
21589 SET_EXPR_LOCATION (ret
.value
, loc
);
21590 ret
.original_code
= TRANSACTION_EXPR
;
21591 if (!parens
.require_close (parser
))
21593 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
21601 ret
.original_code
= ERROR_MARK
;
21602 ret
.original_type
= NULL
;
21604 parser
->in_transaction
= old_in
;
21607 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
21608 "%<__transaction_atomic%> without transactional memory support enabled"
21609 : "%<__transaction_relaxed %> "
21610 "without transactional memory support enabled"));
21612 set_c_expr_source_range (&ret
, loc
, loc
);
21617 /* Parse a __transaction_cancel statement (GCC Extension).
21619 transaction-cancel-statement:
21620 __transaction_cancel transaction-attribute[opt] ;
21622 Note that the only valid attribute is "outer".
21626 c_parser_transaction_cancel (c_parser
*parser
)
21628 location_t loc
= c_parser_peek_token (parser
)->location
;
21630 bool is_outer
= false;
21632 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
21633 c_parser_consume_token (parser
);
21635 attrs
= c_parser_transaction_attributes (parser
);
21637 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
21641 error_at (loc
, "%<__transaction_cancel%> without "
21642 "transactional memory support enabled");
21645 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
21647 error_at (loc
, "%<__transaction_cancel%> within a "
21648 "%<__transaction_relaxed%>");
21653 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
21654 && !is_tm_may_cancel_outer (current_function_decl
))
21656 error_at (loc
, "outer %<__transaction_cancel%> not "
21657 "within outer %<__transaction_atomic%> or "
21658 "a %<transaction_may_cancel_outer%> function");
21662 else if (parser
->in_transaction
== 0)
21664 error_at (loc
, "%<__transaction_cancel%> not within "
21665 "%<__transaction_atomic%>");
21669 return add_stmt (build_tm_abort_call (loc
, is_outer
));
21672 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
21675 /* Parse a single source file. */
21678 c_parse_file (void)
21680 /* Use local storage to begin. If the first token is a pragma, parse it.
21681 If it is #pragma GCC pch_preprocess, then this will load a PCH file
21682 which will cause garbage collection. */
21685 memset (&tparser
, 0, sizeof tparser
);
21686 tparser
.translate_strings_p
= true;
21687 tparser
.tokens
= &tparser
.tokens_buf
[0];
21688 the_parser
= &tparser
;
21690 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
21691 c_parser_pragma_pch_preprocess (&tparser
);
21693 c_common_no_more_pch ();
21695 the_parser
= ggc_alloc
<c_parser
> ();
21696 *the_parser
= tparser
;
21697 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
21698 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
21700 /* Initialize EH, if we've been told to do so. */
21701 if (flag_exceptions
)
21702 using_eh_for_cleanups ();
21704 c_parser_translation_unit (the_parser
);
21708 /* Parse the body of a function declaration marked with "__RTL".
21710 The RTL parser works on the level of characters read from a
21711 FILE *, whereas c_parser works at the level of tokens.
21712 Square this circle by consuming all of the tokens up to and
21713 including the closing brace, recording the start/end of the RTL
21714 fragment, and reopening the file and re-reading the relevant
21715 lines within the RTL parser.
21717 This requires the opening and closing braces of the C function
21718 to be on separate lines from the RTL they wrap.
21720 Take ownership of START_WITH_PASS, if non-NULL. */
21723 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
21725 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
21727 free (start_with_pass
);
21731 location_t start_loc
= c_parser_peek_token (parser
)->location
;
21733 /* Consume all tokens, up to the closing brace, handling
21734 matching pairs of braces in the rtl dump. */
21735 int num_open_braces
= 1;
21738 switch (c_parser_peek_token (parser
)->type
)
21740 case CPP_OPEN_BRACE
:
21743 case CPP_CLOSE_BRACE
:
21744 if (--num_open_braces
== 0)
21745 goto found_closing_brace
;
21748 error_at (start_loc
, "no closing brace");
21749 free (start_with_pass
);
21754 c_parser_consume_token (parser
);
21757 found_closing_brace
:
21758 /* At the closing brace; record its location. */
21759 location_t end_loc
= c_parser_peek_token (parser
)->location
;
21761 /* Consume the closing brace. */
21762 c_parser_consume_token (parser
);
21764 /* Invoke the RTL parser. */
21765 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
21767 free (start_with_pass
);
21771 /* Run the backend on the cfun created above, transferring ownership of
21772 START_WITH_PASS. */
21773 run_rtl_passes (start_with_pass
);
21776 #include "gt-c-c-parser.h"