1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2020 Free Software Foundation, Inc.
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 Make sure all relevant comments, and all relevant code from all
26 actions, brought over from old parser. Verify exact correspondence
29 Add testcases covering every input symbol in every state in old and
32 Include full syntax for GNU C, including erroneous cases accepted
33 with error messages, in syntax productions in comments.
35 Make more diagnostics in the front end generally take an explicit
36 location rather than implicitly using input_location. */
39 #define INCLUDE_UNIQUE_PTR
41 #include "coretypes.h"
46 #include "stringpool.h"
49 #include "stor-layout.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
54 #include "c-family/c-objc.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
63 #include "gcc-rich-location.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
73 /* We need to walk over decls with incomplete struct/union/enum types
74 after parsing the whole translation unit.
75 In finish_decl(), if the decl is static, has incomplete
76 struct/union/enum type, it is appeneded to incomplete_record_decls.
77 In c_parser_translation_unit(), we iterate over incomplete_record_decls
78 and report error if any of the decls are still incomplete. */
80 vec
<tree
> incomplete_record_decls
;
83 set_c_expr_source_range (c_expr
*expr
,
84 location_t start
, location_t finish
)
86 expr
->src_range
.m_start
= start
;
87 expr
->src_range
.m_finish
= finish
;
89 set_source_range (expr
->value
, start
, finish
);
93 set_c_expr_source_range (c_expr
*expr
,
94 source_range src_range
)
96 expr
->src_range
= src_range
;
98 set_source_range (expr
->value
, src_range
);
102 /* Initialization routine for this file. */
107 /* The only initialization required is of the reserved word
113 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
114 the c_token structure. */
115 gcc_assert (RID_MAX
<= 255);
122 mask
|= D_ASM
| D_EXT
;
126 if (!c_dialect_objc ())
127 mask
|= D_OBJC
| D_CXX_OBJC
;
129 ridpointers
= ggc_cleared_vec_alloc
<tree
> ((int) RID_MAX
);
130 for (i
= 0; i
< num_c_common_reswords
; i
++)
132 /* If a keyword is disabled, do not enter it into the table
133 and so create a canonical spelling that isn't a keyword. */
134 if (c_common_reswords
[i
].disable
& mask
)
137 && (c_common_reswords
[i
].disable
& D_CXXWARN
))
139 id
= get_identifier (c_common_reswords
[i
].word
);
140 C_SET_RID_CODE (id
, RID_CXX_COMPAT_WARN
);
141 C_IS_RESERVED_WORD (id
) = 1;
146 id
= get_identifier (c_common_reswords
[i
].word
);
147 C_SET_RID_CODE (id
, c_common_reswords
[i
].rid
);
148 C_IS_RESERVED_WORD (id
) = 1;
149 ridpointers
[(int) c_common_reswords
[i
].rid
] = id
;
152 for (i
= 0; i
< NUM_INT_N_ENTS
; i
++)
154 /* We always create the symbols but they aren't always supported. */
156 sprintf (name
, "__int%d", int_n_data
[i
].bitsize
);
157 id
= get_identifier (name
);
158 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
159 C_IS_RESERVED_WORD (id
) = 1;
161 sprintf (name
, "__int%d__", int_n_data
[i
].bitsize
);
162 id
= get_identifier (name
);
163 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
164 C_IS_RESERVED_WORD (id
) = 1;
168 /* A parser structure recording information about the state and
169 context of parsing. Includes lexer information with up to two
170 tokens of look-ahead; more are not needed for C. */
171 struct GTY(()) c_parser
{
172 /* The look-ahead tokens. */
173 c_token
* GTY((skip
)) tokens
;
174 /* Buffer for look-ahead tokens. */
175 c_token tokens_buf
[4];
176 /* How many look-ahead tokens are available (0 - 4, or
177 more if parsing from pre-lexed tokens). */
178 unsigned int tokens_avail
;
179 /* Raw look-ahead tokens, used only for checking in Objective-C
180 whether '[[' starts attributes. */
181 vec
<c_token
, va_gc
> *raw_tokens
;
182 /* The number of raw look-ahead tokens that have since been fully
184 unsigned int raw_tokens_used
;
185 /* True if a syntax error is being recovered from; false otherwise.
186 c_parser_error sets this flag. It should clear this flag when
187 enough tokens have been consumed to recover from the error. */
188 BOOL_BITFIELD error
: 1;
189 /* True if we're processing a pragma, and shouldn't automatically
190 consume CPP_PRAGMA_EOL. */
191 BOOL_BITFIELD in_pragma
: 1;
192 /* True if we're parsing the outermost block of an if statement. */
193 BOOL_BITFIELD in_if_block
: 1;
194 /* True if we want to lex a translated, joined string (for an
195 initial #pragma pch_preprocess). Otherwise the parser is
196 responsible for concatenating strings and translating to the
197 execution character set as needed. */
198 BOOL_BITFIELD lex_joined_string
: 1;
199 /* True if, when the parser is concatenating string literals, it
200 should translate them to the execution character set (false
201 inside attributes). */
202 BOOL_BITFIELD translate_strings_p
: 1;
204 /* Objective-C specific parser/lexer information. */
206 /* True if we are in a context where the Objective-C "PQ" keywords
207 are considered keywords. */
208 BOOL_BITFIELD objc_pq_context
: 1;
209 /* True if we are parsing a (potential) Objective-C foreach
210 statement. This is set to true after we parsed 'for (' and while
211 we wait for 'in' or ';' to decide if it's a standard C for loop or an
212 Objective-C foreach loop. */
213 BOOL_BITFIELD objc_could_be_foreach_context
: 1;
214 /* The following flag is needed to contextualize Objective-C lexical
215 analysis. In some cases (e.g., 'int NSObject;'), it is
216 undesirable to bind an identifier to an Objective-C class, even
217 if a class with that name exists. */
218 BOOL_BITFIELD objc_need_raw_identifier
: 1;
219 /* Nonzero if we're processing a __transaction statement. The value
220 is 1 | TM_STMT_ATTR_*. */
221 unsigned int in_transaction
: 4;
222 /* True if we are in a context where the Objective-C "Property attribute"
223 keywords are valid. */
224 BOOL_BITFIELD objc_property_attr_context
: 1;
226 /* Location of the last consumed token. */
227 location_t last_token_location
;
230 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
233 c_parser_tokens_buf (c_parser
*parser
, unsigned n
)
235 return &parser
->tokens_buf
[n
];
238 /* Return the error state of PARSER. */
241 c_parser_error (c_parser
*parser
)
243 return parser
->error
;
246 /* Set the error state of PARSER to ERR. */
249 c_parser_set_error (c_parser
*parser
, bool err
)
255 /* The actual parser and external interface. ??? Does this need to be
256 garbage-collected? */
258 static GTY (()) c_parser
*the_parser
;
260 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
261 context-sensitive postprocessing of the token is not done. */
264 c_lex_one_token (c_parser
*parser
, c_token
*token
, bool raw
= false)
266 timevar_push (TV_LEX
);
268 if (raw
|| vec_safe_length (parser
->raw_tokens
) == 0)
270 token
->type
= c_lex_with_flags (&token
->value
, &token
->location
,
272 (parser
->lex_joined_string
273 ? 0 : C_LEX_STRING_NO_JOIN
));
274 token
->id_kind
= C_ID_NONE
;
275 token
->keyword
= RID_MAX
;
276 token
->pragma_kind
= PRAGMA_NONE
;
280 /* Use a token previously lexed as a raw look-ahead token, and
281 complete the processing on it. */
282 *token
= (*parser
->raw_tokens
)[parser
->raw_tokens_used
];
283 ++parser
->raw_tokens_used
;
284 if (parser
->raw_tokens_used
== vec_safe_length (parser
->raw_tokens
))
286 vec_free (parser
->raw_tokens
);
287 parser
->raw_tokens_used
= 0;
300 bool objc_force_identifier
= parser
->objc_need_raw_identifier
;
301 if (c_dialect_objc ())
302 parser
->objc_need_raw_identifier
= false;
304 if (C_IS_RESERVED_WORD (token
->value
))
306 enum rid rid_code
= C_RID_CODE (token
->value
);
308 if (rid_code
== RID_CXX_COMPAT_WARN
)
310 warning_at (token
->location
,
312 "identifier %qE conflicts with C++ keyword",
315 else if (rid_code
>= RID_FIRST_ADDR_SPACE
316 && rid_code
<= RID_LAST_ADDR_SPACE
)
319 as
= (addr_space_t
) (rid_code
- RID_FIRST_ADDR_SPACE
);
320 targetm
.addr_space
.diagnose_usage (as
, token
->location
);
321 token
->id_kind
= C_ID_ADDRSPACE
;
322 token
->keyword
= rid_code
;
325 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code
))
327 /* We found an Objective-C "pq" keyword (in, out,
328 inout, bycopy, byref, oneway). They need special
329 care because the interpretation depends on the
331 if (parser
->objc_pq_context
)
333 token
->type
= CPP_KEYWORD
;
334 token
->keyword
= rid_code
;
337 else if (parser
->objc_could_be_foreach_context
338 && rid_code
== RID_IN
)
340 /* We are in Objective-C, inside a (potential)
341 foreach context (which means after having
342 parsed 'for (', but before having parsed ';'),
343 and we found 'in'. We consider it the keyword
344 which terminates the declaration at the
345 beginning of a foreach-statement. Note that
346 this means you can't use 'in' for anything else
347 in that context; in particular, in Objective-C
348 you can't use 'in' as the name of the running
349 variable in a C for loop. We could potentially
350 try to add code here to disambiguate, but it
351 seems a reasonable limitation. */
352 token
->type
= CPP_KEYWORD
;
353 token
->keyword
= rid_code
;
356 /* Else, "pq" keywords outside of the "pq" context are
357 not keywords, and we fall through to the code for
360 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code
))
362 /* We found an Objective-C "property attribute"
363 keyword (getter, setter, readonly, etc). These are
364 only valid in the property context. */
365 if (parser
->objc_property_attr_context
)
367 token
->type
= CPP_KEYWORD
;
368 token
->keyword
= rid_code
;
371 /* Else they are not special keywords.
374 else if (c_dialect_objc ()
375 && (OBJC_IS_AT_KEYWORD (rid_code
)
376 || OBJC_IS_CXX_KEYWORD (rid_code
)))
378 /* We found one of the Objective-C "@" keywords (defs,
379 selector, synchronized, etc) or one of the
380 Objective-C "cxx" keywords (class, private,
381 protected, public, try, catch, throw) without a
382 preceding '@' sign. Do nothing and fall through to
383 the code for normal tokens (in C++ we would still
384 consider the CXX ones keywords, but not in C). */
389 token
->type
= CPP_KEYWORD
;
390 token
->keyword
= rid_code
;
395 decl
= lookup_name (token
->value
);
398 if (TREE_CODE (decl
) == TYPE_DECL
)
400 token
->id_kind
= C_ID_TYPENAME
;
404 else if (c_dialect_objc ())
406 tree objc_interface_decl
= objc_is_class_name (token
->value
);
407 /* Objective-C class names are in the same namespace as
408 variables and typedefs, and hence are shadowed by local
410 if (objc_interface_decl
411 && (!objc_force_identifier
|| global_bindings_p ()))
413 token
->value
= objc_interface_decl
;
414 token
->id_kind
= C_ID_CLASSNAME
;
418 token
->id_kind
= C_ID_ID
;
422 /* This only happens in Objective-C; it must be a keyword. */
423 token
->type
= CPP_KEYWORD
;
424 switch (C_RID_CODE (token
->value
))
426 /* Replace 'class' with '@class', 'private' with '@private',
427 etc. This prevents confusion with the C++ keyword
428 'class', and makes the tokens consistent with other
429 Objective-C 'AT' keywords. For example '@class' is
430 reported as RID_AT_CLASS which is consistent with
431 '@synchronized', which is reported as
434 case RID_CLASS
: token
->keyword
= RID_AT_CLASS
; break;
435 case RID_PRIVATE
: token
->keyword
= RID_AT_PRIVATE
; break;
436 case RID_PROTECTED
: token
->keyword
= RID_AT_PROTECTED
; break;
437 case RID_PUBLIC
: token
->keyword
= RID_AT_PUBLIC
; break;
438 case RID_THROW
: token
->keyword
= RID_AT_THROW
; break;
439 case RID_TRY
: token
->keyword
= RID_AT_TRY
; break;
440 case RID_CATCH
: token
->keyword
= RID_AT_CATCH
; break;
441 case RID_SYNCHRONIZED
: token
->keyword
= RID_AT_SYNCHRONIZED
; break;
442 default: token
->keyword
= C_RID_CODE (token
->value
);
447 case CPP_CLOSE_PAREN
:
449 /* These tokens may affect the interpretation of any identifiers
450 following, if doing Objective-C. */
451 if (c_dialect_objc ())
452 parser
->objc_need_raw_identifier
= false;
455 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
456 token
->pragma_kind
= (enum pragma_kind
) TREE_INT_CST_LOW (token
->value
);
463 timevar_pop (TV_LEX
);
466 /* Return a pointer to the next token from PARSER, reading it in if
470 c_parser_peek_token (c_parser
*parser
)
472 if (parser
->tokens_avail
== 0)
474 c_lex_one_token (parser
, &parser
->tokens
[0]);
475 parser
->tokens_avail
= 1;
477 return &parser
->tokens
[0];
480 /* Return a pointer to the next-but-one token from PARSER, reading it
481 in if necessary. The next token is already read in. */
484 c_parser_peek_2nd_token (c_parser
*parser
)
486 if (parser
->tokens_avail
>= 2)
487 return &parser
->tokens
[1];
488 gcc_assert (parser
->tokens_avail
== 1);
489 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
490 gcc_assert (parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
491 c_lex_one_token (parser
, &parser
->tokens
[1]);
492 parser
->tokens_avail
= 2;
493 return &parser
->tokens
[1];
496 /* Return a pointer to the Nth token from PARSER, reading it
497 in if necessary. The N-1th token is already read in. */
500 c_parser_peek_nth_token (c_parser
*parser
, unsigned int n
)
502 /* N is 1-based, not zero-based. */
505 if (parser
->tokens_avail
>= n
)
506 return &parser
->tokens
[n
- 1];
507 gcc_assert (parser
->tokens_avail
== n
- 1);
508 c_lex_one_token (parser
, &parser
->tokens
[n
- 1]);
509 parser
->tokens_avail
= n
;
510 return &parser
->tokens
[n
- 1];
513 /* Return a pointer to the Nth token from PARSER, reading it in as a
514 raw look-ahead token if necessary. The N-1th token is already read
515 in. Raw look-ahead tokens remain available for when the non-raw
516 functions above are called. */
519 c_parser_peek_nth_token_raw (c_parser
*parser
, unsigned int n
)
521 /* N is 1-based, not zero-based. */
524 if (parser
->tokens_avail
>= n
)
525 return &parser
->tokens
[n
- 1];
526 unsigned int raw_len
= vec_safe_length (parser
->raw_tokens
);
527 unsigned int raw_avail
528 = parser
->tokens_avail
+ raw_len
- parser
->raw_tokens_used
;
529 gcc_assert (raw_avail
>= n
- 1);
531 return &(*parser
->raw_tokens
)[parser
->raw_tokens_used
532 + n
- 1 - parser
->tokens_avail
];
533 vec_safe_reserve (parser
->raw_tokens
, 1);
534 parser
->raw_tokens
->quick_grow (raw_len
+ 1);
535 c_lex_one_token (parser
, &(*parser
->raw_tokens
)[raw_len
], true);
536 return &(*parser
->raw_tokens
)[raw_len
];
540 c_keyword_starts_typename (enum rid keyword
)
575 if (keyword
>= RID_FIRST_INT_N
576 && keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
577 && int_n_enabled_p
[keyword
- RID_FIRST_INT_N
])
583 /* Return true if TOKEN can start a type name,
586 c_token_starts_typename (c_token
*token
)
591 switch (token
->id_kind
)
600 gcc_assert (c_dialect_objc ());
606 return c_keyword_starts_typename (token
->keyword
);
608 if (c_dialect_objc ())
616 /* Return true if the next token from PARSER can start a type name,
617 false otherwise. LA specifies how to do lookahead in order to
618 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
621 c_parser_next_tokens_start_typename (c_parser
*parser
, enum c_lookahead_kind la
)
623 c_token
*token
= c_parser_peek_token (parser
);
624 if (c_token_starts_typename (token
))
627 /* Try a bit harder to detect an unknown typename. */
628 if (la
!= cla_prefer_id
629 && token
->type
== CPP_NAME
630 && token
->id_kind
== C_ID_ID
632 /* Do not try too hard when we could have "object in array". */
633 && !parser
->objc_could_be_foreach_context
635 && (la
== cla_prefer_type
636 || c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
637 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
639 /* Only unknown identifiers. */
640 && !lookup_name (token
->value
))
646 /* Return true if TOKEN is a type qualifier, false otherwise. */
648 c_token_is_qualifier (c_token
*token
)
653 switch (token
->id_kind
)
661 switch (token
->keyword
)
679 /* Return true if the next token from PARSER is a type qualifier,
682 c_parser_next_token_is_qualifier (c_parser
*parser
)
684 c_token
*token
= c_parser_peek_token (parser
);
685 return c_token_is_qualifier (token
);
688 /* Return true if TOKEN can start declaration specifiers (not
689 including standard attributes), false otherwise. */
691 c_token_starts_declspecs (c_token
*token
)
696 switch (token
->id_kind
)
705 gcc_assert (c_dialect_objc ());
711 switch (token
->keyword
)
752 if (token
->keyword
>= RID_FIRST_INT_N
753 && token
->keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
754 && int_n_enabled_p
[token
->keyword
- RID_FIRST_INT_N
])
759 if (c_dialect_objc ())
768 /* Return true if TOKEN can start declaration specifiers (not
769 including standard attributes) or a static assertion, false
772 c_token_starts_declaration (c_token
*token
)
774 if (c_token_starts_declspecs (token
)
775 || token
->keyword
== RID_STATIC_ASSERT
)
781 /* Return true if the next token from PARSER can start declaration
782 specifiers (not including standard attributes), false
785 c_parser_next_token_starts_declspecs (c_parser
*parser
)
787 c_token
*token
= c_parser_peek_token (parser
);
789 /* In Objective-C, a classname normally starts a declspecs unless it
790 is immediately followed by a dot. In that case, it is the
791 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
792 setter/getter on the class. c_token_starts_declspecs() can't
793 differentiate between the two cases because it only checks the
794 current token, so we have a special check here. */
795 if (c_dialect_objc ()
796 && token
->type
== CPP_NAME
797 && token
->id_kind
== C_ID_CLASSNAME
798 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
801 return c_token_starts_declspecs (token
);
804 /* Return true if the next tokens from PARSER can start declaration
805 specifiers (not including standard attributes) or a static
806 assertion, false otherwise. */
808 c_parser_next_tokens_start_declaration (c_parser
*parser
)
810 c_token
*token
= c_parser_peek_token (parser
);
813 if (c_dialect_objc ()
814 && token
->type
== CPP_NAME
815 && token
->id_kind
== C_ID_CLASSNAME
816 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
819 /* Labels do not start declarations. */
820 if (token
->type
== CPP_NAME
821 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
824 if (c_token_starts_declaration (token
))
827 if (c_parser_next_tokens_start_typename (parser
, cla_nonabstract_decl
))
833 /* Consume the next token from PARSER. */
836 c_parser_consume_token (c_parser
*parser
)
838 gcc_assert (parser
->tokens_avail
>= 1);
839 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
840 gcc_assert (!parser
->in_pragma
|| parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
841 gcc_assert (parser
->error
|| parser
->tokens
[0].type
!= CPP_PRAGMA
);
842 parser
->last_token_location
= parser
->tokens
[0].location
;
843 if (parser
->tokens
!= &parser
->tokens_buf
[0])
845 else if (parser
->tokens_avail
>= 2)
847 parser
->tokens
[0] = parser
->tokens
[1];
848 if (parser
->tokens_avail
>= 3)
850 parser
->tokens
[1] = parser
->tokens
[2];
851 if (parser
->tokens_avail
>= 4)
852 parser
->tokens
[2] = parser
->tokens
[3];
855 parser
->tokens_avail
--;
858 /* Expect the current token to be a #pragma. Consume it and remember
859 that we've begun parsing a pragma. */
862 c_parser_consume_pragma (c_parser
*parser
)
864 gcc_assert (!parser
->in_pragma
);
865 gcc_assert (parser
->tokens_avail
>= 1);
866 gcc_assert (parser
->tokens
[0].type
== CPP_PRAGMA
);
867 if (parser
->tokens
!= &parser
->tokens_buf
[0])
869 else if (parser
->tokens_avail
>= 2)
871 parser
->tokens
[0] = parser
->tokens
[1];
872 if (parser
->tokens_avail
>= 3)
873 parser
->tokens
[1] = parser
->tokens
[2];
875 parser
->tokens_avail
--;
876 parser
->in_pragma
= true;
879 /* Update the global input_location from TOKEN. */
881 c_parser_set_source_position_from_token (c_token
*token
)
883 if (token
->type
!= CPP_EOF
)
885 input_location
= token
->location
;
889 /* Helper function for c_parser_error.
890 Having peeked a token of kind TOK1_KIND that might signify
891 a conflict marker, peek successor tokens to determine
892 if we actually do have a conflict marker.
893 Specifically, we consider a run of 7 '<', '=' or '>' characters
894 at the start of a line as a conflict marker.
895 These come through the lexer as three pairs and a single,
896 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
897 If it returns true, *OUT_LOC is written to with the location/range
901 c_parser_peek_conflict_marker (c_parser
*parser
, enum cpp_ttype tok1_kind
,
904 c_token
*token2
= c_parser_peek_2nd_token (parser
);
905 if (token2
->type
!= tok1_kind
)
907 c_token
*token3
= c_parser_peek_nth_token (parser
, 3);
908 if (token3
->type
!= tok1_kind
)
910 c_token
*token4
= c_parser_peek_nth_token (parser
, 4);
911 if (token4
->type
!= conflict_marker_get_final_tok_kind (tok1_kind
))
914 /* It must be at the start of the line. */
915 location_t start_loc
= c_parser_peek_token (parser
)->location
;
916 if (LOCATION_COLUMN (start_loc
) != 1)
919 /* We have a conflict marker. Construct a location of the form:
922 with start == caret, finishing at the end of the marker. */
923 location_t finish_loc
= get_finish (token4
->location
);
924 *out_loc
= make_location (start_loc
, start_loc
, finish_loc
);
929 /* Issue a diagnostic of the form
930 FILE:LINE: MESSAGE before TOKEN
931 where TOKEN is the next token in the input stream of PARSER.
932 MESSAGE (specified by the caller) is usually of the form "expected
935 Use RICHLOC as the location of the diagnostic.
937 Do not issue a diagnostic if still recovering from an error.
939 Return true iff an error was actually emitted.
941 ??? This is taken from the C++ parser, but building up messages in
942 this way is not i18n-friendly and some other approach should be
946 c_parser_error_richloc (c_parser
*parser
, const char *gmsgid
,
947 rich_location
*richloc
)
949 c_token
*token
= c_parser_peek_token (parser
);
952 parser
->error
= true;
956 /* If this is actually a conflict marker, report it as such. */
957 if (token
->type
== CPP_LSHIFT
958 || token
->type
== CPP_RSHIFT
959 || token
->type
== CPP_EQ_EQ
)
962 if (c_parser_peek_conflict_marker (parser
, token
->type
, &loc
))
964 error_at (loc
, "version control conflict marker in file");
969 c_parse_error (gmsgid
,
970 /* Because c_parse_error does not understand
971 CPP_KEYWORD, keywords are treated like
973 (token
->type
== CPP_KEYWORD
? CPP_NAME
: token
->type
),
974 /* ??? The C parser does not save the cpp flags of a
975 token, we need to pass 0 here and we will not get
976 the source spelling of some tokens but rather the
977 canonical spelling. */
978 token
->value
, /*flags=*/0, richloc
);
982 /* As c_parser_error_richloc, but issue the message at the
983 location of PARSER's next token, or at input_location
984 if the next token is EOF. */
987 c_parser_error (c_parser
*parser
, const char *gmsgid
)
989 c_token
*token
= c_parser_peek_token (parser
);
990 c_parser_set_source_position_from_token (token
);
991 rich_location
richloc (line_table
, input_location
);
992 return c_parser_error_richloc (parser
, gmsgid
, &richloc
);
995 /* Some tokens naturally come in pairs e.g.'(' and ')'.
996 This class is for tracking such a matching pair of symbols.
997 In particular, it tracks the location of the first token,
998 so that if the second token is missing, we can highlight the
999 location of the first token when notifying the user about the
1002 template <typename traits_t
>
1006 /* token_pair's ctor. */
1007 token_pair () : m_open_loc (UNKNOWN_LOCATION
) {}
1009 /* If the next token is the opening symbol for this pair, consume it and
1011 Otherwise, issue an error and return false.
1012 In either case, record the location of the opening token. */
1014 bool require_open (c_parser
*parser
)
1016 c_token
*token
= c_parser_peek_token (parser
);
1018 m_open_loc
= token
->location
;
1020 return c_parser_require (parser
, traits_t::open_token_type
,
1021 traits_t::open_gmsgid
);
1024 /* Consume the next token from PARSER, recording its location as
1025 that of the opening token within the pair. */
1027 void consume_open (c_parser
*parser
)
1029 c_token
*token
= c_parser_peek_token (parser
);
1030 gcc_assert (token
->type
== traits_t::open_token_type
);
1031 m_open_loc
= token
->location
;
1032 c_parser_consume_token (parser
);
1035 /* If the next token is the closing symbol for this pair, consume it
1037 Otherwise, issue an error, highlighting the location of the
1038 corresponding opening token, and return false. */
1040 bool require_close (c_parser
*parser
) const
1042 return c_parser_require (parser
, traits_t::close_token_type
,
1043 traits_t::close_gmsgid
, m_open_loc
);
1046 /* Like token_pair::require_close, except that tokens will be skipped
1047 until the desired token is found. An error message is still produced
1048 if the next token is not as expected. */
1050 void skip_until_found_close (c_parser
*parser
) const
1052 c_parser_skip_until_found (parser
, traits_t::close_token_type
,
1053 traits_t::close_gmsgid
, m_open_loc
);
1057 location_t m_open_loc
;
1060 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1062 struct matching_paren_traits
1064 static const enum cpp_ttype open_token_type
= CPP_OPEN_PAREN
;
1065 static const char * const open_gmsgid
;
1066 static const enum cpp_ttype close_token_type
= CPP_CLOSE_PAREN
;
1067 static const char * const close_gmsgid
;
1070 const char * const matching_paren_traits::open_gmsgid
= "expected %<(%>";
1071 const char * const matching_paren_traits::close_gmsgid
= "expected %<)%>";
1073 /* "matching_parens" is a token_pair<T> class for tracking matching
1074 pairs of parentheses. */
1076 typedef token_pair
<matching_paren_traits
> matching_parens
;
1078 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1080 struct matching_brace_traits
1082 static const enum cpp_ttype open_token_type
= CPP_OPEN_BRACE
;
1083 static const char * const open_gmsgid
;
1084 static const enum cpp_ttype close_token_type
= CPP_CLOSE_BRACE
;
1085 static const char * const close_gmsgid
;
1088 const char * const matching_brace_traits::open_gmsgid
= "expected %<{%>";
1089 const char * const matching_brace_traits::close_gmsgid
= "expected %<}%>";
1091 /* "matching_braces" is a token_pair<T> class for tracking matching
1094 typedef token_pair
<matching_brace_traits
> matching_braces
;
1096 /* Get a description of the matching symbol to TYPE e.g. "(" for
1100 get_matching_symbol (enum cpp_ttype type
)
1107 case CPP_CLOSE_PAREN
:
1109 case CPP_CLOSE_BRACE
:
1114 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1115 issue the error MSGID. If MSGID is NULL then a message has already
1116 been produced and no message will be produced this time. Returns
1117 true if found, false otherwise.
1119 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1120 within any error as the location of an "opening" token matching
1121 the close token TYPE (e.g. the location of the '(' when TYPE is
1124 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1125 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1126 attempt to generate a fix-it hint for the problem.
1127 Otherwise msgid describes multiple token types (e.g.
1128 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1129 generate a fix-it hint. */
1132 c_parser_require (c_parser
*parser
,
1133 enum cpp_ttype type
,
1135 location_t matching_location
,
1136 bool type_is_unique
)
1138 if (c_parser_next_token_is (parser
, type
))
1140 c_parser_consume_token (parser
);
1145 location_t next_token_loc
= c_parser_peek_token (parser
)->location
;
1146 gcc_rich_location
richloc (next_token_loc
);
1148 /* Potentially supply a fix-it hint, suggesting to add the
1149 missing token immediately after the *previous* token.
1150 This may move the primary location within richloc. */
1151 if (!parser
->error
&& type_is_unique
)
1152 maybe_suggest_missing_token_insertion (&richloc
, type
,
1153 parser
->last_token_location
);
1155 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1156 Attempt to consolidate diagnostics by printing it as a
1157 secondary range within the main diagnostic. */
1158 bool added_matching_location
= false;
1159 if (matching_location
!= UNKNOWN_LOCATION
)
1160 added_matching_location
1161 = richloc
.add_location_if_nearby (matching_location
);
1163 if (c_parser_error_richloc (parser
, msgid
, &richloc
))
1164 /* If we weren't able to consolidate matching_location, then
1165 print it as a secondary diagnostic. */
1166 if (matching_location
!= UNKNOWN_LOCATION
&& !added_matching_location
)
1167 inform (matching_location
, "to match this %qs",
1168 get_matching_symbol (type
));
1174 /* If the next token is the indicated keyword, consume it. Otherwise,
1175 issue the error MSGID. Returns true if found, false otherwise. */
1178 c_parser_require_keyword (c_parser
*parser
,
1182 if (c_parser_next_token_is_keyword (parser
, keyword
))
1184 c_parser_consume_token (parser
);
1189 c_parser_error (parser
, msgid
);
1194 /* Like c_parser_require, except that tokens will be skipped until the
1195 desired token is found. An error message is still produced if the
1196 next token is not as expected. If MSGID is NULL then a message has
1197 already been produced and no message will be produced this
1200 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1201 within any error as the location of an "opening" token matching
1202 the close token TYPE (e.g. the location of the '(' when TYPE is
1203 CPP_CLOSE_PAREN). */
1206 c_parser_skip_until_found (c_parser
*parser
,
1207 enum cpp_ttype type
,
1209 location_t matching_location
)
1211 unsigned nesting_depth
= 0;
1213 if (c_parser_require (parser
, type
, msgid
, matching_location
))
1216 /* Skip tokens until the desired token is found. */
1219 /* Peek at the next token. */
1220 c_token
*token
= c_parser_peek_token (parser
);
1221 /* If we've reached the token we want, consume it and stop. */
1222 if (token
->type
== type
&& !nesting_depth
)
1224 c_parser_consume_token (parser
);
1228 /* If we've run out of tokens, stop. */
1229 if (token
->type
== CPP_EOF
)
1231 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1233 if (token
->type
== CPP_OPEN_BRACE
1234 || token
->type
== CPP_OPEN_PAREN
1235 || token
->type
== CPP_OPEN_SQUARE
)
1237 else if (token
->type
== CPP_CLOSE_BRACE
1238 || token
->type
== CPP_CLOSE_PAREN
1239 || token
->type
== CPP_CLOSE_SQUARE
)
1241 if (nesting_depth
-- == 0)
1244 /* Consume this token. */
1245 c_parser_consume_token (parser
);
1247 parser
->error
= false;
1250 /* Skip tokens until the end of a parameter is found, but do not
1251 consume the comma, semicolon or closing delimiter. */
1254 c_parser_skip_to_end_of_parameter (c_parser
*parser
)
1256 unsigned nesting_depth
= 0;
1260 c_token
*token
= c_parser_peek_token (parser
);
1261 if ((token
->type
== CPP_COMMA
|| token
->type
== CPP_SEMICOLON
)
1264 /* If we've run out of tokens, stop. */
1265 if (token
->type
== CPP_EOF
)
1267 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1269 if (token
->type
== CPP_OPEN_BRACE
1270 || token
->type
== CPP_OPEN_PAREN
1271 || token
->type
== CPP_OPEN_SQUARE
)
1273 else if (token
->type
== CPP_CLOSE_BRACE
1274 || token
->type
== CPP_CLOSE_PAREN
1275 || token
->type
== CPP_CLOSE_SQUARE
)
1277 if (nesting_depth
-- == 0)
1280 /* Consume this token. */
1281 c_parser_consume_token (parser
);
1283 parser
->error
= false;
1286 /* Expect to be at the end of the pragma directive and consume an
1287 end of line marker. */
1290 c_parser_skip_to_pragma_eol (c_parser
*parser
, bool error_if_not_eol
= true)
1292 gcc_assert (parser
->in_pragma
);
1293 parser
->in_pragma
= false;
1295 if (error_if_not_eol
&& c_parser_peek_token (parser
)->type
!= CPP_PRAGMA_EOL
)
1296 c_parser_error (parser
, "expected end of line");
1298 cpp_ttype token_type
;
1301 c_token
*token
= c_parser_peek_token (parser
);
1302 token_type
= token
->type
;
1303 if (token_type
== CPP_EOF
)
1305 c_parser_consume_token (parser
);
1307 while (token_type
!= CPP_PRAGMA_EOL
);
1309 parser
->error
= false;
1312 /* Skip tokens until we have consumed an entire block, or until we
1313 have consumed a non-nested ';'. */
1316 c_parser_skip_to_end_of_block_or_statement (c_parser
*parser
)
1318 unsigned nesting_depth
= 0;
1319 bool save_error
= parser
->error
;
1325 /* Peek at the next token. */
1326 token
= c_parser_peek_token (parser
);
1328 switch (token
->type
)
1333 case CPP_PRAGMA_EOL
:
1334 if (parser
->in_pragma
)
1339 /* If the next token is a ';', we have reached the
1340 end of the statement. */
1343 /* Consume the ';'. */
1344 c_parser_consume_token (parser
);
1349 case CPP_CLOSE_BRACE
:
1350 /* If the next token is a non-nested '}', then we have
1351 reached the end of the current block. */
1352 if (nesting_depth
== 0 || --nesting_depth
== 0)
1354 c_parser_consume_token (parser
);
1359 case CPP_OPEN_BRACE
:
1360 /* If it the next token is a '{', then we are entering a new
1361 block. Consume the entire block. */
1366 /* If we see a pragma, consume the whole thing at once. We
1367 have some safeguards against consuming pragmas willy-nilly.
1368 Normally, we'd expect to be here with parser->error set,
1369 which disables these safeguards. But it's possible to get
1370 here for secondary error recovery, after parser->error has
1372 c_parser_consume_pragma (parser
);
1373 c_parser_skip_to_pragma_eol (parser
);
1374 parser
->error
= save_error
;
1381 c_parser_consume_token (parser
);
1385 parser
->error
= false;
1388 /* CPP's options (initialized by c-opts.c). */
1389 extern cpp_options
*cpp_opts
;
1391 /* Save the warning flags which are controlled by __extension__. */
1394 disable_extension_diagnostics (void)
1397 | (warn_pointer_arith
<< 1)
1398 | (warn_traditional
<< 2)
1400 | (warn_long_long
<< 4)
1401 | (warn_cxx_compat
<< 5)
1402 | (warn_overlength_strings
<< 6)
1403 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1404 play tricks to properly restore it. */
1405 | ((warn_c90_c99_compat
== 1) << 7)
1406 | ((warn_c90_c99_compat
== -1) << 8)
1407 /* Similarly for warn_c99_c11_compat. */
1408 | ((warn_c99_c11_compat
== 1) << 9)
1409 | ((warn_c99_c11_compat
== -1) << 10)
1410 /* Similarly for warn_c11_c2x_compat. */
1411 | ((warn_c11_c2x_compat
== 1) << 11)
1412 | ((warn_c11_c2x_compat
== -1) << 12)
1414 cpp_opts
->cpp_pedantic
= pedantic
= 0;
1415 warn_pointer_arith
= 0;
1416 cpp_opts
->cpp_warn_traditional
= warn_traditional
= 0;
1418 cpp_opts
->cpp_warn_long_long
= warn_long_long
= 0;
1419 warn_cxx_compat
= 0;
1420 warn_overlength_strings
= 0;
1421 warn_c90_c99_compat
= 0;
1422 warn_c99_c11_compat
= 0;
1423 warn_c11_c2x_compat
= 0;
1427 /* Restore the warning flags which are controlled by __extension__.
1428 FLAGS is the return value from disable_extension_diagnostics. */
1431 restore_extension_diagnostics (int flags
)
1433 cpp_opts
->cpp_pedantic
= pedantic
= flags
& 1;
1434 warn_pointer_arith
= (flags
>> 1) & 1;
1435 cpp_opts
->cpp_warn_traditional
= warn_traditional
= (flags
>> 2) & 1;
1436 flag_iso
= (flags
>> 3) & 1;
1437 cpp_opts
->cpp_warn_long_long
= warn_long_long
= (flags
>> 4) & 1;
1438 warn_cxx_compat
= (flags
>> 5) & 1;
1439 warn_overlength_strings
= (flags
>> 6) & 1;
1440 /* See above for why is this needed. */
1441 warn_c90_c99_compat
= (flags
>> 7) & 1 ? 1 : ((flags
>> 8) & 1 ? -1 : 0);
1442 warn_c99_c11_compat
= (flags
>> 9) & 1 ? 1 : ((flags
>> 10) & 1 ? -1 : 0);
1443 warn_c11_c2x_compat
= (flags
>> 11) & 1 ? 1 : ((flags
>> 12) & 1 ? -1 : 0);
1446 /* Helper data structure for parsing #pragma acc routine. */
1447 struct oacc_routine_data
{
1448 bool error_seen
; /* Set if error has been reported. */
1449 bool fndecl_seen
; /* Set if one fn decl/definition has been seen already. */
1454 static bool c_parser_nth_token_starts_std_attributes (c_parser
*,
1456 static tree
c_parser_std_attribute_specifier_sequence (c_parser
*);
1457 static void c_parser_external_declaration (c_parser
*);
1458 static void c_parser_asm_definition (c_parser
*);
1459 static void c_parser_declaration_or_fndef (c_parser
*, bool, bool, bool,
1460 bool, bool, tree
*, vec
<c_token
>,
1461 bool have_attrs
= false,
1463 struct oacc_routine_data
* = NULL
,
1465 static void c_parser_static_assert_declaration_no_semi (c_parser
*);
1466 static void c_parser_static_assert_declaration (c_parser
*);
1467 static struct c_typespec
c_parser_enum_specifier (c_parser
*);
1468 static struct c_typespec
c_parser_struct_or_union_specifier (c_parser
*);
1469 static tree
c_parser_struct_declaration (c_parser
*);
1470 static struct c_typespec
c_parser_typeof_specifier (c_parser
*);
1471 static tree
c_parser_alignas_specifier (c_parser
*);
1472 static struct c_declarator
*c_parser_direct_declarator (c_parser
*, bool,
1474 static struct c_declarator
*c_parser_direct_declarator_inner (c_parser
*,
1476 struct c_declarator
*);
1477 static struct c_arg_info
*c_parser_parms_declarator (c_parser
*, bool, tree
,
1479 static struct c_arg_info
*c_parser_parms_list_declarator (c_parser
*, tree
,
1481 static struct c_parm
*c_parser_parameter_declaration (c_parser
*, tree
, bool);
1482 static tree
c_parser_simple_asm_expr (c_parser
*);
1483 static tree
c_parser_gnu_attributes (c_parser
*);
1484 static struct c_expr
c_parser_initializer (c_parser
*);
1485 static struct c_expr
c_parser_braced_init (c_parser
*, tree
, bool,
1487 static void c_parser_initelt (c_parser
*, struct obstack
*);
1488 static void c_parser_initval (c_parser
*, struct c_expr
*,
1490 static tree
c_parser_compound_statement (c_parser
*);
1491 static void c_parser_compound_statement_nostart (c_parser
*);
1492 static void c_parser_label (c_parser
*);
1493 static void c_parser_statement (c_parser
*, bool *, location_t
* = NULL
);
1494 static void c_parser_statement_after_labels (c_parser
*, bool *,
1495 vec
<tree
> * = NULL
);
1496 static tree
c_parser_c99_block_statement (c_parser
*, bool *,
1497 location_t
* = NULL
);
1498 static void c_parser_if_statement (c_parser
*, bool *, vec
<tree
> *);
1499 static void c_parser_switch_statement (c_parser
*, bool *);
1500 static void c_parser_while_statement (c_parser
*, bool, unsigned short, bool *);
1501 static void c_parser_do_statement (c_parser
*, bool, unsigned short);
1502 static void c_parser_for_statement (c_parser
*, bool, unsigned short, bool *);
1503 static tree
c_parser_asm_statement (c_parser
*);
1504 static tree
c_parser_asm_operands (c_parser
*);
1505 static tree
c_parser_asm_goto_operands (c_parser
*);
1506 static tree
c_parser_asm_clobbers (c_parser
*);
1507 static struct c_expr
c_parser_expr_no_commas (c_parser
*, struct c_expr
*,
1509 static struct c_expr
c_parser_conditional_expression (c_parser
*,
1510 struct c_expr
*, tree
);
1511 static struct c_expr
c_parser_binary_expression (c_parser
*, struct c_expr
*,
1513 static struct c_expr
c_parser_cast_expression (c_parser
*, struct c_expr
*);
1514 static struct c_expr
c_parser_unary_expression (c_parser
*);
1515 static struct c_expr
c_parser_sizeof_expression (c_parser
*);
1516 static struct c_expr
c_parser_alignof_expression (c_parser
*);
1517 static struct c_expr
c_parser_postfix_expression (c_parser
*);
1518 static struct c_expr
c_parser_postfix_expression_after_paren_type (c_parser
*,
1519 struct c_type_name
*,
1521 static struct c_expr
c_parser_postfix_expression_after_primary (c_parser
*,
1524 static tree
c_parser_transaction (c_parser
*, enum rid
);
1525 static struct c_expr
c_parser_transaction_expression (c_parser
*, enum rid
);
1526 static tree
c_parser_transaction_cancel (c_parser
*);
1527 static struct c_expr
c_parser_expression (c_parser
*);
1528 static struct c_expr
c_parser_expression_conv (c_parser
*);
1529 static vec
<tree
, va_gc
> *c_parser_expr_list (c_parser
*, bool, bool,
1530 vec
<tree
, va_gc
> **, location_t
*,
1531 tree
*, vec
<location_t
> *,
1532 unsigned int * = NULL
);
1533 static struct c_expr
c_parser_has_attribute_expression (c_parser
*);
1535 static void c_parser_oacc_declare (c_parser
*);
1536 static void c_parser_oacc_enter_exit_data (c_parser
*, bool);
1537 static void c_parser_oacc_update (c_parser
*);
1538 static void c_parser_omp_construct (c_parser
*, bool *);
1539 static void c_parser_omp_threadprivate (c_parser
*);
1540 static void c_parser_omp_barrier (c_parser
*);
1541 static void c_parser_omp_depobj (c_parser
*);
1542 static void c_parser_omp_flush (c_parser
*);
1543 static tree
c_parser_omp_for_loop (location_t
, c_parser
*, enum tree_code
,
1544 tree
, tree
*, bool *);
1545 static void c_parser_omp_taskwait (c_parser
*);
1546 static void c_parser_omp_taskyield (c_parser
*);
1547 static void c_parser_omp_cancel (c_parser
*);
1549 enum pragma_context
{ pragma_external
, pragma_struct
, pragma_param
,
1550 pragma_stmt
, pragma_compound
};
1551 static bool c_parser_pragma (c_parser
*, enum pragma_context
, bool *);
1552 static void c_parser_omp_cancellation_point (c_parser
*, enum pragma_context
);
1553 static bool c_parser_omp_target (c_parser
*, enum pragma_context
, bool *);
1554 static void c_parser_omp_end_declare_target (c_parser
*);
1555 static void c_parser_omp_declare (c_parser
*, enum pragma_context
);
1556 static void c_parser_omp_requires (c_parser
*);
1557 static bool c_parser_omp_ordered (c_parser
*, enum pragma_context
, bool *);
1558 static void c_parser_oacc_routine (c_parser
*, enum pragma_context
);
1560 /* These Objective-C parser functions are only ever called when
1561 compiling Objective-C. */
1562 static void c_parser_objc_class_definition (c_parser
*, tree
);
1563 static void c_parser_objc_class_instance_variables (c_parser
*);
1564 static void c_parser_objc_class_declaration (c_parser
*);
1565 static void c_parser_objc_alias_declaration (c_parser
*);
1566 static void c_parser_objc_protocol_definition (c_parser
*, tree
);
1567 static bool c_parser_objc_method_type (c_parser
*);
1568 static void c_parser_objc_method_definition (c_parser
*);
1569 static void c_parser_objc_methodprotolist (c_parser
*);
1570 static void c_parser_objc_methodproto (c_parser
*);
1571 static tree
c_parser_objc_method_decl (c_parser
*, bool, tree
*, tree
*);
1572 static tree
c_parser_objc_type_name (c_parser
*);
1573 static tree
c_parser_objc_protocol_refs (c_parser
*);
1574 static void c_parser_objc_try_catch_finally_statement (c_parser
*);
1575 static void c_parser_objc_synchronized_statement (c_parser
*);
1576 static tree
c_parser_objc_selector (c_parser
*);
1577 static tree
c_parser_objc_selector_arg (c_parser
*);
1578 static tree
c_parser_objc_receiver (c_parser
*);
1579 static tree
c_parser_objc_message_args (c_parser
*);
1580 static tree
c_parser_objc_keywordexpr (c_parser
*);
1581 static void c_parser_objc_at_property_declaration (c_parser
*);
1582 static void c_parser_objc_at_synthesize_declaration (c_parser
*);
1583 static void c_parser_objc_at_dynamic_declaration (c_parser
*);
1584 static bool c_parser_objc_diagnose_bad_element_prefix
1585 (c_parser
*, struct c_declspecs
*);
1587 static void c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
);
1589 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1592 external-declarations
1594 external-declarations:
1595 external-declaration
1596 external-declarations external-declaration
1605 c_parser_translation_unit (c_parser
*parser
)
1607 if (c_parser_next_token_is (parser
, CPP_EOF
))
1609 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1610 "ISO C forbids an empty translation unit");
1614 void *obstack_position
= obstack_alloc (&parser_obstack
, 0);
1615 mark_valid_location_for_stdc_pragma (false);
1619 c_parser_external_declaration (parser
);
1620 obstack_free (&parser_obstack
, obstack_position
);
1622 while (c_parser_next_token_is_not (parser
, CPP_EOF
));
1627 FOR_EACH_VEC_ELT (incomplete_record_decls
, i
, decl
)
1628 if (DECL_SIZE (decl
) == NULL_TREE
&& TREE_TYPE (decl
) != error_mark_node
)
1629 error ("storage size of %q+D isn%'t known", decl
);
1631 if (current_omp_declare_target_attribute
)
1634 error ("%<#pragma omp declare target%> without corresponding "
1635 "%<#pragma omp end declare target%>");
1636 current_omp_declare_target_attribute
= 0;
1640 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1642 external-declaration:
1648 external-declaration:
1651 __extension__ external-declaration
1655 external-declaration:
1656 objc-class-definition
1657 objc-class-declaration
1658 objc-alias-declaration
1659 objc-protocol-definition
1660 objc-method-definition
1665 c_parser_external_declaration (c_parser
*parser
)
1668 switch (c_parser_peek_token (parser
)->type
)
1671 switch (c_parser_peek_token (parser
)->keyword
)
1674 ext
= disable_extension_diagnostics ();
1675 c_parser_consume_token (parser
);
1676 c_parser_external_declaration (parser
);
1677 restore_extension_diagnostics (ext
);
1680 c_parser_asm_definition (parser
);
1682 case RID_AT_INTERFACE
:
1683 case RID_AT_IMPLEMENTATION
:
1684 gcc_assert (c_dialect_objc ());
1685 c_parser_objc_class_definition (parser
, NULL_TREE
);
1688 gcc_assert (c_dialect_objc ());
1689 c_parser_objc_class_declaration (parser
);
1692 gcc_assert (c_dialect_objc ());
1693 c_parser_objc_alias_declaration (parser
);
1695 case RID_AT_PROTOCOL
:
1696 gcc_assert (c_dialect_objc ());
1697 c_parser_objc_protocol_definition (parser
, NULL_TREE
);
1699 case RID_AT_PROPERTY
:
1700 gcc_assert (c_dialect_objc ());
1701 c_parser_objc_at_property_declaration (parser
);
1703 case RID_AT_SYNTHESIZE
:
1704 gcc_assert (c_dialect_objc ());
1705 c_parser_objc_at_synthesize_declaration (parser
);
1707 case RID_AT_DYNAMIC
:
1708 gcc_assert (c_dialect_objc ());
1709 c_parser_objc_at_dynamic_declaration (parser
);
1712 gcc_assert (c_dialect_objc ());
1713 c_parser_consume_token (parser
);
1714 objc_finish_implementation ();
1721 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1722 "ISO C does not allow extra %<;%> outside of a function");
1723 c_parser_consume_token (parser
);
1726 mark_valid_location_for_stdc_pragma (true);
1727 c_parser_pragma (parser
, pragma_external
, NULL
);
1728 mark_valid_location_for_stdc_pragma (false);
1732 if (c_dialect_objc ())
1734 c_parser_objc_method_definition (parser
);
1737 /* Else fall through, and yield a syntax error trying to parse
1738 as a declaration or function definition. */
1742 /* A declaration or a function definition (or, in Objective-C,
1743 an @interface or @protocol with prefix attributes). We can
1744 only tell which after parsing the declaration specifiers, if
1745 any, and the first declarator. */
1746 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
1752 static void c_finish_omp_declare_simd (c_parser
*, tree
, tree
, vec
<c_token
>);
1753 static void c_finish_oacc_routine (struct oacc_routine_data
*, tree
, bool);
1755 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1758 add_debug_begin_stmt (location_t loc
)
1760 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1761 if (!MAY_HAVE_DEBUG_MARKER_STMTS
|| !building_stmt_list_p ())
1764 tree stmt
= build0 (DEBUG_BEGIN_STMT
, void_type_node
);
1765 SET_EXPR_LOCATION (stmt
, loc
);
1769 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1770 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1771 is accepted; otherwise (old-style parameter declarations) only other
1772 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1773 assertion is accepted; otherwise (old-style parameter declarations)
1774 it is not. If NESTED is true, we are inside a function or parsing
1775 old-style parameter declarations; any functions encountered are
1776 nested functions and declaration specifiers are required; otherwise
1777 we are at top level and functions are normal functions and
1778 declaration specifiers may be optional. If EMPTY_OK is true, empty
1779 declarations are OK (subject to all other constraints); otherwise
1780 (old-style parameter declarations) they are diagnosed. If
1781 START_ATTR_OK is true, the declaration specifiers may start with
1782 attributes (GNU or standard); otherwise they may not.
1783 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1784 declaration when parsing an Objective-C foreach statement.
1785 FALLTHRU_ATTR_P is used to signal whether this function parsed
1786 "__attribute__((fallthrough));". ATTRS are any standard attributes
1787 parsed in the caller (in contexts where such attributes had to be
1788 parsed to determine whether what follows is a declaration or a
1789 statement); HAVE_ATTRS says whether there were any such attributes
1793 declaration-specifiers init-declarator-list[opt] ;
1794 static_assert-declaration
1796 function-definition:
1797 declaration-specifiers[opt] declarator declaration-list[opt]
1802 declaration-list declaration
1804 init-declarator-list:
1806 init-declarator-list , init-declarator
1809 declarator simple-asm-expr[opt] gnu-attributes[opt]
1810 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1814 nested-function-definition:
1815 declaration-specifiers declarator declaration-list[opt]
1821 gnu-attributes objc-class-definition
1822 gnu-attributes objc-category-definition
1823 gnu-attributes objc-protocol-definition
1825 The simple-asm-expr and gnu-attributes are GNU extensions.
1827 This function does not handle __extension__; that is handled in its
1828 callers. ??? Following the old parser, __extension__ may start
1829 external declarations, declarations in functions and declarations
1830 at the start of "for" loops, but not old-style parameter
1833 C99 requires declaration specifiers in a function definition; the
1834 absence is diagnosed through the diagnosis of implicit int. In GNU
1835 C we also allow but diagnose declarations without declaration
1836 specifiers, but only at top level (elsewhere they conflict with
1839 In Objective-C, declarations of the looping variable in a foreach
1840 statement are exceptionally terminated by 'in' (for example, 'for
1841 (NSObject *object in array) { ... }').
1846 threadprivate-directive
1850 gimple-function-definition:
1851 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1852 declaration-list[opt] compound-statement
1854 rtl-function-definition:
1855 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1856 declaration-list[opt] compound-statement */
1859 c_parser_declaration_or_fndef (c_parser
*parser
, bool fndef_ok
,
1860 bool static_assert_ok
, bool empty_ok
,
1861 bool nested
, bool start_attr_ok
,
1862 tree
*objc_foreach_object_declaration
,
1863 vec
<c_token
> omp_declare_simd_clauses
,
1864 bool have_attrs
, tree attrs
,
1865 struct oacc_routine_data
*oacc_routine_data
,
1866 bool *fallthru_attr_p
)
1868 struct c_declspecs
*specs
;
1870 tree all_prefix_attrs
;
1871 bool diagnosed_no_specs
= false;
1872 location_t here
= c_parser_peek_token (parser
)->location
;
1874 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
1876 if (static_assert_ok
1877 && c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
1879 c_parser_static_assert_declaration (parser
);
1882 specs
= build_null_declspecs ();
1884 /* Handle any standard attributes parsed in the caller. */
1887 declspecs_add_attrs (here
, specs
, attrs
);
1888 specs
->non_std_attrs_seen_p
= false;
1891 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1892 if (c_parser_peek_token (parser
)->type
== CPP_NAME
1893 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
1894 && (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
1895 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
1896 && (!nested
|| !lookup_name (c_parser_peek_token (parser
)->value
)))
1898 tree name
= c_parser_peek_token (parser
)->value
;
1900 /* Issue a warning about NAME being an unknown type name, perhaps
1901 with some kind of hint.
1902 If the user forgot a "struct" etc, suggest inserting
1903 it. Otherwise, attempt to look for misspellings. */
1904 gcc_rich_location
richloc (here
);
1905 if (tag_exists_p (RECORD_TYPE
, name
))
1907 /* This is not C++ with its implicit typedef. */
1908 richloc
.add_fixit_insert_before ("struct ");
1910 "unknown type name %qE;"
1911 " use %<struct%> keyword to refer to the type",
1914 else if (tag_exists_p (UNION_TYPE
, name
))
1916 richloc
.add_fixit_insert_before ("union ");
1918 "unknown type name %qE;"
1919 " use %<union%> keyword to refer to the type",
1922 else if (tag_exists_p (ENUMERAL_TYPE
, name
))
1924 richloc
.add_fixit_insert_before ("enum ");
1926 "unknown type name %qE;"
1927 " use %<enum%> keyword to refer to the type",
1932 auto_diagnostic_group d
;
1933 name_hint hint
= lookup_name_fuzzy (name
, FUZZY_LOOKUP_TYPENAME
,
1935 if (const char *suggestion
= hint
.suggestion ())
1937 richloc
.add_fixit_replace (suggestion
);
1939 "unknown type name %qE; did you mean %qs?",
1943 error_at (here
, "unknown type name %qE", name
);
1946 /* Parse declspecs normally to get a correct pointer type, but avoid
1947 a further "fails to be a type name" error. Refuse nested functions
1948 since it is not how the user likely wants us to recover. */
1949 c_parser_peek_token (parser
)->type
= CPP_KEYWORD
;
1950 c_parser_peek_token (parser
)->keyword
= RID_VOID
;
1951 c_parser_peek_token (parser
)->value
= error_mark_node
;
1955 /* When there are standard attributes at the start of the
1956 declaration (to apply to the entity being declared), an
1957 init-declarator-list or function definition must be present. */
1958 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
1961 c_parser_declspecs (parser
, specs
, true, true, start_attr_ok
,
1962 true, true, start_attr_ok
, true, cla_nonabstract_decl
);
1965 c_parser_skip_to_end_of_block_or_statement (parser
);
1968 if (nested
&& !specs
->declspecs_seen_p
)
1970 c_parser_error (parser
, "expected declaration specifiers");
1971 c_parser_skip_to_end_of_block_or_statement (parser
);
1975 finish_declspecs (specs
);
1976 bool auto_type_p
= specs
->typespec_word
== cts_auto_type
;
1977 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
1980 error_at (here
, "%<__auto_type%> in empty declaration");
1981 else if (specs
->typespec_kind
== ctsk_none
1982 && attribute_fallthrough_p (specs
->attrs
))
1984 if (fallthru_attr_p
!= NULL
)
1985 *fallthru_attr_p
= true;
1988 tree fn
= build_call_expr_internal_loc (here
, IFN_FALLTHROUGH
,
1993 pedwarn (here
, OPT_Wattributes
,
1994 "%<fallthrough%> attribute at top level");
1996 else if (empty_ok
&& !(have_attrs
1997 && specs
->non_std_attrs_seen_p
))
2001 shadow_tag_warned (specs
, 1);
2002 pedwarn (here
, 0, "empty declaration");
2004 c_parser_consume_token (parser
);
2005 if (oacc_routine_data
)
2006 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2010 /* Provide better error recovery. Note that a type name here is usually
2011 better diagnosed as a redeclaration. */
2013 && specs
->typespec_kind
== ctsk_tagdef
2014 && c_parser_next_token_starts_declspecs (parser
)
2015 && !c_parser_next_token_is (parser
, CPP_NAME
))
2017 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
2018 parser
->error
= false;
2019 shadow_tag_warned (specs
, 1);
2022 else if (c_dialect_objc () && !auto_type_p
)
2024 /* Prefix attributes are an error on method decls. */
2025 switch (c_parser_peek_token (parser
)->type
)
2029 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2033 warning_at (c_parser_peek_token (parser
)->location
,
2035 "prefix attributes are ignored for methods");
2036 specs
->attrs
= NULL_TREE
;
2039 c_parser_objc_method_definition (parser
);
2041 c_parser_objc_methodproto (parser
);
2047 /* This is where we parse 'attributes @interface ...',
2048 'attributes @implementation ...', 'attributes @protocol ...'
2049 (where attributes could be, for example, __attribute__
2052 switch (c_parser_peek_token (parser
)->keyword
)
2054 case RID_AT_INTERFACE
:
2056 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2058 c_parser_objc_class_definition (parser
, specs
->attrs
);
2062 case RID_AT_IMPLEMENTATION
:
2064 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2068 warning_at (c_parser_peek_token (parser
)->location
,
2070 "prefix attributes are ignored for implementations");
2071 specs
->attrs
= NULL_TREE
;
2073 c_parser_objc_class_definition (parser
, NULL_TREE
);
2077 case RID_AT_PROTOCOL
:
2079 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2081 c_parser_objc_protocol_definition (parser
, specs
->attrs
);
2088 case RID_AT_PROPERTY
:
2091 c_parser_error (parser
, "unexpected attribute");
2092 specs
->attrs
= NULL
;
2099 else if (attribute_fallthrough_p (specs
->attrs
))
2100 warning_at (here
, OPT_Wattributes
,
2101 "%<fallthrough%> attribute not followed by %<;%>");
2103 pending_xref_error ();
2104 prefix_attrs
= specs
->attrs
;
2105 all_prefix_attrs
= prefix_attrs
;
2106 specs
->attrs
= NULL_TREE
;
2109 struct c_declarator
*declarator
;
2112 tree fnbody
= NULL_TREE
;
2113 /* Declaring either one or more declarators (in which case we
2114 should diagnose if there were no declaration specifiers) or a
2115 function definition (in which case the diagnostic for
2116 implicit int suffices). */
2117 declarator
= c_parser_declarator (parser
,
2118 specs
->typespec_kind
!= ctsk_none
,
2119 C_DTR_NORMAL
, &dummy
);
2120 if (declarator
== NULL
)
2122 if (omp_declare_simd_clauses
.exists ())
2123 c_finish_omp_declare_simd (parser
, NULL_TREE
, NULL_TREE
,
2124 omp_declare_simd_clauses
);
2125 if (oacc_routine_data
)
2126 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2127 c_parser_skip_to_end_of_block_or_statement (parser
);
2130 if (auto_type_p
&& declarator
->kind
!= cdk_id
)
2133 "%<__auto_type%> requires a plain identifier"
2135 c_parser_skip_to_end_of_block_or_statement (parser
);
2138 if (c_parser_next_token_is (parser
, CPP_EQ
)
2139 || c_parser_next_token_is (parser
, CPP_COMMA
)
2140 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
2141 || c_parser_next_token_is_keyword (parser
, RID_ASM
)
2142 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
)
2143 || c_parser_next_token_is_keyword (parser
, RID_IN
))
2145 tree asm_name
= NULL_TREE
;
2146 tree postfix_attrs
= NULL_TREE
;
2147 if (!diagnosed_no_specs
&& !specs
->declspecs_seen_p
)
2149 diagnosed_no_specs
= true;
2150 pedwarn (here
, 0, "data definition has no type or storage class");
2152 /* Having seen a data definition, there cannot now be a
2153 function definition. */
2155 if (c_parser_next_token_is_keyword (parser
, RID_ASM
))
2156 asm_name
= c_parser_simple_asm_expr (parser
);
2157 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2159 postfix_attrs
= c_parser_gnu_attributes (parser
);
2160 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2162 /* This means there is an attribute specifier after
2163 the declarator in a function definition. Provide
2164 some more information for the user. */
2165 error_at (here
, "attributes should be specified before the "
2166 "declarator in a function definition");
2167 c_parser_skip_to_end_of_block_or_statement (parser
);
2171 if (c_parser_next_token_is (parser
, CPP_EQ
))
2175 location_t init_loc
;
2176 c_parser_consume_token (parser
);
2179 init_loc
= c_parser_peek_token (parser
)->location
;
2180 rich_location
richloc (line_table
, init_loc
);
2181 start_init (NULL_TREE
, asm_name
, global_bindings_p (), &richloc
);
2182 /* A parameter is initialized, which is invalid. Don't
2183 attempt to instrument the initializer. */
2184 int flag_sanitize_save
= flag_sanitize
;
2185 if (nested
&& !empty_ok
)
2187 init
= c_parser_expr_no_commas (parser
, NULL
);
2188 flag_sanitize
= flag_sanitize_save
;
2189 if (TREE_CODE (init
.value
) == COMPONENT_REF
2190 && DECL_C_BIT_FIELD (TREE_OPERAND (init
.value
, 1)))
2192 "%<__auto_type%> used with a bit-field"
2194 init
= convert_lvalue_to_rvalue (init_loc
, init
, true, true);
2195 tree init_type
= TREE_TYPE (init
.value
);
2196 /* As with typeof, remove all qualifiers from atomic types. */
2197 if (init_type
!= error_mark_node
&& TYPE_ATOMIC (init_type
))
2199 = c_build_qualified_type (init_type
, TYPE_UNQUALIFIED
);
2200 bool vm_type
= variably_modified_type_p (init_type
,
2203 init
.value
= save_expr (init
.value
);
2205 specs
->typespec_kind
= ctsk_typeof
;
2206 specs
->locations
[cdw_typedef
] = init_loc
;
2207 specs
->typedef_p
= true;
2208 specs
->type
= init_type
;
2211 bool maybe_const
= true;
2212 tree type_expr
= c_fully_fold (init
.value
, false,
2214 specs
->expr_const_operands
&= maybe_const
;
2216 specs
->expr
= build2 (COMPOUND_EXPR
,
2217 TREE_TYPE (type_expr
),
2218 specs
->expr
, type_expr
);
2220 specs
->expr
= type_expr
;
2222 d
= start_decl (declarator
, specs
, true,
2223 chainon (postfix_attrs
, all_prefix_attrs
));
2225 d
= error_mark_node
;
2226 if (omp_declare_simd_clauses
.exists ())
2227 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2228 omp_declare_simd_clauses
);
2232 /* The declaration of the variable is in effect while
2233 its initializer is parsed. */
2234 d
= start_decl (declarator
, specs
, true,
2235 chainon (postfix_attrs
, all_prefix_attrs
));
2237 d
= error_mark_node
;
2238 if (omp_declare_simd_clauses
.exists ())
2239 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2240 omp_declare_simd_clauses
);
2241 init_loc
= c_parser_peek_token (parser
)->location
;
2242 rich_location
richloc (line_table
, init_loc
);
2243 start_init (d
, asm_name
, global_bindings_p (), &richloc
);
2244 /* A parameter is initialized, which is invalid. Don't
2245 attempt to instrument the initializer. */
2246 int flag_sanitize_save
= flag_sanitize
;
2247 if (TREE_CODE (d
) == PARM_DECL
)
2249 init
= c_parser_initializer (parser
);
2250 flag_sanitize
= flag_sanitize_save
;
2253 if (oacc_routine_data
)
2254 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2255 if (d
!= error_mark_node
)
2257 maybe_warn_string_init (init_loc
, TREE_TYPE (d
), init
);
2258 finish_decl (d
, init_loc
, init
.value
,
2259 init
.original_type
, asm_name
);
2267 "%<__auto_type%> requires an initialized "
2268 "data declaration");
2269 c_parser_skip_to_end_of_block_or_statement (parser
);
2272 tree d
= start_decl (declarator
, specs
, false,
2273 chainon (postfix_attrs
,
2276 && TREE_CODE (d
) == FUNCTION_DECL
2277 && DECL_ARGUMENTS (d
) == NULL_TREE
2278 && DECL_INITIAL (d
) == NULL_TREE
)
2280 /* Find the innermost declarator that is neither cdk_id
2282 const struct c_declarator
*decl
= declarator
;
2283 const struct c_declarator
*last_non_id_attrs
= NULL
;
2291 last_non_id_attrs
= decl
;
2292 decl
= decl
->declarator
;
2296 decl
= decl
->declarator
;
2307 /* If it exists and is cdk_function, use its parameters. */
2308 if (last_non_id_attrs
2309 && last_non_id_attrs
->kind
== cdk_function
)
2310 DECL_ARGUMENTS (d
) = last_non_id_attrs
->u
.arg_info
->parms
;
2312 if (omp_declare_simd_clauses
.exists ())
2314 tree parms
= NULL_TREE
;
2315 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2317 struct c_declarator
*ce
= declarator
;
2319 if (ce
->kind
== cdk_function
)
2321 parms
= ce
->u
.arg_info
->parms
;
2325 ce
= ce
->declarator
;
2328 temp_store_parm_decls (d
, parms
);
2329 c_finish_omp_declare_simd (parser
, d
, parms
,
2330 omp_declare_simd_clauses
);
2332 temp_pop_parm_decls ();
2334 if (oacc_routine_data
)
2335 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2337 finish_decl (d
, UNKNOWN_LOCATION
, NULL_TREE
,
2338 NULL_TREE
, asm_name
);
2340 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2343 *objc_foreach_object_declaration
= d
;
2345 *objc_foreach_object_declaration
= error_mark_node
;
2348 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2353 "%<__auto_type%> may only be used with"
2354 " a single declarator");
2355 c_parser_skip_to_end_of_block_or_statement (parser
);
2358 c_parser_consume_token (parser
);
2359 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2360 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
2363 all_prefix_attrs
= prefix_attrs
;
2366 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2368 c_parser_consume_token (parser
);
2371 else if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2373 /* This can only happen in Objective-C: we found the
2374 'in' that terminates the declaration inside an
2375 Objective-C foreach statement. Do not consume the
2376 token, so that the caller can use it to determine
2377 that this indeed is a foreach context. */
2382 c_parser_error (parser
, "expected %<,%> or %<;%>");
2383 c_parser_skip_to_end_of_block_or_statement (parser
);
2387 else if (auto_type_p
)
2390 "%<__auto_type%> requires an initialized data declaration");
2391 c_parser_skip_to_end_of_block_or_statement (parser
);
2396 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, "
2397 "%<asm%> or %<__attribute__%>");
2398 c_parser_skip_to_end_of_block_or_statement (parser
);
2401 /* Function definition (nested or otherwise). */
2404 pedwarn (here
, OPT_Wpedantic
, "ISO C forbids nested functions");
2405 c_push_function_context ();
2407 if (!start_function (specs
, declarator
, all_prefix_attrs
))
2409 /* At this point we've consumed:
2410 declaration-specifiers declarator
2411 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2412 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2414 declaration-specifiers declarator
2415 aren't grokkable as a function definition, so we have
2417 gcc_assert (!c_parser_next_token_is (parser
, CPP_SEMICOLON
));
2418 if (c_parser_next_token_starts_declspecs (parser
))
2421 declaration-specifiers declarator decl-specs
2422 then assume we have a missing semicolon, which would
2424 declaration-specifiers declarator decl-specs
2427 <~~~~~~~~~ declaration ~~~~~~~~~~>
2428 Use c_parser_require to get an error with a fix-it hint. */
2429 c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>");
2430 parser
->error
= false;
2434 /* This can appear in many cases looking nothing like a
2435 function definition, so we don't give a more specific
2436 error suggesting there was one. */
2437 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2438 "or %<__attribute__%>");
2441 c_pop_function_context ();
2445 if (DECL_DECLARED_INLINE_P (current_function_decl
))
2446 tv
= TV_PARSE_INLINE
;
2449 auto_timevar
at (g_timer
, tv
);
2451 /* Parse old-style parameter declarations. ??? Attributes are
2452 not allowed to start declaration specifiers here because of a
2453 syntax conflict between a function declaration with attribute
2454 suffix and a function definition with an attribute prefix on
2455 first old-style parameter declaration. Following the old
2456 parser, they are not accepted on subsequent old-style
2457 parameter declarations either. However, there is no
2458 ambiguity after the first declaration, nor indeed on the
2459 first as long as we don't allow postfix attributes after a
2460 declarator with a nonempty identifier list in a definition;
2461 and postfix attributes have never been accepted here in
2462 function definitions either. */
2463 while (c_parser_next_token_is_not (parser
, CPP_EOF
)
2464 && c_parser_next_token_is_not (parser
, CPP_OPEN_BRACE
))
2465 c_parser_declaration_or_fndef (parser
, false, false, false,
2466 true, false, NULL
, vNULL
);
2467 store_parm_decls ();
2468 if (omp_declare_simd_clauses
.exists ())
2469 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2470 omp_declare_simd_clauses
);
2471 if (oacc_routine_data
)
2472 c_finish_oacc_routine (oacc_routine_data
, current_function_decl
, true);
2473 DECL_STRUCT_FUNCTION (current_function_decl
)->function_start_locus
2474 = c_parser_peek_token (parser
)->location
;
2476 /* If the definition was marked with __RTL, use the RTL parser now,
2477 consuming the function body. */
2478 if (specs
->declspec_il
== cdil_rtl
)
2480 c_parser_parse_rtl_body (parser
, specs
->gimple_or_rtl_pass
);
2482 /* Normally, store_parm_decls sets next_is_function_body,
2483 anticipating a function body. We need a push_scope/pop_scope
2484 pair to flush out this state, or subsequent function parsing
2492 /* If the definition was marked with __GIMPLE then parse the
2493 function body as GIMPLE. */
2494 else if (specs
->declspec_il
!= cdil_none
)
2496 bool saved
= in_late_binary_op
;
2497 in_late_binary_op
= true;
2498 c_parser_parse_gimple_body (parser
, specs
->gimple_or_rtl_pass
,
2500 specs
->entry_bb_count
);
2501 in_late_binary_op
= saved
;
2504 fnbody
= c_parser_compound_statement (parser
);
2505 tree fndecl
= current_function_decl
;
2508 tree decl
= current_function_decl
;
2509 /* Mark nested functions as needing static-chain initially.
2510 lower_nested_functions will recompute it but the
2511 DECL_STATIC_CHAIN flag is also used before that happens,
2512 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2513 DECL_STATIC_CHAIN (decl
) = 1;
2516 c_pop_function_context ();
2517 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl
), DECL_EXPR
, decl
));
2525 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2526 if (specs
->declspec_il
!= cdil_none
)
2527 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
2533 /* Parse an asm-definition (asm() outside a function body). This is a
2541 c_parser_asm_definition (c_parser
*parser
)
2543 tree asm_str
= c_parser_simple_asm_expr (parser
);
2545 symtab
->finalize_toplevel_asm (asm_str
);
2546 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
2549 /* Parse a static assertion (C11 6.7.10).
2551 static_assert-declaration:
2552 static_assert-declaration-no-semi ;
2556 c_parser_static_assert_declaration (c_parser
*parser
)
2558 c_parser_static_assert_declaration_no_semi (parser
);
2560 || !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
2561 c_parser_skip_to_end_of_block_or_statement (parser
);
2564 /* Parse a static assertion (C11 6.7.10), without the trailing
2567 static_assert-declaration-no-semi:
2568 _Static_assert ( constant-expression , string-literal )
2571 static_assert-declaration-no-semi:
2572 _Static_assert ( constant-expression )
2576 c_parser_static_assert_declaration_no_semi (c_parser
*parser
)
2578 location_t assert_loc
, value_loc
;
2580 tree string
= NULL_TREE
;
2582 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
));
2583 assert_loc
= c_parser_peek_token (parser
)->location
;
2585 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2586 "ISO C99 does not support %<_Static_assert%>");
2588 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2589 "ISO C90 does not support %<_Static_assert%>");
2590 c_parser_consume_token (parser
);
2591 matching_parens parens
;
2592 if (!parens
.require_open (parser
))
2594 location_t value_tok_loc
= c_parser_peek_token (parser
)->location
;
2595 value
= c_parser_expr_no_commas (parser
, NULL
).value
;
2596 value_loc
= EXPR_LOC_OR_LOC (value
, value_tok_loc
);
2597 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2599 c_parser_consume_token (parser
);
2600 switch (c_parser_peek_token (parser
)->type
)
2606 case CPP_UTF8STRING
:
2607 string
= c_parser_string_literal (parser
, false, true).value
;
2610 c_parser_error (parser
, "expected string literal");
2614 else if (flag_isoc11
)
2615 /* If pedantic for pre-C11, the use of _Static_assert itself will
2616 have been diagnosed, so do not also diagnose the use of this
2617 new C2X feature of _Static_assert. */
2618 pedwarn_c11 (assert_loc
, OPT_Wpedantic
,
2619 "ISO C11 does not support omitting the string in "
2620 "%<_Static_assert%>");
2621 parens
.require_close (parser
);
2623 if (!INTEGRAL_TYPE_P (TREE_TYPE (value
)))
2625 error_at (value_loc
, "expression in static assertion is not an integer");
2628 if (TREE_CODE (value
) != INTEGER_CST
)
2630 value
= c_fully_fold (value
, false, NULL
);
2631 /* Strip no-op conversions. */
2632 STRIP_TYPE_NOPS (value
);
2633 if (TREE_CODE (value
) == INTEGER_CST
)
2634 pedwarn (value_loc
, OPT_Wpedantic
, "expression in static assertion "
2635 "is not an integer constant expression");
2637 if (TREE_CODE (value
) != INTEGER_CST
)
2639 error_at (value_loc
, "expression in static assertion is not constant");
2642 constant_expression_warning (value
);
2643 if (integer_zerop (value
))
2646 error_at (assert_loc
, "static assertion failed: %E", string
);
2648 error_at (assert_loc
, "static assertion failed");
2652 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2653 6.7, C11 6.7), adding them to SPECS (which may already include some).
2654 Storage class specifiers are accepted iff SCSPEC_OK; type
2655 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2656 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2657 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2658 addition to the syntax shown, standard attributes are accepted at
2659 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2660 unlike gnu-attributes, they are not accepted in the middle of the
2661 list. (This combines various different syntax productions in the C
2662 standard, and in some cases gnu-attributes and standard attributes
2663 at the start may already have been parsed before this function is
2666 declaration-specifiers:
2667 storage-class-specifier declaration-specifiers[opt]
2668 type-specifier declaration-specifiers[opt]
2669 type-qualifier declaration-specifiers[opt]
2670 function-specifier declaration-specifiers[opt]
2671 alignment-specifier declaration-specifiers[opt]
2673 Function specifiers (inline) are from C99, and are currently
2674 handled as storage class specifiers, as is __thread. Alignment
2675 specifiers are from C11.
2677 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2678 storage-class-specifier:
2686 (_Thread_local is new in C11.)
2688 C99 6.7.4, C11 6.7.4:
2693 (_Noreturn is new in C11.)
2695 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2708 [_Imaginary removed in C99 TC2]
2709 struct-or-union-specifier
2712 atomic-type-specifier
2714 (_Bool and _Complex are new in C99.)
2715 (atomic-type-specifier is new in C11.)
2717 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2723 address-space-qualifier
2726 (restrict is new in C99.)
2727 (_Atomic is new in C11.)
2731 declaration-specifiers:
2732 gnu-attributes declaration-specifiers[opt]
2738 identifier recognized by the target
2740 storage-class-specifier:
2754 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2755 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2757 atomic-type-specifier
2758 _Atomic ( type-name )
2763 class-name objc-protocol-refs[opt]
2764 typedef-name objc-protocol-refs
2769 c_parser_declspecs (c_parser
*parser
, struct c_declspecs
*specs
,
2770 bool scspec_ok
, bool typespec_ok
, bool start_attr_ok
,
2771 bool alignspec_ok
, bool auto_type_ok
,
2772 bool start_std_attr_ok
, bool end_std_attr_ok
,
2773 enum c_lookahead_kind la
)
2775 bool attrs_ok
= start_attr_ok
;
2776 bool seen_type
= specs
->typespec_kind
!= ctsk_none
;
2779 gcc_assert (la
== cla_prefer_id
);
2781 if (start_std_attr_ok
2782 && c_parser_nth_token_starts_std_attributes (parser
, 1))
2784 gcc_assert (!specs
->non_std_attrs_seen_p
);
2785 location_t loc
= c_parser_peek_token (parser
)->location
;
2786 tree attrs
= c_parser_std_attribute_specifier_sequence (parser
);
2787 declspecs_add_attrs (loc
, specs
, attrs
);
2788 specs
->non_std_attrs_seen_p
= false;
2791 while (c_parser_next_token_is (parser
, CPP_NAME
)
2792 || c_parser_next_token_is (parser
, CPP_KEYWORD
)
2793 || (c_dialect_objc () && c_parser_next_token_is (parser
, CPP_LESS
)))
2795 struct c_typespec t
;
2798 location_t loc
= c_parser_peek_token (parser
)->location
;
2800 /* If we cannot accept a type, exit if the next token must start
2801 one. Also, if we already have seen a tagged definition,
2802 a typename would be an error anyway and likely the user
2803 has simply forgotten a semicolon, so we exit. */
2804 if ((!typespec_ok
|| specs
->typespec_kind
== ctsk_tagdef
)
2805 && c_parser_next_tokens_start_typename (parser
, la
)
2806 && !c_parser_next_token_is_qualifier (parser
)
2807 && !c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
))
2810 if (c_parser_next_token_is (parser
, CPP_NAME
))
2812 c_token
*name_token
= c_parser_peek_token (parser
);
2813 tree value
= name_token
->value
;
2814 c_id_kind kind
= name_token
->id_kind
;
2816 if (kind
== C_ID_ADDRSPACE
)
2819 = name_token
->keyword
- RID_FIRST_ADDR_SPACE
;
2820 declspecs_add_addrspace (name_token
->location
, specs
, as
);
2821 c_parser_consume_token (parser
);
2826 gcc_assert (!c_parser_next_token_is_qualifier (parser
));
2828 /* If we cannot accept a type, and the next token must start one,
2829 exit. Do the same if we already have seen a tagged definition,
2830 since it would be an error anyway and likely the user has simply
2831 forgotten a semicolon. */
2832 if (seen_type
|| !c_parser_next_tokens_start_typename (parser
, la
))
2835 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2836 a C_ID_CLASSNAME. */
2837 c_parser_consume_token (parser
);
2840 if (kind
== C_ID_ID
)
2842 error_at (loc
, "unknown type name %qE", value
);
2843 t
.kind
= ctsk_typedef
;
2844 t
.spec
= error_mark_node
;
2846 else if (kind
== C_ID_TYPENAME
2847 && (!c_dialect_objc ()
2848 || c_parser_next_token_is_not (parser
, CPP_LESS
)))
2850 t
.kind
= ctsk_typedef
;
2851 /* For a typedef name, record the meaning, not the name.
2852 In case of 'foo foo, bar;'. */
2853 t
.spec
= lookup_name (value
);
2857 tree proto
= NULL_TREE
;
2858 gcc_assert (c_dialect_objc ());
2860 if (c_parser_next_token_is (parser
, CPP_LESS
))
2861 proto
= c_parser_objc_protocol_refs (parser
);
2862 t
.spec
= objc_get_protocol_qualified_type (value
, proto
);
2865 t
.expr_const_operands
= true;
2866 declspecs_add_type (name_token
->location
, specs
, t
);
2869 if (c_parser_next_token_is (parser
, CPP_LESS
))
2871 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2872 nisse@lysator.liu.se. */
2874 gcc_assert (c_dialect_objc ());
2875 if (!typespec_ok
|| seen_type
)
2877 proto
= c_parser_objc_protocol_refs (parser
);
2879 t
.spec
= objc_get_protocol_qualified_type (NULL_TREE
, proto
);
2881 t
.expr_const_operands
= true;
2882 declspecs_add_type (loc
, specs
, t
);
2885 gcc_assert (c_parser_next_token_is (parser
, CPP_KEYWORD
));
2886 switch (c_parser_peek_token (parser
)->keyword
)
2899 /* TODO: Distinguish between function specifiers (inline, noreturn)
2900 and storage class specifiers, either here or in
2901 declspecs_add_scspec. */
2902 declspecs_add_scspec (loc
, specs
,
2903 c_parser_peek_token (parser
)->value
);
2904 c_parser_consume_token (parser
);
2936 if (c_dialect_objc ())
2937 parser
->objc_need_raw_identifier
= true;
2938 t
.kind
= ctsk_resword
;
2939 t
.spec
= c_parser_peek_token (parser
)->value
;
2941 t
.expr_const_operands
= true;
2942 declspecs_add_type (loc
, specs
, t
);
2943 c_parser_consume_token (parser
);
2950 t
= c_parser_enum_specifier (parser
);
2951 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
2952 declspecs_add_type (loc
, specs
, t
);
2960 t
= c_parser_struct_or_union_specifier (parser
);
2961 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
2962 declspecs_add_type (loc
, specs
, t
);
2965 /* ??? The old parser rejected typeof after other type
2966 specifiers, but is a syntax error the best way of
2968 if (!typespec_ok
|| seen_type
)
2972 t
= c_parser_typeof_specifier (parser
);
2973 declspecs_add_type (loc
, specs
, t
);
2976 /* C parser handling of Objective-C constructs needs
2977 checking for correct lvalue-to-rvalue conversions, and
2978 the code in build_modify_expr handling various
2979 Objective-C cases, and that in build_unary_op handling
2980 Objective-C cases for increment / decrement, also needs
2981 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
2982 and objc_types_are_equivalent may also need updates. */
2983 if (c_dialect_objc ())
2984 sorry ("%<_Atomic%> in Objective-C");
2986 pedwarn_c99 (loc
, OPT_Wpedantic
,
2987 "ISO C99 does not support the %<_Atomic%> qualifier");
2989 pedwarn_c99 (loc
, OPT_Wpedantic
,
2990 "ISO C90 does not support the %<_Atomic%> qualifier");
2993 value
= c_parser_peek_token (parser
)->value
;
2994 c_parser_consume_token (parser
);
2995 if (typespec_ok
&& c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
2997 /* _Atomic ( type-name ). */
2999 c_parser_consume_token (parser
);
3000 struct c_type_name
*type
= c_parser_type_name (parser
);
3001 t
.kind
= ctsk_typeof
;
3002 t
.spec
= error_mark_node
;
3004 t
.expr_const_operands
= true;
3006 t
.spec
= groktypename (type
, &t
.expr
,
3007 &t
.expr_const_operands
);
3008 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3010 if (t
.spec
!= error_mark_node
)
3012 if (TREE_CODE (t
.spec
) == ARRAY_TYPE
)
3013 error_at (loc
, "%<_Atomic%>-qualified array type");
3014 else if (TREE_CODE (t
.spec
) == FUNCTION_TYPE
)
3015 error_at (loc
, "%<_Atomic%>-qualified function type");
3016 else if (TYPE_QUALS (t
.spec
) != TYPE_UNQUALIFIED
)
3017 error_at (loc
, "%<_Atomic%> applied to a qualified type");
3019 t
.spec
= c_build_qualified_type (t
.spec
, TYPE_QUAL_ATOMIC
);
3021 declspecs_add_type (loc
, specs
, t
);
3024 declspecs_add_qual (loc
, specs
, value
);
3030 declspecs_add_qual (loc
, specs
, c_parser_peek_token (parser
)->value
);
3031 c_parser_consume_token (parser
);
3036 attrs
= c_parser_gnu_attributes (parser
);
3037 declspecs_add_attrs (loc
, specs
, attrs
);
3042 align
= c_parser_alignas_specifier (parser
);
3043 declspecs_add_alignas (loc
, specs
, align
);
3047 error_at (loc
, "%<__GIMPLE%> only valid with %<-fgimple%>");
3048 c_parser_consume_token (parser
);
3049 specs
->declspec_il
= cdil_gimple
;
3050 specs
->locations
[cdw_gimple
] = loc
;
3051 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3054 c_parser_consume_token (parser
);
3055 specs
->declspec_il
= cdil_rtl
;
3056 specs
->locations
[cdw_rtl
] = loc
;
3057 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3065 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3066 specs
->postfix_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3069 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3072 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3074 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3076 enum gnu-attributes[opt] identifier
3078 The form with trailing comma is new in C99. The forms with
3079 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3080 without commas in the syntax (assignment expressions, not just
3081 conditional expressions); assignment expressions will be diagnosed
3086 enumerator-list , enumerator
3089 enumeration-constant attribute-specifier-sequence[opt]
3090 enumeration-constant attribute-specifier-sequence[opt]
3091 = constant-expression
3096 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3097 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3098 = constant-expression
3102 static struct c_typespec
3103 c_parser_enum_specifier (c_parser
*parser
)
3105 struct c_typespec ret
;
3106 bool have_std_attrs
;
3107 tree std_attrs
= NULL_TREE
;
3109 tree ident
= NULL_TREE
;
3110 location_t enum_loc
;
3111 location_t ident_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3112 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ENUM
));
3113 c_parser_consume_token (parser
);
3114 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3116 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3117 attrs
= c_parser_gnu_attributes (parser
);
3118 enum_loc
= c_parser_peek_token (parser
)->location
;
3119 /* Set the location in case we create a decl now. */
3120 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3121 if (c_parser_next_token_is (parser
, CPP_NAME
))
3123 ident
= c_parser_peek_token (parser
)->value
;
3124 ident_loc
= c_parser_peek_token (parser
)->location
;
3125 enum_loc
= ident_loc
;
3126 c_parser_consume_token (parser
);
3128 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3130 /* Parse an enum definition. */
3131 struct c_enum_contents the_enum
;
3134 /* We chain the enumerators in reverse order, then put them in
3135 forward order at the end. */
3137 timevar_push (TV_PARSE_ENUM
);
3138 type
= start_enum (enum_loc
, &the_enum
, ident
);
3140 c_parser_consume_token (parser
);
3148 location_t comma_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3149 location_t decl_loc
, value_loc
;
3150 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
3152 /* Give a nicer error for "enum {}". */
3153 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3156 error_at (c_parser_peek_token (parser
)->location
,
3157 "empty enum is invalid");
3158 parser
->error
= true;
3161 c_parser_error (parser
, "expected identifier");
3162 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3163 values
= error_mark_node
;
3166 token
= c_parser_peek_token (parser
);
3167 enum_id
= token
->value
;
3168 /* Set the location in case we create a decl now. */
3169 c_parser_set_source_position_from_token (token
);
3170 decl_loc
= value_loc
= token
->location
;
3171 c_parser_consume_token (parser
);
3172 /* Parse any specified attributes. */
3173 tree std_attrs
= NULL_TREE
;
3174 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3175 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3176 tree enum_attrs
= chainon (std_attrs
,
3177 c_parser_gnu_attributes (parser
));
3178 if (c_parser_next_token_is (parser
, CPP_EQ
))
3180 c_parser_consume_token (parser
);
3181 value_loc
= c_parser_peek_token (parser
)->location
;
3182 enum_value
= c_parser_expr_no_commas (parser
, NULL
).value
;
3185 enum_value
= NULL_TREE
;
3186 enum_decl
= build_enumerator (decl_loc
, value_loc
,
3187 &the_enum
, enum_id
, enum_value
);
3189 decl_attributes (&TREE_PURPOSE (enum_decl
), enum_attrs
, 0);
3190 TREE_CHAIN (enum_decl
) = values
;
3193 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3195 comma_loc
= c_parser_peek_token (parser
)->location
;
3197 c_parser_consume_token (parser
);
3199 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3202 pedwarn_c90 (comma_loc
, OPT_Wpedantic
,
3203 "comma at end of enumerator list");
3204 c_parser_consume_token (parser
);
3209 c_parser_error (parser
, "expected %<,%> or %<}%>");
3210 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3211 values
= error_mark_node
;
3215 postfix_attrs
= c_parser_gnu_attributes (parser
);
3216 ret
.spec
= finish_enum (type
, nreverse (values
),
3218 chainon (attrs
, postfix_attrs
)));
3219 ret
.kind
= ctsk_tagdef
;
3220 ret
.expr
= NULL_TREE
;
3221 ret
.expr_const_operands
= true;
3222 timevar_pop (TV_PARSE_ENUM
);
3227 c_parser_error (parser
, "expected %<{%>");
3228 ret
.spec
= error_mark_node
;
3229 ret
.kind
= ctsk_tagref
;
3230 ret
.expr
= NULL_TREE
;
3231 ret
.expr_const_operands
= true;
3234 /* Attributes may only appear when the members are defined or in
3235 certain forward declarations (treat enum forward declarations in
3236 GNU C analogously to struct and union forward declarations in
3238 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3239 c_parser_error (parser
, "expected %<;%>");
3240 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
, have_std_attrs
,
3242 /* In ISO C, enumerated types can be referred to only if already
3244 if (pedantic
&& !COMPLETE_TYPE_P (ret
.spec
))
3247 pedwarn (enum_loc
, OPT_Wpedantic
,
3248 "ISO C forbids forward references to %<enum%> types");
3253 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3255 struct-or-union-specifier:
3256 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3257 identifier[opt] { struct-contents } gnu-attributes[opt]
3258 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3262 struct-declaration-list
3264 struct-declaration-list:
3265 struct-declaration ;
3266 struct-declaration-list struct-declaration ;
3273 struct-declaration-list struct-declaration
3275 struct-declaration-list:
3276 struct-declaration-list ;
3279 (Note that in the syntax here, unlike that in ISO C, the semicolons
3280 are included here rather than in struct-declaration, in order to
3281 describe the syntax with extra semicolons and missing semicolon at
3286 struct-declaration-list:
3287 @defs ( class-name )
3289 (Note this does not include a trailing semicolon, but can be
3290 followed by further declarations, and gets a pedwarn-if-pedantic
3291 when followed by a semicolon.) */
3293 static struct c_typespec
3294 c_parser_struct_or_union_specifier (c_parser
*parser
)
3296 struct c_typespec ret
;
3297 bool have_std_attrs
;
3298 tree std_attrs
= NULL_TREE
;
3300 tree ident
= NULL_TREE
;
3301 location_t struct_loc
;
3302 location_t ident_loc
= UNKNOWN_LOCATION
;
3303 enum tree_code code
;
3304 switch (c_parser_peek_token (parser
)->keyword
)
3315 struct_loc
= c_parser_peek_token (parser
)->location
;
3316 c_parser_consume_token (parser
);
3317 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3319 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3320 attrs
= c_parser_gnu_attributes (parser
);
3322 /* Set the location in case we create a decl now. */
3323 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3325 if (c_parser_next_token_is (parser
, CPP_NAME
))
3327 ident
= c_parser_peek_token (parser
)->value
;
3328 ident_loc
= c_parser_peek_token (parser
)->location
;
3329 struct_loc
= ident_loc
;
3330 c_parser_consume_token (parser
);
3332 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3334 /* Parse a struct or union definition. Start the scope of the
3335 tag before parsing components. */
3336 class c_struct_parse_info
*struct_info
;
3337 tree type
= start_struct (struct_loc
, code
, ident
, &struct_info
);
3339 /* We chain the components in reverse order, then put them in
3340 forward order at the end. Each struct-declaration may
3341 declare multiple components (comma-separated), so we must use
3342 chainon to join them, although when parsing each
3343 struct-declaration we can use TREE_CHAIN directly.
3345 The theory behind all this is that there will be more
3346 semicolon separated fields than comma separated fields, and
3347 so we'll be minimizing the number of node traversals required
3350 timevar_push (TV_PARSE_STRUCT
);
3351 contents
= NULL_TREE
;
3352 c_parser_consume_token (parser
);
3353 /* Handle the Objective-C @defs construct,
3354 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3355 if (c_parser_next_token_is_keyword (parser
, RID_AT_DEFS
))
3358 gcc_assert (c_dialect_objc ());
3359 c_parser_consume_token (parser
);
3360 matching_parens parens
;
3361 if (!parens
.require_open (parser
))
3363 if (c_parser_next_token_is (parser
, CPP_NAME
)
3364 && c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
)
3366 name
= c_parser_peek_token (parser
)->value
;
3367 c_parser_consume_token (parser
);
3371 c_parser_error (parser
, "expected class name");
3372 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
3375 parens
.skip_until_found_close (parser
);
3376 contents
= nreverse (objc_get_class_ivars (name
));
3379 /* Parse the struct-declarations and semicolons. Problems with
3380 semicolons are diagnosed here; empty structures are diagnosed
3385 /* Parse any stray semicolon. */
3386 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3388 location_t semicolon_loc
3389 = c_parser_peek_token (parser
)->location
;
3390 gcc_rich_location
richloc (semicolon_loc
);
3391 richloc
.add_fixit_remove ();
3392 pedwarn (&richloc
, OPT_Wpedantic
,
3393 "extra semicolon in struct or union specified");
3394 c_parser_consume_token (parser
);
3397 /* Stop if at the end of the struct or union contents. */
3398 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3400 c_parser_consume_token (parser
);
3403 /* Accept #pragmas at struct scope. */
3404 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
3406 c_parser_pragma (parser
, pragma_struct
, NULL
);
3409 /* Parse some comma-separated declarations, but not the
3410 trailing semicolon if any. */
3411 decls
= c_parser_struct_declaration (parser
);
3412 contents
= chainon (decls
, contents
);
3413 /* If no semicolon follows, either we have a parse error or
3414 are at the end of the struct or union and should
3416 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3417 c_parser_consume_token (parser
);
3420 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3421 pedwarn (c_parser_peek_token (parser
)->location
, 0,
3422 "no semicolon at end of struct or union");
3423 else if (parser
->error
3424 || !c_parser_next_token_starts_declspecs (parser
))
3426 c_parser_error (parser
, "expected %<;%>");
3427 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3431 /* If we come here, we have already emitted an error
3432 for an expected `;', identifier or `(', and we also
3433 recovered already. Go on with the next field. */
3436 postfix_attrs
= c_parser_gnu_attributes (parser
);
3437 ret
.spec
= finish_struct (struct_loc
, type
, nreverse (contents
),
3439 chainon (attrs
, postfix_attrs
)),
3441 ret
.kind
= ctsk_tagdef
;
3442 ret
.expr
= NULL_TREE
;
3443 ret
.expr_const_operands
= true;
3444 timevar_pop (TV_PARSE_STRUCT
);
3449 c_parser_error (parser
, "expected %<{%>");
3450 ret
.spec
= error_mark_node
;
3451 ret
.kind
= ctsk_tagref
;
3452 ret
.expr
= NULL_TREE
;
3453 ret
.expr_const_operands
= true;
3456 /* Attributes may only appear when the members are defined or in
3457 certain forward declarations. */
3458 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3459 c_parser_error (parser
, "expected %<;%>");
3460 /* ??? Existing practice is that GNU attributes are ignored after
3461 the struct or union keyword when not defining the members. */
3462 ret
= parser_xref_tag (ident_loc
, code
, ident
, have_std_attrs
, std_attrs
);
3466 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3467 *without* the trailing semicolon.
3470 attribute-specifier-sequence[opt] specifier-qualifier-list
3471 attribute-specifier-sequence[opt] struct-declarator-list
3472 static_assert-declaration-no-semi
3474 specifier-qualifier-list:
3475 type-specifier specifier-qualifier-list[opt]
3476 type-qualifier specifier-qualifier-list[opt]
3477 alignment-specifier specifier-qualifier-list[opt]
3478 gnu-attributes specifier-qualifier-list[opt]
3480 struct-declarator-list:
3482 struct-declarator-list , gnu-attributes[opt] struct-declarator
3485 declarator gnu-attributes[opt]
3486 declarator[opt] : constant-expression gnu-attributes[opt]
3491 __extension__ struct-declaration
3492 specifier-qualifier-list
3494 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3495 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3496 any expression without commas in the syntax (assignment
3497 expressions, not just conditional expressions); assignment
3498 expressions will be diagnosed as non-constant. */
3501 c_parser_struct_declaration (c_parser
*parser
)
3503 struct c_declspecs
*specs
;
3505 tree all_prefix_attrs
;
3507 location_t decl_loc
;
3508 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
3512 ext
= disable_extension_diagnostics ();
3513 c_parser_consume_token (parser
);
3514 decl
= c_parser_struct_declaration (parser
);
3515 restore_extension_diagnostics (ext
);
3518 if (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
3520 c_parser_static_assert_declaration_no_semi (parser
);
3523 specs
= build_null_declspecs ();
3524 decl_loc
= c_parser_peek_token (parser
)->location
;
3525 /* Strictly by the standard, we shouldn't allow _Alignas here,
3526 but it appears to have been intended to allow it there, so
3527 we're keeping it as it is until WG14 reaches a conclusion
3529 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3530 c_parser_declspecs (parser
, specs
, false, true, true,
3531 true, false, true, true, cla_nonabstract_decl
);
3534 if (!specs
->declspecs_seen_p
)
3536 c_parser_error (parser
, "expected specifier-qualifier-list");
3539 finish_declspecs (specs
);
3540 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3541 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3544 if (specs
->typespec_kind
== ctsk_none
)
3546 pedwarn (decl_loc
, OPT_Wpedantic
,
3547 "ISO C forbids member declarations with no members");
3548 shadow_tag_warned (specs
, pedantic
);
3553 /* Support for unnamed structs or unions as members of
3554 structs or unions (which is [a] useful and [b] supports
3558 ret
= grokfield (c_parser_peek_token (parser
)->location
,
3559 build_id_declarator (NULL_TREE
), specs
,
3562 decl_attributes (&ret
, attrs
, 0);
3567 /* Provide better error recovery. Note that a type name here is valid,
3568 and will be treated as a field name. */
3569 if (specs
->typespec_kind
== ctsk_tagdef
3570 && TREE_CODE (specs
->type
) != ENUMERAL_TYPE
3571 && c_parser_next_token_starts_declspecs (parser
)
3572 && !c_parser_next_token_is (parser
, CPP_NAME
))
3574 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
3575 parser
->error
= false;
3579 pending_xref_error ();
3580 prefix_attrs
= specs
->attrs
;
3581 all_prefix_attrs
= prefix_attrs
;
3582 specs
->attrs
= NULL_TREE
;
3586 /* Declaring one or more declarators or un-named bit-fields. */
3587 struct c_declarator
*declarator
;
3589 if (c_parser_next_token_is (parser
, CPP_COLON
))
3590 declarator
= build_id_declarator (NULL_TREE
);
3592 declarator
= c_parser_declarator (parser
,
3593 specs
->typespec_kind
!= ctsk_none
,
3594 C_DTR_NORMAL
, &dummy
);
3595 if (declarator
== NULL
)
3597 c_parser_skip_to_end_of_block_or_statement (parser
);
3600 if (c_parser_next_token_is (parser
, CPP_COLON
)
3601 || c_parser_next_token_is (parser
, CPP_COMMA
)
3602 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3603 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3604 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3606 tree postfix_attrs
= NULL_TREE
;
3607 tree width
= NULL_TREE
;
3609 if (c_parser_next_token_is (parser
, CPP_COLON
))
3611 c_parser_consume_token (parser
);
3612 width
= c_parser_expr_no_commas (parser
, NULL
).value
;
3614 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3615 postfix_attrs
= c_parser_gnu_attributes (parser
);
3616 d
= grokfield (c_parser_peek_token (parser
)->location
,
3617 declarator
, specs
, width
, &all_prefix_attrs
);
3618 decl_attributes (&d
, chainon (postfix_attrs
,
3619 all_prefix_attrs
), 0);
3620 DECL_CHAIN (d
) = decls
;
3622 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3623 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
3626 all_prefix_attrs
= prefix_attrs
;
3627 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3628 c_parser_consume_token (parser
);
3629 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3630 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3632 /* Semicolon consumed in caller. */
3637 c_parser_error (parser
, "expected %<,%>, %<;%> or %<}%>");
3643 c_parser_error (parser
,
3644 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3645 "%<__attribute__%>");
3652 /* Parse a typeof specifier (a GNU extension).
3655 typeof ( expression )
3656 typeof ( type-name )
3659 static struct c_typespec
3660 c_parser_typeof_specifier (c_parser
*parser
)
3662 struct c_typespec ret
;
3663 ret
.kind
= ctsk_typeof
;
3664 ret
.spec
= error_mark_node
;
3665 ret
.expr
= NULL_TREE
;
3666 ret
.expr_const_operands
= true;
3667 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TYPEOF
));
3668 c_parser_consume_token (parser
);
3669 c_inhibit_evaluation_warnings
++;
3671 matching_parens parens
;
3672 if (!parens
.require_open (parser
))
3674 c_inhibit_evaluation_warnings
--;
3678 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3680 struct c_type_name
*type
= c_parser_type_name (parser
);
3681 c_inhibit_evaluation_warnings
--;
3685 ret
.spec
= groktypename (type
, &ret
.expr
, &ret
.expr_const_operands
);
3686 pop_maybe_used (variably_modified_type_p (ret
.spec
, NULL_TREE
));
3692 location_t here
= c_parser_peek_token (parser
)->location
;
3693 struct c_expr expr
= c_parser_expression (parser
);
3694 c_inhibit_evaluation_warnings
--;
3696 if (TREE_CODE (expr
.value
) == COMPONENT_REF
3697 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
3698 error_at (here
, "%<typeof%> applied to a bit-field");
3699 mark_exp_read (expr
.value
);
3700 ret
.spec
= TREE_TYPE (expr
.value
);
3701 was_vm
= variably_modified_type_p (ret
.spec
, NULL_TREE
);
3702 /* This is returned with the type so that when the type is
3703 evaluated, this can be evaluated. */
3705 ret
.expr
= c_fully_fold (expr
.value
, false, &ret
.expr_const_operands
);
3706 pop_maybe_used (was_vm
);
3707 /* For use in macros such as those in <stdatomic.h>, remove all
3708 qualifiers from atomic types. (const can be an issue for more macros
3709 using typeof than just the <stdatomic.h> ones.) */
3710 if (ret
.spec
!= error_mark_node
&& TYPE_ATOMIC (ret
.spec
))
3711 ret
.spec
= c_build_qualified_type (ret
.spec
, TYPE_UNQUALIFIED
);
3713 parens
.skip_until_found_close (parser
);
3717 /* Parse an alignment-specifier.
3721 alignment-specifier:
3722 _Alignas ( type-name )
3723 _Alignas ( constant-expression )
3727 c_parser_alignas_specifier (c_parser
* parser
)
3729 tree ret
= error_mark_node
;
3730 location_t loc
= c_parser_peek_token (parser
)->location
;
3731 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
));
3732 c_parser_consume_token (parser
);
3734 pedwarn_c99 (loc
, OPT_Wpedantic
,
3735 "ISO C99 does not support %<_Alignas%>");
3737 pedwarn_c99 (loc
, OPT_Wpedantic
,
3738 "ISO C90 does not support %<_Alignas%>");
3739 matching_parens parens
;
3740 if (!parens
.require_open (parser
))
3742 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3744 struct c_type_name
*type
= c_parser_type_name (parser
);
3746 ret
= c_sizeof_or_alignof_type (loc
, groktypename (type
, NULL
, NULL
),
3750 ret
= c_parser_expr_no_commas (parser
, NULL
).value
;
3751 parens
.skip_until_found_close (parser
);
3755 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3756 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3757 a typedef name may be redeclared; otherwise it may not. KIND
3758 indicates which kind of declarator is wanted. Returns a valid
3759 declarator except in the case of a syntax error in which case NULL is
3760 returned. *SEEN_ID is set to true if an identifier being declared is
3761 seen; this is used to diagnose bad forms of abstract array declarators
3762 and to determine whether an identifier list is syntactically permitted.
3765 pointer[opt] direct-declarator
3769 ( gnu-attributes[opt] declarator )
3770 direct-declarator array-declarator
3771 direct-declarator ( parameter-type-list )
3772 direct-declarator ( identifier-list[opt] )
3775 * type-qualifier-list[opt]
3776 * type-qualifier-list[opt] pointer
3778 type-qualifier-list:
3781 type-qualifier-list type-qualifier
3782 type-qualifier-list gnu-attributes
3785 [ type-qualifier-list[opt] assignment-expression[opt] ]
3786 [ static type-qualifier-list[opt] assignment-expression ]
3787 [ type-qualifier-list static assignment-expression ]
3788 [ type-qualifier-list[opt] * ]
3790 parameter-type-list:
3792 parameter-list , ...
3795 parameter-declaration
3796 parameter-list , parameter-declaration
3798 parameter-declaration:
3799 declaration-specifiers declarator gnu-attributes[opt]
3800 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3804 identifier-list , identifier
3806 abstract-declarator:
3808 pointer[opt] direct-abstract-declarator
3810 direct-abstract-declarator:
3811 ( gnu-attributes[opt] abstract-declarator )
3812 direct-abstract-declarator[opt] array-declarator
3813 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3818 direct-declarator ( parameter-forward-declarations
3819 parameter-type-list[opt] )
3821 direct-abstract-declarator:
3822 direct-abstract-declarator[opt] ( parameter-forward-declarations
3823 parameter-type-list[opt] )
3825 parameter-forward-declarations:
3827 parameter-forward-declarations parameter-list ;
3829 The uses of gnu-attributes shown above are GNU extensions.
3831 Some forms of array declarator are not included in C99 in the
3832 syntax for abstract declarators; these are disallowed elsewhere.
3833 This may be a defect (DR#289).
3835 This function also accepts an omitted abstract declarator as being
3836 an abstract declarator, although not part of the formal syntax. */
3838 struct c_declarator
*
3839 c_parser_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3842 /* Parse any initial pointer part. */
3843 if (c_parser_next_token_is (parser
, CPP_MULT
))
3845 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
3846 struct c_declarator
*inner
;
3847 c_parser_consume_token (parser
);
3848 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
3849 false, false, true, false, cla_prefer_id
);
3850 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
3854 return make_pointer_declarator (quals_attrs
, inner
);
3856 /* Now we have a direct declarator, direct abstract declarator or
3857 nothing (which counts as a direct abstract declarator here). */
3858 return c_parser_direct_declarator (parser
, type_seen_p
, kind
, seen_id
);
3861 /* Parse a direct declarator or direct abstract declarator; arguments
3862 as c_parser_declarator. */
3864 static struct c_declarator
*
3865 c_parser_direct_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3868 /* The direct declarator must start with an identifier (possibly
3869 omitted) or a parenthesized declarator (possibly abstract). In
3870 an ordinary declarator, initial parentheses must start a
3871 parenthesized declarator. In an abstract declarator or parameter
3872 declarator, they could start a parenthesized declarator or a
3873 parameter list. To tell which, the open parenthesis and any
3874 following gnu-attributes must be read. If a declaration
3875 specifier or standard attributes follow, then it is a parameter
3876 list; if the specifier is a typedef name, there might be an
3877 ambiguity about redeclaring it, which is resolved in the
3878 direction of treating it as a typedef name. If a close
3879 parenthesis follows, it is also an empty parameter list, as the
3880 syntax does not permit empty abstract declarators. Otherwise, it
3881 is a parenthesized declarator (in which case the analysis may be
3882 repeated inside it, recursively).
3884 ??? There is an ambiguity in a parameter declaration "int
3885 (__attribute__((foo)) x)", where x is not a typedef name: it
3886 could be an abstract declarator for a function, or declare x with
3887 parentheses. The proper resolution of this ambiguity needs
3888 documenting. At present we follow an accident of the old
3889 parser's implementation, whereby the first parameter must have
3890 some declaration specifiers other than just gnu-attributes. Thus as
3891 a parameter declaration it is treated as a parenthesized
3892 parameter named x, and as an abstract declarator it is
3895 ??? Also following the old parser, gnu-attributes inside an empty
3896 parameter list are ignored, making it a list not yielding a
3897 prototype, rather than giving an error or making it have one
3898 parameter with implicit type int.
3900 ??? Also following the old parser, typedef names may be
3901 redeclared in declarators, but not Objective-C class names. */
3903 if (kind
!= C_DTR_ABSTRACT
3904 && c_parser_next_token_is (parser
, CPP_NAME
)
3906 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
3907 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
3908 || c_parser_peek_token (parser
)->id_kind
== C_ID_ID
))
3910 struct c_declarator
*inner
3911 = build_id_declarator (c_parser_peek_token (parser
)->value
);
3913 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3914 c_parser_consume_token (parser
);
3915 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3916 inner
->u
.id
.attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3917 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3920 if (kind
!= C_DTR_NORMAL
3921 && c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
3922 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
3924 struct c_declarator
*inner
= build_id_declarator (NULL_TREE
);
3925 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3926 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3929 /* Either we are at the end of an abstract declarator, or we have
3932 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3935 struct c_declarator
*inner
;
3936 c_parser_consume_token (parser
);
3937 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
3939 attrs
= c_parser_gnu_attributes (parser
);
3940 if (kind
!= C_DTR_NORMAL
3941 && (c_parser_next_token_starts_declspecs (parser
)
3943 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3944 || c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
)))
3946 struct c_arg_info
*args
3947 = c_parser_parms_declarator (parser
, kind
== C_DTR_NORMAL
,
3948 attrs
, have_gnu_attrs
);
3953 inner
= build_id_declarator (NULL_TREE
);
3955 && args
->types
!= error_mark_node
3956 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
3957 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3960 = c_parser_std_attribute_specifier_sequence (parser
);
3962 inner
= build_attrs_declarator (std_attrs
, inner
);
3964 inner
= build_function_declarator (args
, inner
);
3965 return c_parser_direct_declarator_inner (parser
, *seen_id
,
3969 /* A parenthesized declarator. */
3970 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
3971 if (inner
!= NULL
&& attrs
!= NULL
)
3972 inner
= build_attrs_declarator (attrs
, inner
);
3973 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
3975 c_parser_consume_token (parser
);
3979 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3983 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3990 if (kind
== C_DTR_NORMAL
)
3992 c_parser_error (parser
, "expected identifier or %<(%>");
3996 return build_id_declarator (NULL_TREE
);
4000 /* Parse part of a direct declarator or direct abstract declarator,
4001 given that some (in INNER) has already been parsed; ID_PRESENT is
4002 true if an identifier is present, false for an abstract
4005 static struct c_declarator
*
4006 c_parser_direct_declarator_inner (c_parser
*parser
, bool id_present
,
4007 struct c_declarator
*inner
)
4009 /* Parse a sequence of array declarators and parameter lists. */
4010 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4011 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4013 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
4014 struct c_declarator
*declarator
;
4015 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4018 struct c_expr dimen
;
4019 dimen
.value
= NULL_TREE
;
4020 dimen
.original_code
= ERROR_MARK
;
4021 dimen
.original_type
= NULL_TREE
;
4022 c_parser_consume_token (parser
);
4023 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4024 false, false, false, false, cla_prefer_id
);
4025 static_seen
= c_parser_next_token_is_keyword (parser
, RID_STATIC
);
4027 c_parser_consume_token (parser
);
4028 if (static_seen
&& !quals_attrs
->declspecs_seen_p
)
4029 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4030 false, false, false, false, cla_prefer_id
);
4031 if (!quals_attrs
->declspecs_seen_p
)
4033 /* If "static" is present, there must be an array dimension.
4034 Otherwise, there may be a dimension, "*", or no
4039 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4043 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4045 dimen
.value
= NULL_TREE
;
4048 else if (c_parser_next_token_is (parser
, CPP_MULT
))
4050 if (c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_SQUARE
)
4052 dimen
.value
= NULL_TREE
;
4054 c_parser_consume_token (parser
);
4059 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4065 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4068 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4069 c_parser_consume_token (parser
);
4072 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4077 dimen
= convert_lvalue_to_rvalue (brace_loc
, dimen
, true, true);
4078 declarator
= build_array_declarator (brace_loc
, dimen
.value
, quals_attrs
,
4079 static_seen
, star_seen
);
4080 if (declarator
== NULL
)
4082 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4085 = c_parser_std_attribute_specifier_sequence (parser
);
4087 inner
= build_attrs_declarator (std_attrs
, inner
);
4089 inner
= set_array_declarator_inner (declarator
, inner
);
4090 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4092 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4095 struct c_arg_info
*args
;
4096 c_parser_consume_token (parser
);
4097 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4099 attrs
= c_parser_gnu_attributes (parser
);
4100 args
= c_parser_parms_declarator (parser
, id_present
, attrs
,
4107 && args
->types
!= error_mark_node
4108 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4109 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4112 = c_parser_std_attribute_specifier_sequence (parser
);
4114 inner
= build_attrs_declarator (std_attrs
, inner
);
4116 inner
= build_function_declarator (args
, inner
);
4117 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4123 /* Parse a parameter list or identifier list, including the closing
4124 parenthesis but not the opening one. ATTRS are the gnu-attributes
4125 at the start of the list. ID_LIST_OK is true if an identifier list
4126 is acceptable; such a list must not have attributes at the start.
4127 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4128 attributes) were present (in which case standard attributes cannot
4131 static struct c_arg_info
*
4132 c_parser_parms_declarator (c_parser
*parser
, bool id_list_ok
, tree attrs
,
4133 bool have_gnu_attrs
)
4136 declare_parm_level ();
4137 /* If the list starts with an identifier, it is an identifier list.
4138 Otherwise, it is either a prototype list or an empty list. */
4141 && c_parser_next_token_is (parser
, CPP_NAME
)
4142 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4144 /* Look ahead to detect typos in type names. */
4145 && c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
4146 && c_parser_peek_2nd_token (parser
)->type
!= CPP_MULT
4147 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
4148 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_SQUARE
4149 && c_parser_peek_2nd_token (parser
)->type
!= CPP_KEYWORD
)
4151 tree list
= NULL_TREE
, *nextp
= &list
;
4152 while (c_parser_next_token_is (parser
, CPP_NAME
)
4153 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
4155 *nextp
= build_tree_list (NULL_TREE
,
4156 c_parser_peek_token (parser
)->value
);
4157 nextp
= & TREE_CHAIN (*nextp
);
4158 c_parser_consume_token (parser
);
4159 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
4161 c_parser_consume_token (parser
);
4162 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4164 c_parser_error (parser
, "expected identifier");
4168 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4170 struct c_arg_info
*ret
= build_arg_info ();
4172 c_parser_consume_token (parser
);
4178 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4186 struct c_arg_info
*ret
4187 = c_parser_parms_list_declarator (parser
, attrs
, NULL
, have_gnu_attrs
);
4193 /* Parse a parameter list (possibly empty), including the closing
4194 parenthesis but not the opening one. ATTRS are the gnu-attributes
4195 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4196 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4197 which means standard attributes cannot start the list. EXPR is
4198 NULL or an expression that needs to be evaluated for the side
4199 effects of array size expressions in the parameters. */
4201 static struct c_arg_info
*
4202 c_parser_parms_list_declarator (c_parser
*parser
, tree attrs
, tree expr
,
4203 bool have_gnu_attrs
)
4205 bool bad_parm
= false;
4207 /* ??? Following the old parser, forward parameter declarations may
4208 use abstract declarators, and if no real parameter declarations
4209 follow the forward declarations then this is not diagnosed. Also
4210 note as above that gnu-attributes are ignored as the only contents of
4211 the parentheses, or as the only contents after forward
4213 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4215 struct c_arg_info
*ret
= build_arg_info ();
4216 c_parser_consume_token (parser
);
4219 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4221 struct c_arg_info
*ret
= build_arg_info ();
4223 if (flag_allow_parameterless_variadic_functions
)
4225 /* F (...) is allowed. */
4226 ret
->types
= NULL_TREE
;
4230 /* Suppress -Wold-style-definition for this case. */
4231 ret
->types
= error_mark_node
;
4232 error_at (c_parser_peek_token (parser
)->location
,
4233 "ISO C requires a named argument before %<...%>");
4235 c_parser_consume_token (parser
);
4236 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4238 c_parser_consume_token (parser
);
4243 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4248 /* Nonempty list of parameters, either terminated with semicolon
4249 (forward declarations; recurse) or with close parenthesis (normal
4250 function) or with ", ... )" (variadic function). */
4253 /* Parse a parameter. */
4254 struct c_parm
*parm
= c_parser_parameter_declaration (parser
, attrs
,
4257 have_gnu_attrs
= false;
4261 push_parm_decl (parm
, &expr
);
4262 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4265 c_parser_consume_token (parser
);
4266 mark_forward_parm_decls ();
4267 bool new_have_gnu_attrs
4268 = c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
);
4269 new_attrs
= c_parser_gnu_attributes (parser
);
4270 return c_parser_parms_list_declarator (parser
, new_attrs
, expr
,
4271 new_have_gnu_attrs
);
4273 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4275 c_parser_consume_token (parser
);
4279 return get_parm_info (false, expr
);
4281 if (!c_parser_require (parser
, CPP_COMMA
,
4282 "expected %<;%>, %<,%> or %<)%>",
4283 UNKNOWN_LOCATION
, false))
4285 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4288 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4290 c_parser_consume_token (parser
);
4291 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4293 c_parser_consume_token (parser
);
4297 return get_parm_info (true, expr
);
4301 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4309 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4310 start of the declaration if it is the first parameter;
4311 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4314 static struct c_parm
*
4315 c_parser_parameter_declaration (c_parser
*parser
, tree attrs
,
4316 bool have_gnu_attrs
)
4318 struct c_declspecs
*specs
;
4319 struct c_declarator
*declarator
;
4321 tree postfix_attrs
= NULL_TREE
;
4324 /* Accept #pragmas between parameter declarations. */
4325 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
4326 c_parser_pragma (parser
, pragma_param
, NULL
);
4328 if (!c_parser_next_token_starts_declspecs (parser
)
4329 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4331 c_token
*token
= c_parser_peek_token (parser
);
4334 c_parser_set_source_position_from_token (token
);
4335 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
4337 auto_diagnostic_group d
;
4338 name_hint hint
= lookup_name_fuzzy (token
->value
,
4339 FUZZY_LOOKUP_TYPENAME
,
4341 if (const char *suggestion
= hint
.suggestion ())
4343 gcc_rich_location
richloc (token
->location
);
4344 richloc
.add_fixit_replace (suggestion
);
4346 "unknown type name %qE; did you mean %qs?",
4347 token
->value
, suggestion
);
4350 error_at (token
->location
, "unknown type name %qE", token
->value
);
4351 parser
->error
= true;
4353 /* ??? In some Objective-C cases '...' isn't applicable so there
4354 should be a different message. */
4356 c_parser_error (parser
,
4357 "expected declaration specifiers or %<...%>");
4358 c_parser_skip_to_end_of_parameter (parser
);
4362 location_t start_loc
= c_parser_peek_token (parser
)->location
;
4364 specs
= build_null_declspecs ();
4367 declspecs_add_attrs (input_location
, specs
, attrs
);
4370 c_parser_declspecs (parser
, specs
, true, true, true, true, false,
4371 !have_gnu_attrs
, true, cla_nonabstract_decl
);
4372 finish_declspecs (specs
);
4373 pending_xref_error ();
4374 prefix_attrs
= specs
->attrs
;
4375 specs
->attrs
= NULL_TREE
;
4376 declarator
= c_parser_declarator (parser
,
4377 specs
->typespec_kind
!= ctsk_none
,
4378 C_DTR_PARM
, &dummy
);
4379 if (declarator
== NULL
)
4381 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
4384 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4385 postfix_attrs
= c_parser_gnu_attributes (parser
);
4387 /* Generate a location for the parameter, ranging from the start of the
4388 initial token to the end of the final token.
4390 If we have a identifier, then use it for the caret location, e.g.
4392 extern int callee (int one, int (*two)(int, int), float three);
4393 ~~~~~~^~~~~~~~~~~~~~
4395 otherwise, reuse the start location for the caret location e.g.:
4397 extern int callee (int one, int (*)(int, int), float three);
4400 location_t end_loc
= parser
->last_token_location
;
4402 /* Find any cdk_id declarator; determine if we have an identifier. */
4403 c_declarator
*id_declarator
= declarator
;
4404 while (id_declarator
&& id_declarator
->kind
!= cdk_id
)
4405 id_declarator
= id_declarator
->declarator
;
4406 location_t caret_loc
= (id_declarator
->u
.id
.id
4407 ? id_declarator
->id_loc
4409 location_t param_loc
= make_location (caret_loc
, start_loc
, end_loc
);
4411 return build_c_parm (specs
, chainon (postfix_attrs
, prefix_attrs
),
4412 declarator
, param_loc
);
4415 /* Parse a string literal in an asm expression. It should not be
4416 translated, and wide string literals are an error although
4417 permitted by the syntax. This is a GNU extension.
4424 c_parser_asm_string_literal (c_parser
*parser
)
4427 int save_flag
= warn_overlength_strings
;
4428 warn_overlength_strings
= 0;
4429 str
= c_parser_string_literal (parser
, false, false).value
;
4430 warn_overlength_strings
= save_flag
;
4434 /* Parse a simple asm expression. This is used in restricted
4435 contexts, where a full expression with inputs and outputs does not
4436 make sense. This is a GNU extension.
4439 asm ( asm-string-literal )
4443 c_parser_simple_asm_expr (c_parser
*parser
)
4446 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
4447 c_parser_consume_token (parser
);
4448 matching_parens parens
;
4449 if (!parens
.require_open (parser
))
4451 str
= c_parser_asm_string_literal (parser
);
4452 if (!parens
.require_close (parser
))
4454 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4461 c_parser_gnu_attribute_any_word (c_parser
*parser
)
4463 tree attr_name
= NULL_TREE
;
4465 if (c_parser_next_token_is (parser
, CPP_KEYWORD
))
4467 /* ??? See comment above about what keywords are accepted here. */
4469 switch (c_parser_peek_token (parser
)->keyword
)
4500 case RID_TRANSACTION_ATOMIC
:
4501 case RID_TRANSACTION_CANCEL
:
4517 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4518 attr_name
= ridpointers
[(int) c_parser_peek_token (parser
)->keyword
];
4520 else if (c_parser_next_token_is (parser
, CPP_NAME
))
4521 attr_name
= c_parser_peek_token (parser
)->value
;
4526 /* Parse attribute arguments. This is a common form of syntax
4527 covering all currently valid GNU and standard attributes.
4529 gnu-attribute-arguments:
4531 identifier , nonempty-expr-list
4534 where the "identifier" must not be declared as a type. ??? Why not
4535 allow identifiers declared as types to start the arguments? */
4538 c_parser_attribute_arguments (c_parser
*parser
, bool takes_identifier
,
4539 bool require_string
, bool allow_empty_args
)
4541 vec
<tree
, va_gc
> *expr_list
;
4543 /* Parse the attribute contents. If they start with an
4544 identifier which is followed by a comma or close
4545 parenthesis, then the arguments start with that
4546 identifier; otherwise they are an expression list.
4547 In objective-c the identifier may be a classname. */
4548 if (c_parser_next_token_is (parser
, CPP_NAME
)
4549 && (c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4550 || (c_dialect_objc ()
4551 && c_parser_peek_token (parser
)->id_kind
4553 && ((c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
4554 || (c_parser_peek_2nd_token (parser
)->type
4555 == CPP_CLOSE_PAREN
))
4556 && (takes_identifier
4557 || (c_dialect_objc ()
4558 && c_parser_peek_token (parser
)->id_kind
4559 == C_ID_CLASSNAME
)))
4561 tree arg1
= c_parser_peek_token (parser
)->value
;
4562 c_parser_consume_token (parser
);
4563 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4564 attr_args
= build_tree_list (NULL_TREE
, arg1
);
4568 c_parser_consume_token (parser
);
4569 expr_list
= c_parser_expr_list (parser
, false, true,
4570 NULL
, NULL
, NULL
, NULL
);
4571 tree_list
= build_tree_list_vec (expr_list
);
4572 attr_args
= tree_cons (NULL_TREE
, arg1
, tree_list
);
4573 release_tree_vector (expr_list
);
4578 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4580 if (!allow_empty_args
)
4581 error_at (c_parser_peek_token (parser
)->location
,
4582 "parentheses must be omitted if "
4583 "attribute argument list is empty");
4584 attr_args
= NULL_TREE
;
4586 else if (require_string
)
4588 /* The only valid argument for this attribute is a string
4589 literal. Handle this specially here to avoid accepting
4590 string literals with excess parentheses. */
4591 tree string
= c_parser_string_literal (parser
, false, true).value
;
4592 attr_args
= build_tree_list (NULL_TREE
, string
);
4596 expr_list
= c_parser_expr_list (parser
, false, true,
4597 NULL
, NULL
, NULL
, NULL
);
4598 attr_args
= build_tree_list_vec (expr_list
);
4599 release_tree_vector (expr_list
);
4605 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4609 gnu-attributes gnu-attribute
4612 __attribute__ ( ( gnu-attribute-list ) )
4616 gnu-attribute_list , gnu-attrib
4621 any-word ( gnu-attribute-arguments )
4623 where "any-word" may be any identifier (including one declared as a
4624 type), a reserved word storage class specifier, type specifier or
4625 type qualifier. ??? This still leaves out most reserved keywords
4626 (following the old parser), shouldn't we include them?
4627 When EXPECT_COMMA is true, expect the attribute to be preceded
4628 by a comma and fail if it isn't.
4629 When EMPTY_OK is true, allow and consume any number of consecutive
4630 commas with no attributes in between. */
4633 c_parser_gnu_attribute (c_parser
*parser
, tree attrs
,
4634 bool expect_comma
= false, bool empty_ok
= true)
4636 bool comma_first
= c_parser_next_token_is (parser
, CPP_COMMA
);
4638 && !c_parser_next_token_is (parser
, CPP_NAME
)
4639 && !c_parser_next_token_is (parser
, CPP_KEYWORD
))
4642 while (c_parser_next_token_is (parser
, CPP_COMMA
))
4644 c_parser_consume_token (parser
);
4649 tree attr_name
= c_parser_gnu_attribute_any_word (parser
);
4650 if (attr_name
== NULL_TREE
)
4653 attr_name
= canonicalize_attr_name (attr_name
);
4654 c_parser_consume_token (parser
);
4657 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4659 if (expect_comma
&& !comma_first
)
4661 /* A comma is missing between the last attribute on the chain
4663 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4665 return error_mark_node
;
4667 attr
= build_tree_list (attr_name
, NULL_TREE
);
4668 /* Add this attribute to the list. */
4669 attrs
= chainon (attrs
, attr
);
4672 c_parser_consume_token (parser
);
4675 = c_parser_attribute_arguments (parser
,
4676 attribute_takes_identifier_p (attr_name
),
4679 attr
= build_tree_list (attr_name
, attr_args
);
4680 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4681 c_parser_consume_token (parser
);
4684 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4686 return error_mark_node
;
4689 if (expect_comma
&& !comma_first
)
4691 /* A comma is missing between the last attribute on the chain
4693 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4695 return error_mark_node
;
4698 /* Add this attribute to the list. */
4699 attrs
= chainon (attrs
, attr
);
4704 c_parser_gnu_attributes (c_parser
*parser
)
4706 tree attrs
= NULL_TREE
;
4707 while (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4709 bool save_translate_strings_p
= parser
->translate_strings_p
;
4710 parser
->translate_strings_p
= false;
4711 /* Consume the `__attribute__' keyword. */
4712 c_parser_consume_token (parser
);
4713 /* Look for the two `(' tokens. */
4714 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4716 parser
->translate_strings_p
= save_translate_strings_p
;
4719 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4721 parser
->translate_strings_p
= save_translate_strings_p
;
4722 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4725 /* Parse the attribute list. Require a comma between successive
4726 (possibly empty) attributes. */
4727 for (bool expect_comma
= false; ; expect_comma
= true)
4729 /* Parse a single attribute. */
4730 tree attr
= c_parser_gnu_attribute (parser
, attrs
, expect_comma
);
4731 if (attr
== error_mark_node
)
4738 /* Look for the two `)' tokens. */
4739 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4740 c_parser_consume_token (parser
);
4743 parser
->translate_strings_p
= save_translate_strings_p
;
4744 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4748 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4749 c_parser_consume_token (parser
);
4752 parser
->translate_strings_p
= save_translate_strings_p
;
4753 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4757 parser
->translate_strings_p
= save_translate_strings_p
;
4763 /* Parse an optional balanced token sequence.
4765 balanced-token-sequence:
4767 balanced-token-sequence balanced-token
4770 ( balanced-token-sequence[opt] )
4771 [ balanced-token-sequence[opt] ]
4772 { balanced-token-sequence[opt] }
4773 any token other than ()[]{}
4777 c_parser_balanced_token_sequence (c_parser
*parser
)
4781 c_token
*token
= c_parser_peek_token (parser
);
4782 switch (token
->type
)
4784 case CPP_OPEN_BRACE
:
4786 matching_braces braces
;
4787 braces
.consume_open (parser
);
4788 c_parser_balanced_token_sequence (parser
);
4789 braces
.require_close (parser
);
4793 case CPP_OPEN_PAREN
:
4795 matching_parens parens
;
4796 parens
.consume_open (parser
);
4797 c_parser_balanced_token_sequence (parser
);
4798 parens
.require_close (parser
);
4802 case CPP_OPEN_SQUARE
:
4803 c_parser_consume_token (parser
);
4804 c_parser_balanced_token_sequence (parser
);
4805 c_parser_require (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
4808 case CPP_CLOSE_BRACE
:
4809 case CPP_CLOSE_PAREN
:
4810 case CPP_CLOSE_SQUARE
:
4815 c_parser_consume_token (parser
);
4821 /* Parse standard (C2X) attributes (including GNU attributes in the
4824 attribute-specifier-sequence:
4825 attribute-specifier-sequence[opt] attribute-specifier
4827 attribute-specifier:
4828 [ [ attribute-list ] ]
4832 attribute-list, attribute[opt]
4835 attribute-token attribute-argument-clause[opt]
4839 attribute-prefixed-token
4844 attribute-prefixed-token:
4845 attribute-prefix :: identifier
4850 attribute-argument-clause:
4851 ( balanced-token-sequence[opt] )
4853 Keywords are accepted as identifiers for this purpose.
4857 c_parser_std_attribute (c_parser
*parser
, bool for_tm
)
4859 c_token
*token
= c_parser_peek_token (parser
);
4860 tree ns
, name
, attribute
;
4862 /* Parse the attribute-token. */
4863 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
4865 c_parser_error (parser
, "expected identifier");
4866 return error_mark_node
;
4868 name
= canonicalize_attr_name (token
->value
);
4869 c_parser_consume_token (parser
);
4870 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
4873 c_parser_consume_token (parser
);
4874 token
= c_parser_peek_token (parser
);
4875 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
4877 c_parser_error (parser
, "expected identifier");
4878 return error_mark_node
;
4880 name
= canonicalize_attr_name (token
->value
);
4881 c_parser_consume_token (parser
);
4885 attribute
= build_tree_list (build_tree_list (ns
, name
), NULL_TREE
);
4887 /* Parse the arguments, if any. */
4888 const attribute_spec
*as
= lookup_attribute_spec (TREE_PURPOSE (attribute
));
4889 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4892 location_t open_loc
= c_parser_peek_token (parser
)->location
;
4893 matching_parens parens
;
4894 parens
.consume_open (parser
);
4895 if ((as
&& as
->max_length
== 0)
4896 /* Special-case the transactional-memory attribute "outer",
4897 which is specially handled but not registered as an
4898 attribute, to avoid allowing arbitrary balanced token
4899 sequences as arguments. */
4900 || is_attribute_p ("outer", name
))
4902 error_at (open_loc
, "%qE attribute does not take any arguments", name
);
4903 parens
.skip_until_found_close (parser
);
4904 return error_mark_node
;
4908 bool takes_identifier
4910 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
4911 && attribute_takes_identifier_p (name
));
4914 && strcmp (IDENTIFIER_POINTER (name
), "deprecated") == 0);
4915 TREE_VALUE (attribute
)
4916 = c_parser_attribute_arguments (parser
, takes_identifier
,
4917 require_string
, false);
4920 c_parser_balanced_token_sequence (parser
);
4921 parens
.require_close (parser
);
4924 if (ns
== NULL_TREE
&& !for_tm
&& !as
&& !is_attribute_p ("nodiscard", name
))
4926 /* An attribute with standard syntax and no namespace specified
4927 is a constraint violation if it is not one of the known
4928 standard attributes (of which nodiscard is the only one
4929 without a handler in GCC). Diagnose it here with a pedwarn
4930 and then discard it to prevent a duplicate warning later. */
4931 pedwarn (input_location
, OPT_Wattributes
, "%qE attribute ignored",
4933 return error_mark_node
;
4939 c_parser_std_attribute_specifier (c_parser
*parser
, bool for_tm
)
4941 bool seen_deprecated
= false;
4942 bool seen_fallthrough
= false;
4943 bool seen_maybe_unused
= false;
4944 location_t loc
= c_parser_peek_token (parser
)->location
;
4945 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
4947 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
4949 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
4953 pedwarn_c11 (loc
, OPT_Wpedantic
,
4954 "ISO C does not support %<[[]]%> attributes before C2X");
4955 tree attributes
= NULL_TREE
;
4958 c_token
*token
= c_parser_peek_token (parser
);
4959 if (token
->type
== CPP_CLOSE_SQUARE
)
4961 if (token
->type
== CPP_COMMA
)
4963 c_parser_consume_token (parser
);
4966 tree attribute
= c_parser_std_attribute (parser
, for_tm
);
4967 if (attribute
!= error_mark_node
)
4969 bool duplicate
= false;
4970 tree name
= get_attribute_name (attribute
);
4971 tree ns
= get_attribute_namespace (attribute
);
4972 if (ns
== NULL_TREE
)
4974 /* Some standard attributes may appear at most once in
4975 each attribute list. Diagnose duplicates and remove
4976 them from the list to avoid subsequent diagnostics
4977 such as the more general one for multiple
4978 "fallthrough" attributes in the same place (including
4979 in separate attribute lists in the same attribute
4980 specifier sequence, which is not a constraint
4982 if (is_attribute_p ("deprecated", name
))
4984 if (seen_deprecated
)
4986 error ("attribute %<deprecated%> can appear at most "
4987 "once in an attribute-list");
4990 seen_deprecated
= true;
4992 else if (is_attribute_p ("fallthrough", name
))
4994 if (seen_fallthrough
)
4996 error ("attribute %<fallthrough%> can appear at most "
4997 "once in an attribute-list");
5000 seen_fallthrough
= true;
5002 else if (is_attribute_p ("maybe_unused", name
))
5004 if (seen_maybe_unused
)
5006 error ("attribute %<maybe_unused%> can appear at most "
5007 "once in an attribute-list");
5010 seen_maybe_unused
= true;
5015 TREE_CHAIN (attribute
) = attributes
;
5016 attributes
= attribute
;
5019 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5022 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5023 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5024 return nreverse (attributes
);
5027 /* Look past an optional balanced token sequence of raw look-ahead
5028 tokens starting with the *Nth token. *N is updated to point to the
5029 following token. Return true if such a sequence was found, false
5030 if the tokens parsed were not balanced. */
5033 c_parser_check_balanced_raw_token_sequence (c_parser
*parser
, unsigned int *n
)
5037 c_token
*token
= c_parser_peek_nth_token_raw (parser
, *n
);
5038 switch (token
->type
)
5040 case CPP_OPEN_BRACE
:
5043 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5045 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5046 if (token
->type
== CPP_CLOSE_BRACE
)
5056 case CPP_OPEN_PAREN
:
5059 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5061 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5062 if (token
->type
== CPP_CLOSE_PAREN
)
5072 case CPP_OPEN_SQUARE
:
5075 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5077 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5078 if (token
->type
== CPP_CLOSE_SQUARE
)
5088 case CPP_CLOSE_BRACE
:
5089 case CPP_CLOSE_PAREN
:
5090 case CPP_CLOSE_SQUARE
:
5101 /* Return whether standard attributes start with the Nth token. */
5104 c_parser_nth_token_starts_std_attributes (c_parser
*parser
, unsigned int n
)
5106 if (!(c_parser_peek_nth_token (parser
, n
)->type
== CPP_OPEN_SQUARE
5107 && c_parser_peek_nth_token (parser
, n
+ 1)->type
== CPP_OPEN_SQUARE
))
5109 /* In C, '[[' must start attributes. In Objective-C, we need to
5110 check whether '[[' is matched by ']]'. */
5111 if (!c_dialect_objc ())
5114 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
5116 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
5117 if (token
->type
!= CPP_CLOSE_SQUARE
)
5119 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
5120 return token
->type
== CPP_CLOSE_SQUARE
;
5124 c_parser_std_attribute_specifier_sequence (c_parser
*parser
)
5126 tree attributes
= NULL_TREE
;
5129 tree attrs
= c_parser_std_attribute_specifier (parser
, false);
5130 attributes
= chainon (attributes
, attrs
);
5132 while (c_parser_nth_token_starts_std_attributes (parser
, 1));
5136 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5137 says whether alignment specifiers are OK (only in cases that might
5138 be the type name of a compound literal).
5141 specifier-qualifier-list abstract-declarator[opt]
5144 struct c_type_name
*
5145 c_parser_type_name (c_parser
*parser
, bool alignas_ok
)
5147 struct c_declspecs
*specs
= build_null_declspecs ();
5148 struct c_declarator
*declarator
;
5149 struct c_type_name
*ret
;
5151 c_parser_declspecs (parser
, specs
, false, true, true, alignas_ok
, false,
5152 false, true, cla_prefer_type
);
5153 if (!specs
->declspecs_seen_p
)
5155 c_parser_error (parser
, "expected specifier-qualifier-list");
5158 if (specs
->type
!= error_mark_node
)
5160 pending_xref_error ();
5161 finish_declspecs (specs
);
5163 declarator
= c_parser_declarator (parser
,
5164 specs
->typespec_kind
!= ctsk_none
,
5165 C_DTR_ABSTRACT
, &dummy
);
5166 if (declarator
== NULL
)
5168 ret
= XOBNEW (&parser_obstack
, struct c_type_name
);
5170 ret
->declarator
= declarator
;
5174 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5177 assignment-expression
5178 { initializer-list }
5179 { initializer-list , }
5182 designation[opt] initializer
5183 initializer-list , designation[opt] initializer
5190 designator-list designator
5197 [ constant-expression ]
5209 [ constant-expression ... constant-expression ]
5211 Any expression without commas is accepted in the syntax for the
5212 constant-expressions, with non-constant expressions rejected later.
5214 This function is only used for top-level initializers; for nested
5215 ones, see c_parser_initval. */
5217 static struct c_expr
5218 c_parser_initializer (c_parser
*parser
)
5220 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
5221 return c_parser_braced_init (parser
, NULL_TREE
, false, NULL
);
5225 location_t loc
= c_parser_peek_token (parser
)->location
;
5226 ret
= c_parser_expr_no_commas (parser
, NULL
);
5227 if (TREE_CODE (ret
.value
) != STRING_CST
5228 && TREE_CODE (ret
.value
) != COMPOUND_LITERAL_EXPR
)
5229 ret
= convert_lvalue_to_rvalue (loc
, ret
, true, true);
5234 /* The location of the last comma within the current initializer list,
5235 or UNKNOWN_LOCATION if not within one. */
5237 location_t last_init_list_comma
;
5239 /* Parse a braced initializer list. TYPE is the type specified for a
5240 compound literal, and NULL_TREE for other initializers and for
5241 nested braced lists. NESTED_P is true for nested braced lists,
5242 false for the list of a compound literal or the list that is the
5243 top-level initializer in a declaration. */
5245 static struct c_expr
5246 c_parser_braced_init (c_parser
*parser
, tree type
, bool nested_p
,
5247 struct obstack
*outer_obstack
)
5250 struct obstack braced_init_obstack
;
5251 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
5252 gcc_obstack_init (&braced_init_obstack
);
5253 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
5254 matching_braces braces
;
5255 braces
.consume_open (parser
);
5258 finish_implicit_inits (brace_loc
, outer_obstack
);
5259 push_init_level (brace_loc
, 0, &braced_init_obstack
);
5262 really_start_incremental_init (type
);
5263 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5265 pedwarn (brace_loc
, OPT_Wpedantic
, "ISO C forbids empty initializer braces");
5269 /* Parse a non-empty initializer list, possibly with a trailing
5273 c_parser_initelt (parser
, &braced_init_obstack
);
5276 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5278 last_init_list_comma
= c_parser_peek_token (parser
)->location
;
5279 c_parser_consume_token (parser
);
5283 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5287 c_token
*next_tok
= c_parser_peek_token (parser
);
5288 if (next_tok
->type
!= CPP_CLOSE_BRACE
)
5291 ret
.original_code
= ERROR_MARK
;
5292 ret
.original_type
= NULL
;
5293 braces
.skip_until_found_close (parser
);
5294 pop_init_level (brace_loc
, 0, &braced_init_obstack
, last_init_list_comma
);
5295 obstack_free (&braced_init_obstack
, NULL
);
5298 location_t close_loc
= next_tok
->location
;
5299 c_parser_consume_token (parser
);
5300 ret
= pop_init_level (brace_loc
, 0, &braced_init_obstack
, close_loc
);
5301 obstack_free (&braced_init_obstack
, NULL
);
5302 set_c_expr_source_range (&ret
, brace_loc
, close_loc
);
5306 /* Parse a nested initializer, including designators. */
5309 c_parser_initelt (c_parser
*parser
, struct obstack
* braced_init_obstack
)
5311 /* Parse any designator or designator list. A single array
5312 designator may have the subsequent "=" omitted in GNU C, but a
5313 longer list or a structure member designator may not. */
5314 if (c_parser_next_token_is (parser
, CPP_NAME
)
5315 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
5317 /* Old-style structure member designator. */
5318 set_init_label (c_parser_peek_token (parser
)->location
,
5319 c_parser_peek_token (parser
)->value
,
5320 c_parser_peek_token (parser
)->location
,
5321 braced_init_obstack
);
5322 /* Use the colon as the error location. */
5323 pedwarn (c_parser_peek_2nd_token (parser
)->location
, OPT_Wpedantic
,
5324 "obsolete use of designated initializer with %<:%>");
5325 c_parser_consume_token (parser
);
5326 c_parser_consume_token (parser
);
5330 /* des_seen is 0 if there have been no designators, 1 if there
5331 has been a single array designator and 2 otherwise. */
5333 /* Location of a designator. */
5334 location_t des_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5335 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
5336 || c_parser_next_token_is (parser
, CPP_DOT
))
5338 int des_prev
= des_seen
;
5340 des_loc
= c_parser_peek_token (parser
)->location
;
5343 if (c_parser_next_token_is (parser
, CPP_DOT
))
5346 c_parser_consume_token (parser
);
5347 if (c_parser_next_token_is (parser
, CPP_NAME
))
5349 set_init_label (des_loc
, c_parser_peek_token (parser
)->value
,
5350 c_parser_peek_token (parser
)->location
,
5351 braced_init_obstack
);
5352 c_parser_consume_token (parser
);
5358 init
.original_code
= ERROR_MARK
;
5359 init
.original_type
= NULL
;
5360 c_parser_error (parser
, "expected identifier");
5361 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5362 process_init_element (input_location
, init
, false,
5363 braced_init_obstack
);
5370 location_t ellipsis_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5371 location_t array_index_loc
= UNKNOWN_LOCATION
;
5372 /* ??? Following the old parser, [ objc-receiver
5373 objc-message-args ] is accepted as an initializer,
5374 being distinguished from a designator by what follows
5375 the first assignment expression inside the square
5376 brackets, but after a first array designator a
5377 subsequent square bracket is for Objective-C taken to
5378 start an expression, using the obsolete form of
5379 designated initializer without '=', rather than
5380 possibly being a second level of designation: in LALR
5381 terms, the '[' is shifted rather than reducing
5382 designator to designator-list. */
5383 if (des_prev
== 1 && c_dialect_objc ())
5385 des_seen
= des_prev
;
5388 if (des_prev
== 0 && c_dialect_objc ())
5390 /* This might be an array designator or an
5391 Objective-C message expression. If the former,
5392 continue parsing here; if the latter, parse the
5393 remainder of the initializer given the starting
5394 primary-expression. ??? It might make sense to
5395 distinguish when des_prev == 1 as well; see
5396 previous comment. */
5398 struct c_expr mexpr
;
5399 c_parser_consume_token (parser
);
5400 if (c_parser_peek_token (parser
)->type
== CPP_NAME
5401 && ((c_parser_peek_token (parser
)->id_kind
5403 || (c_parser_peek_token (parser
)->id_kind
5404 == C_ID_CLASSNAME
)))
5406 /* Type name receiver. */
5407 tree id
= c_parser_peek_token (parser
)->value
;
5408 c_parser_consume_token (parser
);
5409 rec
= objc_get_class_reference (id
);
5410 goto parse_message_args
;
5412 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
5413 mark_exp_read (first
);
5414 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
)
5415 || c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5416 goto array_desig_after_first
;
5417 /* Expression receiver. So far only one part
5418 without commas has been parsed; there might be
5419 more of the expression. */
5421 while (c_parser_next_token_is (parser
, CPP_COMMA
))
5424 location_t comma_loc
, exp_loc
;
5425 comma_loc
= c_parser_peek_token (parser
)->location
;
5426 c_parser_consume_token (parser
);
5427 exp_loc
= c_parser_peek_token (parser
)->location
;
5428 next
= c_parser_expr_no_commas (parser
, NULL
);
5429 next
= convert_lvalue_to_rvalue (exp_loc
, next
,
5431 rec
= build_compound_expr (comma_loc
, rec
, next
.value
);
5434 /* Now parse the objc-message-args. */
5435 args
= c_parser_objc_message_args (parser
);
5436 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5439 = objc_build_message_expr (rec
, args
);
5440 mexpr
.original_code
= ERROR_MARK
;
5441 mexpr
.original_type
= NULL
;
5442 /* Now parse and process the remainder of the
5443 initializer, starting with this message
5444 expression as a primary-expression. */
5445 c_parser_initval (parser
, &mexpr
, braced_init_obstack
);
5448 c_parser_consume_token (parser
);
5449 array_index_loc
= c_parser_peek_token (parser
)->location
;
5450 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
5451 mark_exp_read (first
);
5452 array_desig_after_first
:
5453 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5455 ellipsis_loc
= c_parser_peek_token (parser
)->location
;
5456 c_parser_consume_token (parser
);
5457 second
= c_parser_expr_no_commas (parser
, NULL
).value
;
5458 mark_exp_read (second
);
5462 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5464 c_parser_consume_token (parser
);
5465 set_init_index (array_index_loc
, first
, second
,
5466 braced_init_obstack
);
5468 pedwarn (ellipsis_loc
, OPT_Wpedantic
,
5469 "ISO C forbids specifying range of elements to initialize");
5472 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5478 if (c_parser_next_token_is (parser
, CPP_EQ
))
5480 pedwarn_c90 (des_loc
, OPT_Wpedantic
,
5481 "ISO C90 forbids specifying subobject "
5483 c_parser_consume_token (parser
);
5488 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
5489 "obsolete use of designated initializer without %<=%>");
5494 init
.original_code
= ERROR_MARK
;
5495 init
.original_type
= NULL
;
5496 c_parser_error (parser
, "expected %<=%>");
5497 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5498 process_init_element (input_location
, init
, false,
5499 braced_init_obstack
);
5505 c_parser_initval (parser
, NULL
, braced_init_obstack
);
5508 /* Parse a nested initializer; as c_parser_initializer but parses
5509 initializers within braced lists, after any designators have been
5510 applied. If AFTER is not NULL then it is an Objective-C message
5511 expression which is the primary-expression starting the
5515 c_parser_initval (c_parser
*parser
, struct c_expr
*after
,
5516 struct obstack
* braced_init_obstack
)
5519 gcc_assert (!after
|| c_dialect_objc ());
5520 location_t loc
= c_parser_peek_token (parser
)->location
;
5522 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
) && !after
)
5523 init
= c_parser_braced_init (parser
, NULL_TREE
, true,
5524 braced_init_obstack
);
5527 init
= c_parser_expr_no_commas (parser
, after
);
5528 if (init
.value
!= NULL_TREE
5529 && TREE_CODE (init
.value
) != STRING_CST
5530 && TREE_CODE (init
.value
) != COMPOUND_LITERAL_EXPR
)
5531 init
= convert_lvalue_to_rvalue (loc
, init
, true, true);
5533 process_init_element (loc
, init
, false, braced_init_obstack
);
5536 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5537 C99 6.8.2, C11 6.8.2).
5540 { block-item-list[opt] }
5541 { label-declarations block-item-list }
5545 block-item-list block-item
5557 { label-declarations block-item-list }
5560 __extension__ nested-declaration
5561 nested-function-definition
5565 label-declarations label-declaration
5568 __label__ identifier-list ;
5570 Allowing the mixing of declarations and code is new in C99. The
5571 GNU syntax also permits (not shown above) labels at the end of
5572 compound statements, which yield an error. We don't allow labels
5573 on declarations; this might seem like a natural extension, but
5574 there would be a conflict between gnu-attributes on the label and
5575 prefix gnu-attributes on the declaration. ??? The syntax follows the
5576 old parser in requiring something after label declarations.
5577 Although they are erroneous if the labels declared aren't defined,
5578 is it useful for the syntax to be this way?
5599 cancellation-point-directive */
5602 c_parser_compound_statement (c_parser
*parser
)
5605 location_t brace_loc
;
5606 brace_loc
= c_parser_peek_token (parser
)->location
;
5607 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
5609 /* Ensure a scope is entered and left anyway to avoid confusion
5610 if we have just prepared to enter a function body. */
5611 stmt
= c_begin_compound_stmt (true);
5612 c_end_compound_stmt (brace_loc
, stmt
, true);
5613 return error_mark_node
;
5615 stmt
= c_begin_compound_stmt (true);
5616 c_parser_compound_statement_nostart (parser
);
5618 return c_end_compound_stmt (brace_loc
, stmt
, true);
5621 /* Parse a compound statement except for the opening brace. This is
5622 used for parsing both compound statements and statement expressions
5623 (which follow different paths to handling the opening). */
5626 c_parser_compound_statement_nostart (c_parser
*parser
)
5628 bool last_stmt
= false;
5629 bool last_label
= false;
5630 bool save_valid_for_pragma
= valid_location_for_stdc_pragma_p ();
5631 location_t label_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5632 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5634 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
5635 c_parser_consume_token (parser
);
5638 mark_valid_location_for_stdc_pragma (true);
5639 if (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5641 /* Read zero or more forward-declarations for labels that nested
5642 functions can jump to. */
5643 mark_valid_location_for_stdc_pragma (false);
5644 while (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5646 label_loc
= c_parser_peek_token (parser
)->location
;
5647 c_parser_consume_token (parser
);
5648 /* Any identifiers, including those declared as type names,
5653 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
5655 c_parser_error (parser
, "expected identifier");
5659 = declare_label (c_parser_peek_token (parser
)->value
);
5660 C_DECLARED_LABEL_FLAG (label
) = 1;
5661 add_stmt (build_stmt (label_loc
, DECL_EXPR
, label
));
5662 c_parser_consume_token (parser
);
5663 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5664 c_parser_consume_token (parser
);
5668 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
5670 pedwarn (label_loc
, OPT_Wpedantic
, "ISO C forbids label declarations");
5672 /* We must now have at least one statement, label or declaration. */
5673 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5675 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5676 c_parser_error (parser
, "expected declaration or statement");
5677 c_parser_consume_token (parser
);
5680 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_BRACE
))
5682 location_t loc
= c_parser_peek_token (parser
)->location
;
5683 loc
= expansion_point_location_if_in_system_header (loc
);
5684 /* Standard attributes may start a statement or a declaration. */
5686 = c_parser_nth_token_starts_std_attributes (parser
, 1);
5687 tree std_attrs
= NULL_TREE
;
5689 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5690 if (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5691 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5692 || (c_parser_next_token_is (parser
, CPP_NAME
)
5693 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5695 c_warn_unused_attributes (std_attrs
);
5696 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5697 label_loc
= c_parser_peek_2nd_token (parser
)->location
;
5699 label_loc
= c_parser_peek_token (parser
)->location
;
5702 mark_valid_location_for_stdc_pragma (false);
5703 c_parser_label (parser
);
5705 else if (!last_label
5706 && (c_parser_next_tokens_start_declaration (parser
)
5708 && c_parser_next_token_is (parser
, CPP_SEMICOLON
))))
5711 mark_valid_location_for_stdc_pragma (false);
5712 bool fallthru_attr_p
= false;
5713 c_parser_declaration_or_fndef (parser
, true, !have_std_attrs
,
5714 true, true, true, NULL
,
5715 vNULL
, have_std_attrs
, std_attrs
,
5716 NULL
, &fallthru_attr_p
);
5717 if (last_stmt
&& !fallthru_attr_p
)
5718 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5719 "ISO C90 forbids mixed declarations and code");
5720 last_stmt
= fallthru_attr_p
;
5722 else if (!last_label
5723 && c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
5725 /* __extension__ can start a declaration, but is also an
5726 unary operator that can start an expression. Consume all
5727 but the last of a possible series of __extension__ to
5728 determine which. If standard attributes have already
5729 been seen, it must start a statement, not a declaration,
5730 but standard attributes starting a declaration may appear
5731 after __extension__. */
5732 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
5733 && (c_parser_peek_2nd_token (parser
)->keyword
5735 c_parser_consume_token (parser
);
5737 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
5738 || c_parser_nth_token_starts_std_attributes (parser
, 2)))
5741 ext
= disable_extension_diagnostics ();
5742 c_parser_consume_token (parser
);
5744 mark_valid_location_for_stdc_pragma (false);
5745 c_parser_declaration_or_fndef (parser
, true, true, true, true,
5747 /* Following the old parser, __extension__ does not
5748 disable this diagnostic. */
5749 restore_extension_diagnostics (ext
);
5751 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5752 "ISO C90 forbids mixed declarations and code");
5758 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
5761 c_parser_error (parser
, "expected declaration or statement");
5762 /* External pragmas, and some omp pragmas, are not associated
5763 with regular c code, and so are not to be considered statements
5764 syntactically. This ensures that the user doesn't put them
5765 places that would turn into syntax errors if the directive
5767 if (c_parser_pragma (parser
,
5768 last_label
? pragma_stmt
: pragma_compound
,
5770 last_label
= false, last_stmt
= true;
5772 else if (c_parser_next_token_is (parser
, CPP_EOF
))
5774 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5775 c_parser_error (parser
, "expected declaration or statement");
5778 else if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
5780 if (parser
->in_if_block
)
5782 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5783 error_at (loc
, "expected %<}%> before %<else%>");
5788 error_at (loc
, "%<else%> without a previous %<if%>");
5789 c_parser_consume_token (parser
);
5796 c_warn_unused_attributes (std_attrs
);
5799 mark_valid_location_for_stdc_pragma (false);
5800 c_parser_statement_after_labels (parser
, NULL
);
5803 parser
->error
= false;
5806 error_at (label_loc
, "label at end of compound statement");
5807 c_parser_consume_token (parser
);
5808 /* Restore the value we started with. */
5809 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5812 /* Parse all consecutive labels, possibly preceded by standard
5813 attributes. In this context, a statement is required, not a
5814 declaration, so attributes must be followed by a statement that is
5815 not just a semicolon. */
5818 c_parser_all_labels (c_parser
*parser
)
5820 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
5822 tree std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5823 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5824 c_parser_error (parser
, "expected statement");
5826 c_warn_unused_attributes (std_attrs
);
5828 while (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5829 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5830 || (c_parser_next_token_is (parser
, CPP_NAME
)
5831 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5832 c_parser_label (parser
);
5835 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5838 identifier : gnu-attributes[opt]
5839 case constant-expression :
5845 case constant-expression ... constant-expression :
5847 The use of gnu-attributes on labels is a GNU extension. The syntax in
5848 GNU C accepts any expressions without commas, non-constant
5849 expressions being rejected later. Any standard
5850 attribute-specifier-sequence before the first label has been parsed
5851 in the caller, to distinguish statements from declarations. Any
5852 attribute-specifier-sequence after the label is parsed in this
5856 c_parser_label (c_parser
*parser
)
5858 location_t loc1
= c_parser_peek_token (parser
)->location
;
5859 tree label
= NULL_TREE
;
5861 /* Remember whether this case or a user-defined label is allowed to fall
5863 bool fallthrough_p
= c_parser_peek_token (parser
)->flags
& PREV_FALLTHROUGH
;
5865 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5868 c_parser_consume_token (parser
);
5869 exp1
= c_parser_expr_no_commas (parser
, NULL
).value
;
5870 if (c_parser_next_token_is (parser
, CPP_COLON
))
5872 c_parser_consume_token (parser
);
5873 label
= do_case (loc1
, exp1
, NULL_TREE
);
5875 else if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5877 c_parser_consume_token (parser
);
5878 exp2
= c_parser_expr_no_commas (parser
, NULL
).value
;
5879 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5880 label
= do_case (loc1
, exp1
, exp2
);
5883 c_parser_error (parser
, "expected %<:%> or %<...%>");
5885 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
5887 c_parser_consume_token (parser
);
5888 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5889 label
= do_case (loc1
, NULL_TREE
, NULL_TREE
);
5893 tree name
= c_parser_peek_token (parser
)->value
;
5896 location_t loc2
= c_parser_peek_token (parser
)->location
;
5897 gcc_assert (c_parser_next_token_is (parser
, CPP_NAME
));
5898 c_parser_consume_token (parser
);
5899 gcc_assert (c_parser_next_token_is (parser
, CPP_COLON
));
5900 c_parser_consume_token (parser
);
5901 attrs
= c_parser_gnu_attributes (parser
);
5902 tlab
= define_label (loc2
, name
);
5905 decl_attributes (&tlab
, attrs
, 0);
5906 label
= add_stmt (build_stmt (loc1
, LABEL_EXPR
, tlab
));
5911 if (TREE_CODE (label
) == LABEL_EXPR
)
5912 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label
)) = fallthrough_p
;
5914 FALLTHROUGH_LABEL_P (CASE_LABEL (label
)) = fallthrough_p
;
5916 /* Standard attributes are only allowed here if they start a
5917 statement, not a declaration (including the case of an
5918 attribute-declaration with only attributes). */
5920 = c_parser_nth_token_starts_std_attributes (parser
, 1);
5921 tree std_attrs
= NULL_TREE
;
5923 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5925 /* Allow '__attribute__((fallthrough));'. */
5927 && c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
5929 location_t loc
= c_parser_peek_token (parser
)->location
;
5930 tree attrs
= c_parser_gnu_attributes (parser
);
5931 if (attribute_fallthrough_p (attrs
))
5933 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5935 tree fn
= build_call_expr_internal_loc (loc
,
5941 warning_at (loc
, OPT_Wattributes
, "%<fallthrough%> attribute "
5942 "not followed by %<;%>");
5944 else if (attrs
!= NULL_TREE
)
5945 warning_at (loc
, OPT_Wattributes
, "only attribute %<fallthrough%>"
5946 " can be applied to a null statement");
5948 if (c_parser_next_tokens_start_declaration (parser
)
5950 && c_parser_next_token_is (parser
, CPP_SEMICOLON
)))
5952 error_at (c_parser_peek_token (parser
)->location
,
5953 "a label can only be part of a statement and "
5954 "a declaration is not a statement");
5955 c_parser_declaration_or_fndef (parser
, /*fndef_ok*/ false,
5956 /*static_assert_ok*/ true,
5957 /*empty_ok*/ true, /*nested*/ true,
5958 /*start_attr_ok*/ true, NULL
,
5959 vNULL
, have_std_attrs
, std_attrs
);
5962 /* Nonempty attributes on the following statement are ignored. */
5963 c_warn_unused_attributes (std_attrs
);
5967 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5971 attribute-specifier-sequence[opt] compound-statement
5972 expression-statement
5973 attribute-specifier-sequence[opt] selection-statement
5974 attribute-specifier-sequence[opt] iteration-statement
5975 attribute-specifier-sequence[opt] jump-statement
5978 attribute-specifier-sequence[opt] label statement
5980 expression-statement:
5982 attribute-specifier-sequence expression ;
5984 selection-statement:
5988 iteration-statement:
5997 return expression[opt] ;
6002 attribute-specifier-sequence[opt] asm-statement
6007 expression-statement:
6013 attribute-specifier-sequence[opt] objc-throw-statement
6014 attribute-specifier-sequence[opt] objc-try-catch-statement
6015 attribute-specifier-sequence[opt] objc-synchronized-statement
6017 objc-throw-statement:
6024 attribute-specifier-sequence[opt] openacc-construct
6033 parallel-directive structured-block
6036 kernels-directive structured-block
6039 data-directive structured-block
6042 loop-directive structured-block
6047 attribute-specifier-sequence[opt] openmp-construct
6056 parallel-for-construct
6057 parallel-for-simd-construct
6058 parallel-sections-construct
6065 parallel-directive structured-block
6068 for-directive iteration-statement
6071 simd-directive iteration-statements
6074 for-simd-directive iteration-statements
6077 sections-directive section-scope
6080 single-directive structured-block
6082 parallel-for-construct:
6083 parallel-for-directive iteration-statement
6085 parallel-for-simd-construct:
6086 parallel-for-simd-directive iteration-statement
6088 parallel-sections-construct:
6089 parallel-sections-directive section-scope
6092 master-directive structured-block
6095 critical-directive structured-block
6098 atomic-directive expression-statement
6101 ordered-directive structured-block
6103 Transactional Memory:
6106 attribute-specifier-sequence[opt] transaction-statement
6107 attribute-specifier-sequence[opt] transaction-cancel-statement
6109 IF_P is used to track whether there's a (possibly labeled) if statement
6110 which is not enclosed in braces and has an else clause. This is used to
6111 implement -Wparentheses. */
6114 c_parser_statement (c_parser
*parser
, bool *if_p
, location_t
*loc_after_labels
)
6116 c_parser_all_labels (parser
);
6117 if (loc_after_labels
)
6118 *loc_after_labels
= c_parser_peek_token (parser
)->location
;
6119 c_parser_statement_after_labels (parser
, if_p
, NULL
);
6122 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6123 of if-else-if conditions. All labels and standard attributes have
6124 been parsed in the caller.
6126 IF_P is used to track whether there's a (possibly labeled) if statement
6127 which is not enclosed in braces and has an else clause. This is used to
6128 implement -Wparentheses. */
6131 c_parser_statement_after_labels (c_parser
*parser
, bool *if_p
,
6134 location_t loc
= c_parser_peek_token (parser
)->location
;
6135 tree stmt
= NULL_TREE
;
6136 bool in_if_block
= parser
->in_if_block
;
6137 parser
->in_if_block
= false;
6141 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_BRACE
)
6142 add_debug_begin_stmt (loc
);
6144 switch (c_parser_peek_token (parser
)->type
)
6146 case CPP_OPEN_BRACE
:
6147 add_stmt (c_parser_compound_statement (parser
));
6150 switch (c_parser_peek_token (parser
)->keyword
)
6153 c_parser_if_statement (parser
, if_p
, chain
);
6156 c_parser_switch_statement (parser
, if_p
);
6159 c_parser_while_statement (parser
, false, 0, if_p
);
6162 c_parser_do_statement (parser
, 0, false);
6165 c_parser_for_statement (parser
, false, 0, if_p
);
6168 c_parser_consume_token (parser
);
6169 if (c_parser_next_token_is (parser
, CPP_NAME
))
6171 stmt
= c_finish_goto_label (loc
,
6172 c_parser_peek_token (parser
)->value
);
6173 c_parser_consume_token (parser
);
6175 else if (c_parser_next_token_is (parser
, CPP_MULT
))
6179 c_parser_consume_token (parser
);
6180 val
= c_parser_expression (parser
);
6181 val
= convert_lvalue_to_rvalue (loc
, val
, false, true);
6182 stmt
= c_finish_goto_ptr (loc
, val
.value
);
6185 c_parser_error (parser
, "expected identifier or %<*%>");
6186 goto expect_semicolon
;
6188 c_parser_consume_token (parser
);
6189 stmt
= c_finish_bc_stmt (loc
, &c_cont_label
, false);
6190 goto expect_semicolon
;
6192 c_parser_consume_token (parser
);
6193 stmt
= c_finish_bc_stmt (loc
, &c_break_label
, true);
6194 goto expect_semicolon
;
6196 c_parser_consume_token (parser
);
6197 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6199 stmt
= c_finish_return (loc
, NULL_TREE
, NULL_TREE
);
6200 c_parser_consume_token (parser
);
6204 location_t xloc
= c_parser_peek_token (parser
)->location
;
6205 struct c_expr expr
= c_parser_expression_conv (parser
);
6206 mark_exp_read (expr
.value
);
6207 stmt
= c_finish_return (EXPR_LOC_OR_LOC (expr
.value
, xloc
),
6208 expr
.value
, expr
.original_type
);
6209 goto expect_semicolon
;
6213 stmt
= c_parser_asm_statement (parser
);
6215 case RID_TRANSACTION_ATOMIC
:
6216 case RID_TRANSACTION_RELAXED
:
6217 stmt
= c_parser_transaction (parser
,
6218 c_parser_peek_token (parser
)->keyword
);
6220 case RID_TRANSACTION_CANCEL
:
6221 stmt
= c_parser_transaction_cancel (parser
);
6222 goto expect_semicolon
;
6224 gcc_assert (c_dialect_objc ());
6225 c_parser_consume_token (parser
);
6226 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6228 stmt
= objc_build_throw_stmt (loc
, NULL_TREE
);
6229 c_parser_consume_token (parser
);
6233 struct c_expr expr
= c_parser_expression (parser
);
6234 expr
= convert_lvalue_to_rvalue (loc
, expr
, false, false);
6235 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
6236 stmt
= objc_build_throw_stmt (loc
, expr
.value
);
6237 goto expect_semicolon
;
6241 gcc_assert (c_dialect_objc ());
6242 c_parser_objc_try_catch_finally_statement (parser
);
6244 case RID_AT_SYNCHRONIZED
:
6245 gcc_assert (c_dialect_objc ());
6246 c_parser_objc_synchronized_statement (parser
);
6250 /* Allow '__attribute__((fallthrough));'. */
6251 tree attrs
= c_parser_gnu_attributes (parser
);
6252 if (attribute_fallthrough_p (attrs
))
6254 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6256 tree fn
= build_call_expr_internal_loc (loc
,
6261 c_parser_consume_token (parser
);
6264 warning_at (loc
, OPT_Wattributes
,
6265 "%<fallthrough%> attribute not followed "
6268 else if (attrs
!= NULL_TREE
)
6269 warning_at (loc
, OPT_Wattributes
, "only attribute %<fallthrough%>"
6270 " can be applied to a null statement");
6278 c_parser_consume_token (parser
);
6280 case CPP_CLOSE_PAREN
:
6281 case CPP_CLOSE_SQUARE
:
6282 /* Avoid infinite loop in error recovery:
6283 c_parser_skip_until_found stops at a closing nesting
6284 delimiter without consuming it, but here we need to consume
6285 it to proceed further. */
6286 c_parser_error (parser
, "expected statement");
6287 c_parser_consume_token (parser
);
6290 c_parser_pragma (parser
, pragma_stmt
, if_p
);
6294 stmt
= c_finish_expr_stmt (loc
, c_parser_expression_conv (parser
).value
);
6296 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
6299 /* Two cases cannot and do not have line numbers associated: If stmt
6300 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6301 cannot hold line numbers. But that's OK because the statement
6302 will either be changed to a MODIFY_EXPR during gimplification of
6303 the statement expr, or discarded. If stmt was compound, but
6304 without new variables, we will have skipped the creation of a
6305 BIND and will have a bare STATEMENT_LIST. But that's OK because
6306 (recursively) all of the component statements should already have
6307 line numbers assigned. ??? Can we discard no-op statements
6309 if (EXPR_LOCATION (stmt
) == UNKNOWN_LOCATION
)
6310 protected_set_expr_location (stmt
, loc
);
6312 parser
->in_if_block
= in_if_block
;
6315 /* Parse the condition from an if, do, while or for statements. */
6318 c_parser_condition (c_parser
*parser
)
6320 location_t loc
= c_parser_peek_token (parser
)->location
;
6322 cond
= c_parser_expression_conv (parser
).value
;
6323 cond
= c_objc_common_truthvalue_conversion (loc
, cond
);
6324 cond
= c_fully_fold (cond
, false, NULL
);
6325 if (warn_sequence_point
)
6326 verify_sequence_points (cond
);
6330 /* Parse a parenthesized condition from an if, do or while statement.
6336 c_parser_paren_condition (c_parser
*parser
)
6339 matching_parens parens
;
6340 if (!parens
.require_open (parser
))
6341 return error_mark_node
;
6342 cond
= c_parser_condition (parser
);
6343 parens
.skip_until_found_close (parser
);
6347 /* Parse a statement which is a block in C99.
6349 IF_P is used to track whether there's a (possibly labeled) if statement
6350 which is not enclosed in braces and has an else clause. This is used to
6351 implement -Wparentheses. */
6354 c_parser_c99_block_statement (c_parser
*parser
, bool *if_p
,
6355 location_t
*loc_after_labels
)
6357 tree block
= c_begin_compound_stmt (flag_isoc99
);
6358 location_t loc
= c_parser_peek_token (parser
)->location
;
6359 c_parser_statement (parser
, if_p
, loc_after_labels
);
6360 return c_end_compound_stmt (loc
, block
, flag_isoc99
);
6363 /* Parse the body of an if statement. This is just parsing a
6364 statement but (a) it is a block in C99, (b) we track whether the
6365 body is an if statement for the sake of -Wparentheses warnings, (c)
6366 we handle an empty body specially for the sake of -Wempty-body
6367 warnings, and (d) we call parser_compound_statement directly
6368 because c_parser_statement_after_labels resets
6369 parser->in_if_block.
6371 IF_P is used to track whether there's a (possibly labeled) if statement
6372 which is not enclosed in braces and has an else clause. This is used to
6373 implement -Wparentheses. */
6376 c_parser_if_body (c_parser
*parser
, bool *if_p
,
6377 const token_indent_info
&if_tinfo
)
6379 tree block
= c_begin_compound_stmt (flag_isoc99
);
6380 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6381 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6382 token_indent_info body_tinfo
6383 = get_token_indent_info (c_parser_peek_token (parser
));
6385 c_parser_all_labels (parser
);
6386 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6388 location_t loc
= c_parser_peek_token (parser
)->location
;
6389 add_stmt (build_empty_stmt (loc
));
6390 c_parser_consume_token (parser
);
6391 if (!c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6392 warning_at (loc
, OPT_Wempty_body
,
6393 "suggest braces around empty body in an %<if%> statement");
6395 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6396 add_stmt (c_parser_compound_statement (parser
));
6399 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6400 c_parser_statement_after_labels (parser
, if_p
);
6403 token_indent_info next_tinfo
6404 = get_token_indent_info (c_parser_peek_token (parser
));
6405 warn_for_misleading_indentation (if_tinfo
, body_tinfo
, next_tinfo
);
6406 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6407 && next_tinfo
.type
!= CPP_SEMICOLON
)
6408 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6409 if_tinfo
.location
, RID_IF
);
6411 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6414 /* Parse the else body of an if statement. This is just parsing a
6415 statement but (a) it is a block in C99, (b) we handle an empty body
6416 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6417 of if-else-if conditions. */
6420 c_parser_else_body (c_parser
*parser
, const token_indent_info
&else_tinfo
,
6423 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6424 tree block
= c_begin_compound_stmt (flag_isoc99
);
6425 token_indent_info body_tinfo
6426 = get_token_indent_info (c_parser_peek_token (parser
));
6427 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6429 c_parser_all_labels (parser
);
6430 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6432 location_t loc
= c_parser_peek_token (parser
)->location
;
6435 "suggest braces around empty body in an %<else%> statement");
6436 add_stmt (build_empty_stmt (loc
));
6437 c_parser_consume_token (parser
);
6441 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6442 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6443 c_parser_statement_after_labels (parser
, NULL
, chain
);
6446 token_indent_info next_tinfo
6447 = get_token_indent_info (c_parser_peek_token (parser
));
6448 warn_for_misleading_indentation (else_tinfo
, body_tinfo
, next_tinfo
);
6449 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6450 && next_tinfo
.type
!= CPP_SEMICOLON
)
6451 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6452 else_tinfo
.location
, RID_ELSE
);
6454 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6457 /* We might need to reclassify any previously-lexed identifier, e.g.
6458 when we've left a for loop with an if-statement without else in the
6459 body - we might have used a wrong scope for the token. See PR67784. */
6462 c_parser_maybe_reclassify_token (c_parser
*parser
)
6464 if (c_parser_next_token_is (parser
, CPP_NAME
))
6466 c_token
*token
= c_parser_peek_token (parser
);
6468 if (token
->id_kind
!= C_ID_CLASSNAME
)
6470 tree decl
= lookup_name (token
->value
);
6472 token
->id_kind
= C_ID_ID
;
6475 if (TREE_CODE (decl
) == TYPE_DECL
)
6476 token
->id_kind
= C_ID_TYPENAME
;
6478 else if (c_dialect_objc ())
6480 tree objc_interface_decl
= objc_is_class_name (token
->value
);
6481 /* Objective-C class names are in the same namespace as
6482 variables and typedefs, and hence are shadowed by local
6484 if (objc_interface_decl
)
6486 token
->value
= objc_interface_decl
;
6487 token
->id_kind
= C_ID_CLASSNAME
;
6494 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6497 if ( expression ) statement
6498 if ( expression ) statement else statement
6500 CHAIN is a vector of if-else-if conditions.
6501 IF_P is used to track whether there's a (possibly labeled) if statement
6502 which is not enclosed in braces and has an else clause. This is used to
6503 implement -Wparentheses. */
6506 c_parser_if_statement (c_parser
*parser
, bool *if_p
, vec
<tree
> *chain
)
6511 bool nested_if
= false;
6512 tree first_body
, second_body
;
6515 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_IF
));
6516 token_indent_info if_tinfo
6517 = get_token_indent_info (c_parser_peek_token (parser
));
6518 c_parser_consume_token (parser
);
6519 block
= c_begin_compound_stmt (flag_isoc99
);
6520 loc
= c_parser_peek_token (parser
)->location
;
6521 cond
= c_parser_paren_condition (parser
);
6522 in_if_block
= parser
->in_if_block
;
6523 parser
->in_if_block
= true;
6524 first_body
= c_parser_if_body (parser
, &nested_if
, if_tinfo
);
6525 parser
->in_if_block
= in_if_block
;
6527 if (warn_duplicated_cond
)
6528 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond
), cond
, &chain
);
6530 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6532 token_indent_info else_tinfo
6533 = get_token_indent_info (c_parser_peek_token (parser
));
6534 c_parser_consume_token (parser
);
6535 if (warn_duplicated_cond
)
6537 if (c_parser_next_token_is_keyword (parser
, RID_IF
)
6540 /* We've got "if (COND) else if (COND2)". Start the
6541 condition chain and add COND as the first element. */
6542 chain
= new vec
<tree
> ();
6543 if (!CONSTANT_CLASS_P (cond
) && !TREE_SIDE_EFFECTS (cond
))
6544 chain
->safe_push (cond
);
6546 else if (!c_parser_next_token_is_keyword (parser
, RID_IF
))
6548 /* This is if-else without subsequent if. Zap the condition
6549 chain; we would have already warned at this point. */
6554 second_body
= c_parser_else_body (parser
, else_tinfo
, chain
);
6555 /* Set IF_P to true to indicate that this if statement has an
6556 else clause. This may trigger the Wparentheses warning
6557 below when we get back up to the parent if statement. */
6563 second_body
= NULL_TREE
;
6565 /* Diagnose an ambiguous else if if-then-else is nested inside
6568 warning_at (loc
, OPT_Wdangling_else
,
6569 "suggest explicit braces to avoid ambiguous %<else%>");
6571 if (warn_duplicated_cond
)
6573 /* This if statement does not have an else clause. We don't
6574 need the condition chain anymore. */
6579 c_finish_if_stmt (loc
, cond
, first_body
, second_body
);
6580 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6582 c_parser_maybe_reclassify_token (parser
);
6585 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6588 switch (expression) statement
6592 c_parser_switch_statement (c_parser
*parser
, bool *if_p
)
6595 tree block
, expr
, body
, save_break
;
6596 location_t switch_loc
= c_parser_peek_token (parser
)->location
;
6597 location_t switch_cond_loc
;
6598 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SWITCH
));
6599 c_parser_consume_token (parser
);
6600 block
= c_begin_compound_stmt (flag_isoc99
);
6601 bool explicit_cast_p
= false;
6602 matching_parens parens
;
6603 if (parens
.require_open (parser
))
6605 switch_cond_loc
= c_parser_peek_token (parser
)->location
;
6606 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
6607 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
6608 explicit_cast_p
= true;
6609 ce
= c_parser_expression (parser
);
6610 ce
= convert_lvalue_to_rvalue (switch_cond_loc
, ce
, true, false);
6612 /* ??? expr has no valid location? */
6613 parens
.skip_until_found_close (parser
);
6617 switch_cond_loc
= UNKNOWN_LOCATION
;
6618 expr
= error_mark_node
;
6619 ce
.original_type
= error_mark_node
;
6621 c_start_case (switch_loc
, switch_cond_loc
, expr
, explicit_cast_p
);
6622 save_break
= c_break_label
;
6623 c_break_label
= NULL_TREE
;
6624 location_t loc_after_labels
;
6625 bool open_brace_p
= c_parser_peek_token (parser
)->type
== CPP_OPEN_BRACE
;
6626 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6627 location_t next_loc
= c_parser_peek_token (parser
)->location
;
6628 if (!open_brace_p
&& c_parser_peek_token (parser
)->type
!= CPP_SEMICOLON
)
6629 warn_for_multistatement_macros (loc_after_labels
, next_loc
, switch_loc
,
6633 location_t here
= c_parser_peek_token (parser
)->location
;
6634 tree t
= build1 (LABEL_EXPR
, void_type_node
, c_break_label
);
6635 SET_EXPR_LOCATION (t
, here
);
6636 SWITCH_BREAK_LABEL_P (c_break_label
) = 1;
6637 append_to_statement_list_force (t
, &body
);
6639 c_finish_case (body
, ce
.original_type
);
6640 c_break_label
= save_break
;
6641 add_stmt (c_end_compound_stmt (switch_loc
, block
, flag_isoc99
));
6642 c_parser_maybe_reclassify_token (parser
);
6645 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6648 while (expression) statement
6650 IF_P is used to track whether there's a (possibly labeled) if statement
6651 which is not enclosed in braces and has an else clause. This is used to
6652 implement -Wparentheses. */
6655 c_parser_while_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6658 tree block
, cond
, body
, save_break
, save_cont
;
6660 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_WHILE
));
6661 token_indent_info while_tinfo
6662 = get_token_indent_info (c_parser_peek_token (parser
));
6663 c_parser_consume_token (parser
);
6664 block
= c_begin_compound_stmt (flag_isoc99
);
6665 loc
= c_parser_peek_token (parser
)->location
;
6666 cond
= c_parser_paren_condition (parser
);
6667 if (ivdep
&& cond
!= error_mark_node
)
6668 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6669 build_int_cst (integer_type_node
,
6670 annot_expr_ivdep_kind
),
6672 if (unroll
&& cond
!= error_mark_node
)
6673 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6674 build_int_cst (integer_type_node
,
6675 annot_expr_unroll_kind
),
6676 build_int_cst (integer_type_node
, unroll
));
6677 save_break
= c_break_label
;
6678 c_break_label
= NULL_TREE
;
6679 save_cont
= c_cont_label
;
6680 c_cont_label
= NULL_TREE
;
6682 token_indent_info body_tinfo
6683 = get_token_indent_info (c_parser_peek_token (parser
));
6685 location_t loc_after_labels
;
6686 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
6687 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6688 c_finish_loop (loc
, loc
, cond
, UNKNOWN_LOCATION
, NULL
, body
,
6689 c_break_label
, c_cont_label
, true);
6690 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6691 c_parser_maybe_reclassify_token (parser
);
6693 token_indent_info next_tinfo
6694 = get_token_indent_info (c_parser_peek_token (parser
));
6695 warn_for_misleading_indentation (while_tinfo
, body_tinfo
, next_tinfo
);
6697 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
6698 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
6699 while_tinfo
.location
, RID_WHILE
);
6701 c_break_label
= save_break
;
6702 c_cont_label
= save_cont
;
6705 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6708 do statement while ( expression ) ;
6712 c_parser_do_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
)
6714 tree block
, cond
, body
, save_break
, save_cont
, new_break
, new_cont
;
6716 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_DO
));
6717 c_parser_consume_token (parser
);
6718 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6719 warning_at (c_parser_peek_token (parser
)->location
,
6721 "suggest braces around empty body in %<do%> statement");
6722 block
= c_begin_compound_stmt (flag_isoc99
);
6723 loc
= c_parser_peek_token (parser
)->location
;
6724 save_break
= c_break_label
;
6725 c_break_label
= NULL_TREE
;
6726 save_cont
= c_cont_label
;
6727 c_cont_label
= NULL_TREE
;
6728 body
= c_parser_c99_block_statement (parser
, NULL
);
6729 c_parser_require_keyword (parser
, RID_WHILE
, "expected %<while%>");
6730 new_break
= c_break_label
;
6731 c_break_label
= save_break
;
6732 new_cont
= c_cont_label
;
6733 c_cont_label
= save_cont
;
6734 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
6735 cond
= c_parser_paren_condition (parser
);
6736 if (ivdep
&& cond
!= error_mark_node
)
6737 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6738 build_int_cst (integer_type_node
,
6739 annot_expr_ivdep_kind
),
6741 if (unroll
&& cond
!= error_mark_node
)
6742 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6743 build_int_cst (integer_type_node
,
6744 annot_expr_unroll_kind
),
6745 build_int_cst (integer_type_node
, unroll
));
6746 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
6747 c_parser_skip_to_end_of_block_or_statement (parser
);
6748 c_finish_loop (loc
, cond_loc
, cond
, UNKNOWN_LOCATION
, NULL
, body
,
6749 new_break
, new_cont
, false);
6750 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6753 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6756 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6757 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6759 The form with a declaration is new in C99.
6761 ??? In accordance with the old parser, the declaration may be a
6762 nested function, which is then rejected in check_for_loop_decls,
6763 but does it make any sense for this to be included in the grammar?
6764 Note in particular that the nested function does not include a
6765 trailing ';', whereas the "declaration" production includes one.
6766 Also, can we reject bad declarations earlier and cheaper than
6767 check_for_loop_decls?
6769 In Objective-C, there are two additional variants:
6772 for ( expression in expresssion ) statement
6773 for ( declaration in expression ) statement
6775 This is inconsistent with C, because the second variant is allowed
6776 even if c99 is not enabled.
6778 The rest of the comment documents these Objective-C foreach-statement.
6780 Here is the canonical example of the first variant:
6781 for (object in array) { do something with object }
6782 we call the first expression ("object") the "object_expression" and
6783 the second expression ("array") the "collection_expression".
6784 object_expression must be an lvalue of type "id" (a generic Objective-C
6785 object) because the loop works by assigning to object_expression the
6786 various objects from the collection_expression. collection_expression
6787 must evaluate to something of type "id" which responds to the method
6788 countByEnumeratingWithState:objects:count:.
6790 The canonical example of the second variant is:
6791 for (id object in array) { do something with object }
6792 which is completely equivalent to
6795 for (object in array) { do something with object }
6797 Note that initizializing 'object' in some way (eg, "for ((object =
6798 xxx) in array) { do something with object }") is possibly
6799 technically valid, but completely pointless as 'object' will be
6800 assigned to something else as soon as the loop starts. We should
6801 most likely reject it (TODO).
6803 The beginning of the Objective-C foreach-statement looks exactly
6804 like the beginning of the for-statement, and we can tell it is a
6805 foreach-statement only because the initial declaration or
6806 expression is terminated by 'in' instead of ';'.
6808 IF_P is used to track whether there's a (possibly labeled) if statement
6809 which is not enclosed in braces and has an else clause. This is used to
6810 implement -Wparentheses. */
6813 c_parser_for_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6816 tree block
, cond
, incr
, save_break
, save_cont
, body
;
6817 /* The following are only used when parsing an ObjC foreach statement. */
6818 tree object_expression
;
6819 /* Silence the bogus uninitialized warning. */
6820 tree collection_expression
= NULL
;
6821 location_t loc
= c_parser_peek_token (parser
)->location
;
6822 location_t for_loc
= loc
;
6823 location_t cond_loc
= UNKNOWN_LOCATION
;
6824 location_t incr_loc
= UNKNOWN_LOCATION
;
6825 bool is_foreach_statement
= false;
6826 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
6827 token_indent_info for_tinfo
6828 = get_token_indent_info (c_parser_peek_token (parser
));
6829 c_parser_consume_token (parser
);
6830 /* Open a compound statement in Objective-C as well, just in case this is
6831 as foreach expression. */
6832 block
= c_begin_compound_stmt (flag_isoc99
|| c_dialect_objc ());
6833 cond
= error_mark_node
;
6834 incr
= error_mark_node
;
6835 matching_parens parens
;
6836 if (parens
.require_open (parser
))
6838 /* Parse the initialization declaration or expression. */
6839 object_expression
= error_mark_node
;
6840 parser
->objc_could_be_foreach_context
= c_dialect_objc ();
6841 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6843 parser
->objc_could_be_foreach_context
= false;
6844 c_parser_consume_token (parser
);
6845 c_finish_expr_stmt (loc
, NULL_TREE
);
6847 else if (c_parser_next_tokens_start_declaration (parser
)
6848 || c_parser_nth_token_starts_std_attributes (parser
, 1))
6850 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
6851 &object_expression
, vNULL
);
6852 parser
->objc_could_be_foreach_context
= false;
6854 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6856 c_parser_consume_token (parser
);
6857 is_foreach_statement
= true;
6858 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6859 c_parser_error (parser
, "multiple iterating variables in "
6860 "fast enumeration");
6863 check_for_loop_decls (for_loc
, flag_isoc99
);
6865 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
6867 /* __extension__ can start a declaration, but is also an
6868 unary operator that can start an expression. Consume all
6869 but the last of a possible series of __extension__ to
6871 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
6872 && (c_parser_peek_2nd_token (parser
)->keyword
6874 c_parser_consume_token (parser
);
6875 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
6876 || c_parser_nth_token_starts_std_attributes (parser
, 2))
6879 ext
= disable_extension_diagnostics ();
6880 c_parser_consume_token (parser
);
6881 c_parser_declaration_or_fndef (parser
, true, true, true, true,
6882 true, &object_expression
, vNULL
);
6883 parser
->objc_could_be_foreach_context
= false;
6885 restore_extension_diagnostics (ext
);
6886 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6888 c_parser_consume_token (parser
);
6889 is_foreach_statement
= true;
6890 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6891 c_parser_error (parser
, "multiple iterating variables in "
6892 "fast enumeration");
6895 check_for_loop_decls (for_loc
, flag_isoc99
);
6905 tree init_expression
;
6906 ce
= c_parser_expression (parser
);
6907 init_expression
= ce
.value
;
6908 parser
->objc_could_be_foreach_context
= false;
6909 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6911 c_parser_consume_token (parser
);
6912 is_foreach_statement
= true;
6913 if (! lvalue_p (init_expression
))
6914 c_parser_error (parser
, "invalid iterating variable in "
6915 "fast enumeration");
6917 = c_fully_fold (init_expression
, false, NULL
);
6921 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6922 init_expression
= ce
.value
;
6923 c_finish_expr_stmt (loc
, init_expression
);
6924 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6929 /* Parse the loop condition. In the case of a foreach
6930 statement, there is no loop condition. */
6931 gcc_assert (!parser
->objc_could_be_foreach_context
);
6932 if (!is_foreach_statement
)
6934 cond_loc
= c_parser_peek_token (parser
)->location
;
6935 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6939 c_parser_error (parser
, "missing loop condition in loop "
6940 "with %<GCC ivdep%> pragma");
6941 cond
= error_mark_node
;
6945 c_parser_error (parser
, "missing loop condition in loop "
6946 "with %<GCC unroll%> pragma");
6947 cond
= error_mark_node
;
6951 c_parser_consume_token (parser
);
6957 cond
= c_parser_condition (parser
);
6958 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6961 if (ivdep
&& cond
!= error_mark_node
)
6962 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6963 build_int_cst (integer_type_node
,
6964 annot_expr_ivdep_kind
),
6966 if (unroll
&& cond
!= error_mark_node
)
6967 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6968 build_int_cst (integer_type_node
,
6969 annot_expr_unroll_kind
),
6970 build_int_cst (integer_type_node
, unroll
));
6972 /* Parse the increment expression (the third expression in a
6973 for-statement). In the case of a foreach-statement, this is
6974 the expression that follows the 'in'. */
6975 loc
= incr_loc
= c_parser_peek_token (parser
)->location
;
6976 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
6978 if (is_foreach_statement
)
6980 c_parser_error (parser
,
6981 "missing collection in fast enumeration");
6982 collection_expression
= error_mark_node
;
6985 incr
= c_process_expr_stmt (loc
, NULL_TREE
);
6989 if (is_foreach_statement
)
6990 collection_expression
6991 = c_fully_fold (c_parser_expression (parser
).value
, false, NULL
);
6994 struct c_expr ce
= c_parser_expression (parser
);
6995 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6996 incr
= c_process_expr_stmt (loc
, ce
.value
);
6999 parens
.skip_until_found_close (parser
);
7001 save_break
= c_break_label
;
7002 c_break_label
= NULL_TREE
;
7003 save_cont
= c_cont_label
;
7004 c_cont_label
= NULL_TREE
;
7006 token_indent_info body_tinfo
7007 = get_token_indent_info (c_parser_peek_token (parser
));
7009 location_t loc_after_labels
;
7010 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
7011 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
7013 if (is_foreach_statement
)
7014 objc_finish_foreach_loop (for_loc
, object_expression
,
7015 collection_expression
, body
, c_break_label
,
7018 c_finish_loop (for_loc
, cond_loc
, cond
, incr_loc
, incr
, body
,
7019 c_break_label
, c_cont_label
, true);
7020 add_stmt (c_end_compound_stmt (for_loc
, block
,
7021 flag_isoc99
|| c_dialect_objc ()));
7022 c_parser_maybe_reclassify_token (parser
);
7024 token_indent_info next_tinfo
7025 = get_token_indent_info (c_parser_peek_token (parser
));
7026 warn_for_misleading_indentation (for_tinfo
, body_tinfo
, next_tinfo
);
7028 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
7029 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
7030 for_tinfo
.location
, RID_FOR
);
7032 c_break_label
= save_break
;
7033 c_cont_label
= save_cont
;
7036 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7037 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7046 asm-qualifier-list asm-qualifier
7050 asm asm-qualifier-list[opt] ( asm-argument ) ;
7054 asm-string-literal : asm-operands[opt]
7055 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7056 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7058 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7061 The form with asm-goto-operands is valid if and only if the
7062 asm-qualifier-list contains goto, and is the only allowed form in that case.
7063 Duplicate asm-qualifiers are not allowed.
7065 The :: token is considered equivalent to two consecutive : tokens. */
7068 c_parser_asm_statement (c_parser
*parser
)
7070 tree str
, outputs
, inputs
, clobbers
, labels
, ret
;
7072 location_t asm_loc
= c_parser_peek_token (parser
)->location
;
7073 int section
, nsections
;
7075 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
7076 c_parser_consume_token (parser
);
7078 /* Handle the asm-qualifier-list. */
7079 location_t volatile_loc
= UNKNOWN_LOCATION
;
7080 location_t inline_loc
= UNKNOWN_LOCATION
;
7081 location_t goto_loc
= UNKNOWN_LOCATION
;
7084 c_token
*token
= c_parser_peek_token (parser
);
7085 location_t loc
= token
->location
;
7086 switch (token
->keyword
)
7091 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7092 inform (volatile_loc
, "first seen here");
7096 c_parser_consume_token (parser
);
7102 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7103 inform (inline_loc
, "first seen here");
7107 c_parser_consume_token (parser
);
7113 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7114 inform (goto_loc
, "first seen here");
7118 c_parser_consume_token (parser
);
7123 error_at (loc
, "%qE is not a valid %<asm%> qualifier", token
->value
);
7124 c_parser_consume_token (parser
);
7133 bool is_volatile
= (volatile_loc
!= UNKNOWN_LOCATION
);
7134 bool is_inline
= (inline_loc
!= UNKNOWN_LOCATION
);
7135 bool is_goto
= (goto_loc
!= UNKNOWN_LOCATION
);
7139 matching_parens parens
;
7140 if (!parens
.require_open (parser
))
7143 str
= c_parser_asm_string_literal (parser
);
7144 if (str
== NULL_TREE
)
7145 goto error_close_paren
;
7148 outputs
= NULL_TREE
;
7150 clobbers
= NULL_TREE
;
7153 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7156 /* Parse each colon-delimited section of operands. */
7157 nsections
= 3 + is_goto
;
7158 for (section
= 0; section
< nsections
; ++section
)
7160 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
7163 if (section
== nsections
)
7165 c_parser_error (parser
, "expected %<)%>");
7166 goto error_close_paren
;
7168 c_parser_consume_token (parser
);
7170 else if (!c_parser_require (parser
, CPP_COLON
,
7172 ? G_("expected %<:%>")
7173 : G_("expected %<:%> or %<)%>"),
7174 UNKNOWN_LOCATION
, is_goto
))
7175 goto error_close_paren
;
7177 /* Once past any colon, we're no longer a simple asm. */
7180 if ((!c_parser_next_token_is (parser
, CPP_COLON
)
7181 && !c_parser_next_token_is (parser
, CPP_SCOPE
)
7182 && !c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7187 /* For asm goto, we don't allow output operands, but reserve
7188 the slot for a future extension that does allow them. */
7190 outputs
= c_parser_asm_operands (parser
);
7193 inputs
= c_parser_asm_operands (parser
);
7196 clobbers
= c_parser_asm_clobbers (parser
);
7199 labels
= c_parser_asm_goto_operands (parser
);
7205 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7210 if (!parens
.require_close (parser
))
7212 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7216 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
7217 c_parser_skip_to_end_of_block_or_statement (parser
);
7219 ret
= build_asm_stmt (is_volatile
,
7220 build_asm_expr (asm_loc
, str
, outputs
, inputs
,
7221 clobbers
, labels
, simple
, is_inline
));
7227 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7231 /* Parse asm operands, a GNU extension.
7235 asm-operands , asm-operand
7238 asm-string-literal ( expression )
7239 [ identifier ] asm-string-literal ( expression )
7243 c_parser_asm_operands (c_parser
*parser
)
7245 tree list
= NULL_TREE
;
7250 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
7252 c_parser_consume_token (parser
);
7253 if (c_parser_next_token_is (parser
, CPP_NAME
))
7255 tree id
= c_parser_peek_token (parser
)->value
;
7256 c_parser_consume_token (parser
);
7257 name
= build_string (IDENTIFIER_LENGTH (id
),
7258 IDENTIFIER_POINTER (id
));
7262 c_parser_error (parser
, "expected identifier");
7263 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
7266 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
7271 str
= c_parser_asm_string_literal (parser
);
7272 if (str
== NULL_TREE
)
7274 matching_parens parens
;
7275 if (!parens
.require_open (parser
))
7277 expr
= c_parser_expression (parser
);
7278 mark_exp_read (expr
.value
);
7279 if (!parens
.require_close (parser
))
7281 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7284 list
= chainon (list
, build_tree_list (build_tree_list (name
, str
),
7286 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7287 c_parser_consume_token (parser
);
7294 /* Parse asm clobbers, a GNU extension.
7298 asm-clobbers , asm-string-literal
7302 c_parser_asm_clobbers (c_parser
*parser
)
7304 tree list
= NULL_TREE
;
7307 tree str
= c_parser_asm_string_literal (parser
);
7309 list
= tree_cons (NULL_TREE
, str
, list
);
7312 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7313 c_parser_consume_token (parser
);
7320 /* Parse asm goto labels, a GNU extension.
7324 asm-goto-operands , identifier
7328 c_parser_asm_goto_operands (c_parser
*parser
)
7330 tree list
= NULL_TREE
;
7335 if (c_parser_next_token_is (parser
, CPP_NAME
))
7337 c_token
*tok
= c_parser_peek_token (parser
);
7339 label
= lookup_label_for_goto (tok
->location
, name
);
7340 c_parser_consume_token (parser
);
7341 TREE_USED (label
) = 1;
7345 c_parser_error (parser
, "expected identifier");
7349 name
= build_string (IDENTIFIER_LENGTH (name
),
7350 IDENTIFIER_POINTER (name
));
7351 list
= tree_cons (name
, label
, list
);
7352 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7353 c_parser_consume_token (parser
);
7355 return nreverse (list
);
7359 /* Parse a possibly concatenated sequence of string literals.
7360 TRANSLATE says whether to translate them to the execution character
7361 set; WIDE_OK says whether any kind of prefixed string literal is
7362 permitted in this context. This code is based on that in
7366 c_parser_string_literal (c_parser
*parser
, bool translate
, bool wide_ok
)
7370 struct obstack str_ob
;
7371 struct obstack loc_ob
;
7372 cpp_string str
, istr
, *strs
;
7374 location_t loc
, last_tok_loc
;
7375 enum cpp_ttype type
;
7376 tree value
, string_tree
;
7378 tok
= c_parser_peek_token (parser
);
7379 loc
= tok
->location
;
7380 last_tok_loc
= linemap_resolve_location (line_table
, loc
,
7381 LRK_MACRO_DEFINITION_LOCATION
,
7390 case CPP_UTF8STRING
:
7391 string_tree
= tok
->value
;
7395 c_parser_error (parser
, "expected string literal");
7397 ret
.value
= NULL_TREE
;
7398 ret
.original_code
= ERROR_MARK
;
7399 ret
.original_type
= NULL_TREE
;
7403 /* Try to avoid the overhead of creating and destroying an obstack
7404 for the common case of just one string. */
7405 switch (c_parser_peek_2nd_token (parser
)->type
)
7408 c_parser_consume_token (parser
);
7409 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7410 str
.len
= TREE_STRING_LENGTH (string_tree
);
7419 case CPP_UTF8STRING
:
7420 gcc_obstack_init (&str_ob
);
7421 gcc_obstack_init (&loc_ob
);
7425 c_parser_consume_token (parser
);
7427 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7428 str
.len
= TREE_STRING_LENGTH (string_tree
);
7429 if (type
!= tok
->type
)
7431 if (type
== CPP_STRING
)
7433 else if (tok
->type
!= CPP_STRING
)
7434 error ("unsupported non-standard concatenation "
7435 "of string literals");
7437 obstack_grow (&str_ob
, &str
, sizeof (cpp_string
));
7438 obstack_grow (&loc_ob
, &last_tok_loc
, sizeof (location_t
));
7439 tok
= c_parser_peek_token (parser
);
7440 string_tree
= tok
->value
;
7442 = linemap_resolve_location (line_table
, tok
->location
,
7443 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
7445 while (tok
->type
== CPP_STRING
7446 || tok
->type
== CPP_WSTRING
7447 || tok
->type
== CPP_STRING16
7448 || tok
->type
== CPP_STRING32
7449 || tok
->type
== CPP_UTF8STRING
);
7450 strs
= (cpp_string
*) obstack_finish (&str_ob
);
7453 if (count
> 1 && !in_system_header_at (input_location
))
7454 warning (OPT_Wtraditional
,
7455 "traditional C rejects string constant concatenation");
7457 if ((type
== CPP_STRING
|| wide_ok
)
7459 ? cpp_interpret_string
: cpp_interpret_string_notranslate
)
7460 (parse_in
, strs
, count
, &istr
, type
)))
7462 value
= build_string (istr
.len
, (const char *) istr
.text
);
7463 free (CONST_CAST (unsigned char *, istr
.text
));
7466 location_t
*locs
= (location_t
*) obstack_finish (&loc_ob
);
7467 gcc_assert (g_string_concat_db
);
7468 g_string_concat_db
->record_string_concatenation (count
, locs
);
7473 if (type
!= CPP_STRING
&& !wide_ok
)
7475 error_at (loc
, "a wide string is invalid in this context");
7478 /* Callers cannot generally handle error_mark_node in this
7479 context, so return the empty string instead. An error has
7480 been issued, either above or from cpp_interpret_string. */
7485 case CPP_UTF8STRING
:
7486 value
= build_string (1, "");
7489 value
= build_string (TYPE_PRECISION (char16_type_node
)
7490 / TYPE_PRECISION (char_type_node
),
7491 "\0"); /* char16_t is 16 bits */
7494 value
= build_string (TYPE_PRECISION (char32_type_node
)
7495 / TYPE_PRECISION (char_type_node
),
7496 "\0\0\0"); /* char32_t is 32 bits */
7499 value
= build_string (TYPE_PRECISION (wchar_type_node
)
7500 / TYPE_PRECISION (char_type_node
),
7501 "\0\0\0"); /* widest supported wchar_t
7511 case CPP_UTF8STRING
:
7512 TREE_TYPE (value
) = char_array_type_node
;
7515 TREE_TYPE (value
) = char16_array_type_node
;
7518 TREE_TYPE (value
) = char32_array_type_node
;
7521 TREE_TYPE (value
) = wchar_array_type_node
;
7523 value
= fix_string_type (value
);
7527 obstack_free (&str_ob
, 0);
7528 obstack_free (&loc_ob
, 0);
7532 ret
.original_code
= STRING_CST
;
7533 ret
.original_type
= NULL_TREE
;
7534 set_c_expr_source_range (&ret
, get_range_from_loc (line_table
, loc
));
7538 /* Parse an expression other than a compound expression; that is, an
7539 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7540 AFTER is not NULL then it is an Objective-C message expression which
7541 is the primary-expression starting the expression as an initializer.
7543 assignment-expression:
7544 conditional-expression
7545 unary-expression assignment-operator assignment-expression
7547 assignment-operator: one of
7548 = *= /= %= += -= <<= >>= &= ^= |=
7550 In GNU C we accept any conditional expression on the LHS and
7551 diagnose the invalid lvalue rather than producing a syntax
7554 static struct c_expr
7555 c_parser_expr_no_commas (c_parser
*parser
, struct c_expr
*after
,
7556 tree omp_atomic_lhs
)
7558 struct c_expr lhs
, rhs
, ret
;
7559 enum tree_code code
;
7560 location_t op_location
, exp_location
;
7561 gcc_assert (!after
|| c_dialect_objc ());
7562 lhs
= c_parser_conditional_expression (parser
, after
, omp_atomic_lhs
);
7563 op_location
= c_parser_peek_token (parser
)->location
;
7564 switch (c_parser_peek_token (parser
)->type
)
7573 code
= TRUNC_DIV_EXPR
;
7576 code
= TRUNC_MOD_EXPR
;
7591 code
= BIT_AND_EXPR
;
7594 code
= BIT_XOR_EXPR
;
7597 code
= BIT_IOR_EXPR
;
7602 c_parser_consume_token (parser
);
7603 exp_location
= c_parser_peek_token (parser
)->location
;
7604 rhs
= c_parser_expr_no_commas (parser
, NULL
);
7605 rhs
= convert_lvalue_to_rvalue (exp_location
, rhs
, true, true);
7607 ret
.value
= build_modify_expr (op_location
, lhs
.value
, lhs
.original_type
,
7608 code
, exp_location
, rhs
.value
,
7610 set_c_expr_source_range (&ret
, lhs
.get_start (), rhs
.get_finish ());
7611 if (code
== NOP_EXPR
)
7612 ret
.original_code
= MODIFY_EXPR
;
7615 TREE_NO_WARNING (ret
.value
) = 1;
7616 ret
.original_code
= ERROR_MARK
;
7618 ret
.original_type
= NULL
;
7622 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7623 AFTER is not NULL then it is an Objective-C message expression which is
7624 the primary-expression starting the expression as an initializer.
7626 conditional-expression:
7627 logical-OR-expression
7628 logical-OR-expression ? expression : conditional-expression
7632 conditional-expression:
7633 logical-OR-expression ? : conditional-expression
7636 static struct c_expr
7637 c_parser_conditional_expression (c_parser
*parser
, struct c_expr
*after
,
7638 tree omp_atomic_lhs
)
7640 struct c_expr cond
, exp1
, exp2
, ret
;
7641 location_t start
, cond_loc
, colon_loc
;
7643 gcc_assert (!after
|| c_dialect_objc ());
7645 cond
= c_parser_binary_expression (parser
, after
, omp_atomic_lhs
);
7647 if (c_parser_next_token_is_not (parser
, CPP_QUERY
))
7649 if (cond
.value
!= error_mark_node
)
7650 start
= cond
.get_start ();
7652 start
= UNKNOWN_LOCATION
;
7653 cond_loc
= c_parser_peek_token (parser
)->location
;
7654 cond
= convert_lvalue_to_rvalue (cond_loc
, cond
, true, true);
7655 c_parser_consume_token (parser
);
7656 if (c_parser_next_token_is (parser
, CPP_COLON
))
7658 tree eptype
= NULL_TREE
;
7660 location_t middle_loc
= c_parser_peek_token (parser
)->location
;
7661 pedwarn (middle_loc
, OPT_Wpedantic
,
7662 "ISO C forbids omitting the middle term of a %<?:%> expression");
7663 if (TREE_CODE (cond
.value
) == EXCESS_PRECISION_EXPR
)
7665 eptype
= TREE_TYPE (cond
.value
);
7666 cond
.value
= TREE_OPERAND (cond
.value
, 0);
7668 tree e
= cond
.value
;
7669 while (TREE_CODE (e
) == COMPOUND_EXPR
)
7670 e
= TREE_OPERAND (e
, 1);
7671 warn_for_omitted_condop (middle_loc
, e
);
7672 /* Make sure first operand is calculated only once. */
7673 exp1
.value
= save_expr (default_conversion (cond
.value
));
7675 exp1
.value
= build1 (EXCESS_PRECISION_EXPR
, eptype
, exp1
.value
);
7676 exp1
.original_type
= NULL
;
7677 exp1
.src_range
= cond
.src_range
;
7678 cond
.value
= c_objc_common_truthvalue_conversion (cond_loc
, exp1
.value
);
7679 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_true_node
;
7684 = c_objc_common_truthvalue_conversion
7685 (cond_loc
, default_conversion (cond
.value
));
7686 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_false_node
;
7687 exp1
= c_parser_expression_conv (parser
);
7688 mark_exp_read (exp1
.value
);
7689 c_inhibit_evaluation_warnings
+=
7690 ((cond
.value
== truthvalue_true_node
)
7691 - (cond
.value
== truthvalue_false_node
));
7694 colon_loc
= c_parser_peek_token (parser
)->location
;
7695 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7697 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7699 ret
.original_code
= ERROR_MARK
;
7700 ret
.original_type
= NULL
;
7704 location_t exp2_loc
= c_parser_peek_token (parser
)->location
;
7705 exp2
= c_parser_conditional_expression (parser
, NULL
, NULL_TREE
);
7706 exp2
= convert_lvalue_to_rvalue (exp2_loc
, exp2
, true, true);
7708 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7709 location_t loc1
= make_location (exp1
.get_start (), exp1
.src_range
);
7710 location_t loc2
= make_location (exp2
.get_start (), exp2
.src_range
);
7711 ret
.value
= build_conditional_expr (colon_loc
, cond
.value
,
7712 cond
.original_code
== C_MAYBE_CONST_EXPR
,
7713 exp1
.value
, exp1
.original_type
, loc1
,
7714 exp2
.value
, exp2
.original_type
, loc2
);
7715 ret
.original_code
= ERROR_MARK
;
7716 if (exp1
.value
== error_mark_node
|| exp2
.value
== error_mark_node
)
7717 ret
.original_type
= NULL
;
7722 /* If both sides are enum type, the default conversion will have
7723 made the type of the result be an integer type. We want to
7724 remember the enum types we started with. */
7725 t1
= exp1
.original_type
? exp1
.original_type
: TREE_TYPE (exp1
.value
);
7726 t2
= exp2
.original_type
? exp2
.original_type
: TREE_TYPE (exp2
.value
);
7727 ret
.original_type
= ((t1
!= error_mark_node
7728 && t2
!= error_mark_node
7729 && (TYPE_MAIN_VARIANT (t1
)
7730 == TYPE_MAIN_VARIANT (t2
)))
7734 set_c_expr_source_range (&ret
, start
, exp2
.get_finish ());
7738 /* Parse a binary expression; that is, a logical-OR-expression (C90
7739 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7740 NULL then it is an Objective-C message expression which is the
7741 primary-expression starting the expression as an initializer.
7743 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7744 when it should be the unfolded lhs. In a valid OpenMP source,
7745 one of the operands of the toplevel binary expression must be equal
7746 to it. In that case, just return a build2 created binary operation
7747 rather than result of parser_build_binary_op.
7749 multiplicative-expression:
7751 multiplicative-expression * cast-expression
7752 multiplicative-expression / cast-expression
7753 multiplicative-expression % cast-expression
7755 additive-expression:
7756 multiplicative-expression
7757 additive-expression + multiplicative-expression
7758 additive-expression - multiplicative-expression
7762 shift-expression << additive-expression
7763 shift-expression >> additive-expression
7765 relational-expression:
7767 relational-expression < shift-expression
7768 relational-expression > shift-expression
7769 relational-expression <= shift-expression
7770 relational-expression >= shift-expression
7772 equality-expression:
7773 relational-expression
7774 equality-expression == relational-expression
7775 equality-expression != relational-expression
7779 AND-expression & equality-expression
7781 exclusive-OR-expression:
7783 exclusive-OR-expression ^ AND-expression
7785 inclusive-OR-expression:
7786 exclusive-OR-expression
7787 inclusive-OR-expression | exclusive-OR-expression
7789 logical-AND-expression:
7790 inclusive-OR-expression
7791 logical-AND-expression && inclusive-OR-expression
7793 logical-OR-expression:
7794 logical-AND-expression
7795 logical-OR-expression || logical-AND-expression
7798 static struct c_expr
7799 c_parser_binary_expression (c_parser
*parser
, struct c_expr
*after
,
7800 tree omp_atomic_lhs
)
7802 /* A binary expression is parsed using operator-precedence parsing,
7803 with the operands being cast expressions. All the binary
7804 operators are left-associative. Thus a binary expression is of
7807 E0 op1 E1 op2 E2 ...
7809 which we represent on a stack. On the stack, the precedence
7810 levels are strictly increasing. When a new operator is
7811 encountered of higher precedence than that at the top of the
7812 stack, it is pushed; its LHS is the top expression, and its RHS
7813 is everything parsed until it is popped. When a new operator is
7814 encountered with precedence less than or equal to that at the top
7815 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7816 by the result of the operation until the operator at the top of
7817 the stack has lower precedence than the new operator or there is
7818 only one element on the stack; then the top expression is the LHS
7819 of the new operator. In the case of logical AND and OR
7820 expressions, we also need to adjust c_inhibit_evaluation_warnings
7821 as appropriate when the operators are pushed and popped. */
7824 /* The expression at this stack level. */
7826 /* The precedence of the operator on its left, PREC_NONE at the
7827 bottom of the stack. */
7828 enum c_parser_prec prec
;
7829 /* The operation on its left. */
7831 /* The source location of this operation. */
7833 /* The sizeof argument if expr.original_code == SIZEOF_EXPR. */
7837 /* Location of the binary operator. */
7838 location_t binary_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
7841 switch (stack[sp].op) \
7843 case TRUTH_ANDIF_EXPR: \
7844 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7845 == truthvalue_false_node); \
7847 case TRUTH_ORIF_EXPR: \
7848 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7849 == truthvalue_true_node); \
7851 case TRUNC_DIV_EXPR: \
7852 if (stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7853 && stack[sp].expr.original_code == SIZEOF_EXPR) \
7855 tree type0 = stack[sp - 1].sizeof_arg; \
7856 tree type1 = stack[sp].sizeof_arg; \
7857 tree first_arg = type0; \
7858 if (!TYPE_P (type0)) \
7859 type0 = TREE_TYPE (type0); \
7860 if (!TYPE_P (type1)) \
7861 type1 = TREE_TYPE (type1); \
7862 if (POINTER_TYPE_P (type0) \
7863 && comptypes (TREE_TYPE (type0), type1) \
7864 && !(TREE_CODE (first_arg) == PARM_DECL \
7865 && C_ARRAY_PARAMETER (first_arg) \
7866 && warn_sizeof_array_argument)) \
7868 auto_diagnostic_group d; \
7869 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7870 "division %<sizeof (%T) / sizeof (%T)%> " \
7871 "does not compute the number of array " \
7874 if (DECL_P (first_arg)) \
7875 inform (DECL_SOURCE_LOCATION (first_arg), \
7876 "first %<sizeof%> operand was declared here"); \
7883 stack[sp - 1].expr \
7884 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7885 stack[sp - 1].expr, true, true); \
7887 = convert_lvalue_to_rvalue (stack[sp].loc, \
7888 stack[sp].expr, true, true); \
7889 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
7890 && c_parser_peek_token (parser)->type == CPP_SEMICOLON \
7891 && ((1 << stack[sp].prec) \
7892 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \
7893 | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \
7894 && stack[sp].op != TRUNC_MOD_EXPR \
7895 && stack[0].expr.value != error_mark_node \
7896 && stack[1].expr.value != error_mark_node \
7897 && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7898 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \
7899 stack[0].expr.value \
7900 = build2 (stack[1].op, TREE_TYPE (stack[0].expr.value), \
7901 stack[0].expr.value, stack[1].expr.value); \
7903 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7905 stack[sp - 1].expr, \
7909 gcc_assert (!after
|| c_dialect_objc ());
7910 stack
[0].loc
= c_parser_peek_token (parser
)->location
;
7911 stack
[0].expr
= c_parser_cast_expression (parser
, after
);
7912 stack
[0].prec
= PREC_NONE
;
7913 stack
[0].sizeof_arg
= c_last_sizeof_arg
;
7917 enum c_parser_prec oprec
;
7918 enum tree_code ocode
;
7919 source_range src_range
;
7922 switch (c_parser_peek_token (parser
)->type
)
7930 ocode
= TRUNC_DIV_EXPR
;
7934 ocode
= TRUNC_MOD_EXPR
;
7946 ocode
= LSHIFT_EXPR
;
7950 ocode
= RSHIFT_EXPR
;
7964 case CPP_GREATER_EQ
:
7977 oprec
= PREC_BITAND
;
7978 ocode
= BIT_AND_EXPR
;
7981 oprec
= PREC_BITXOR
;
7982 ocode
= BIT_XOR_EXPR
;
7986 ocode
= BIT_IOR_EXPR
;
7989 oprec
= PREC_LOGAND
;
7990 ocode
= TRUTH_ANDIF_EXPR
;
7994 ocode
= TRUTH_ORIF_EXPR
;
7997 /* Not a binary operator, so end of the binary
8001 binary_loc
= c_parser_peek_token (parser
)->location
;
8002 while (oprec
<= stack
[sp
].prec
)
8004 c_parser_consume_token (parser
);
8007 case TRUTH_ANDIF_EXPR
:
8008 src_range
= stack
[sp
].expr
.src_range
;
8010 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
8011 stack
[sp
].expr
, true, true);
8012 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
8013 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
8014 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
8015 == truthvalue_false_node
);
8016 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
8018 case TRUTH_ORIF_EXPR
:
8019 src_range
= stack
[sp
].expr
.src_range
;
8021 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
8022 stack
[sp
].expr
, true, true);
8023 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
8024 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
8025 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
8026 == truthvalue_true_node
);
8027 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
8033 stack
[sp
].loc
= binary_loc
;
8034 stack
[sp
].expr
= c_parser_cast_expression (parser
, NULL
);
8035 stack
[sp
].prec
= oprec
;
8036 stack
[sp
].op
= ocode
;
8037 stack
[sp
].sizeof_arg
= c_last_sizeof_arg
;
8042 return stack
[0].expr
;
8046 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8047 is not NULL then it is an Objective-C message expression which is the
8048 primary-expression starting the expression as an initializer.
8052 ( type-name ) unary-expression
8055 static struct c_expr
8056 c_parser_cast_expression (c_parser
*parser
, struct c_expr
*after
)
8058 location_t cast_loc
= c_parser_peek_token (parser
)->location
;
8059 gcc_assert (!after
|| c_dialect_objc ());
8061 return c_parser_postfix_expression_after_primary (parser
,
8063 /* If the expression begins with a parenthesized type name, it may
8064 be either a cast or a compound literal; we need to see whether
8065 the next character is '{' to tell the difference. If not, it is
8066 an unary expression. Full detection of unknown typenames here
8067 would require a 3-token lookahead. */
8068 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8069 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8071 struct c_type_name
*type_name
;
8074 matching_parens parens
;
8075 parens
.consume_open (parser
);
8076 type_name
= c_parser_type_name (parser
, true);
8077 parens
.skip_until_found_close (parser
);
8078 if (type_name
== NULL
)
8081 ret
.original_code
= ERROR_MARK
;
8082 ret
.original_type
= NULL
;
8086 /* Save casted types in the function's used types hash table. */
8087 used_types_insert (type_name
->specs
->type
);
8089 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8090 return c_parser_postfix_expression_after_paren_type (parser
, type_name
,
8092 if (type_name
->specs
->alignas_p
)
8093 error_at (type_name
->specs
->locations
[cdw_alignas
],
8094 "alignment specified for type name in cast");
8096 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
8097 expr
= c_parser_cast_expression (parser
, NULL
);
8098 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
8100 ret
.value
= c_cast_expr (cast_loc
, type_name
, expr
.value
);
8101 if (ret
.value
&& expr
.value
)
8102 set_c_expr_source_range (&ret
, cast_loc
, expr
.get_finish ());
8103 ret
.original_code
= ERROR_MARK
;
8104 ret
.original_type
= NULL
;
8108 return c_parser_unary_expression (parser
);
8111 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8117 unary-operator cast-expression
8118 sizeof unary-expression
8119 sizeof ( type-name )
8121 unary-operator: one of
8127 __alignof__ unary-expression
8128 __alignof__ ( type-name )
8131 (C11 permits _Alignof with type names only.)
8133 unary-operator: one of
8134 __extension__ __real__ __imag__
8136 Transactional Memory:
8139 transaction-expression
8141 In addition, the GNU syntax treats ++ and -- as unary operators, so
8142 they may be applied to cast expressions with errors for non-lvalues
8145 static struct c_expr
8146 c_parser_unary_expression (c_parser
*parser
)
8149 struct c_expr ret
, op
;
8150 location_t op_loc
= c_parser_peek_token (parser
)->location
;
8153 ret
.original_code
= ERROR_MARK
;
8154 ret
.original_type
= NULL
;
8155 switch (c_parser_peek_token (parser
)->type
)
8158 c_parser_consume_token (parser
);
8159 exp_loc
= c_parser_peek_token (parser
)->location
;
8160 op
= c_parser_cast_expression (parser
, NULL
);
8162 op
= default_function_array_read_conversion (exp_loc
, op
);
8163 return parser_build_unary_op (op_loc
, PREINCREMENT_EXPR
, op
);
8164 case CPP_MINUS_MINUS
:
8165 c_parser_consume_token (parser
);
8166 exp_loc
= c_parser_peek_token (parser
)->location
;
8167 op
= c_parser_cast_expression (parser
, NULL
);
8169 op
= default_function_array_read_conversion (exp_loc
, op
);
8170 return parser_build_unary_op (op_loc
, PREDECREMENT_EXPR
, op
);
8172 c_parser_consume_token (parser
);
8173 op
= c_parser_cast_expression (parser
, NULL
);
8174 mark_exp_read (op
.value
);
8175 return parser_build_unary_op (op_loc
, ADDR_EXPR
, op
);
8178 c_parser_consume_token (parser
);
8179 exp_loc
= c_parser_peek_token (parser
)->location
;
8180 op
= c_parser_cast_expression (parser
, NULL
);
8181 finish
= op
.get_finish ();
8182 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8183 location_t combined_loc
= make_location (op_loc
, op_loc
, finish
);
8184 ret
.value
= build_indirect_ref (combined_loc
, op
.value
, RO_UNARY_STAR
);
8185 ret
.src_range
.m_start
= op_loc
;
8186 ret
.src_range
.m_finish
= finish
;
8190 if (!c_dialect_objc () && !in_system_header_at (input_location
))
8193 "traditional C rejects the unary plus operator");
8194 c_parser_consume_token (parser
);
8195 exp_loc
= c_parser_peek_token (parser
)->location
;
8196 op
= c_parser_cast_expression (parser
, NULL
);
8197 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8198 return parser_build_unary_op (op_loc
, CONVERT_EXPR
, op
);
8200 c_parser_consume_token (parser
);
8201 exp_loc
= c_parser_peek_token (parser
)->location
;
8202 op
= c_parser_cast_expression (parser
, NULL
);
8203 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8204 return parser_build_unary_op (op_loc
, NEGATE_EXPR
, op
);
8206 c_parser_consume_token (parser
);
8207 exp_loc
= c_parser_peek_token (parser
)->location
;
8208 op
= c_parser_cast_expression (parser
, NULL
);
8209 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8210 return parser_build_unary_op (op_loc
, BIT_NOT_EXPR
, op
);
8212 c_parser_consume_token (parser
);
8213 exp_loc
= c_parser_peek_token (parser
)->location
;
8214 op
= c_parser_cast_expression (parser
, NULL
);
8215 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8216 return parser_build_unary_op (op_loc
, TRUTH_NOT_EXPR
, op
);
8218 /* Refer to the address of a label as a pointer. */
8219 c_parser_consume_token (parser
);
8220 if (c_parser_next_token_is (parser
, CPP_NAME
))
8222 ret
.value
= finish_label_address_expr
8223 (c_parser_peek_token (parser
)->value
, op_loc
);
8224 set_c_expr_source_range (&ret
, op_loc
,
8225 c_parser_peek_token (parser
)->get_finish ());
8226 c_parser_consume_token (parser
);
8230 c_parser_error (parser
, "expected identifier");
8235 switch (c_parser_peek_token (parser
)->keyword
)
8238 return c_parser_sizeof_expression (parser
);
8240 return c_parser_alignof_expression (parser
);
8241 case RID_BUILTIN_HAS_ATTRIBUTE
:
8242 return c_parser_has_attribute_expression (parser
);
8244 c_parser_consume_token (parser
);
8245 ext
= disable_extension_diagnostics ();
8246 ret
= c_parser_cast_expression (parser
, NULL
);
8247 restore_extension_diagnostics (ext
);
8250 c_parser_consume_token (parser
);
8251 exp_loc
= c_parser_peek_token (parser
)->location
;
8252 op
= c_parser_cast_expression (parser
, NULL
);
8253 op
= default_function_array_conversion (exp_loc
, op
);
8254 return parser_build_unary_op (op_loc
, REALPART_EXPR
, op
);
8256 c_parser_consume_token (parser
);
8257 exp_loc
= c_parser_peek_token (parser
)->location
;
8258 op
= c_parser_cast_expression (parser
, NULL
);
8259 op
= default_function_array_conversion (exp_loc
, op
);
8260 return parser_build_unary_op (op_loc
, IMAGPART_EXPR
, op
);
8261 case RID_TRANSACTION_ATOMIC
:
8262 case RID_TRANSACTION_RELAXED
:
8263 return c_parser_transaction_expression (parser
,
8264 c_parser_peek_token (parser
)->keyword
);
8266 return c_parser_postfix_expression (parser
);
8269 return c_parser_postfix_expression (parser
);
8273 /* Parse a sizeof expression. */
8275 static struct c_expr
8276 c_parser_sizeof_expression (c_parser
*parser
)
8279 struct c_expr result
;
8280 location_t expr_loc
;
8281 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SIZEOF
));
8284 location_t finish
= UNKNOWN_LOCATION
;
8286 start
= c_parser_peek_token (parser
)->location
;
8288 c_parser_consume_token (parser
);
8289 c_inhibit_evaluation_warnings
++;
8291 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8292 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8294 /* Either sizeof ( type-name ) or sizeof unary-expression
8295 starting with a compound literal. */
8296 struct c_type_name
*type_name
;
8297 matching_parens parens
;
8298 parens
.consume_open (parser
);
8299 expr_loc
= c_parser_peek_token (parser
)->location
;
8300 type_name
= c_parser_type_name (parser
, true);
8301 parens
.skip_until_found_close (parser
);
8302 finish
= parser
->tokens_buf
[0].location
;
8303 if (type_name
== NULL
)
8306 c_inhibit_evaluation_warnings
--;
8309 ret
.original_code
= ERROR_MARK
;
8310 ret
.original_type
= NULL
;
8313 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8315 expr
= c_parser_postfix_expression_after_paren_type (parser
,
8318 finish
= expr
.get_finish ();
8321 /* sizeof ( type-name ). */
8322 if (type_name
->specs
->alignas_p
)
8323 error_at (type_name
->specs
->locations
[cdw_alignas
],
8324 "alignment specified for type name in %<sizeof%>");
8325 c_inhibit_evaluation_warnings
--;
8327 result
= c_expr_sizeof_type (expr_loc
, type_name
);
8331 expr_loc
= c_parser_peek_token (parser
)->location
;
8332 expr
= c_parser_unary_expression (parser
);
8333 finish
= expr
.get_finish ();
8335 c_inhibit_evaluation_warnings
--;
8337 mark_exp_read (expr
.value
);
8338 if (TREE_CODE (expr
.value
) == COMPONENT_REF
8339 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
8340 error_at (expr_loc
, "%<sizeof%> applied to a bit-field");
8341 result
= c_expr_sizeof_expr (expr_loc
, expr
);
8343 if (finish
== UNKNOWN_LOCATION
)
8345 set_c_expr_source_range (&result
, start
, finish
);
8349 /* Parse an alignof expression. */
8351 static struct c_expr
8352 c_parser_alignof_expression (c_parser
*parser
)
8355 location_t start_loc
= c_parser_peek_token (parser
)->location
;
8357 tree alignof_spelling
= c_parser_peek_token (parser
)->value
;
8358 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNOF
));
8359 bool is_c11_alignof
= strcmp (IDENTIFIER_POINTER (alignof_spelling
),
8361 /* A diagnostic is not required for the use of this identifier in
8362 the implementation namespace; only diagnose it for the C11
8363 spelling because of existing code using the other spellings. */
8367 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C99 does not support %qE",
8370 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C90 does not support %qE",
8373 c_parser_consume_token (parser
);
8374 c_inhibit_evaluation_warnings
++;
8376 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8377 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8379 /* Either __alignof__ ( type-name ) or __alignof__
8380 unary-expression starting with a compound literal. */
8382 struct c_type_name
*type_name
;
8384 matching_parens parens
;
8385 parens
.consume_open (parser
);
8386 loc
= c_parser_peek_token (parser
)->location
;
8387 type_name
= c_parser_type_name (parser
, true);
8388 end_loc
= c_parser_peek_token (parser
)->location
;
8389 parens
.skip_until_found_close (parser
);
8390 if (type_name
== NULL
)
8393 c_inhibit_evaluation_warnings
--;
8396 ret
.original_code
= ERROR_MARK
;
8397 ret
.original_type
= NULL
;
8400 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8402 expr
= c_parser_postfix_expression_after_paren_type (parser
,
8407 /* alignof ( type-name ). */
8408 if (type_name
->specs
->alignas_p
)
8409 error_at (type_name
->specs
->locations
[cdw_alignas
],
8410 "alignment specified for type name in %qE",
8412 c_inhibit_evaluation_warnings
--;
8414 ret
.value
= c_sizeof_or_alignof_type (loc
, groktypename (type_name
,
8416 false, is_c11_alignof
, 1);
8417 ret
.original_code
= ERROR_MARK
;
8418 ret
.original_type
= NULL
;
8419 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
8425 expr
= c_parser_unary_expression (parser
);
8426 end_loc
= expr
.src_range
.m_finish
;
8428 mark_exp_read (expr
.value
);
8429 c_inhibit_evaluation_warnings
--;
8433 OPT_Wpedantic
, "ISO C does not allow %<%E (expression)%>",
8435 ret
.value
= c_alignof_expr (start_loc
, expr
.value
);
8436 ret
.original_code
= ERROR_MARK
;
8437 ret
.original_type
= NULL
;
8438 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
8443 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8446 static struct c_expr
8447 c_parser_has_attribute_expression (c_parser
*parser
)
8449 gcc_assert (c_parser_next_token_is_keyword (parser
,
8450 RID_BUILTIN_HAS_ATTRIBUTE
));
8451 c_parser_consume_token (parser
);
8453 c_inhibit_evaluation_warnings
++;
8455 matching_parens parens
;
8456 if (!parens
.require_open (parser
))
8458 c_inhibit_evaluation_warnings
--;
8461 struct c_expr result
;
8462 result
.set_error ();
8463 result
.original_code
= ERROR_MARK
;
8464 result
.original_type
= NULL
;
8468 /* Treat the type argument the same way as in typeof for the purposes
8469 of warnings. FIXME: Generalize this so the warning refers to
8470 __builtin_has_attribute rather than typeof. */
8473 /* The first operand: one of DECL, EXPR, or TYPE. */
8474 tree oper
= NULL_TREE
;
8475 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
8477 struct c_type_name
*tname
= c_parser_type_name (parser
);
8481 oper
= groktypename (tname
, NULL
, NULL
);
8482 pop_maybe_used (variably_modified_type_p (oper
, NULL_TREE
));
8487 struct c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
8488 c_inhibit_evaluation_warnings
--;
8490 if (cexpr
.value
!= error_mark_node
)
8492 mark_exp_read (cexpr
.value
);
8494 tree etype
= TREE_TYPE (oper
);
8495 bool was_vm
= variably_modified_type_p (etype
, NULL_TREE
);
8496 /* This is returned with the type so that when the type is
8497 evaluated, this can be evaluated. */
8499 oper
= c_fully_fold (oper
, false, NULL
);
8500 pop_maybe_used (was_vm
);
8504 struct c_expr result
;
8505 result
.original_code
= ERROR_MARK
;
8506 result
.original_type
= NULL
;
8508 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8510 /* Consume the closing parenthesis if that's the next token
8511 in the likely case the built-in was invoked with fewer
8512 than two arguments. */
8513 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8514 c_parser_consume_token (parser
);
8515 c_inhibit_evaluation_warnings
--;
8516 result
.set_error ();
8520 bool save_translate_strings_p
= parser
->translate_strings_p
;
8522 location_t atloc
= c_parser_peek_token (parser
)->location
;
8523 /* Parse a single attribute. Require no leading comma and do not
8524 allow empty attributes. */
8525 tree attr
= c_parser_gnu_attribute (parser
, NULL_TREE
, false, false);
8527 parser
->translate_strings_p
= save_translate_strings_p
;
8529 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8530 c_parser_consume_token (parser
);
8533 c_parser_error (parser
, "expected identifier");
8534 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8536 result
.set_error ();
8542 error_at (atloc
, "expected identifier");
8543 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8545 result
.set_error ();
8549 result
.original_code
= INTEGER_CST
;
8550 result
.original_type
= boolean_type_node
;
8552 if (has_attribute (atloc
, oper
, attr
, default_conversion
))
8553 result
.value
= boolean_true_node
;
8555 result
.value
= boolean_false_node
;
8560 /* Helper function to read arguments of builtins which are interfaces
8561 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8562 others. The name of the builtin is passed using BNAME parameter.
8563 Function returns true if there were no errors while parsing and
8564 stores the arguments in CEXPR_LIST. If it returns true,
8565 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8568 c_parser_get_builtin_args (c_parser
*parser
, const char *bname
,
8569 vec
<c_expr_t
, va_gc
> **ret_cexpr_list
,
8571 location_t
*out_close_paren_loc
)
8573 location_t loc
= c_parser_peek_token (parser
)->location
;
8574 vec
<c_expr_t
, va_gc
> *cexpr_list
;
8576 bool saved_force_folding_builtin_constant_p
;
8578 *ret_cexpr_list
= NULL
;
8579 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
8581 error_at (loc
, "cannot take address of %qs", bname
);
8585 c_parser_consume_token (parser
);
8587 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8589 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
8590 c_parser_consume_token (parser
);
8594 saved_force_folding_builtin_constant_p
8595 = force_folding_builtin_constant_p
;
8596 force_folding_builtin_constant_p
|= choose_expr_p
;
8597 expr
= c_parser_expr_no_commas (parser
, NULL
);
8598 force_folding_builtin_constant_p
8599 = saved_force_folding_builtin_constant_p
;
8600 vec_alloc (cexpr_list
, 1);
8601 vec_safe_push (cexpr_list
, expr
);
8602 while (c_parser_next_token_is (parser
, CPP_COMMA
))
8604 c_parser_consume_token (parser
);
8605 expr
= c_parser_expr_no_commas (parser
, NULL
);
8606 vec_safe_push (cexpr_list
, expr
);
8609 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
8610 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
8613 *ret_cexpr_list
= cexpr_list
;
8617 /* This represents a single generic-association. */
8619 struct c_generic_association
8621 /* The location of the starting token of the type. */
8622 location_t type_location
;
8623 /* The association's type, or NULL_TREE for 'default'. */
8625 /* The association's expression. */
8626 struct c_expr expression
;
8629 /* Parse a generic-selection. (C11 6.5.1.1).
8632 _Generic ( assignment-expression , generic-assoc-list )
8636 generic-assoc-list , generic-association
8638 generic-association:
8639 type-name : assignment-expression
8640 default : assignment-expression
8643 static struct c_expr
8644 c_parser_generic_selection (c_parser
*parser
)
8646 struct c_expr selector
, error_expr
;
8648 struct c_generic_association matched_assoc
;
8649 bool match_found
= false;
8650 location_t generic_loc
, selector_loc
;
8652 error_expr
.original_code
= ERROR_MARK
;
8653 error_expr
.original_type
= NULL
;
8654 error_expr
.set_error ();
8655 matched_assoc
.type_location
= UNKNOWN_LOCATION
;
8656 matched_assoc
.type
= NULL_TREE
;
8657 matched_assoc
.expression
= error_expr
;
8659 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_GENERIC
));
8660 generic_loc
= c_parser_peek_token (parser
)->location
;
8661 c_parser_consume_token (parser
);
8663 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
8664 "ISO C99 does not support %<_Generic%>");
8666 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
8667 "ISO C90 does not support %<_Generic%>");
8669 matching_parens parens
;
8670 if (!parens
.require_open (parser
))
8673 c_inhibit_evaluation_warnings
++;
8674 selector_loc
= c_parser_peek_token (parser
)->location
;
8675 selector
= c_parser_expr_no_commas (parser
, NULL
);
8676 selector
= default_function_array_conversion (selector_loc
, selector
);
8677 c_inhibit_evaluation_warnings
--;
8679 if (selector
.value
== error_mark_node
)
8681 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8684 selector_type
= TREE_TYPE (selector
.value
);
8685 /* In ISO C terms, rvalues (including the controlling expression of
8686 _Generic) do not have qualified types. */
8687 if (TREE_CODE (selector_type
) != ARRAY_TYPE
)
8688 selector_type
= TYPE_MAIN_VARIANT (selector_type
);
8689 /* In ISO C terms, _Noreturn is not part of the type of expressions
8690 such as &abort, but in GCC it is represented internally as a type
8692 if (FUNCTION_POINTER_TYPE_P (selector_type
)
8693 && TYPE_QUALS (TREE_TYPE (selector_type
)) != TYPE_UNQUALIFIED
)
8695 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type
)));
8697 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8699 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8703 auto_vec
<c_generic_association
> associations
;
8706 struct c_generic_association assoc
, *iter
;
8708 c_token
*token
= c_parser_peek_token (parser
);
8710 assoc
.type_location
= token
->location
;
8711 if (token
->type
== CPP_KEYWORD
&& token
->keyword
== RID_DEFAULT
)
8713 c_parser_consume_token (parser
);
8714 assoc
.type
= NULL_TREE
;
8718 struct c_type_name
*type_name
;
8720 type_name
= c_parser_type_name (parser
);
8721 if (type_name
== NULL
)
8723 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8726 assoc
.type
= groktypename (type_name
, NULL
, NULL
);
8727 if (assoc
.type
== error_mark_node
)
8729 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8733 if (TREE_CODE (assoc
.type
) == FUNCTION_TYPE
)
8734 error_at (assoc
.type_location
,
8735 "%<_Generic%> association has function type");
8736 else if (!COMPLETE_TYPE_P (assoc
.type
))
8737 error_at (assoc
.type_location
,
8738 "%<_Generic%> association has incomplete type");
8740 if (variably_modified_type_p (assoc
.type
, NULL_TREE
))
8741 error_at (assoc
.type_location
,
8742 "%<_Generic%> association has "
8743 "variable length type");
8746 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
8748 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8752 assoc
.expression
= c_parser_expr_no_commas (parser
, NULL
);
8753 if (assoc
.expression
.value
== error_mark_node
)
8755 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8759 for (ix
= 0; associations
.iterate (ix
, &iter
); ++ix
)
8761 if (assoc
.type
== NULL_TREE
)
8763 if (iter
->type
== NULL_TREE
)
8765 error_at (assoc
.type_location
,
8766 "duplicate %<default%> case in %<_Generic%>");
8767 inform (iter
->type_location
, "original %<default%> is here");
8770 else if (iter
->type
!= NULL_TREE
)
8772 if (comptypes (assoc
.type
, iter
->type
))
8774 error_at (assoc
.type_location
,
8775 "%<_Generic%> specifies two compatible types");
8776 inform (iter
->type_location
, "compatible type is here");
8781 if (assoc
.type
== NULL_TREE
)
8785 matched_assoc
= assoc
;
8789 else if (comptypes (assoc
.type
, selector_type
))
8791 if (!match_found
|| matched_assoc
.type
== NULL_TREE
)
8793 matched_assoc
= assoc
;
8798 error_at (assoc
.type_location
,
8799 "%<_Generic%> selector matches multiple associations");
8800 inform (matched_assoc
.type_location
,
8801 "other match is here");
8805 associations
.safe_push (assoc
);
8807 if (c_parser_peek_token (parser
)->type
!= CPP_COMMA
)
8809 c_parser_consume_token (parser
);
8812 if (!parens
.require_close (parser
))
8814 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8820 error_at (selector_loc
, "%<_Generic%> selector of type %qT is not "
8821 "compatible with any association",
8826 return matched_assoc
.expression
;
8829 /* Check the validity of a function pointer argument *EXPR (argument
8830 position POS) to __builtin_tgmath. Return the number of function
8831 arguments if possibly valid; return 0 having reported an error if
8835 check_tgmath_function (c_expr
*expr
, unsigned int pos
)
8837 tree type
= TREE_TYPE (expr
->value
);
8838 if (!FUNCTION_POINTER_TYPE_P (type
))
8840 error_at (expr
->get_location (),
8841 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8845 type
= TREE_TYPE (type
);
8846 if (!prototype_p (type
))
8848 error_at (expr
->get_location (),
8849 "argument %u of %<__builtin_tgmath%> is unprototyped", pos
);
8852 if (stdarg_p (type
))
8854 error_at (expr
->get_location (),
8855 "argument %u of %<__builtin_tgmath%> has variable arguments",
8859 unsigned int nargs
= 0;
8860 function_args_iterator iter
;
8862 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
8864 if (t
== void_type_node
)
8870 error_at (expr
->get_location (),
8871 "argument %u of %<__builtin_tgmath%> has no arguments", pos
);
8877 /* Ways in which a parameter or return value of a type-generic macro
8878 may vary between the different functions the macro may call. */
8879 enum tgmath_parm_kind
8881 tgmath_fixed
, tgmath_real
, tgmath_complex
8884 /* Helper function for c_parser_postfix_expression. Parse predefined
8887 static struct c_expr
8888 c_parser_predefined_identifier (c_parser
*parser
)
8890 location_t loc
= c_parser_peek_token (parser
)->location
;
8891 switch (c_parser_peek_token (parser
)->keyword
)
8893 case RID_FUNCTION_NAME
:
8894 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
8895 "identifier", "__FUNCTION__");
8897 case RID_PRETTY_FUNCTION_NAME
:
8898 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
8899 "identifier", "__PRETTY_FUNCTION__");
8901 case RID_C99_FUNCTION_NAME
:
8902 pedwarn_c90 (loc
, OPT_Wpedantic
, "ISO C90 does not support "
8903 "%<__func__%> predefined identifier");
8910 expr
.original_code
= ERROR_MARK
;
8911 expr
.original_type
= NULL
;
8912 expr
.value
= fname_decl (loc
, c_parser_peek_token (parser
)->keyword
,
8913 c_parser_peek_token (parser
)->value
);
8914 set_c_expr_source_range (&expr
, loc
, loc
);
8915 c_parser_consume_token (parser
);
8919 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8920 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8921 call c_parser_postfix_expression_after_paren_type on encountering them.
8925 postfix-expression [ expression ]
8926 postfix-expression ( argument-expression-list[opt] )
8927 postfix-expression . identifier
8928 postfix-expression -> identifier
8929 postfix-expression ++
8930 postfix-expression --
8931 ( type-name ) { initializer-list }
8932 ( type-name ) { initializer-list , }
8934 argument-expression-list:
8936 argument-expression-list , argument-expression
8949 (treated as a keyword in GNU C)
8952 ( compound-statement )
8953 __builtin_va_arg ( assignment-expression , type-name )
8954 __builtin_offsetof ( type-name , offsetof-member-designator )
8955 __builtin_choose_expr ( assignment-expression ,
8956 assignment-expression ,
8957 assignment-expression )
8958 __builtin_types_compatible_p ( type-name , type-name )
8959 __builtin_tgmath ( expr-list )
8960 __builtin_complex ( assignment-expression , assignment-expression )
8961 __builtin_shuffle ( assignment-expression , assignment-expression )
8962 __builtin_shuffle ( assignment-expression ,
8963 assignment-expression ,
8964 assignment-expression, )
8965 __builtin_convertvector ( assignment-expression , type-name )
8967 offsetof-member-designator:
8969 offsetof-member-designator . identifier
8970 offsetof-member-designator [ expression ]
8975 [ objc-receiver objc-message-args ]
8976 @selector ( objc-selector-arg )
8977 @protocol ( identifier )
8978 @encode ( type-name )
8980 Classname . identifier
8983 static struct c_expr
8984 c_parser_postfix_expression (c_parser
*parser
)
8986 struct c_expr expr
, e1
;
8987 struct c_type_name
*t1
, *t2
;
8988 location_t loc
= c_parser_peek_token (parser
)->location
;
8989 source_range tok_range
= c_parser_peek_token (parser
)->get_range ();
8990 expr
.original_code
= ERROR_MARK
;
8991 expr
.original_type
= NULL
;
8992 switch (c_parser_peek_token (parser
)->type
)
8995 expr
.value
= c_parser_peek_token (parser
)->value
;
8996 set_c_expr_source_range (&expr
, tok_range
);
8997 loc
= c_parser_peek_token (parser
)->location
;
8998 c_parser_consume_token (parser
);
8999 if (TREE_CODE (expr
.value
) == FIXED_CST
9000 && !targetm
.fixed_point_supported_p ())
9002 error_at (loc
, "fixed-point types not supported for this target");
9011 expr
.value
= c_parser_peek_token (parser
)->value
;
9012 /* For the purpose of warning when a pointer is compared with
9013 a zero character constant. */
9014 expr
.original_type
= char_type_node
;
9015 set_c_expr_source_range (&expr
, tok_range
);
9016 c_parser_consume_token (parser
);
9022 case CPP_UTF8STRING
:
9023 expr
= c_parser_string_literal (parser
, parser
->translate_strings_p
,
9026 case CPP_OBJC_STRING
:
9027 gcc_assert (c_dialect_objc ());
9029 = objc_build_string_object (c_parser_peek_token (parser
)->value
);
9030 set_c_expr_source_range (&expr
, tok_range
);
9031 c_parser_consume_token (parser
);
9034 switch (c_parser_peek_token (parser
)->id_kind
)
9038 tree id
= c_parser_peek_token (parser
)->value
;
9039 c_parser_consume_token (parser
);
9040 expr
.value
= build_external_ref (loc
, id
,
9041 (c_parser_peek_token (parser
)->type
9043 &expr
.original_type
);
9044 set_c_expr_source_range (&expr
, tok_range
);
9047 case C_ID_CLASSNAME
:
9049 /* Here we parse the Objective-C 2.0 Class.name dot
9051 tree class_name
= c_parser_peek_token (parser
)->value
;
9053 c_parser_consume_token (parser
);
9054 gcc_assert (c_dialect_objc ());
9055 if (!c_parser_require (parser
, CPP_DOT
, "expected %<.%>"))
9060 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9062 c_parser_error (parser
, "expected identifier");
9066 c_token
*component_tok
= c_parser_peek_token (parser
);
9067 component
= component_tok
->value
;
9068 location_t end_loc
= component_tok
->get_finish ();
9069 c_parser_consume_token (parser
);
9070 expr
.value
= objc_build_class_component_ref (class_name
,
9072 set_c_expr_source_range (&expr
, loc
, end_loc
);
9076 c_parser_error (parser
, "expected expression");
9081 case CPP_OPEN_PAREN
:
9082 /* A parenthesized expression, statement expression or compound
9084 if (c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_BRACE
)
9086 /* A statement expression. */
9088 location_t brace_loc
;
9089 c_parser_consume_token (parser
);
9090 brace_loc
= c_parser_peek_token (parser
)->location
;
9091 c_parser_consume_token (parser
);
9092 /* If we've not yet started the current function's statement list,
9093 or we're in the parameter scope of an old-style function
9094 declaration, statement expressions are not allowed. */
9095 if (!building_stmt_list_p () || old_style_parameter_scope ())
9097 error_at (loc
, "braced-group within expression allowed "
9098 "only inside a function");
9099 parser
->error
= true;
9100 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
9101 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9105 stmt
= c_begin_stmt_expr ();
9106 c_parser_compound_statement_nostart (parser
);
9107 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9108 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9110 pedwarn (loc
, OPT_Wpedantic
,
9111 "ISO C forbids braced-groups within expressions");
9112 expr
.value
= c_finish_stmt_expr (brace_loc
, stmt
);
9113 set_c_expr_source_range (&expr
, loc
, close_loc
);
9114 mark_exp_read (expr
.value
);
9118 /* A parenthesized expression. */
9119 location_t loc_open_paren
= c_parser_peek_token (parser
)->location
;
9120 c_parser_consume_token (parser
);
9121 expr
= c_parser_expression (parser
);
9122 if (TREE_CODE (expr
.value
) == MODIFY_EXPR
)
9123 TREE_NO_WARNING (expr
.value
) = 1;
9124 if (expr
.original_code
!= C_MAYBE_CONST_EXPR
9125 && expr
.original_code
!= SIZEOF_EXPR
)
9126 expr
.original_code
= ERROR_MARK
;
9127 /* Don't change EXPR.ORIGINAL_TYPE. */
9128 location_t loc_close_paren
= c_parser_peek_token (parser
)->location
;
9129 set_c_expr_source_range (&expr
, loc_open_paren
, loc_close_paren
);
9130 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9131 "expected %<)%>", loc_open_paren
);
9135 switch (c_parser_peek_token (parser
)->keyword
)
9137 case RID_FUNCTION_NAME
:
9138 case RID_PRETTY_FUNCTION_NAME
:
9139 case RID_C99_FUNCTION_NAME
:
9140 expr
= c_parser_predefined_identifier (parser
);
9144 location_t start_loc
= loc
;
9145 c_parser_consume_token (parser
);
9146 matching_parens parens
;
9147 if (!parens
.require_open (parser
))
9152 e1
= c_parser_expr_no_commas (parser
, NULL
);
9153 mark_exp_read (e1
.value
);
9154 e1
.value
= c_fully_fold (e1
.value
, false, NULL
);
9155 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9157 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9161 loc
= c_parser_peek_token (parser
)->location
;
9162 t1
= c_parser_type_name (parser
);
9163 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9164 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9172 tree type_expr
= NULL_TREE
;
9173 expr
.value
= c_build_va_arg (start_loc
, e1
.value
, loc
,
9174 groktypename (t1
, &type_expr
, NULL
));
9177 expr
.value
= build2 (C_MAYBE_CONST_EXPR
,
9178 TREE_TYPE (expr
.value
), type_expr
,
9180 C_MAYBE_CONST_EXPR_NON_CONST (expr
.value
) = true;
9182 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
9188 c_parser_consume_token (parser
);
9189 matching_parens parens
;
9190 if (!parens
.require_open (parser
))
9195 t1
= c_parser_type_name (parser
);
9197 parser
->error
= true;
9198 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9199 gcc_assert (parser
->error
);
9202 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9206 tree type
= groktypename (t1
, NULL
, NULL
);
9208 if (type
== error_mark_node
)
9209 offsetof_ref
= error_mark_node
;
9212 offsetof_ref
= build1 (INDIRECT_REF
, type
, null_pointer_node
);
9213 SET_EXPR_LOCATION (offsetof_ref
, loc
);
9215 /* Parse the second argument to __builtin_offsetof. We
9216 must have one identifier, and beyond that we want to
9217 accept sub structure and sub array references. */
9218 if (c_parser_next_token_is (parser
, CPP_NAME
))
9220 c_token
*comp_tok
= c_parser_peek_token (parser
);
9221 offsetof_ref
= build_component_ref
9222 (loc
, offsetof_ref
, comp_tok
->value
, comp_tok
->location
);
9223 c_parser_consume_token (parser
);
9224 while (c_parser_next_token_is (parser
, CPP_DOT
)
9225 || c_parser_next_token_is (parser
,
9227 || c_parser_next_token_is (parser
,
9230 if (c_parser_next_token_is (parser
, CPP_DEREF
))
9232 loc
= c_parser_peek_token (parser
)->location
;
9233 offsetof_ref
= build_array_ref (loc
,
9238 else if (c_parser_next_token_is (parser
, CPP_DOT
))
9241 c_parser_consume_token (parser
);
9242 if (c_parser_next_token_is_not (parser
,
9245 c_parser_error (parser
, "expected identifier");
9248 c_token
*comp_tok
= c_parser_peek_token (parser
);
9249 offsetof_ref
= build_component_ref
9250 (loc
, offsetof_ref
, comp_tok
->value
,
9251 comp_tok
->location
);
9252 c_parser_consume_token (parser
);
9258 loc
= c_parser_peek_token (parser
)->location
;
9259 c_parser_consume_token (parser
);
9260 ce
= c_parser_expression (parser
);
9261 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
9263 idx
= c_fully_fold (idx
, false, NULL
);
9264 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
9266 offsetof_ref
= build_array_ref (loc
, offsetof_ref
, idx
);
9271 c_parser_error (parser
, "expected identifier");
9272 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9273 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9275 expr
.value
= fold_offsetof (offsetof_ref
);
9276 set_c_expr_source_range (&expr
, loc
, end_loc
);
9279 case RID_CHOOSE_EXPR
:
9281 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9282 c_expr_t
*e1_p
, *e2_p
, *e3_p
;
9284 location_t close_paren_loc
;
9286 c_parser_consume_token (parser
);
9287 if (!c_parser_get_builtin_args (parser
,
9288 "__builtin_choose_expr",
9296 if (vec_safe_length (cexpr_list
) != 3)
9298 error_at (loc
, "wrong number of arguments to "
9299 "%<__builtin_choose_expr%>");
9304 e1_p
= &(*cexpr_list
)[0];
9305 e2_p
= &(*cexpr_list
)[1];
9306 e3_p
= &(*cexpr_list
)[2];
9309 mark_exp_read (e2_p
->value
);
9310 mark_exp_read (e3_p
->value
);
9311 if (TREE_CODE (c
) != INTEGER_CST
9312 || !INTEGRAL_TYPE_P (TREE_TYPE (c
)))
9314 "first argument to %<__builtin_choose_expr%> not"
9316 constant_expression_warning (c
);
9317 expr
= integer_zerop (c
) ? *e3_p
: *e2_p
;
9318 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9321 case RID_TYPES_COMPATIBLE_P
:
9323 c_parser_consume_token (parser
);
9324 matching_parens parens
;
9325 if (!parens
.require_open (parser
))
9330 t1
= c_parser_type_name (parser
);
9336 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9338 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9342 t2
= c_parser_type_name (parser
);
9348 location_t close_paren_loc
= c_parser_peek_token (parser
)->location
;
9349 parens
.skip_until_found_close (parser
);
9351 e1
= groktypename (t1
, NULL
, NULL
);
9352 e2
= groktypename (t2
, NULL
, NULL
);
9353 if (e1
== error_mark_node
|| e2
== error_mark_node
)
9359 e1
= TYPE_MAIN_VARIANT (e1
);
9360 e2
= TYPE_MAIN_VARIANT (e2
);
9363 = comptypes (e1
, e2
) ? integer_one_node
: integer_zero_node
;
9364 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9367 case RID_BUILTIN_TGMATH
:
9369 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9370 location_t close_paren_loc
;
9372 c_parser_consume_token (parser
);
9373 if (!c_parser_get_builtin_args (parser
,
9382 if (vec_safe_length (cexpr_list
) < 3)
9384 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9391 FOR_EACH_VEC_ELT (*cexpr_list
, i
, p
)
9392 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
9393 unsigned int nargs
= check_tgmath_function (&(*cexpr_list
)[0], 1);
9399 if (vec_safe_length (cexpr_list
) < nargs
)
9401 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9405 unsigned int num_functions
= vec_safe_length (cexpr_list
) - nargs
;
9406 if (num_functions
< 2)
9408 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9413 /* The first NUM_FUNCTIONS expressions are the function
9414 pointers. The remaining NARGS expressions are the
9415 arguments that are to be passed to one of those
9416 functions, chosen following <tgmath.h> rules. */
9417 for (unsigned int j
= 1; j
< num_functions
; j
++)
9419 unsigned int this_nargs
9420 = check_tgmath_function (&(*cexpr_list
)[j
], j
+ 1);
9421 if (this_nargs
== 0)
9426 if (this_nargs
!= nargs
)
9428 error_at ((*cexpr_list
)[j
].get_location (),
9429 "argument %u of %<__builtin_tgmath%> has "
9430 "wrong number of arguments", j
+ 1);
9436 /* The functions all have the same number of arguments.
9437 Determine whether arguments and return types vary in
9438 ways permitted for <tgmath.h> functions. */
9439 /* The first entry in each of these vectors is for the
9440 return type, subsequent entries for parameter
9442 auto_vec
<enum tgmath_parm_kind
> parm_kind (nargs
+ 1);
9443 auto_vec
<tree
> parm_first (nargs
+ 1);
9444 auto_vec
<bool> parm_complex (nargs
+ 1);
9445 auto_vec
<bool> parm_varies (nargs
+ 1);
9446 tree first_type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[0].value
));
9447 tree first_ret
= TYPE_MAIN_VARIANT (TREE_TYPE (first_type
));
9448 parm_first
.quick_push (first_ret
);
9449 parm_complex
.quick_push (TREE_CODE (first_ret
) == COMPLEX_TYPE
);
9450 parm_varies
.quick_push (false);
9451 function_args_iterator iter
;
9453 unsigned int argpos
;
9454 FOREACH_FUNCTION_ARGS (first_type
, t
, iter
)
9456 if (t
== void_type_node
)
9458 parm_first
.quick_push (TYPE_MAIN_VARIANT (t
));
9459 parm_complex
.quick_push (TREE_CODE (t
) == COMPLEX_TYPE
);
9460 parm_varies
.quick_push (false);
9462 for (unsigned int j
= 1; j
< num_functions
; j
++)
9464 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9465 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
9466 if (ret
!= parm_first
[0])
9468 parm_varies
[0] = true;
9469 if (!SCALAR_FLOAT_TYPE_P (parm_first
[0])
9470 && !COMPLEX_FLOAT_TYPE_P (parm_first
[0]))
9472 error_at ((*cexpr_list
)[0].get_location (),
9473 "invalid type-generic return type for "
9474 "argument %u of %<__builtin_tgmath%>",
9479 if (!SCALAR_FLOAT_TYPE_P (ret
)
9480 && !COMPLEX_FLOAT_TYPE_P (ret
))
9482 error_at ((*cexpr_list
)[j
].get_location (),
9483 "invalid type-generic return type for "
9484 "argument %u of %<__builtin_tgmath%>",
9490 if (TREE_CODE (ret
) == COMPLEX_TYPE
)
9491 parm_complex
[0] = true;
9493 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9495 if (t
== void_type_node
)
9497 t
= TYPE_MAIN_VARIANT (t
);
9498 if (t
!= parm_first
[argpos
])
9500 parm_varies
[argpos
] = true;
9501 if (!SCALAR_FLOAT_TYPE_P (parm_first
[argpos
])
9502 && !COMPLEX_FLOAT_TYPE_P (parm_first
[argpos
]))
9504 error_at ((*cexpr_list
)[0].get_location (),
9505 "invalid type-generic type for "
9506 "argument %u of argument %u of "
9507 "%<__builtin_tgmath%>", argpos
, 1);
9511 if (!SCALAR_FLOAT_TYPE_P (t
)
9512 && !COMPLEX_FLOAT_TYPE_P (t
))
9514 error_at ((*cexpr_list
)[j
].get_location (),
9515 "invalid type-generic type for "
9516 "argument %u of argument %u of "
9517 "%<__builtin_tgmath%>", argpos
, j
+ 1);
9522 if (TREE_CODE (t
) == COMPLEX_TYPE
)
9523 parm_complex
[argpos
] = true;
9527 enum tgmath_parm_kind max_variation
= tgmath_fixed
;
9528 for (unsigned int j
= 0; j
<= nargs
; j
++)
9530 enum tgmath_parm_kind this_kind
;
9533 if (parm_complex
[j
])
9534 max_variation
= this_kind
= tgmath_complex
;
9537 this_kind
= tgmath_real
;
9538 if (max_variation
!= tgmath_complex
)
9539 max_variation
= tgmath_real
;
9543 this_kind
= tgmath_fixed
;
9544 parm_kind
.quick_push (this_kind
);
9546 if (max_variation
== tgmath_fixed
)
9548 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
9549 "all have the same type");
9554 /* Identify a parameter (not the return type) that varies,
9555 including with complex types if any variation includes
9556 complex types; there must be at least one such
9558 unsigned int tgarg
= 0;
9559 for (unsigned int j
= 1; j
<= nargs
; j
++)
9560 if (parm_kind
[j
] == max_variation
)
9567 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
9568 "lack type-generic parameter");
9573 /* Determine the type of the relevant parameter for each
9575 auto_vec
<tree
> tg_type (num_functions
);
9576 for (unsigned int j
= 0; j
< num_functions
; j
++)
9578 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9580 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9582 if (argpos
== tgarg
)
9584 tg_type
.quick_push (TYPE_MAIN_VARIANT (t
));
9591 /* Verify that the corresponding types are different for
9592 all the listed functions. Also determine whether all
9593 the types are complex, whether all the types are
9594 standard or binary, and whether all the types are
9596 bool all_complex
= true;
9597 bool all_binary
= true;
9598 bool all_decimal
= true;
9599 hash_set
<tree
> tg_types
;
9600 FOR_EACH_VEC_ELT (tg_type
, i
, t
)
9602 if (TREE_CODE (t
) == COMPLEX_TYPE
)
9603 all_decimal
= false;
9606 all_complex
= false;
9607 if (DECIMAL_FLOAT_TYPE_P (t
))
9610 all_decimal
= false;
9612 if (tg_types
.add (t
))
9614 error_at ((*cexpr_list
)[i
].get_location (),
9615 "duplicate type-generic parameter type for "
9616 "function argument %u of %<__builtin_tgmath%>",
9623 /* Verify that other parameters and the return type whose
9624 types vary have their types varying in the correct
9626 for (unsigned int j
= 0; j
< num_functions
; j
++)
9628 tree exp_type
= tg_type
[j
];
9629 tree exp_real_type
= exp_type
;
9630 if (TREE_CODE (exp_type
) == COMPLEX_TYPE
)
9631 exp_real_type
= TREE_TYPE (exp_type
);
9632 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9633 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
9634 if ((parm_kind
[0] == tgmath_complex
&& ret
!= exp_type
)
9635 || (parm_kind
[0] == tgmath_real
&& ret
!= exp_real_type
))
9637 error_at ((*cexpr_list
)[j
].get_location (),
9638 "bad return type for function argument %u "
9639 "of %<__builtin_tgmath%>", j
+ 1);
9644 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9646 if (t
== void_type_node
)
9648 t
= TYPE_MAIN_VARIANT (t
);
9649 if ((parm_kind
[argpos
] == tgmath_complex
9651 || (parm_kind
[argpos
] == tgmath_real
9652 && t
!= exp_real_type
))
9654 error_at ((*cexpr_list
)[j
].get_location (),
9655 "bad type for argument %u of "
9656 "function argument %u of "
9657 "%<__builtin_tgmath%>", argpos
, j
+ 1);
9665 /* The functions listed are a valid set of functions for a
9666 <tgmath.h> macro to select between. Identify the
9667 matching function, if any. First, the argument types
9668 must be combined following <tgmath.h> rules. Integer
9669 types are treated as _Decimal64 if any type-generic
9670 argument is decimal, or if the only alternatives for
9671 type-generic arguments are of decimal types, and are
9672 otherwise treated as double (or _Complex double for
9673 complex integer types, or _Float64 or _Complex _Float64
9674 if all the return types are the same _FloatN or
9675 _FloatNx type). After that adjustment, types are
9676 combined following the usual arithmetic conversions.
9677 If the function only accepts complex arguments, a
9678 complex type is produced. */
9679 bool arg_complex
= all_complex
;
9680 bool arg_binary
= all_binary
;
9681 bool arg_int_decimal
= all_decimal
;
9682 for (unsigned int j
= 1; j
<= nargs
; j
++)
9684 if (parm_kind
[j
] == tgmath_fixed
)
9686 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9687 tree type
= TREE_TYPE (ce
->value
);
9688 if (!INTEGRAL_TYPE_P (type
)
9689 && !SCALAR_FLOAT_TYPE_P (type
)
9690 && TREE_CODE (type
) != COMPLEX_TYPE
)
9692 error_at (ce
->get_location (),
9693 "invalid type of argument %u of type-generic "
9698 if (DECIMAL_FLOAT_TYPE_P (type
))
9700 arg_int_decimal
= true;
9703 error_at (ce
->get_location (),
9704 "decimal floating-point argument %u to "
9705 "complex-only type-generic function", j
);
9709 else if (all_binary
)
9711 error_at (ce
->get_location (),
9712 "decimal floating-point argument %u to "
9713 "binary-only type-generic function", j
);
9717 else if (arg_complex
)
9719 error_at (ce
->get_location (),
9720 "both complex and decimal floating-point "
9721 "arguments to type-generic function");
9725 else if (arg_binary
)
9727 error_at (ce
->get_location (),
9728 "both binary and decimal floating-point "
9729 "arguments to type-generic function");
9734 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
9737 if (COMPLEX_FLOAT_TYPE_P (type
))
9741 error_at (ce
->get_location (),
9742 "complex argument %u to "
9743 "decimal-only type-generic function", j
);
9747 else if (arg_int_decimal
)
9749 error_at (ce
->get_location (),
9750 "both complex and decimal floating-point "
9751 "arguments to type-generic function");
9756 else if (SCALAR_FLOAT_TYPE_P (type
))
9761 error_at (ce
->get_location (),
9762 "binary argument %u to "
9763 "decimal-only type-generic function", j
);
9767 else if (arg_int_decimal
)
9769 error_at (ce
->get_location (),
9770 "both binary and decimal floating-point "
9771 "arguments to type-generic function");
9777 /* For a macro rounding its result to a narrower type, map
9778 integer types to _Float64 not double if the return type
9779 is a _FloatN or _FloatNx type. */
9780 bool arg_int_float64
= false;
9781 if (parm_kind
[0] == tgmath_fixed
9782 && SCALAR_FLOAT_TYPE_P (parm_first
[0])
9783 && float64_type_node
!= NULL_TREE
)
9784 for (unsigned int j
= 0; j
< NUM_FLOATN_NX_TYPES
; j
++)
9785 if (parm_first
[0] == FLOATN_TYPE_NODE (j
))
9787 arg_int_float64
= true;
9790 tree arg_real
= NULL_TREE
;
9791 for (unsigned int j
= 1; j
<= nargs
; j
++)
9793 if (parm_kind
[j
] == tgmath_fixed
)
9795 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9796 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (ce
->value
));
9797 if (TREE_CODE (type
) == COMPLEX_TYPE
)
9798 type
= TREE_TYPE (type
);
9799 if (INTEGRAL_TYPE_P (type
))
9800 type
= (arg_int_decimal
9801 ? dfloat64_type_node
9804 : double_type_node
);
9805 if (arg_real
== NULL_TREE
)
9808 arg_real
= common_type (arg_real
, type
);
9809 if (arg_real
== error_mark_node
)
9815 tree arg_type
= (arg_complex
9816 ? build_complex_type (arg_real
)
9819 /* Look for a function to call with type-generic parameter
9821 c_expr_t
*fn
= NULL
;
9822 for (unsigned int j
= 0; j
< num_functions
; j
++)
9824 if (tg_type
[j
] == arg_type
)
9826 fn
= &(*cexpr_list
)[j
];
9831 && parm_kind
[0] == tgmath_fixed
9832 && SCALAR_FLOAT_TYPE_P (parm_first
[0]))
9834 /* Presume this is a macro that rounds its result to a
9835 narrower type, and look for the first function with
9836 at least the range and precision of the argument
9838 for (unsigned int j
= 0; j
< num_functions
; j
++)
9841 != (TREE_CODE (tg_type
[j
]) == COMPLEX_TYPE
))
9843 tree real_tg_type
= (arg_complex
9844 ? TREE_TYPE (tg_type
[j
])
9846 if (DECIMAL_FLOAT_TYPE_P (arg_real
)
9847 != DECIMAL_FLOAT_TYPE_P (real_tg_type
))
9849 scalar_float_mode arg_mode
9850 = SCALAR_FLOAT_TYPE_MODE (arg_real
);
9851 scalar_float_mode tg_mode
9852 = SCALAR_FLOAT_TYPE_MODE (real_tg_type
);
9853 const real_format
*arg_fmt
= REAL_MODE_FORMAT (arg_mode
);
9854 const real_format
*tg_fmt
= REAL_MODE_FORMAT (tg_mode
);
9855 if (arg_fmt
->b
== tg_fmt
->b
9856 && arg_fmt
->p
<= tg_fmt
->p
9857 && arg_fmt
->emax
<= tg_fmt
->emax
9858 && (arg_fmt
->emin
- arg_fmt
->p
9859 >= tg_fmt
->emin
- tg_fmt
->p
))
9861 fn
= &(*cexpr_list
)[j
];
9868 error_at (loc
, "no matching function for type-generic call");
9873 /* Construct a call to FN. */
9874 vec
<tree
, va_gc
> *args
;
9875 vec_alloc (args
, nargs
);
9876 vec
<tree
, va_gc
> *origtypes
;
9877 vec_alloc (origtypes
, nargs
);
9878 auto_vec
<location_t
> arg_loc (nargs
);
9879 for (unsigned int j
= 0; j
< nargs
; j
++)
9881 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
];
9882 args
->quick_push (ce
->value
);
9883 arg_loc
.quick_push (ce
->get_location ());
9884 origtypes
->quick_push (ce
->original_type
);
9886 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fn
->value
,
9888 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9891 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN
:
9893 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9896 location_t close_paren_loc
;
9898 c_parser_consume_token (parser
);
9899 if (!c_parser_get_builtin_args (parser
,
9900 "__builtin_call_with_static_chain",
9907 if (vec_safe_length (cexpr_list
) != 2)
9909 error_at (loc
, "wrong number of arguments to "
9910 "%<__builtin_call_with_static_chain%>");
9915 expr
= (*cexpr_list
)[0];
9916 e2_p
= &(*cexpr_list
)[1];
9917 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
9918 chain_value
= e2_p
->value
;
9919 mark_exp_read (chain_value
);
9921 if (TREE_CODE (expr
.value
) != CALL_EXPR
)
9922 error_at (loc
, "first argument to "
9923 "%<__builtin_call_with_static_chain%> "
9924 "must be a call expression");
9925 else if (TREE_CODE (TREE_TYPE (chain_value
)) != POINTER_TYPE
)
9926 error_at (loc
, "second argument to "
9927 "%<__builtin_call_with_static_chain%> "
9928 "must be a pointer type");
9930 CALL_EXPR_STATIC_CHAIN (expr
.value
) = chain_value
;
9931 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9934 case RID_BUILTIN_COMPLEX
:
9936 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9937 c_expr_t
*e1_p
, *e2_p
;
9938 location_t close_paren_loc
;
9940 c_parser_consume_token (parser
);
9941 if (!c_parser_get_builtin_args (parser
,
9942 "__builtin_complex",
9950 if (vec_safe_length (cexpr_list
) != 2)
9952 error_at (loc
, "wrong number of arguments to "
9953 "%<__builtin_complex%>");
9958 e1_p
= &(*cexpr_list
)[0];
9959 e2_p
= &(*cexpr_list
)[1];
9961 *e1_p
= convert_lvalue_to_rvalue (loc
, *e1_p
, true, true);
9962 if (TREE_CODE (e1_p
->value
) == EXCESS_PRECISION_EXPR
)
9963 e1_p
->value
= convert (TREE_TYPE (e1_p
->value
),
9964 TREE_OPERAND (e1_p
->value
, 0));
9965 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
9966 if (TREE_CODE (e2_p
->value
) == EXCESS_PRECISION_EXPR
)
9967 e2_p
->value
= convert (TREE_TYPE (e2_p
->value
),
9968 TREE_OPERAND (e2_p
->value
, 0));
9969 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
9970 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
9971 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
))
9972 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
)))
9974 error_at (loc
, "%<__builtin_complex%> operand "
9975 "not of real binary floating-point type");
9979 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p
->value
))
9980 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p
->value
)))
9983 "%<__builtin_complex%> operands of different types");
9987 pedwarn_c90 (loc
, OPT_Wpedantic
,
9988 "ISO C90 does not support complex types");
9989 expr
.value
= build2_loc (loc
, COMPLEX_EXPR
,
9992 (TREE_TYPE (e1_p
->value
))),
9993 e1_p
->value
, e2_p
->value
);
9994 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9997 case RID_BUILTIN_SHUFFLE
:
9999 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10002 location_t close_paren_loc
;
10004 c_parser_consume_token (parser
);
10005 if (!c_parser_get_builtin_args (parser
,
10006 "__builtin_shuffle",
10007 &cexpr_list
, false,
10014 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
10015 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
10017 if (vec_safe_length (cexpr_list
) == 2)
10018 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10020 (*cexpr_list
)[1].value
);
10022 else if (vec_safe_length (cexpr_list
) == 3)
10023 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10024 (*cexpr_list
)[1].value
,
10025 (*cexpr_list
)[2].value
);
10028 error_at (loc
, "wrong number of arguments to "
10029 "%<__builtin_shuffle%>");
10032 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10035 case RID_BUILTIN_CONVERTVECTOR
:
10037 location_t start_loc
= loc
;
10038 c_parser_consume_token (parser
);
10039 matching_parens parens
;
10040 if (!parens
.require_open (parser
))
10045 e1
= c_parser_expr_no_commas (parser
, NULL
);
10046 mark_exp_read (e1
.value
);
10047 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10049 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10053 loc
= c_parser_peek_token (parser
)->location
;
10054 t1
= c_parser_type_name (parser
);
10055 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10056 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10062 tree type_expr
= NULL_TREE
;
10063 expr
.value
= c_build_vec_convert (start_loc
, e1
.value
, loc
,
10064 groktypename (t1
, &type_expr
,
10066 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10070 case RID_AT_SELECTOR
:
10072 gcc_assert (c_dialect_objc ());
10073 c_parser_consume_token (parser
);
10074 matching_parens parens
;
10075 if (!parens
.require_open (parser
))
10080 tree sel
= c_parser_objc_selector_arg (parser
);
10081 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10082 parens
.skip_until_found_close (parser
);
10083 expr
.value
= objc_build_selector_expr (loc
, sel
);
10084 set_c_expr_source_range (&expr
, loc
, close_loc
);
10087 case RID_AT_PROTOCOL
:
10089 gcc_assert (c_dialect_objc ());
10090 c_parser_consume_token (parser
);
10091 matching_parens parens
;
10092 if (!parens
.require_open (parser
))
10097 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10099 c_parser_error (parser
, "expected identifier");
10100 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10104 tree id
= c_parser_peek_token (parser
)->value
;
10105 c_parser_consume_token (parser
);
10106 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10107 parens
.skip_until_found_close (parser
);
10108 expr
.value
= objc_build_protocol_expr (id
);
10109 set_c_expr_source_range (&expr
, loc
, close_loc
);
10112 case RID_AT_ENCODE
:
10114 /* Extension to support C-structures in the archiver. */
10115 gcc_assert (c_dialect_objc ());
10116 c_parser_consume_token (parser
);
10117 matching_parens parens
;
10118 if (!parens
.require_open (parser
))
10123 t1
= c_parser_type_name (parser
);
10127 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10130 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10131 parens
.skip_until_found_close (parser
);
10132 tree type
= groktypename (t1
, NULL
, NULL
);
10133 expr
.value
= objc_build_encode_expr (type
);
10134 set_c_expr_source_range (&expr
, loc
, close_loc
);
10138 expr
= c_parser_generic_selection (parser
);
10141 c_parser_error (parser
, "expected expression");
10146 case CPP_OPEN_SQUARE
:
10147 if (c_dialect_objc ())
10149 tree receiver
, args
;
10150 c_parser_consume_token (parser
);
10151 receiver
= c_parser_objc_receiver (parser
);
10152 args
= c_parser_objc_message_args (parser
);
10153 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10154 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10156 expr
.value
= objc_build_message_expr (receiver
, args
);
10157 set_c_expr_source_range (&expr
, loc
, close_loc
);
10160 /* Else fall through to report error. */
10163 c_parser_error (parser
, "expected expression");
10168 return c_parser_postfix_expression_after_primary
10169 (parser
, EXPR_LOC_OR_LOC (expr
.value
, loc
), expr
);
10172 /* Parse a postfix expression after a parenthesized type name: the
10173 brace-enclosed initializer of a compound literal, possibly followed
10174 by some postfix operators. This is separate because it is not
10175 possible to tell until after the type name whether a cast
10176 expression has a cast or a compound literal, or whether the operand
10177 of sizeof is a parenthesized type name or starts with a compound
10178 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10179 location of the first token after the parentheses around the type
10182 static struct c_expr
10183 c_parser_postfix_expression_after_paren_type (c_parser
*parser
,
10184 struct c_type_name
*type_name
,
10185 location_t type_loc
)
10188 struct c_expr init
;
10190 struct c_expr expr
;
10191 location_t start_loc
;
10192 tree type_expr
= NULL_TREE
;
10193 bool type_expr_const
= true;
10194 check_compound_literal_type (type_loc
, type_name
);
10195 rich_location
richloc (line_table
, type_loc
);
10196 start_init (NULL_TREE
, NULL
, 0, &richloc
);
10197 type
= groktypename (type_name
, &type_expr
, &type_expr_const
);
10198 start_loc
= c_parser_peek_token (parser
)->location
;
10199 if (type
!= error_mark_node
&& C_TYPE_VARIABLE_SIZE (type
))
10201 error_at (type_loc
, "compound literal has variable size");
10202 type
= error_mark_node
;
10204 init
= c_parser_braced_init (parser
, type
, false, NULL
);
10206 maybe_warn_string_init (type_loc
, type
, init
);
10208 if (type
!= error_mark_node
10209 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type
))
10210 && current_function_decl
)
10212 error ("compound literal qualified by address-space qualifier");
10213 type
= error_mark_node
;
10216 pedwarn_c90 (start_loc
, OPT_Wpedantic
, "ISO C90 forbids compound literals");
10217 non_const
= ((init
.value
&& TREE_CODE (init
.value
) == CONSTRUCTOR
)
10218 ? CONSTRUCTOR_NON_CONST (init
.value
)
10219 : init
.original_code
== C_MAYBE_CONST_EXPR
);
10220 non_const
|= !type_expr_const
;
10221 unsigned int alignas_align
= 0;
10222 if (type
!= error_mark_node
10223 && type_name
->specs
->align_log
!= -1)
10225 alignas_align
= 1U << type_name
->specs
->align_log
;
10226 if (alignas_align
< min_align_of_type (type
))
10228 error_at (type_name
->specs
->locations
[cdw_alignas
],
10229 "%<_Alignas%> specifiers cannot reduce "
10230 "alignment of compound literal");
10234 expr
.value
= build_compound_literal (start_loc
, type
, init
.value
, non_const
,
10236 set_c_expr_source_range (&expr
, init
.src_range
);
10237 expr
.original_code
= ERROR_MARK
;
10238 expr
.original_type
= NULL
;
10239 if (type
!= error_mark_node
10240 && expr
.value
!= error_mark_node
10243 if (TREE_CODE (expr
.value
) == C_MAYBE_CONST_EXPR
)
10245 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr
.value
) == NULL_TREE
);
10246 C_MAYBE_CONST_EXPR_PRE (expr
.value
) = type_expr
;
10250 gcc_assert (!non_const
);
10251 expr
.value
= build2 (C_MAYBE_CONST_EXPR
, type
,
10252 type_expr
, expr
.value
);
10255 return c_parser_postfix_expression_after_primary (parser
, start_loc
, expr
);
10258 /* Callback function for sizeof_pointer_memaccess_warning to compare
10262 sizeof_ptr_memacc_comptypes (tree type1
, tree type2
)
10264 return comptypes (type1
, type2
) == 1;
10267 /* Warn for patterns where abs-like function appears to be used incorrectly,
10268 gracefully ignore any non-abs-like function. The warning location should
10269 be LOC. FNDECL is the declaration of called function, it must be a
10270 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10274 warn_for_abs (location_t loc
, tree fndecl
, tree arg
)
10276 /* Avoid warning in unreachable subexpressions. */
10277 if (c_inhibit_evaluation_warnings
)
10280 tree atype
= TREE_TYPE (arg
);
10282 /* Casts from pointers (and thus arrays and fndecls) will generate
10283 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10284 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10285 types and possibly other exotic types. */
10286 if (!INTEGRAL_TYPE_P (atype
)
10287 && !SCALAR_FLOAT_TYPE_P (atype
)
10288 && TREE_CODE (atype
) != COMPLEX_TYPE
)
10291 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
10296 case BUILT_IN_LABS
:
10297 case BUILT_IN_LLABS
:
10298 case BUILT_IN_IMAXABS
:
10299 if (!INTEGRAL_TYPE_P (atype
))
10301 if (SCALAR_FLOAT_TYPE_P (atype
))
10302 warning_at (loc
, OPT_Wabsolute_value
,
10303 "using integer absolute value function %qD when "
10304 "argument is of floating-point type %qT",
10306 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10307 warning_at (loc
, OPT_Wabsolute_value
,
10308 "using integer absolute value function %qD when "
10309 "argument is of complex type %qT", fndecl
, atype
);
10311 gcc_unreachable ();
10314 if (TYPE_UNSIGNED (atype
))
10315 warning_at (loc
, OPT_Wabsolute_value
,
10316 "taking the absolute value of unsigned type %qT "
10317 "has no effect", atype
);
10320 CASE_FLT_FN (BUILT_IN_FABS
):
10321 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS
):
10322 if (!SCALAR_FLOAT_TYPE_P (atype
)
10323 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype
)))
10325 if (INTEGRAL_TYPE_P (atype
))
10326 warning_at (loc
, OPT_Wabsolute_value
,
10327 "using floating-point absolute value function %qD "
10328 "when argument is of integer type %qT", fndecl
, atype
);
10329 else if (DECIMAL_FLOAT_TYPE_P (atype
))
10330 warning_at (loc
, OPT_Wabsolute_value
,
10331 "using floating-point absolute value function %qD "
10332 "when argument is of decimal floating-point type %qT",
10334 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10335 warning_at (loc
, OPT_Wabsolute_value
,
10336 "using floating-point absolute value function %qD when "
10337 "argument is of complex type %qT", fndecl
, atype
);
10339 gcc_unreachable ();
10344 CASE_FLT_FN (BUILT_IN_CABS
):
10345 if (TREE_CODE (atype
) != COMPLEX_TYPE
)
10347 if (INTEGRAL_TYPE_P (atype
))
10348 warning_at (loc
, OPT_Wabsolute_value
,
10349 "using complex absolute value function %qD when "
10350 "argument is of integer type %qT", fndecl
, atype
);
10351 else if (SCALAR_FLOAT_TYPE_P (atype
))
10352 warning_at (loc
, OPT_Wabsolute_value
,
10353 "using complex absolute value function %qD when "
10354 "argument is of floating-point type %qT",
10357 gcc_unreachable ();
10363 case BUILT_IN_FABSD32
:
10364 case BUILT_IN_FABSD64
:
10365 case BUILT_IN_FABSD128
:
10366 if (!DECIMAL_FLOAT_TYPE_P (atype
))
10368 if (INTEGRAL_TYPE_P (atype
))
10369 warning_at (loc
, OPT_Wabsolute_value
,
10370 "using decimal floating-point absolute value "
10371 "function %qD when argument is of integer type %qT",
10373 else if (SCALAR_FLOAT_TYPE_P (atype
))
10374 warning_at (loc
, OPT_Wabsolute_value
,
10375 "using decimal floating-point absolute value "
10376 "function %qD when argument is of floating-point "
10377 "type %qT", fndecl
, atype
);
10378 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10379 warning_at (loc
, OPT_Wabsolute_value
,
10380 "using decimal floating-point absolute value "
10381 "function %qD when argument is of complex type %qT",
10384 gcc_unreachable ();
10393 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl
)))
10396 tree ftype
= TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
10397 if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10399 gcc_assert (TREE_CODE (ftype
) == COMPLEX_TYPE
);
10400 atype
= TREE_TYPE (atype
);
10401 ftype
= TREE_TYPE (ftype
);
10404 if (TYPE_PRECISION (ftype
) < TYPE_PRECISION (atype
))
10405 warning_at (loc
, OPT_Wabsolute_value
,
10406 "absolute value function %qD given an argument of type %qT "
10407 "but has parameter of type %qT which may cause truncation "
10408 "of value", fndecl
, atype
, ftype
);
10412 /* Parse a postfix expression after the initial primary or compound
10413 literal; that is, parse a series of postfix operators.
10415 EXPR_LOC is the location of the primary expression. */
10417 static struct c_expr
10418 c_parser_postfix_expression_after_primary (c_parser
*parser
,
10419 location_t expr_loc
,
10420 struct c_expr expr
)
10422 struct c_expr orig_expr
;
10424 location_t sizeof_arg_loc
[3], comp_loc
;
10425 tree sizeof_arg
[3];
10426 unsigned int literal_zero_mask
;
10428 vec
<tree
, va_gc
> *exprlist
;
10429 vec
<tree
, va_gc
> *origtypes
= NULL
;
10430 vec
<location_t
> arg_loc
= vNULL
;
10436 location_t op_loc
= c_parser_peek_token (parser
)->location
;
10437 switch (c_parser_peek_token (parser
)->type
)
10439 case CPP_OPEN_SQUARE
:
10440 /* Array reference. */
10441 c_parser_consume_token (parser
);
10442 idx
= c_parser_expression (parser
).value
;
10443 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10445 start
= expr
.get_start ();
10446 finish
= parser
->tokens_buf
[0].location
;
10447 expr
.value
= build_array_ref (op_loc
, expr
.value
, idx
);
10448 set_c_expr_source_range (&expr
, start
, finish
);
10449 expr
.original_code
= ERROR_MARK
;
10450 expr
.original_type
= NULL
;
10452 case CPP_OPEN_PAREN
:
10453 /* Function call. */
10454 c_parser_consume_token (parser
);
10455 for (i
= 0; i
< 3; i
++)
10457 sizeof_arg
[i
] = NULL_TREE
;
10458 sizeof_arg_loc
[i
] = UNKNOWN_LOCATION
;
10460 literal_zero_mask
= 0;
10461 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10464 exprlist
= c_parser_expr_list (parser
, true, false, &origtypes
,
10465 sizeof_arg_loc
, sizeof_arg
,
10466 &arg_loc
, &literal_zero_mask
);
10467 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10470 mark_exp_read (expr
.value
);
10471 if (warn_sizeof_pointer_memaccess
)
10472 sizeof_pointer_memaccess_warning (sizeof_arg_loc
,
10473 expr
.value
, exprlist
,
10475 sizeof_ptr_memacc_comptypes
);
10476 if (TREE_CODE (expr
.value
) == FUNCTION_DECL
)
10478 if (fndecl_built_in_p (expr
.value
, BUILT_IN_MEMSET
)
10479 && vec_safe_length (exprlist
) == 3)
10481 tree arg0
= (*exprlist
)[0];
10482 tree arg2
= (*exprlist
)[2];
10483 warn_for_memset (expr_loc
, arg0
, arg2
, literal_zero_mask
);
10485 if (warn_absolute_value
10486 && fndecl_built_in_p (expr
.value
, BUILT_IN_NORMAL
)
10487 && vec_safe_length (exprlist
) == 1)
10488 warn_for_abs (expr_loc
, expr
.value
, (*exprlist
)[0]);
10491 start
= expr
.get_start ();
10492 finish
= parser
->tokens_buf
[0].get_finish ();
10494 = c_build_function_call_vec (expr_loc
, arg_loc
, expr
.value
,
10495 exprlist
, origtypes
);
10496 set_c_expr_source_range (&expr
, start
, finish
);
10498 expr
.original_code
= ERROR_MARK
;
10499 if (TREE_CODE (expr
.value
) == INTEGER_CST
10500 && TREE_CODE (orig_expr
.value
) == FUNCTION_DECL
10501 && fndecl_built_in_p (orig_expr
.value
, BUILT_IN_CONSTANT_P
))
10502 expr
.original_code
= C_MAYBE_CONST_EXPR
;
10503 expr
.original_type
= NULL
;
10506 release_tree_vector (exprlist
);
10507 release_tree_vector (origtypes
);
10509 arg_loc
.release ();
10512 /* Structure element reference. */
10513 c_parser_consume_token (parser
);
10514 expr
= default_function_array_conversion (expr_loc
, expr
);
10515 if (c_parser_next_token_is (parser
, CPP_NAME
))
10517 c_token
*comp_tok
= c_parser_peek_token (parser
);
10518 ident
= comp_tok
->value
;
10519 comp_loc
= comp_tok
->location
;
10523 c_parser_error (parser
, "expected identifier");
10525 expr
.original_code
= ERROR_MARK
;
10526 expr
.original_type
= NULL
;
10529 start
= expr
.get_start ();
10530 finish
= c_parser_peek_token (parser
)->get_finish ();
10531 c_parser_consume_token (parser
);
10532 expr
.value
= build_component_ref (op_loc
, expr
.value
, ident
,
10534 set_c_expr_source_range (&expr
, start
, finish
);
10535 expr
.original_code
= ERROR_MARK
;
10536 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
10537 expr
.original_type
= NULL
;
10540 /* Remember the original type of a bitfield. */
10541 tree field
= TREE_OPERAND (expr
.value
, 1);
10542 if (TREE_CODE (field
) != FIELD_DECL
)
10543 expr
.original_type
= NULL
;
10545 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
10549 /* Structure element reference. */
10550 c_parser_consume_token (parser
);
10551 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, false);
10552 if (c_parser_next_token_is (parser
, CPP_NAME
))
10554 c_token
*comp_tok
= c_parser_peek_token (parser
);
10555 ident
= comp_tok
->value
;
10556 comp_loc
= comp_tok
->location
;
10560 c_parser_error (parser
, "expected identifier");
10562 expr
.original_code
= ERROR_MARK
;
10563 expr
.original_type
= NULL
;
10566 start
= expr
.get_start ();
10567 finish
= c_parser_peek_token (parser
)->get_finish ();
10568 c_parser_consume_token (parser
);
10569 expr
.value
= build_component_ref (op_loc
,
10570 build_indirect_ref (op_loc
,
10574 set_c_expr_source_range (&expr
, start
, finish
);
10575 expr
.original_code
= ERROR_MARK
;
10576 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
10577 expr
.original_type
= NULL
;
10580 /* Remember the original type of a bitfield. */
10581 tree field
= TREE_OPERAND (expr
.value
, 1);
10582 if (TREE_CODE (field
) != FIELD_DECL
)
10583 expr
.original_type
= NULL
;
10585 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
10588 case CPP_PLUS_PLUS
:
10589 /* Postincrement. */
10590 start
= expr
.get_start ();
10591 finish
= c_parser_peek_token (parser
)->get_finish ();
10592 c_parser_consume_token (parser
);
10593 expr
= default_function_array_read_conversion (expr_loc
, expr
);
10594 expr
.value
= build_unary_op (op_loc
, POSTINCREMENT_EXPR
,
10595 expr
.value
, false);
10596 set_c_expr_source_range (&expr
, start
, finish
);
10597 expr
.original_code
= ERROR_MARK
;
10598 expr
.original_type
= NULL
;
10600 case CPP_MINUS_MINUS
:
10601 /* Postdecrement. */
10602 start
= expr
.get_start ();
10603 finish
= c_parser_peek_token (parser
)->get_finish ();
10604 c_parser_consume_token (parser
);
10605 expr
= default_function_array_read_conversion (expr_loc
, expr
);
10606 expr
.value
= build_unary_op (op_loc
, POSTDECREMENT_EXPR
,
10607 expr
.value
, false);
10608 set_c_expr_source_range (&expr
, start
, finish
);
10609 expr
.original_code
= ERROR_MARK
;
10610 expr
.original_type
= NULL
;
10618 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10621 assignment-expression
10622 expression , assignment-expression
10625 static struct c_expr
10626 c_parser_expression (c_parser
*parser
)
10628 location_t tloc
= c_parser_peek_token (parser
)->location
;
10629 struct c_expr expr
;
10630 expr
= c_parser_expr_no_commas (parser
, NULL
);
10631 if (c_parser_next_token_is (parser
, CPP_COMMA
))
10632 expr
= convert_lvalue_to_rvalue (tloc
, expr
, true, false);
10633 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10635 struct c_expr next
;
10637 location_t loc
= c_parser_peek_token (parser
)->location
;
10638 location_t expr_loc
;
10639 c_parser_consume_token (parser
);
10640 expr_loc
= c_parser_peek_token (parser
)->location
;
10641 lhsval
= expr
.value
;
10642 while (TREE_CODE (lhsval
) == COMPOUND_EXPR
)
10643 lhsval
= TREE_OPERAND (lhsval
, 1);
10644 if (DECL_P (lhsval
) || handled_component_p (lhsval
))
10645 mark_exp_read (lhsval
);
10646 next
= c_parser_expr_no_commas (parser
, NULL
);
10647 next
= convert_lvalue_to_rvalue (expr_loc
, next
, true, false);
10648 expr
.value
= build_compound_expr (loc
, expr
.value
, next
.value
);
10649 expr
.original_code
= COMPOUND_EXPR
;
10650 expr
.original_type
= next
.original_type
;
10655 /* Parse an expression and convert functions or arrays to pointers and
10656 lvalues to rvalues. */
10658 static struct c_expr
10659 c_parser_expression_conv (c_parser
*parser
)
10661 struct c_expr expr
;
10662 location_t loc
= c_parser_peek_token (parser
)->location
;
10663 expr
= c_parser_expression (parser
);
10664 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, false);
10668 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10669 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10672 c_parser_check_literal_zero (c_parser
*parser
, unsigned *literal_zero_mask
,
10675 if (idx
>= HOST_BITS_PER_INT
)
10678 c_token
*tok
= c_parser_peek_token (parser
);
10687 /* If a parameter is literal zero alone, remember it
10688 for -Wmemset-transposed-args warning. */
10689 if (integer_zerop (tok
->value
)
10690 && !TREE_OVERFLOW (tok
->value
)
10691 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
10692 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
10693 *literal_zero_mask
|= 1U << idx
;
10699 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10700 functions and arrays to pointers and lvalues to rvalues. If
10701 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10702 locations of function arguments into this vector.
10704 nonempty-expr-list:
10705 assignment-expression
10706 nonempty-expr-list , assignment-expression
10709 static vec
<tree
, va_gc
> *
10710 c_parser_expr_list (c_parser
*parser
, bool convert_p
, bool fold_p
,
10711 vec
<tree
, va_gc
> **p_orig_types
,
10712 location_t
*sizeof_arg_loc
, tree
*sizeof_arg
,
10713 vec
<location_t
> *locations
,
10714 unsigned int *literal_zero_mask
)
10716 vec
<tree
, va_gc
> *ret
;
10717 vec
<tree
, va_gc
> *orig_types
;
10718 struct c_expr expr
;
10719 unsigned int idx
= 0;
10721 ret
= make_tree_vector ();
10722 if (p_orig_types
== NULL
)
10725 orig_types
= make_tree_vector ();
10727 if (literal_zero_mask
)
10728 c_parser_check_literal_zero (parser
, literal_zero_mask
, 0);
10729 expr
= c_parser_expr_no_commas (parser
, NULL
);
10731 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true, true);
10733 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
10734 ret
->quick_push (expr
.value
);
10736 orig_types
->quick_push (expr
.original_type
);
10738 locations
->safe_push (expr
.get_location ());
10739 if (sizeof_arg
!= NULL
10740 && expr
.original_code
== SIZEOF_EXPR
)
10742 sizeof_arg
[0] = c_last_sizeof_arg
;
10743 sizeof_arg_loc
[0] = c_last_sizeof_loc
;
10745 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10747 c_parser_consume_token (parser
);
10748 if (literal_zero_mask
)
10749 c_parser_check_literal_zero (parser
, literal_zero_mask
, idx
+ 1);
10750 expr
= c_parser_expr_no_commas (parser
, NULL
);
10752 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true,
10755 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
10756 vec_safe_push (ret
, expr
.value
);
10758 vec_safe_push (orig_types
, expr
.original_type
);
10760 locations
->safe_push (expr
.get_location ());
10762 && sizeof_arg
!= NULL
10763 && expr
.original_code
== SIZEOF_EXPR
)
10765 sizeof_arg
[idx
] = c_last_sizeof_arg
;
10766 sizeof_arg_loc
[idx
] = c_last_sizeof_loc
;
10770 *p_orig_types
= orig_types
;
10774 /* Parse Objective-C-specific constructs. */
10776 /* Parse an objc-class-definition.
10778 objc-class-definition:
10779 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10780 objc-class-instance-variables[opt] objc-methodprotolist @end
10781 @implementation identifier objc-superclass[opt]
10782 objc-class-instance-variables[opt]
10783 @interface identifier ( identifier ) objc-protocol-refs[opt]
10784 objc-methodprotolist @end
10785 @interface identifier ( ) objc-protocol-refs[opt]
10786 objc-methodprotolist @end
10787 @implementation identifier ( identifier )
10792 "@interface identifier (" must start "@interface identifier (
10793 identifier ) ...": objc-methodprotolist in the first production may
10794 not start with a parenthesized identifier as a declarator of a data
10795 definition with no declaration specifiers if the objc-superclass,
10796 objc-protocol-refs and objc-class-instance-variables are omitted. */
10799 c_parser_objc_class_definition (c_parser
*parser
, tree attributes
)
10804 if (c_parser_next_token_is_keyword (parser
, RID_AT_INTERFACE
))
10806 else if (c_parser_next_token_is_keyword (parser
, RID_AT_IMPLEMENTATION
))
10809 gcc_unreachable ();
10811 c_parser_consume_token (parser
);
10812 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10814 c_parser_error (parser
, "expected identifier");
10817 id1
= c_parser_peek_token (parser
)->value
;
10818 c_parser_consume_token (parser
);
10819 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
10821 /* We have a category or class extension. */
10823 tree proto
= NULL_TREE
;
10824 matching_parens parens
;
10825 parens
.consume_open (parser
);
10826 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10828 if (iface_p
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10830 /* We have a class extension. */
10835 c_parser_error (parser
, "expected identifier or %<)%>");
10836 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10842 id2
= c_parser_peek_token (parser
)->value
;
10843 c_parser_consume_token (parser
);
10845 parens
.skip_until_found_close (parser
);
10848 objc_start_category_implementation (id1
, id2
);
10851 if (c_parser_next_token_is (parser
, CPP_LESS
))
10852 proto
= c_parser_objc_protocol_refs (parser
);
10853 objc_start_category_interface (id1
, id2
, proto
, attributes
);
10854 c_parser_objc_methodprotolist (parser
);
10855 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10856 objc_finish_interface ();
10859 if (c_parser_next_token_is (parser
, CPP_COLON
))
10861 c_parser_consume_token (parser
);
10862 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10864 c_parser_error (parser
, "expected identifier");
10867 superclass
= c_parser_peek_token (parser
)->value
;
10868 c_parser_consume_token (parser
);
10871 superclass
= NULL_TREE
;
10874 tree proto
= NULL_TREE
;
10875 if (c_parser_next_token_is (parser
, CPP_LESS
))
10876 proto
= c_parser_objc_protocol_refs (parser
);
10877 objc_start_class_interface (id1
, superclass
, proto
, attributes
);
10880 objc_start_class_implementation (id1
, superclass
);
10881 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
10882 c_parser_objc_class_instance_variables (parser
);
10885 objc_continue_interface ();
10886 c_parser_objc_methodprotolist (parser
);
10887 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10888 objc_finish_interface ();
10892 objc_continue_implementation ();
10897 /* Parse objc-class-instance-variables.
10899 objc-class-instance-variables:
10900 { objc-instance-variable-decl-list[opt] }
10902 objc-instance-variable-decl-list:
10903 objc-visibility-spec
10904 objc-instance-variable-decl ;
10906 objc-instance-variable-decl-list objc-visibility-spec
10907 objc-instance-variable-decl-list objc-instance-variable-decl ;
10908 objc-instance-variable-decl-list ;
10910 objc-visibility-spec:
10915 objc-instance-variable-decl:
10920 c_parser_objc_class_instance_variables (c_parser
*parser
)
10922 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
10923 c_parser_consume_token (parser
);
10924 while (c_parser_next_token_is_not (parser
, CPP_EOF
))
10927 /* Parse any stray semicolon. */
10928 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
10930 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
10931 "extra semicolon");
10932 c_parser_consume_token (parser
);
10935 /* Stop if at the end of the instance variables. */
10936 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
10938 c_parser_consume_token (parser
);
10941 /* Parse any objc-visibility-spec. */
10942 if (c_parser_next_token_is_keyword (parser
, RID_AT_PRIVATE
))
10944 c_parser_consume_token (parser
);
10945 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE
);
10948 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROTECTED
))
10950 c_parser_consume_token (parser
);
10951 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED
);
10954 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PUBLIC
))
10956 c_parser_consume_token (parser
);
10957 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC
);
10960 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PACKAGE
))
10962 c_parser_consume_token (parser
);
10963 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE
);
10966 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
10968 c_parser_pragma (parser
, pragma_external
, NULL
);
10972 /* Parse some comma-separated declarations. */
10973 decls
= c_parser_struct_declaration (parser
);
10976 /* There is a syntax error. We want to skip the offending
10977 tokens up to the next ';' (included) or '}'
10980 /* First, skip manually a ')' or ']'. This is because they
10981 reduce the nesting level, so c_parser_skip_until_found()
10982 wouldn't be able to skip past them. */
10983 c_token
*token
= c_parser_peek_token (parser
);
10984 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_CLOSE_SQUARE
)
10985 c_parser_consume_token (parser
);
10987 /* Then, do the standard skipping. */
10988 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
10990 /* We hopefully recovered. Start normal parsing again. */
10991 parser
->error
= false;
10996 /* Comma-separated instance variables are chained together
10997 in reverse order; add them one by one. */
10998 tree ivar
= nreverse (decls
);
10999 for (; ivar
; ivar
= DECL_CHAIN (ivar
))
11000 objc_add_instance_variable (copy_node (ivar
));
11002 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11006 /* Parse an objc-class-declaration.
11008 objc-class-declaration:
11009 @class identifier-list ;
11013 c_parser_objc_class_declaration (c_parser
*parser
)
11015 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_CLASS
));
11016 c_parser_consume_token (parser
);
11017 /* Any identifiers, including those declared as type names, are OK
11022 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11024 c_parser_error (parser
, "expected identifier");
11025 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11026 parser
->error
= false;
11029 id
= c_parser_peek_token (parser
)->value
;
11030 objc_declare_class (id
);
11031 c_parser_consume_token (parser
);
11032 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11033 c_parser_consume_token (parser
);
11037 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11040 /* Parse an objc-alias-declaration.
11042 objc-alias-declaration:
11043 @compatibility_alias identifier identifier ;
11047 c_parser_objc_alias_declaration (c_parser
*parser
)
11050 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_ALIAS
));
11051 c_parser_consume_token (parser
);
11052 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11054 c_parser_error (parser
, "expected identifier");
11055 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11058 id1
= c_parser_peek_token (parser
)->value
;
11059 c_parser_consume_token (parser
);
11060 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11062 c_parser_error (parser
, "expected identifier");
11063 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11066 id2
= c_parser_peek_token (parser
)->value
;
11067 c_parser_consume_token (parser
);
11068 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11069 objc_declare_alias (id1
, id2
);
11072 /* Parse an objc-protocol-definition.
11074 objc-protocol-definition:
11075 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11076 @protocol identifier-list ;
11078 "@protocol identifier ;" should be resolved as "@protocol
11079 identifier-list ;": objc-methodprotolist may not start with a
11080 semicolon in the first alternative if objc-protocol-refs are
11084 c_parser_objc_protocol_definition (c_parser
*parser
, tree attributes
)
11086 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROTOCOL
));
11088 c_parser_consume_token (parser
);
11089 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11091 c_parser_error (parser
, "expected identifier");
11094 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
11095 || c_parser_peek_2nd_token (parser
)->type
== CPP_SEMICOLON
)
11097 /* Any identifiers, including those declared as type names, are
11102 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11104 c_parser_error (parser
, "expected identifier");
11107 id
= c_parser_peek_token (parser
)->value
;
11108 objc_declare_protocol (id
, attributes
);
11109 c_parser_consume_token (parser
);
11110 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11111 c_parser_consume_token (parser
);
11115 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11119 tree id
= c_parser_peek_token (parser
)->value
;
11120 tree proto
= NULL_TREE
;
11121 c_parser_consume_token (parser
);
11122 if (c_parser_next_token_is (parser
, CPP_LESS
))
11123 proto
= c_parser_objc_protocol_refs (parser
);
11124 parser
->objc_pq_context
= true;
11125 objc_start_protocol (id
, proto
, attributes
);
11126 c_parser_objc_methodprotolist (parser
);
11127 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
11128 parser
->objc_pq_context
= false;
11129 objc_finish_interface ();
11133 /* Parse an objc-method-type.
11139 Return true if it is a class method (+) and false if it is
11140 an instance method (-).
11143 c_parser_objc_method_type (c_parser
*parser
)
11145 switch (c_parser_peek_token (parser
)->type
)
11148 c_parser_consume_token (parser
);
11151 c_parser_consume_token (parser
);
11154 gcc_unreachable ();
11158 /* Parse an objc-method-definition.
11160 objc-method-definition:
11161 objc-method-type objc-method-decl ;[opt] compound-statement
11165 c_parser_objc_method_definition (c_parser
*parser
)
11167 bool is_class_method
= c_parser_objc_method_type (parser
);
11168 tree decl
, attributes
= NULL_TREE
, expr
= NULL_TREE
;
11169 parser
->objc_pq_context
= true;
11170 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11172 if (decl
== error_mark_node
)
11173 return; /* Bail here. */
11175 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11177 c_parser_consume_token (parser
);
11178 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11179 "extra semicolon in method definition specified");
11182 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11184 c_parser_error (parser
, "expected %<{%>");
11188 parser
->objc_pq_context
= false;
11189 if (objc_start_method_definition (is_class_method
, decl
, attributes
, expr
))
11191 add_stmt (c_parser_compound_statement (parser
));
11192 objc_finish_method_definition (current_function_decl
);
11196 /* This code is executed when we find a method definition
11197 outside of an @implementation context (or invalid for other
11198 reasons). Parse the method (to keep going) but do not emit
11201 c_parser_compound_statement (parser
);
11205 /* Parse an objc-methodprotolist.
11207 objc-methodprotolist:
11209 objc-methodprotolist objc-methodproto
11210 objc-methodprotolist declaration
11211 objc-methodprotolist ;
11215 The declaration is a data definition, which may be missing
11216 declaration specifiers under the same rules and diagnostics as
11217 other data definitions outside functions, and the stray semicolon
11218 is diagnosed the same way as a stray semicolon outside a
11222 c_parser_objc_methodprotolist (c_parser
*parser
)
11226 /* The list is terminated by @end. */
11227 switch (c_parser_peek_token (parser
)->type
)
11229 case CPP_SEMICOLON
:
11230 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11231 "ISO C does not allow extra %<;%> outside of a function");
11232 c_parser_consume_token (parser
);
11236 c_parser_objc_methodproto (parser
);
11239 c_parser_pragma (parser
, pragma_external
, NULL
);
11244 if (c_parser_next_token_is_keyword (parser
, RID_AT_END
))
11246 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
))
11247 c_parser_objc_at_property_declaration (parser
);
11248 else if (c_parser_next_token_is_keyword (parser
, RID_AT_OPTIONAL
))
11250 objc_set_method_opt (true);
11251 c_parser_consume_token (parser
);
11253 else if (c_parser_next_token_is_keyword (parser
, RID_AT_REQUIRED
))
11255 objc_set_method_opt (false);
11256 c_parser_consume_token (parser
);
11259 c_parser_declaration_or_fndef (parser
, false, false, true,
11260 false, true, NULL
, vNULL
);
11266 /* Parse an objc-methodproto.
11269 objc-method-type objc-method-decl ;
11273 c_parser_objc_methodproto (c_parser
*parser
)
11275 bool is_class_method
= c_parser_objc_method_type (parser
);
11276 tree decl
, attributes
= NULL_TREE
;
11278 /* Remember protocol qualifiers in prototypes. */
11279 parser
->objc_pq_context
= true;
11280 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11282 /* Forget protocol qualifiers now. */
11283 parser
->objc_pq_context
= false;
11285 /* Do not allow the presence of attributes to hide an erroneous
11286 method implementation in the interface section. */
11287 if (!c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11289 c_parser_error (parser
, "expected %<;%>");
11293 if (decl
!= error_mark_node
)
11294 objc_add_method_declaration (is_class_method
, decl
, attributes
);
11296 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11299 /* If we are at a position that method attributes may be present, check that
11300 there are not any parsed already (a syntax error) and then collect any
11301 specified at the current location. Finally, if new attributes were present,
11302 check that the next token is legal ( ';' for decls and '{' for defs). */
11305 c_parser_objc_maybe_method_attributes (c_parser
* parser
, tree
* attributes
)
11310 c_parser_error (parser
,
11311 "method attributes must be specified at the end only");
11312 *attributes
= NULL_TREE
;
11316 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
11317 *attributes
= c_parser_gnu_attributes (parser
);
11319 /* If there were no attributes here, just report any earlier error. */
11320 if (*attributes
== NULL_TREE
|| bad
)
11323 /* If the attributes are followed by a ; or {, then just report any earlier
11325 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
11326 || c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11329 /* We've got attributes, but not at the end. */
11330 c_parser_error (parser
,
11331 "expected %<;%> or %<{%> after method attribute definition");
11335 /* Parse an objc-method-decl.
11338 ( objc-type-name ) objc-selector
11340 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11341 objc-keyword-selector objc-optparmlist
11344 objc-keyword-selector:
11346 objc-keyword-selector objc-keyword-decl
11349 objc-selector : ( objc-type-name ) identifier
11350 objc-selector : identifier
11351 : ( objc-type-name ) identifier
11355 objc-optparms objc-optellipsis
11359 objc-opt-parms , parameter-declaration
11367 c_parser_objc_method_decl (c_parser
*parser
, bool is_class_method
,
11368 tree
*attributes
, tree
*expr
)
11370 tree type
= NULL_TREE
;
11372 tree parms
= NULL_TREE
;
11373 bool ellipsis
= false;
11374 bool attr_err
= false;
11376 *attributes
= NULL_TREE
;
11377 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11379 matching_parens parens
;
11380 parens
.consume_open (parser
);
11381 type
= c_parser_objc_type_name (parser
);
11382 parens
.skip_until_found_close (parser
);
11384 sel
= c_parser_objc_selector (parser
);
11385 /* If there is no selector, or a colon follows, we have an
11386 objc-keyword-selector. If there is a selector, and a colon does
11387 not follow, that selector ends the objc-method-decl. */
11388 if (!sel
|| c_parser_next_token_is (parser
, CPP_COLON
))
11391 tree list
= NULL_TREE
;
11394 tree atype
= NULL_TREE
, id
, keyworddecl
;
11395 tree param_attr
= NULL_TREE
;
11396 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11398 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11400 c_parser_consume_token (parser
);
11401 atype
= c_parser_objc_type_name (parser
);
11402 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
11405 /* New ObjC allows attributes on method parameters. */
11406 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
11407 param_attr
= c_parser_gnu_attributes (parser
);
11408 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11410 c_parser_error (parser
, "expected identifier");
11411 return error_mark_node
;
11413 id
= c_parser_peek_token (parser
)->value
;
11414 c_parser_consume_token (parser
);
11415 keyworddecl
= objc_build_keyword_decl (tsel
, atype
, id
, param_attr
);
11416 list
= chainon (list
, keyworddecl
);
11417 tsel
= c_parser_objc_selector (parser
);
11418 if (!tsel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11422 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
11424 /* Parse the optional parameter list. Optional Objective-C
11425 method parameters follow the C syntax, and may include '...'
11426 to denote a variable number of arguments. */
11427 parms
= make_node (TREE_LIST
);
11428 while (c_parser_next_token_is (parser
, CPP_COMMA
))
11430 struct c_parm
*parm
;
11431 c_parser_consume_token (parser
);
11432 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
11435 c_parser_consume_token (parser
);
11436 attr_err
|= c_parser_objc_maybe_method_attributes
11437 (parser
, attributes
) ;
11440 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
11443 parms
= chainon (parms
,
11444 build_tree_list (NULL_TREE
, grokparm (parm
, expr
)));
11449 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
11453 c_parser_error (parser
, "objective-c method declaration is expected");
11454 return error_mark_node
;
11458 return error_mark_node
;
11460 return objc_build_method_signature (is_class_method
, type
, sel
, parms
, ellipsis
);
11463 /* Parse an objc-type-name.
11466 objc-type-qualifiers[opt] type-name
11467 objc-type-qualifiers[opt]
11469 objc-type-qualifiers:
11470 objc-type-qualifier
11471 objc-type-qualifiers objc-type-qualifier
11473 objc-type-qualifier: one of
11474 in out inout bycopy byref oneway
11478 c_parser_objc_type_name (c_parser
*parser
)
11480 tree quals
= NULL_TREE
;
11481 struct c_type_name
*type_name
= NULL
;
11482 tree type
= NULL_TREE
;
11485 c_token
*token
= c_parser_peek_token (parser
);
11486 if (token
->type
== CPP_KEYWORD
11487 && (token
->keyword
== RID_IN
11488 || token
->keyword
== RID_OUT
11489 || token
->keyword
== RID_INOUT
11490 || token
->keyword
== RID_BYCOPY
11491 || token
->keyword
== RID_BYREF
11492 || token
->keyword
== RID_ONEWAY
))
11494 quals
= chainon (build_tree_list (NULL_TREE
, token
->value
), quals
);
11495 c_parser_consume_token (parser
);
11500 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
11501 type_name
= c_parser_type_name (parser
);
11503 type
= groktypename (type_name
, NULL
, NULL
);
11505 /* If the type is unknown, and error has already been produced and
11506 we need to recover from the error. In that case, use NULL_TREE
11507 for the type, as if no type had been specified; this will use the
11508 default type ('id') which is good for error recovery. */
11509 if (type
== error_mark_node
)
11512 return build_tree_list (quals
, type
);
11515 /* Parse objc-protocol-refs.
11517 objc-protocol-refs:
11518 < identifier-list >
11522 c_parser_objc_protocol_refs (c_parser
*parser
)
11524 tree list
= NULL_TREE
;
11525 gcc_assert (c_parser_next_token_is (parser
, CPP_LESS
));
11526 c_parser_consume_token (parser
);
11527 /* Any identifiers, including those declared as type names, are OK
11532 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11534 c_parser_error (parser
, "expected identifier");
11537 id
= c_parser_peek_token (parser
)->value
;
11538 list
= chainon (list
, build_tree_list (NULL_TREE
, id
));
11539 c_parser_consume_token (parser
);
11540 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11541 c_parser_consume_token (parser
);
11545 c_parser_require (parser
, CPP_GREATER
, "expected %<>%>");
11549 /* Parse an objc-try-catch-finally-statement.
11551 objc-try-catch-finally-statement:
11552 @try compound-statement objc-catch-list[opt]
11553 @try compound-statement objc-catch-list[opt] @finally compound-statement
11556 @catch ( objc-catch-parameter-declaration ) compound-statement
11557 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11559 objc-catch-parameter-declaration:
11560 parameter-declaration
11563 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11565 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11566 for C++. Keep them in sync. */
11569 c_parser_objc_try_catch_finally_statement (c_parser
*parser
)
11571 location_t location
;
11574 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_TRY
));
11575 c_parser_consume_token (parser
);
11576 location
= c_parser_peek_token (parser
)->location
;
11577 objc_maybe_warn_exceptions (location
);
11578 stmt
= c_parser_compound_statement (parser
);
11579 objc_begin_try_stmt (location
, stmt
);
11581 while (c_parser_next_token_is_keyword (parser
, RID_AT_CATCH
))
11583 struct c_parm
*parm
;
11584 tree parameter_declaration
= error_mark_node
;
11585 bool seen_open_paren
= false;
11587 c_parser_consume_token (parser
);
11588 matching_parens parens
;
11589 if (!parens
.require_open (parser
))
11590 seen_open_paren
= true;
11591 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
11593 /* We have "@catch (...)" (where the '...' are literally
11594 what is in the code). Skip the '...'.
11595 parameter_declaration is set to NULL_TREE, and
11596 objc_being_catch_clauses() knows that that means
11598 c_parser_consume_token (parser
);
11599 parameter_declaration
= NULL_TREE
;
11603 /* We have "@catch (NSException *exception)" or something
11604 like that. Parse the parameter declaration. */
11605 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
11607 parameter_declaration
= error_mark_node
;
11609 parameter_declaration
= grokparm (parm
, NULL
);
11611 if (seen_open_paren
)
11612 parens
.require_close (parser
);
11615 /* If there was no open parenthesis, we are recovering from
11616 an error, and we are trying to figure out what mistake
11617 the user has made. */
11619 /* If there is an immediate closing parenthesis, the user
11620 probably forgot the opening one (ie, they typed "@catch
11621 NSException *e)". Parse the closing parenthesis and keep
11623 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
11624 c_parser_consume_token (parser
);
11626 /* If these is no immediate closing parenthesis, the user
11627 probably doesn't know that parenthesis are required at
11628 all (ie, they typed "@catch NSException *e"). So, just
11629 forget about the closing parenthesis and keep going. */
11631 objc_begin_catch_clause (parameter_declaration
);
11632 if (c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
11633 c_parser_compound_statement_nostart (parser
);
11634 objc_finish_catch_clause ();
11636 if (c_parser_next_token_is_keyword (parser
, RID_AT_FINALLY
))
11638 c_parser_consume_token (parser
);
11639 location
= c_parser_peek_token (parser
)->location
;
11640 stmt
= c_parser_compound_statement (parser
);
11641 objc_build_finally_clause (location
, stmt
);
11643 objc_finish_try_stmt ();
11646 /* Parse an objc-synchronized-statement.
11648 objc-synchronized-statement:
11649 @synchronized ( expression ) compound-statement
11653 c_parser_objc_synchronized_statement (c_parser
*parser
)
11657 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNCHRONIZED
));
11658 c_parser_consume_token (parser
);
11659 loc
= c_parser_peek_token (parser
)->location
;
11660 objc_maybe_warn_exceptions (loc
);
11661 matching_parens parens
;
11662 if (parens
.require_open (parser
))
11664 struct c_expr ce
= c_parser_expression (parser
);
11665 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
11667 expr
= c_fully_fold (expr
, false, NULL
);
11668 parens
.skip_until_found_close (parser
);
11671 expr
= error_mark_node
;
11672 stmt
= c_parser_compound_statement (parser
);
11673 objc_build_synchronized (loc
, expr
, stmt
);
11676 /* Parse an objc-selector; return NULL_TREE without an error if the
11677 next token is not an objc-selector.
11682 enum struct union if else while do for switch case default
11683 break continue return goto asm sizeof typeof __alignof
11684 unsigned long const short volatile signed restrict _Complex
11685 in out inout bycopy byref oneway int char float double void _Bool
11688 ??? Why this selection of keywords but not, for example, storage
11689 class specifiers? */
11692 c_parser_objc_selector (c_parser
*parser
)
11694 c_token
*token
= c_parser_peek_token (parser
);
11695 tree value
= token
->value
;
11696 if (token
->type
== CPP_NAME
)
11698 c_parser_consume_token (parser
);
11701 if (token
->type
!= CPP_KEYWORD
)
11703 switch (token
->keyword
)
11742 CASE_RID_FLOATN_NX
:
11746 case RID_AUTO_TYPE
:
11751 c_parser_consume_token (parser
);
11758 /* Parse an objc-selector-arg.
11762 objc-keywordname-list
11764 objc-keywordname-list:
11766 objc-keywordname-list objc-keywordname
11774 c_parser_objc_selector_arg (c_parser
*parser
)
11776 tree sel
= c_parser_objc_selector (parser
);
11777 tree list
= NULL_TREE
;
11778 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11782 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11784 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
11785 sel
= c_parser_objc_selector (parser
);
11786 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11792 /* Parse an objc-receiver.
11801 c_parser_objc_receiver (c_parser
*parser
)
11803 location_t loc
= c_parser_peek_token (parser
)->location
;
11805 if (c_parser_peek_token (parser
)->type
== CPP_NAME
11806 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
11807 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
11809 tree id
= c_parser_peek_token (parser
)->value
;
11810 c_parser_consume_token (parser
);
11811 return objc_get_class_reference (id
);
11813 struct c_expr ce
= c_parser_expression (parser
);
11814 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
11815 return c_fully_fold (ce
.value
, false, NULL
);
11818 /* Parse objc-message-args.
11822 objc-keywordarg-list
11824 objc-keywordarg-list:
11826 objc-keywordarg-list objc-keywordarg
11829 objc-selector : objc-keywordexpr
11834 c_parser_objc_message_args (c_parser
*parser
)
11836 tree sel
= c_parser_objc_selector (parser
);
11837 tree list
= NULL_TREE
;
11838 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11843 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11844 return error_mark_node
;
11845 keywordexpr
= c_parser_objc_keywordexpr (parser
);
11846 list
= chainon (list
, build_tree_list (sel
, keywordexpr
));
11847 sel
= c_parser_objc_selector (parser
);
11848 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11854 /* Parse an objc-keywordexpr.
11861 c_parser_objc_keywordexpr (c_parser
*parser
)
11864 vec
<tree
, va_gc
> *expr_list
= c_parser_expr_list (parser
, true, true,
11865 NULL
, NULL
, NULL
, NULL
);
11866 if (vec_safe_length (expr_list
) == 1)
11868 /* Just return the expression, remove a level of
11870 ret
= (*expr_list
)[0];
11874 /* We have a comma expression, we will collapse later. */
11875 ret
= build_tree_list_vec (expr_list
);
11877 release_tree_vector (expr_list
);
11881 /* A check, needed in several places, that ObjC interface, implementation or
11882 method definitions are not prefixed by incorrect items. */
11884 c_parser_objc_diagnose_bad_element_prefix (c_parser
*parser
,
11885 struct c_declspecs
*specs
)
11887 if (!specs
->declspecs_seen_p
|| specs
->non_sc_seen_p
11888 || specs
->typespec_kind
!= ctsk_none
)
11890 c_parser_error (parser
,
11891 "no type or storage class may be specified here,");
11892 c_parser_skip_to_end_of_block_or_statement (parser
);
11898 /* Parse an Objective-C @property declaration. The syntax is:
11900 objc-property-declaration:
11901 '@property' objc-property-attributes[opt] struct-declaration ;
11903 objc-property-attributes:
11904 '(' objc-property-attribute-list ')'
11906 objc-property-attribute-list:
11907 objc-property-attribute
11908 objc-property-attribute-list, objc-property-attribute
11910 objc-property-attribute
11911 'getter' = identifier
11912 'setter' = identifier
11921 @property NSString *name;
11922 @property (readonly) id object;
11923 @property (retain, nonatomic, getter=getTheName) id name;
11924 @property int a, b, c;
11926 PS: This function is identical to cp_parser_objc_at_propery_declaration
11927 for C++. Keep them in sync. */
11929 c_parser_objc_at_property_declaration (c_parser
*parser
)
11931 /* The following variables hold the attributes of the properties as
11932 parsed. They are 'false' or 'NULL_TREE' if the attribute was not
11933 seen. When we see an attribute, we set them to 'true' (if they
11934 are boolean properties) or to the identifier (if they have an
11935 argument, ie, for getter and setter). Note that here we only
11936 parse the list of attributes, check the syntax and accumulate the
11937 attributes that we find. objc_add_property_declaration() will
11938 then process the information. */
11939 bool property_assign
= false;
11940 bool property_copy
= false;
11941 tree property_getter_ident
= NULL_TREE
;
11942 bool property_nonatomic
= false;
11943 bool property_readonly
= false;
11944 bool property_readwrite
= false;
11945 bool property_retain
= false;
11946 tree property_setter_ident
= NULL_TREE
;
11948 /* 'properties' is the list of properties that we read. Usually a
11949 single one, but maybe more (eg, in "@property int a, b, c;" there
11954 loc
= c_parser_peek_token (parser
)->location
;
11955 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
));
11957 c_parser_consume_token (parser
); /* Eat '@property'. */
11959 /* Parse the optional attribute list... */
11960 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11962 matching_parens parens
;
11965 parens
.consume_open (parser
);
11967 /* Property attribute keywords are valid now. */
11968 parser
->objc_property_attr_context
= true;
11972 bool syntax_error
= false;
11973 c_token
*token
= c_parser_peek_token (parser
);
11976 if (token
->type
!= CPP_KEYWORD
)
11978 if (token
->type
== CPP_CLOSE_PAREN
)
11979 c_parser_error (parser
, "expected identifier");
11982 c_parser_consume_token (parser
);
11983 c_parser_error (parser
, "unknown property attribute");
11987 keyword
= token
->keyword
;
11988 c_parser_consume_token (parser
);
11991 case RID_ASSIGN
: property_assign
= true; break;
11992 case RID_COPY
: property_copy
= true; break;
11993 case RID_NONATOMIC
: property_nonatomic
= true; break;
11994 case RID_READONLY
: property_readonly
= true; break;
11995 case RID_READWRITE
: property_readwrite
= true; break;
11996 case RID_RETAIN
: property_retain
= true; break;
12000 if (c_parser_next_token_is_not (parser
, CPP_EQ
))
12002 if (keyword
== RID_GETTER
)
12003 c_parser_error (parser
,
12004 "missing %<=%> (after %<getter%> attribute)");
12006 c_parser_error (parser
,
12007 "missing %<=%> (after %<setter%> attribute)");
12008 syntax_error
= true;
12011 c_parser_consume_token (parser
); /* eat the = */
12012 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12014 c_parser_error (parser
, "expected identifier");
12015 syntax_error
= true;
12018 if (keyword
== RID_SETTER
)
12020 if (property_setter_ident
!= NULL_TREE
)
12021 c_parser_error (parser
, "the %<setter%> attribute may only be specified once");
12023 property_setter_ident
= c_parser_peek_token (parser
)->value
;
12024 c_parser_consume_token (parser
);
12025 if (c_parser_next_token_is_not (parser
, CPP_COLON
))
12026 c_parser_error (parser
, "setter name must terminate with %<:%>");
12028 c_parser_consume_token (parser
);
12032 if (property_getter_ident
!= NULL_TREE
)
12033 c_parser_error (parser
, "the %<getter%> attribute may only be specified once");
12035 property_getter_ident
= c_parser_peek_token (parser
)->value
;
12036 c_parser_consume_token (parser
);
12040 c_parser_error (parser
, "unknown property attribute");
12041 syntax_error
= true;
12048 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12049 c_parser_consume_token (parser
);
12053 parser
->objc_property_attr_context
= false;
12054 parens
.skip_until_found_close (parser
);
12056 /* ... and the property declaration(s). */
12057 properties
= c_parser_struct_declaration (parser
);
12059 if (properties
== error_mark_node
)
12061 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12062 parser
->error
= false;
12066 if (properties
== NULL_TREE
)
12067 c_parser_error (parser
, "expected identifier");
12070 /* Comma-separated properties are chained together in
12071 reverse order; add them one by one. */
12072 properties
= nreverse (properties
);
12074 for (; properties
; properties
= TREE_CHAIN (properties
))
12075 objc_add_property_declaration (loc
, copy_node (properties
),
12076 property_readonly
, property_readwrite
,
12077 property_assign
, property_retain
,
12078 property_copy
, property_nonatomic
,
12079 property_getter_ident
, property_setter_ident
);
12082 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12083 parser
->error
= false;
12086 /* Parse an Objective-C @synthesize declaration. The syntax is:
12088 objc-synthesize-declaration:
12089 @synthesize objc-synthesize-identifier-list ;
12091 objc-synthesize-identifier-list:
12092 objc-synthesize-identifier
12093 objc-synthesize-identifier-list, objc-synthesize-identifier
12095 objc-synthesize-identifier
12097 identifier = identifier
12100 @synthesize MyProperty;
12101 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12103 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12104 for C++. Keep them in sync.
12107 c_parser_objc_at_synthesize_declaration (c_parser
*parser
)
12109 tree list
= NULL_TREE
;
12111 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNTHESIZE
));
12112 loc
= c_parser_peek_token (parser
)->location
;
12114 c_parser_consume_token (parser
);
12117 tree property
, ivar
;
12118 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12120 c_parser_error (parser
, "expected identifier");
12121 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12122 /* Once we find the semicolon, we can resume normal parsing.
12123 We have to reset parser->error manually because
12124 c_parser_skip_until_found() won't reset it for us if the
12125 next token is precisely a semicolon. */
12126 parser
->error
= false;
12129 property
= c_parser_peek_token (parser
)->value
;
12130 c_parser_consume_token (parser
);
12131 if (c_parser_next_token_is (parser
, CPP_EQ
))
12133 c_parser_consume_token (parser
);
12134 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12136 c_parser_error (parser
, "expected identifier");
12137 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12138 parser
->error
= false;
12141 ivar
= c_parser_peek_token (parser
)->value
;
12142 c_parser_consume_token (parser
);
12146 list
= chainon (list
, build_tree_list (ivar
, property
));
12147 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12148 c_parser_consume_token (parser
);
12152 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12153 objc_add_synthesize_declaration (loc
, list
);
12156 /* Parse an Objective-C @dynamic declaration. The syntax is:
12158 objc-dynamic-declaration:
12159 @dynamic identifier-list ;
12162 @dynamic MyProperty;
12163 @dynamic MyProperty, AnotherProperty;
12165 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12166 for C++. Keep them in sync.
12169 c_parser_objc_at_dynamic_declaration (c_parser
*parser
)
12171 tree list
= NULL_TREE
;
12173 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_DYNAMIC
));
12174 loc
= c_parser_peek_token (parser
)->location
;
12176 c_parser_consume_token (parser
);
12180 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12182 c_parser_error (parser
, "expected identifier");
12183 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12184 parser
->error
= false;
12187 property
= c_parser_peek_token (parser
)->value
;
12188 list
= chainon (list
, build_tree_list (NULL_TREE
, property
));
12189 c_parser_consume_token (parser
);
12190 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12191 c_parser_consume_token (parser
);
12195 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12196 objc_add_dynamic_declaration (loc
, list
);
12200 /* Parse a pragma GCC ivdep. */
12203 c_parse_pragma_ivdep (c_parser
*parser
)
12205 c_parser_consume_pragma (parser
);
12206 c_parser_skip_to_pragma_eol (parser
);
12210 /* Parse a pragma GCC unroll. */
12212 static unsigned short
12213 c_parser_pragma_unroll (c_parser
*parser
)
12215 unsigned short unroll
;
12216 c_parser_consume_pragma (parser
);
12217 location_t location
= c_parser_peek_token (parser
)->location
;
12218 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
12219 mark_exp_read (expr
);
12220 expr
= c_fully_fold (expr
, false, NULL
);
12221 HOST_WIDE_INT lunroll
= 0;
12222 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
12223 || TREE_CODE (expr
) != INTEGER_CST
12224 || (lunroll
= tree_to_shwi (expr
)) < 0
12225 || lunroll
>= USHRT_MAX
)
12227 error_at (location
, "%<#pragma GCC unroll%> requires an"
12228 " assignment-expression that evaluates to a non-negative"
12229 " integral constant less than %u", USHRT_MAX
);
12234 unroll
= (unsigned short)lunroll
;
12239 c_parser_skip_to_pragma_eol (parser
);
12243 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12244 should be considered, statements. ALLOW_STMT is true if we're within
12245 the context of a function and such pragmas are to be allowed. Returns
12246 true if we actually parsed such a pragma. */
12249 c_parser_pragma (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
12252 const char *construct
= NULL
;
12254 id
= c_parser_peek_token (parser
)->pragma_kind
;
12255 gcc_assert (id
!= PRAGMA_NONE
);
12259 case PRAGMA_OACC_DECLARE
:
12260 c_parser_oacc_declare (parser
);
12263 case PRAGMA_OACC_ENTER_DATA
:
12264 if (context
!= pragma_compound
)
12266 construct
= "acc enter data";
12268 if (context
== pragma_stmt
)
12270 error_at (c_parser_peek_token (parser
)->location
,
12271 "%<#pragma %s%> may only be used in compound "
12272 "statements", construct
);
12273 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12278 c_parser_oacc_enter_exit_data (parser
, true);
12281 case PRAGMA_OACC_EXIT_DATA
:
12282 if (context
!= pragma_compound
)
12284 construct
= "acc exit data";
12287 c_parser_oacc_enter_exit_data (parser
, false);
12290 case PRAGMA_OACC_ROUTINE
:
12291 if (context
!= pragma_external
)
12293 error_at (c_parser_peek_token (parser
)->location
,
12294 "%<#pragma acc routine%> must be at file scope");
12295 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12298 c_parser_oacc_routine (parser
, context
);
12301 case PRAGMA_OACC_UPDATE
:
12302 if (context
!= pragma_compound
)
12304 construct
= "acc update";
12307 c_parser_oacc_update (parser
);
12310 case PRAGMA_OMP_BARRIER
:
12311 if (context
!= pragma_compound
)
12313 construct
= "omp barrier";
12316 c_parser_omp_barrier (parser
);
12319 case PRAGMA_OMP_DEPOBJ
:
12320 if (context
!= pragma_compound
)
12322 construct
= "omp depobj";
12325 c_parser_omp_depobj (parser
);
12328 case PRAGMA_OMP_FLUSH
:
12329 if (context
!= pragma_compound
)
12331 construct
= "omp flush";
12334 c_parser_omp_flush (parser
);
12337 case PRAGMA_OMP_TASKWAIT
:
12338 if (context
!= pragma_compound
)
12340 construct
= "omp taskwait";
12343 c_parser_omp_taskwait (parser
);
12346 case PRAGMA_OMP_TASKYIELD
:
12347 if (context
!= pragma_compound
)
12349 construct
= "omp taskyield";
12352 c_parser_omp_taskyield (parser
);
12355 case PRAGMA_OMP_CANCEL
:
12356 if (context
!= pragma_compound
)
12358 construct
= "omp cancel";
12361 c_parser_omp_cancel (parser
);
12364 case PRAGMA_OMP_CANCELLATION_POINT
:
12365 c_parser_omp_cancellation_point (parser
, context
);
12368 case PRAGMA_OMP_THREADPRIVATE
:
12369 c_parser_omp_threadprivate (parser
);
12372 case PRAGMA_OMP_TARGET
:
12373 return c_parser_omp_target (parser
, context
, if_p
);
12375 case PRAGMA_OMP_END_DECLARE_TARGET
:
12376 c_parser_omp_end_declare_target (parser
);
12379 case PRAGMA_OMP_SCAN
:
12380 error_at (c_parser_peek_token (parser
)->location
,
12381 "%<#pragma omp scan%> may only be used in "
12382 "a loop construct with %<inscan%> %<reduction%> clause");
12383 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12386 case PRAGMA_OMP_SECTION
:
12387 error_at (c_parser_peek_token (parser
)->location
,
12388 "%<#pragma omp section%> may only be used in "
12389 "%<#pragma omp sections%> construct");
12390 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12393 case PRAGMA_OMP_DECLARE
:
12394 c_parser_omp_declare (parser
, context
);
12397 case PRAGMA_OMP_REQUIRES
:
12398 c_parser_omp_requires (parser
);
12401 case PRAGMA_OMP_ORDERED
:
12402 return c_parser_omp_ordered (parser
, context
, if_p
);
12406 const bool ivdep
= c_parse_pragma_ivdep (parser
);
12407 unsigned short unroll
;
12408 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_UNROLL
)
12409 unroll
= c_parser_pragma_unroll (parser
);
12412 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12413 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12414 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12416 c_parser_error (parser
, "for, while or do statement expected");
12419 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12420 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12421 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12422 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12424 c_parser_do_statement (parser
, ivdep
, unroll
);
12428 case PRAGMA_UNROLL
:
12430 unsigned short unroll
= c_parser_pragma_unroll (parser
);
12432 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_IVDEP
)
12433 ivdep
= c_parse_pragma_ivdep (parser
);
12436 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12437 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12438 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12440 c_parser_error (parser
, "for, while or do statement expected");
12443 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12444 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12445 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12446 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12448 c_parser_do_statement (parser
, ivdep
, unroll
);
12452 case PRAGMA_GCC_PCH_PREPROCESS
:
12453 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
12454 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12457 case PRAGMA_OACC_WAIT
:
12458 if (context
!= pragma_compound
)
12460 construct
= "acc wait";
12463 /* FALL THROUGH. */
12466 if (id
< PRAGMA_FIRST_EXTERNAL
)
12468 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
12471 c_parser_error (parser
, "expected declaration specifiers");
12472 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12475 c_parser_omp_construct (parser
, if_p
);
12481 c_parser_consume_pragma (parser
);
12482 c_invoke_pragma_handler (id
);
12484 /* Skip to EOL, but suppress any error message. Those will have been
12485 generated by the handler routine through calling error, as opposed
12486 to calling c_parser_error. */
12487 parser
->error
= true;
12488 c_parser_skip_to_pragma_eol (parser
);
12493 /* The interface the pragma parsers have to the lexer. */
12496 pragma_lex (tree
*value
, location_t
*loc
)
12498 c_token
*tok
= c_parser_peek_token (the_parser
);
12499 enum cpp_ttype ret
= tok
->type
;
12501 *value
= tok
->value
;
12503 *loc
= tok
->location
;
12505 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
12507 else if (ret
== CPP_STRING
)
12508 *value
= c_parser_string_literal (the_parser
, false, false).value
;
12511 if (ret
== CPP_KEYWORD
)
12513 c_parser_consume_token (the_parser
);
12520 c_parser_pragma_pch_preprocess (c_parser
*parser
)
12524 parser
->lex_joined_string
= true;
12525 c_parser_consume_pragma (parser
);
12526 if (c_parser_next_token_is (parser
, CPP_STRING
))
12528 name
= c_parser_peek_token (parser
)->value
;
12529 c_parser_consume_token (parser
);
12532 c_parser_error (parser
, "expected string literal");
12533 c_parser_skip_to_pragma_eol (parser
);
12534 parser
->lex_joined_string
= false;
12537 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
12540 /* OpenACC and OpenMP parsing routines. */
12542 /* Returns name of the next clause.
12543 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12544 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12545 returned and the token is consumed. */
12547 static pragma_omp_clause
12548 c_parser_omp_clause_name (c_parser
*parser
)
12550 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
12552 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
12553 result
= PRAGMA_OACC_CLAUSE_AUTO
;
12554 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
12555 result
= PRAGMA_OMP_CLAUSE_IF
;
12556 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
12557 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
12558 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12559 result
= PRAGMA_OMP_CLAUSE_FOR
;
12560 else if (c_parser_next_token_is (parser
, CPP_NAME
))
12562 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
12567 if (!strcmp ("aligned", p
))
12568 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
12569 else if (!strcmp ("async", p
))
12570 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
12571 else if (!strcmp ("attach", p
))
12572 result
= PRAGMA_OACC_CLAUSE_ATTACH
;
12575 if (!strcmp ("bind", p
))
12576 result
= PRAGMA_OMP_CLAUSE_BIND
;
12579 if (!strcmp ("collapse", p
))
12580 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
12581 else if (!strcmp ("copy", p
))
12582 result
= PRAGMA_OACC_CLAUSE_COPY
;
12583 else if (!strcmp ("copyin", p
))
12584 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
12585 else if (!strcmp ("copyout", p
))
12586 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12587 else if (!strcmp ("copyprivate", p
))
12588 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
12589 else if (!strcmp ("create", p
))
12590 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12593 if (!strcmp ("defaultmap", p
))
12594 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
12595 else if (!strcmp ("delete", p
))
12596 result
= PRAGMA_OACC_CLAUSE_DELETE
;
12597 else if (!strcmp ("depend", p
))
12598 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
12599 else if (!strcmp ("detach", p
))
12600 result
= PRAGMA_OACC_CLAUSE_DETACH
;
12601 else if (!strcmp ("device", p
))
12602 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
12603 else if (!strcmp ("deviceptr", p
))
12604 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
12605 else if (!strcmp ("device_resident", p
))
12606 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
12607 else if (!strcmp ("device_type", p
))
12608 result
= PRAGMA_OMP_CLAUSE_DEVICE_TYPE
;
12609 else if (!strcmp ("dist_schedule", p
))
12610 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
12613 if (!strcmp ("final", p
))
12614 result
= PRAGMA_OMP_CLAUSE_FINAL
;
12615 else if (!strcmp ("finalize", p
))
12616 result
= PRAGMA_OACC_CLAUSE_FINALIZE
;
12617 else if (!strcmp ("firstprivate", p
))
12618 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
12619 else if (!strcmp ("from", p
))
12620 result
= PRAGMA_OMP_CLAUSE_FROM
;
12623 if (!strcmp ("gang", p
))
12624 result
= PRAGMA_OACC_CLAUSE_GANG
;
12625 else if (!strcmp ("grainsize", p
))
12626 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
12629 if (!strcmp ("hint", p
))
12630 result
= PRAGMA_OMP_CLAUSE_HINT
;
12631 else if (!strcmp ("host", p
))
12632 result
= PRAGMA_OACC_CLAUSE_HOST
;
12635 if (!strcmp ("if_present", p
))
12636 result
= PRAGMA_OACC_CLAUSE_IF_PRESENT
;
12637 else if (!strcmp ("in_reduction", p
))
12638 result
= PRAGMA_OMP_CLAUSE_IN_REDUCTION
;
12639 else if (!strcmp ("inbranch", p
))
12640 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
12641 else if (!strcmp ("independent", p
))
12642 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
12643 else if (!strcmp ("is_device_ptr", p
))
12644 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
12647 if (!strcmp ("lastprivate", p
))
12648 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
12649 else if (!strcmp ("linear", p
))
12650 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
12651 else if (!strcmp ("link", p
))
12652 result
= PRAGMA_OMP_CLAUSE_LINK
;
12655 if (!strcmp ("map", p
))
12656 result
= PRAGMA_OMP_CLAUSE_MAP
;
12657 else if (!strcmp ("mergeable", p
))
12658 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
12661 if (!strcmp ("no_create", p
))
12662 result
= PRAGMA_OACC_CLAUSE_NO_CREATE
;
12663 else if (!strcmp ("nogroup", p
))
12664 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
12665 else if (!strcmp ("nontemporal", p
))
12666 result
= PRAGMA_OMP_CLAUSE_NONTEMPORAL
;
12667 else if (!strcmp ("notinbranch", p
))
12668 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
12669 else if (!strcmp ("nowait", p
))
12670 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
12671 else if (!strcmp ("num_gangs", p
))
12672 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
12673 else if (!strcmp ("num_tasks", p
))
12674 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
12675 else if (!strcmp ("num_teams", p
))
12676 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
12677 else if (!strcmp ("num_threads", p
))
12678 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
12679 else if (!strcmp ("num_workers", p
))
12680 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
12683 if (!strcmp ("ordered", p
))
12684 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
12685 else if (!strcmp ("order", p
))
12686 result
= PRAGMA_OMP_CLAUSE_ORDER
;
12689 if (!strcmp ("parallel", p
))
12690 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
12691 else if (!strcmp ("present", p
))
12692 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
12693 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12695 else if (!strcmp ("present_or_copy", p
)
12696 || !strcmp ("pcopy", p
))
12697 result
= PRAGMA_OACC_CLAUSE_COPY
;
12698 else if (!strcmp ("present_or_copyin", p
)
12699 || !strcmp ("pcopyin", p
))
12700 result
= PRAGMA_OACC_CLAUSE_COPYIN
;
12701 else if (!strcmp ("present_or_copyout", p
)
12702 || !strcmp ("pcopyout", p
))
12703 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12704 else if (!strcmp ("present_or_create", p
)
12705 || !strcmp ("pcreate", p
))
12706 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12707 else if (!strcmp ("priority", p
))
12708 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
12709 else if (!strcmp ("private", p
))
12710 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
12711 else if (!strcmp ("proc_bind", p
))
12712 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
12715 if (!strcmp ("reduction", p
))
12716 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
12719 if (!strcmp ("safelen", p
))
12720 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
12721 else if (!strcmp ("schedule", p
))
12722 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
12723 else if (!strcmp ("sections", p
))
12724 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
12725 else if (!strcmp ("self", p
)) /* "self" is a synonym for "host". */
12726 result
= PRAGMA_OACC_CLAUSE_HOST
;
12727 else if (!strcmp ("seq", p
))
12728 result
= PRAGMA_OACC_CLAUSE_SEQ
;
12729 else if (!strcmp ("shared", p
))
12730 result
= PRAGMA_OMP_CLAUSE_SHARED
;
12731 else if (!strcmp ("simd", p
))
12732 result
= PRAGMA_OMP_CLAUSE_SIMD
;
12733 else if (!strcmp ("simdlen", p
))
12734 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
12737 if (!strcmp ("task_reduction", p
))
12738 result
= PRAGMA_OMP_CLAUSE_TASK_REDUCTION
;
12739 else if (!strcmp ("taskgroup", p
))
12740 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
12741 else if (!strcmp ("thread_limit", p
))
12742 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
12743 else if (!strcmp ("threads", p
))
12744 result
= PRAGMA_OMP_CLAUSE_THREADS
;
12745 else if (!strcmp ("tile", p
))
12746 result
= PRAGMA_OACC_CLAUSE_TILE
;
12747 else if (!strcmp ("to", p
))
12748 result
= PRAGMA_OMP_CLAUSE_TO
;
12751 if (!strcmp ("uniform", p
))
12752 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
12753 else if (!strcmp ("untied", p
))
12754 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
12755 else if (!strcmp ("use_device", p
))
12756 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
12757 else if (!strcmp ("use_device_addr", p
))
12758 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
;
12759 else if (!strcmp ("use_device_ptr", p
))
12760 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
12763 if (!strcmp ("vector", p
))
12764 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
12765 else if (!strcmp ("vector_length", p
))
12766 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
12769 if (!strcmp ("wait", p
))
12770 result
= PRAGMA_OACC_CLAUSE_WAIT
;
12771 else if (!strcmp ("worker", p
))
12772 result
= PRAGMA_OACC_CLAUSE_WORKER
;
12777 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
12778 c_parser_consume_token (parser
);
12783 /* Validate that a clause of the given type does not already exist. */
12786 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
12789 if (tree c
= omp_find_clause (clauses
, code
))
12790 error_at (OMP_CLAUSE_LOCATION (c
), "too many %qs clauses", name
);
12794 Parse wait clause or wait directive parameters. */
12797 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
12799 vec
<tree
, va_gc
> *args
;
12802 matching_parens parens
;
12803 if (!parens
.require_open (parser
))
12806 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
12807 args_tree
= build_tree_list_vec (args
);
12809 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
12811 tree targ
= TREE_VALUE (t
);
12813 if (targ
!= error_mark_node
)
12815 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
12817 c_parser_error (parser
, "expression must be integral");
12818 targ
= error_mark_node
;
12822 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
12824 OMP_CLAUSE_DECL (c
) = targ
;
12825 OMP_CLAUSE_CHAIN (c
) = list
;
12831 release_tree_vector (args
);
12832 parens
.require_close (parser
);
12836 /* OpenACC 2.0, OpenMP 2.5:
12839 variable-list , identifier
12841 If KIND is nonzero, create the appropriate node and install the
12842 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
12843 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
12845 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
12846 return the list created.
12848 The optional ALLOW_DEREF argument is true if list items can use the deref
12852 c_parser_omp_variable_list (c_parser
*parser
,
12853 location_t clause_loc
,
12854 enum omp_clause_code kind
, tree list
,
12855 bool allow_deref
= false)
12857 auto_vec
<c_token
> tokens
;
12858 unsigned int tokens_avail
= 0;
12863 bool array_section_p
= false;
12864 if (kind
== OMP_CLAUSE_DEPEND
)
12866 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
12867 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
12869 struct c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
12870 if (expr
.value
!= error_mark_node
)
12872 tree u
= build_omp_clause (clause_loc
, kind
);
12873 OMP_CLAUSE_DECL (u
) = expr
.value
;
12874 OMP_CLAUSE_CHAIN (u
) = list
;
12878 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
12881 c_parser_consume_token (parser
);
12886 tokens
.truncate (0);
12887 unsigned int nesting_depth
= 0;
12890 c_token
*token
= c_parser_peek_token (parser
);
12891 switch (token
->type
)
12894 case CPP_PRAGMA_EOL
:
12896 case CPP_OPEN_BRACE
:
12897 case CPP_OPEN_PAREN
:
12898 case CPP_OPEN_SQUARE
:
12901 case CPP_CLOSE_BRACE
:
12902 case CPP_CLOSE_PAREN
:
12903 case CPP_CLOSE_SQUARE
:
12904 if (nesting_depth
-- == 0)
12908 if (nesting_depth
== 0)
12913 tokens
.safe_push (*token
);
12914 c_parser_consume_token (parser
);
12920 /* Make sure nothing tries to read past the end of the tokens. */
12922 memset (&eof_token
, 0, sizeof (eof_token
));
12923 eof_token
.type
= CPP_EOF
;
12924 tokens
.safe_push (eof_token
);
12925 tokens
.safe_push (eof_token
);
12927 tokens_avail
= parser
->tokens_avail
;
12928 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
12929 parser
->tokens
= tokens
.address ();
12930 parser
->tokens_avail
= tokens
.length ();
12933 tree t
= NULL_TREE
;
12935 if (c_parser_next_token_is (parser
, CPP_NAME
)
12936 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
12938 t
= lookup_name (c_parser_peek_token (parser
)->value
);
12940 if (t
== NULL_TREE
)
12942 undeclared_variable (c_parser_peek_token (parser
)->location
,
12943 c_parser_peek_token (parser
)->value
);
12944 t
= error_mark_node
;
12947 c_parser_consume_token (parser
);
12949 else if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
12950 && (c_parser_peek_token (parser
)->keyword
== RID_FUNCTION_NAME
12951 || (c_parser_peek_token (parser
)->keyword
12952 == RID_PRETTY_FUNCTION_NAME
)
12953 || (c_parser_peek_token (parser
)->keyword
12954 == RID_C99_FUNCTION_NAME
)))
12955 t
= c_parser_predefined_identifier (parser
).value
;
12959 c_parser_error (parser
, "expected identifier");
12963 if (t
== error_mark_node
)
12965 else if (kind
!= 0)
12969 case OMP_CLAUSE__CACHE_
:
12970 /* The OpenACC cache directive explicitly only allows "array
12971 elements or subarrays". */
12972 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
12974 c_parser_error (parser
, "expected %<[%>");
12975 t
= error_mark_node
;
12979 case OMP_CLAUSE_MAP
:
12980 case OMP_CLAUSE_FROM
:
12981 case OMP_CLAUSE_TO
:
12982 while (c_parser_next_token_is (parser
, CPP_DOT
)
12984 && c_parser_next_token_is (parser
, CPP_DEREF
)))
12986 location_t op_loc
= c_parser_peek_token (parser
)->location
;
12987 if (c_parser_next_token_is (parser
, CPP_DEREF
))
12988 t
= build_simple_mem_ref (t
);
12989 c_parser_consume_token (parser
);
12990 if (!c_parser_next_token_is (parser
, CPP_NAME
))
12992 c_parser_error (parser
, "expected identifier");
12993 t
= error_mark_node
;
12997 c_token
*comp_tok
= c_parser_peek_token (parser
);
12998 tree ident
= comp_tok
->value
;
12999 location_t comp_loc
= comp_tok
->location
;
13000 c_parser_consume_token (parser
);
13001 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
);
13004 case OMP_CLAUSE_DEPEND
:
13005 case OMP_CLAUSE_REDUCTION
:
13006 case OMP_CLAUSE_IN_REDUCTION
:
13007 case OMP_CLAUSE_TASK_REDUCTION
:
13008 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
13010 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
13012 c_parser_consume_token (parser
);
13013 if (!c_parser_next_token_is (parser
, CPP_COLON
))
13015 location_t expr_loc
13016 = c_parser_peek_token (parser
)->location
;
13017 c_expr expr
= c_parser_expression (parser
);
13018 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13020 low_bound
= expr
.value
;
13022 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13023 length
= integer_one_node
;
13026 /* Look for `:'. */
13027 if (!c_parser_require (parser
, CPP_COLON
,
13030 t
= error_mark_node
;
13033 array_section_p
= true;
13034 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13036 location_t expr_loc
13037 = c_parser_peek_token (parser
)->location
;
13038 c_expr expr
= c_parser_expression (parser
);
13039 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13041 length
= expr
.value
;
13044 /* Look for the closing `]'. */
13045 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
13048 t
= error_mark_node
;
13052 t
= tree_cons (low_bound
, length
, t
);
13054 if (kind
== OMP_CLAUSE_DEPEND
13055 && t
!= error_mark_node
13056 && parser
->tokens_avail
!= 2)
13058 if (array_section_p
)
13060 error_at (c_parser_peek_token (parser
)->location
,
13061 "expected %<)%> or %<,%>");
13062 t
= error_mark_node
;
13066 parser
->tokens
= tokens
.address ();
13067 parser
->tokens_avail
= tokens
.length ();
13069 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
13070 if (t
!= error_mark_node
&& parser
->tokens_avail
!= 2)
13072 error_at (c_parser_peek_token (parser
)->location
,
13073 "expected %<)%> or %<,%>");
13074 t
= error_mark_node
;
13083 if (t
!= error_mark_node
)
13085 tree u
= build_omp_clause (clause_loc
, kind
);
13086 OMP_CLAUSE_DECL (u
) = t
;
13087 OMP_CLAUSE_CHAIN (u
) = list
;
13092 list
= tree_cons (t
, NULL_TREE
, list
);
13094 if (kind
== OMP_CLAUSE_DEPEND
)
13096 parser
->tokens
= &parser
->tokens_buf
[0];
13097 parser
->tokens_avail
= tokens_avail
;
13099 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
13102 c_parser_consume_token (parser
);
13109 /* Similarly, but expect leading and trailing parenthesis. This is a very
13110 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13111 argument is true if list items can use the deref (->) operator. */
13114 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
13115 tree list
, bool allow_deref
= false)
13117 /* The clauses location. */
13118 location_t loc
= c_parser_peek_token (parser
)->location
;
13120 matching_parens parens
;
13121 if (parens
.require_open (parser
))
13123 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
, allow_deref
);
13124 parens
.skip_until_found_close (parser
);
13130 copy ( variable-list )
13131 copyin ( variable-list )
13132 copyout ( variable-list )
13133 create ( variable-list )
13134 delete ( variable-list )
13135 present ( variable-list )
13138 no_create ( variable-list )
13139 attach ( variable-list )
13140 detach ( variable-list ) */
13143 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
13146 enum gomp_map_kind kind
;
13149 case PRAGMA_OACC_CLAUSE_ATTACH
:
13150 kind
= GOMP_MAP_ATTACH
;
13152 case PRAGMA_OACC_CLAUSE_COPY
:
13153 kind
= GOMP_MAP_TOFROM
;
13155 case PRAGMA_OACC_CLAUSE_COPYIN
:
13156 kind
= GOMP_MAP_TO
;
13158 case PRAGMA_OACC_CLAUSE_COPYOUT
:
13159 kind
= GOMP_MAP_FROM
;
13161 case PRAGMA_OACC_CLAUSE_CREATE
:
13162 kind
= GOMP_MAP_ALLOC
;
13164 case PRAGMA_OACC_CLAUSE_DELETE
:
13165 kind
= GOMP_MAP_RELEASE
;
13167 case PRAGMA_OACC_CLAUSE_DETACH
:
13168 kind
= GOMP_MAP_DETACH
;
13170 case PRAGMA_OACC_CLAUSE_DEVICE
:
13171 kind
= GOMP_MAP_FORCE_TO
;
13173 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
13174 kind
= GOMP_MAP_DEVICE_RESIDENT
;
13176 case PRAGMA_OACC_CLAUSE_HOST
:
13177 kind
= GOMP_MAP_FORCE_FROM
;
13179 case PRAGMA_OACC_CLAUSE_LINK
:
13180 kind
= GOMP_MAP_LINK
;
13182 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
13183 kind
= GOMP_MAP_IF_PRESENT
;
13185 case PRAGMA_OACC_CLAUSE_PRESENT
:
13186 kind
= GOMP_MAP_FORCE_PRESENT
;
13189 gcc_unreachable ();
13192 nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_MAP
, list
, true);
13194 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13195 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
13201 deviceptr ( variable-list ) */
13204 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
13206 location_t loc
= c_parser_peek_token (parser
)->location
;
13209 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13210 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13211 variable-list must only allow for pointer variables. */
13212 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
13213 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
13215 tree v
= TREE_PURPOSE (t
);
13217 /* FIXME diagnostics: Ideally we should keep individual
13218 locations for all the variables in the var list to make the
13219 following errors more precise. Perhaps
13220 c_parser_omp_var_list_parens() should construct a list of
13221 locations to go along with the var list. */
13223 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
13224 error_at (loc
, "%qD is not a variable", v
);
13225 else if (TREE_TYPE (v
) == error_mark_node
)
13227 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
13228 error_at (loc
, "%qD is not a pointer variable", v
);
13230 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
13231 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
13232 OMP_CLAUSE_DECL (u
) = v
;
13233 OMP_CLAUSE_CHAIN (u
) = list
;
13240 /* OpenACC 2.0, OpenMP 3.0:
13241 collapse ( constant-expression ) */
13244 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
13246 tree c
, num
= error_mark_node
;
13250 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
13251 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
13253 loc
= c_parser_peek_token (parser
)->location
;
13254 matching_parens parens
;
13255 if (parens
.require_open (parser
))
13257 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
13258 parens
.skip_until_found_close (parser
);
13260 if (num
== error_mark_node
)
13262 mark_exp_read (num
);
13263 num
= c_fully_fold (num
, false, NULL
);
13264 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
13265 || !tree_fits_shwi_p (num
)
13266 || (n
= tree_to_shwi (num
)) <= 0
13270 "collapse argument needs positive constant integer expression");
13273 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
13274 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
13275 OMP_CLAUSE_CHAIN (c
) = list
;
13280 copyin ( variable-list ) */
13283 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
13285 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
13289 copyprivate ( variable-list ) */
13292 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
13294 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
13298 default ( none | shared )
13301 default ( none | present ) */
13304 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
13306 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
13307 location_t loc
= c_parser_peek_token (parser
)->location
;
13310 matching_parens parens
;
13311 if (!parens
.require_open (parser
))
13313 if (c_parser_next_token_is (parser
, CPP_NAME
))
13315 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13320 if (strcmp ("none", p
) != 0)
13322 kind
= OMP_CLAUSE_DEFAULT_NONE
;
13326 if (strcmp ("present", p
) != 0 || !is_oacc
)
13328 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
13332 if (strcmp ("shared", p
) != 0 || is_oacc
)
13334 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
13341 c_parser_consume_token (parser
);
13347 c_parser_error (parser
, "expected %<none%> or %<present%>");
13349 c_parser_error (parser
, "expected %<none%> or %<shared%>");
13351 parens
.skip_until_found_close (parser
);
13353 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
13356 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
13357 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
13358 OMP_CLAUSE_CHAIN (c
) = list
;
13359 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
13365 firstprivate ( variable-list ) */
13368 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
13370 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
13374 final ( expression ) */
13377 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
13379 location_t loc
= c_parser_peek_token (parser
)->location
;
13380 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13382 matching_parens parens
;
13384 if (!parens
.require_open (parser
))
13385 t
= error_mark_node
;
13388 location_t eloc
= c_parser_peek_token (parser
)->location
;
13389 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13390 t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
13391 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
13392 t
= c_fully_fold (t
, false, NULL
);
13393 parens
.skip_until_found_close (parser
);
13396 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
13398 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
13399 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
13400 OMP_CLAUSE_CHAIN (c
) = list
;
13404 c_parser_error (parser
, "expected %<(%>");
13409 /* OpenACC, OpenMP 2.5:
13413 if ( directive-name-modifier : expression )
13415 directive-name-modifier:
13416 parallel | task | taskloop | target data | target | target update
13417 | target enter data | target exit data
13420 directive-name-modifier:
13421 ... | simd | cancel */
13424 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
13426 location_t location
= c_parser_peek_token (parser
)->location
;
13427 enum tree_code if_modifier
= ERROR_MARK
;
13429 matching_parens parens
;
13430 if (!parens
.require_open (parser
))
13433 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
13435 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13437 if (strcmp (p
, "cancel") == 0)
13438 if_modifier
= VOID_CST
;
13439 else if (strcmp (p
, "parallel") == 0)
13440 if_modifier
= OMP_PARALLEL
;
13441 else if (strcmp (p
, "simd") == 0)
13442 if_modifier
= OMP_SIMD
;
13443 else if (strcmp (p
, "task") == 0)
13444 if_modifier
= OMP_TASK
;
13445 else if (strcmp (p
, "taskloop") == 0)
13446 if_modifier
= OMP_TASKLOOP
;
13447 else if (strcmp (p
, "target") == 0)
13449 if_modifier
= OMP_TARGET
;
13450 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
13452 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
13453 if (strcmp ("data", p
) == 0)
13454 if_modifier
= OMP_TARGET_DATA
;
13455 else if (strcmp ("update", p
) == 0)
13456 if_modifier
= OMP_TARGET_UPDATE
;
13457 else if (strcmp ("enter", p
) == 0)
13458 if_modifier
= OMP_TARGET_ENTER_DATA
;
13459 else if (strcmp ("exit", p
) == 0)
13460 if_modifier
= OMP_TARGET_EXIT_DATA
;
13461 if (if_modifier
!= OMP_TARGET
)
13464 c_parser_consume_token (parser
);
13468 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
13469 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
13471 if_modifier
= ERROR_MARK
;
13473 if (if_modifier
== OMP_TARGET_ENTER_DATA
13474 || if_modifier
== OMP_TARGET_EXIT_DATA
)
13476 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
13478 p
= IDENTIFIER_POINTER
13479 (c_parser_peek_2nd_token (parser
)->value
);
13480 if (strcmp ("data", p
) == 0)
13484 c_parser_consume_token (parser
);
13488 = c_parser_peek_2nd_token (parser
)->location
;
13489 error_at (loc
, "expected %<data%>");
13490 if_modifier
= ERROR_MARK
;
13495 if (if_modifier
!= ERROR_MARK
)
13497 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13499 c_parser_consume_token (parser
);
13500 c_parser_consume_token (parser
);
13506 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
13507 error_at (loc
, "expected %<:%>");
13509 if_modifier
= ERROR_MARK
;
13514 location_t loc
= c_parser_peek_token (parser
)->location
;
13515 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13516 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
13517 tree t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
), c
;
13518 t
= c_fully_fold (t
, false, NULL
);
13519 parens
.skip_until_found_close (parser
);
13521 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
13522 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
13524 if (if_modifier
!= ERROR_MARK
13525 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
13527 const char *p
= NULL
;
13528 switch (if_modifier
)
13530 case VOID_CST
: p
= "cancel"; break;
13531 case OMP_PARALLEL
: p
= "parallel"; break;
13532 case OMP_SIMD
: p
= "simd"; break;
13533 case OMP_TASK
: p
= "task"; break;
13534 case OMP_TASKLOOP
: p
= "taskloop"; break;
13535 case OMP_TARGET_DATA
: p
= "target data"; break;
13536 case OMP_TARGET
: p
= "target"; break;
13537 case OMP_TARGET_UPDATE
: p
= "target update"; break;
13538 case OMP_TARGET_ENTER_DATA
: p
= "target enter data"; break;
13539 case OMP_TARGET_EXIT_DATA
: p
= "target exit data"; break;
13540 default: gcc_unreachable ();
13542 error_at (location
, "too many %<if%> clauses with %qs modifier",
13546 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
13549 error_at (location
, "too many %<if%> clauses");
13551 error_at (location
, "too many %<if%> clauses without modifier");
13554 else if (if_modifier
== ERROR_MARK
13555 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
13557 error_at (location
, "if any %<if%> clause has modifier, then all "
13558 "%<if%> clauses have to use modifier");
13563 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
13564 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
13565 OMP_CLAUSE_IF_EXPR (c
) = t
;
13566 OMP_CLAUSE_CHAIN (c
) = list
;
13571 lastprivate ( variable-list )
13574 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13577 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
13579 /* The clauses location. */
13580 location_t loc
= c_parser_peek_token (parser
)->location
;
13582 if (c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
13584 bool conditional
= false;
13585 if (c_parser_next_token_is (parser
, CPP_NAME
)
13586 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13589 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13590 if (strcmp (p
, "conditional") == 0)
13592 conditional
= true;
13593 c_parser_consume_token (parser
);
13594 c_parser_consume_token (parser
);
13597 tree nlist
= c_parser_omp_variable_list (parser
, loc
,
13598 OMP_CLAUSE_LASTPRIVATE
, list
);
13599 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
13601 for (tree c
= nlist
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13602 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 1;
13612 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13616 /* FIXME: Should we allow duplicates? */
13617 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
13619 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
13620 OMP_CLAUSE_MERGEABLE
);
13621 OMP_CLAUSE_CHAIN (c
) = list
;
13630 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13633 location_t loc
= c_parser_peek_token (parser
)->location
;
13635 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
13637 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
13638 OMP_CLAUSE_CHAIN (c
) = list
;
13643 num_threads ( expression ) */
13646 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
13648 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
13649 matching_parens parens
;
13650 if (parens
.require_open (parser
))
13652 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13653 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13654 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13655 tree c
, t
= expr
.value
;
13656 t
= c_fully_fold (t
, false, NULL
);
13658 parens
.skip_until_found_close (parser
);
13660 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13662 c_parser_error (parser
, "expected integer expression");
13666 /* Attempt to statically determine when the number isn't positive. */
13667 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13668 build_int_cst (TREE_TYPE (t
), 0));
13669 protected_set_expr_location (c
, expr_loc
);
13670 if (c
== boolean_true_node
)
13672 warning_at (expr_loc
, 0,
13673 "%<num_threads%> value must be positive");
13674 t
= integer_one_node
;
13677 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
13679 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
13680 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
13681 OMP_CLAUSE_CHAIN (c
) = list
;
13689 num_tasks ( expression ) */
13692 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
13694 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
13695 matching_parens parens
;
13696 if (parens
.require_open (parser
))
13698 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13699 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13700 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13701 tree c
, t
= expr
.value
;
13702 t
= c_fully_fold (t
, false, NULL
);
13704 parens
.skip_until_found_close (parser
);
13706 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13708 c_parser_error (parser
, "expected integer expression");
13712 /* Attempt to statically determine when the number isn't positive. */
13713 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13714 build_int_cst (TREE_TYPE (t
), 0));
13715 if (CAN_HAVE_LOCATION_P (c
))
13716 SET_EXPR_LOCATION (c
, expr_loc
);
13717 if (c
== boolean_true_node
)
13719 warning_at (expr_loc
, 0, "%<num_tasks%> value must be positive");
13720 t
= integer_one_node
;
13723 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
13725 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
13726 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
13727 OMP_CLAUSE_CHAIN (c
) = list
;
13735 grainsize ( expression ) */
13738 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
13740 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
13741 matching_parens parens
;
13742 if (parens
.require_open (parser
))
13744 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13745 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13746 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13747 tree c
, t
= expr
.value
;
13748 t
= c_fully_fold (t
, false, NULL
);
13750 parens
.skip_until_found_close (parser
);
13752 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13754 c_parser_error (parser
, "expected integer expression");
13758 /* Attempt to statically determine when the number isn't positive. */
13759 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13760 build_int_cst (TREE_TYPE (t
), 0));
13761 if (CAN_HAVE_LOCATION_P (c
))
13762 SET_EXPR_LOCATION (c
, expr_loc
);
13763 if (c
== boolean_true_node
)
13765 warning_at (expr_loc
, 0, "%<grainsize%> value must be positive");
13766 t
= integer_one_node
;
13769 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
13771 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
13772 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
13773 OMP_CLAUSE_CHAIN (c
) = list
;
13781 priority ( expression ) */
13784 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
13786 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
13787 matching_parens parens
;
13788 if (parens
.require_open (parser
))
13790 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13791 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13792 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13793 tree c
, t
= expr
.value
;
13794 t
= c_fully_fold (t
, false, NULL
);
13796 parens
.skip_until_found_close (parser
);
13798 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13800 c_parser_error (parser
, "expected integer expression");
13804 /* Attempt to statically determine when the number isn't
13806 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
13807 build_int_cst (TREE_TYPE (t
), 0));
13808 if (CAN_HAVE_LOCATION_P (c
))
13809 SET_EXPR_LOCATION (c
, expr_loc
);
13810 if (c
== boolean_true_node
)
13812 warning_at (expr_loc
, 0, "%<priority%> value must be non-negative");
13813 t
= integer_one_node
;
13816 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
13818 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
13819 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
13820 OMP_CLAUSE_CHAIN (c
) = list
;
13828 hint ( expression ) */
13831 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
13833 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
13834 matching_parens parens
;
13835 if (parens
.require_open (parser
))
13837 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13838 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13839 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13840 tree c
, t
= expr
.value
;
13841 t
= c_fully_fold (t
, false, NULL
);
13843 parens
.skip_until_found_close (parser
);
13845 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
13846 || TREE_CODE (t
) != INTEGER_CST
)
13848 c_parser_error (parser
, "expected constant integer expression");
13852 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
13854 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
13855 OMP_CLAUSE_HINT_EXPR (c
) = t
;
13856 OMP_CLAUSE_CHAIN (c
) = list
;
13864 defaultmap ( tofrom : scalar )
13867 defaultmap ( implicit-behavior [ : variable-category ] ) */
13870 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
13872 location_t loc
= c_parser_peek_token (parser
)->location
;
13875 enum omp_clause_defaultmap_kind behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
13876 enum omp_clause_defaultmap_kind category
13877 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
13879 matching_parens parens
;
13880 if (!parens
.require_open (parser
))
13882 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
13884 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
13887 c_parser_error (parser
, "expected %<alloc%>, %<to%>, %<from%>, "
13888 "%<tofrom%>, %<firstprivate%>, %<none%> "
13893 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13898 if (strcmp ("alloc", p
) == 0)
13899 behavior
= OMP_CLAUSE_DEFAULTMAP_ALLOC
;
13901 goto invalid_behavior
;
13905 if (strcmp ("default", p
) == 0)
13906 behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
13908 goto invalid_behavior
;
13912 if (strcmp ("firstprivate", p
) == 0)
13913 behavior
= OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
13914 else if (strcmp ("from", p
) == 0)
13915 behavior
= OMP_CLAUSE_DEFAULTMAP_FROM
;
13917 goto invalid_behavior
;
13921 if (strcmp ("none", p
) == 0)
13922 behavior
= OMP_CLAUSE_DEFAULTMAP_NONE
;
13924 goto invalid_behavior
;
13928 if (strcmp ("tofrom", p
) == 0)
13929 behavior
= OMP_CLAUSE_DEFAULTMAP_TOFROM
;
13930 else if (strcmp ("to", p
) == 0)
13931 behavior
= OMP_CLAUSE_DEFAULTMAP_TO
;
13933 goto invalid_behavior
;
13937 goto invalid_behavior
;
13939 c_parser_consume_token (parser
);
13941 if (!c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
13943 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
13945 if (!c_parser_next_token_is (parser
, CPP_NAME
))
13948 c_parser_error (parser
, "expected %<scalar%>, %<aggregate%> or "
13952 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13956 if (strcmp ("aggregate", p
) == 0)
13957 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
;
13959 goto invalid_category
;
13963 if (strcmp ("pointer", p
) == 0)
13964 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
;
13966 goto invalid_category
;
13970 if (strcmp ("scalar", p
) == 0)
13971 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
;
13973 goto invalid_category
;
13977 goto invalid_category
;
13980 c_parser_consume_token (parser
);
13982 parens
.skip_until_found_close (parser
);
13984 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
13985 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEFAULTMAP
13986 && (category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
13987 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
) == category
13988 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
13989 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)))
13991 enum omp_clause_defaultmap_kind cat
= category
;
13992 location_t loc
= OMP_CLAUSE_LOCATION (c
);
13993 if (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
13994 cat
= OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
);
13998 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
14001 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
14004 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
14007 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
14011 gcc_unreachable ();
14014 error_at (loc
, "too many %<defaultmap%> clauses with %qs category",
14017 error_at (loc
, "too many %<defaultmap%> clauses with unspecified "
14022 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
14023 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c
, behavior
, category
);
14024 OMP_CLAUSE_CHAIN (c
) = list
;
14028 parens
.skip_until_found_close (parser
);
14033 use_device ( variable-list )
14036 use_device_ptr ( variable-list ) */
14039 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
14041 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
14046 use_device_addr ( variable-list ) */
14049 c_parser_omp_clause_use_device_addr (c_parser
*parser
, tree list
)
14051 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_ADDR
,
14056 is_device_ptr ( variable-list ) */
14059 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
14061 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
14065 num_gangs ( expression )
14066 num_workers ( expression )
14067 vector_length ( expression ) */
14070 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
14073 location_t loc
= c_parser_peek_token (parser
)->location
;
14075 matching_parens parens
;
14076 if (!parens
.require_open (parser
))
14079 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14080 c_expr expr
= c_parser_expression (parser
);
14081 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14082 tree c
, t
= expr
.value
;
14083 t
= c_fully_fold (t
, false, NULL
);
14085 parens
.skip_until_found_close (parser
);
14087 if (t
== error_mark_node
)
14089 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14091 error_at (expr_loc
, "%qs expression must be integral",
14092 omp_clause_code_name
[code
]);
14096 /* Attempt to statically determine when the number isn't positive. */
14097 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14098 build_int_cst (TREE_TYPE (t
), 0));
14099 protected_set_expr_location (c
, expr_loc
);
14100 if (c
== boolean_true_node
)
14102 warning_at (expr_loc
, 0,
14103 "%qs value must be positive",
14104 omp_clause_code_name
[code
]);
14105 t
= integer_one_node
;
14108 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14110 c
= build_omp_clause (loc
, code
);
14111 OMP_CLAUSE_OPERAND (c
, 0) = t
;
14112 OMP_CLAUSE_CHAIN (c
) = list
;
14118 gang [( gang-arg-list )]
14119 worker [( [num:] int-expr )]
14120 vector [( [length:] int-expr )]
14122 where gang-arg is one of:
14127 and size-expr may be:
14134 c_parser_oacc_shape_clause (c_parser
*parser
, location_t loc
,
14135 omp_clause_code kind
,
14136 const char *str
, tree list
)
14138 const char *id
= "num";
14139 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
14141 if (kind
== OMP_CLAUSE_VECTOR
)
14144 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14146 c_parser_consume_token (parser
);
14150 c_token
*next
= c_parser_peek_token (parser
);
14153 /* Gang static argument. */
14154 if (kind
== OMP_CLAUSE_GANG
14155 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
14157 c_parser_consume_token (parser
);
14159 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14160 goto cleanup_error
;
14163 if (ops
[idx
] != NULL_TREE
)
14165 c_parser_error (parser
, "too many %<static%> arguments");
14166 goto cleanup_error
;
14169 /* Check for the '*' argument. */
14170 if (c_parser_next_token_is (parser
, CPP_MULT
)
14171 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14172 || c_parser_peek_2nd_token (parser
)->type
14173 == CPP_CLOSE_PAREN
))
14175 c_parser_consume_token (parser
);
14176 ops
[idx
] = integer_minus_one_node
;
14178 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14180 c_parser_consume_token (parser
);
14187 /* Worker num: argument and vector length: arguments. */
14188 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14189 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
14190 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14192 c_parser_consume_token (parser
); /* id */
14193 c_parser_consume_token (parser
); /* ':' */
14196 /* Now collect the actual argument. */
14197 if (ops
[idx
] != NULL_TREE
)
14199 c_parser_error (parser
, "unexpected argument");
14200 goto cleanup_error
;
14203 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14204 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14205 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14206 tree expr
= cexpr
.value
;
14207 if (expr
== error_mark_node
)
14208 goto cleanup_error
;
14210 expr
= c_fully_fold (expr
, false, NULL
);
14212 /* Attempt to statically determine when the number isn't a
14213 positive integer. */
14215 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
14217 c_parser_error (parser
, "expected integer expression");
14221 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
14222 build_int_cst (TREE_TYPE (expr
), 0));
14223 if (c
== boolean_true_node
)
14225 warning_at (loc
, 0,
14226 "%qs value must be positive", str
);
14227 expr
= integer_one_node
;
14232 if (kind
== OMP_CLAUSE_GANG
14233 && c_parser_next_token_is (parser
, CPP_COMMA
))
14235 c_parser_consume_token (parser
);
14242 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14243 goto cleanup_error
;
14246 check_no_duplicate_clause (list
, kind
, str
);
14248 c
= build_omp_clause (loc
, kind
);
14251 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
14253 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
14254 OMP_CLAUSE_CHAIN (c
) = list
;
14259 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14271 c_parser_oacc_simple_clause (location_t loc
, enum omp_clause_code code
,
14274 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14276 tree c
= build_omp_clause (loc
, code
);
14277 OMP_CLAUSE_CHAIN (c
) = list
;
14283 async [( int-expr )] */
14286 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
14289 location_t loc
= c_parser_peek_token (parser
)->location
;
14291 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14293 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14295 c_parser_consume_token (parser
);
14297 t
= c_parser_expression (parser
).value
;
14298 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14299 c_parser_error (parser
, "expected integer expression");
14300 else if (t
== error_mark_node
14301 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14305 t
= c_fully_fold (t
, false, NULL
);
14307 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
14309 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
14310 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
14311 OMP_CLAUSE_CHAIN (c
) = list
;
14318 tile ( size-expr-list ) */
14321 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
14323 tree c
, expr
= error_mark_node
;
14325 tree tile
= NULL_TREE
;
14327 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
14328 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
14330 loc
= c_parser_peek_token (parser
)->location
;
14331 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
14336 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
14339 if (c_parser_next_token_is (parser
, CPP_MULT
)
14340 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14341 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
14343 c_parser_consume_token (parser
);
14344 expr
= integer_zero_node
;
14348 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14349 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14350 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14351 expr
= cexpr
.value
;
14353 if (expr
== error_mark_node
)
14355 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
14360 expr
= c_fully_fold (expr
, false, NULL
);
14362 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
14363 || !tree_fits_shwi_p (expr
)
14364 || tree_to_shwi (expr
) <= 0)
14366 error_at (expr_loc
, "%<tile%> argument needs positive"
14367 " integral constant");
14368 expr
= integer_zero_node
;
14372 tile
= tree_cons (NULL_TREE
, expr
, tile
);
14374 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
14376 /* Consume the trailing ')'. */
14377 c_parser_consume_token (parser
);
14379 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
14380 tile
= nreverse (tile
);
14381 OMP_CLAUSE_TILE_LIST (c
) = tile
;
14382 OMP_CLAUSE_CHAIN (c
) = list
;
14387 wait [( int-expr-list )] */
14390 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
14392 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14394 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14395 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
14398 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
14400 OMP_CLAUSE_DECL (c
) = build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14401 OMP_CLAUSE_CHAIN (c
) = list
;
14410 order ( concurrent ) */
14413 c_parser_omp_clause_order (c_parser
*parser
, tree list
)
14415 location_t loc
= c_parser_peek_token (parser
)->location
;
14419 matching_parens parens
;
14420 if (!parens
.require_open (parser
))
14422 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14424 c_parser_error (parser
, "expected %<concurrent%>");
14427 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14428 if (strcmp (p
, "concurrent") != 0)
14430 c_parser_error (parser
, "expected %<concurrent%>");
14433 c_parser_consume_token (parser
);
14434 parens
.skip_until_found_close (parser
);
14435 /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */
14436 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDER
);
14437 OMP_CLAUSE_CHAIN (c
) = list
;
14441 parens
.skip_until_found_close (parser
);
14447 bind ( teams | parallel | thread ) */
14450 c_parser_omp_clause_bind (c_parser
*parser
, tree list
)
14452 location_t loc
= c_parser_peek_token (parser
)->location
;
14455 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
14457 matching_parens parens
;
14458 if (!parens
.require_open (parser
))
14460 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14463 c_parser_error (parser
,
14464 "expected %<teams%>, %<parallel%> or %<thread%>");
14465 parens
.skip_until_found_close (parser
);
14468 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14469 if (strcmp (p
, "teams") == 0)
14470 kind
= OMP_CLAUSE_BIND_TEAMS
;
14471 else if (strcmp (p
, "parallel") == 0)
14472 kind
= OMP_CLAUSE_BIND_PARALLEL
;
14473 else if (strcmp (p
, "thread") != 0)
14475 c_parser_consume_token (parser
);
14476 parens
.skip_until_found_close (parser
);
14477 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14478 c
= build_omp_clause (loc
, OMP_CLAUSE_BIND
);
14479 OMP_CLAUSE_BIND_KIND (c
) = kind
;
14480 OMP_CLAUSE_CHAIN (c
) = list
;
14489 ordered ( constant-expression ) */
14492 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
14494 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
14496 tree c
, num
= NULL_TREE
;
14498 location_t loc
= c_parser_peek_token (parser
)->location
;
14499 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14501 matching_parens parens
;
14502 parens
.consume_open (parser
);
14503 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
14504 parens
.skip_until_found_close (parser
);
14506 if (num
== error_mark_node
)
14510 mark_exp_read (num
);
14511 num
= c_fully_fold (num
, false, NULL
);
14512 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
14513 || !tree_fits_shwi_p (num
)
14514 || (n
= tree_to_shwi (num
)) <= 0
14517 error_at (loc
, "ordered argument needs positive "
14518 "constant integer expression");
14522 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
14523 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
14524 OMP_CLAUSE_CHAIN (c
) = list
;
14529 private ( variable-list ) */
14532 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
14534 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
14538 reduction ( reduction-operator : variable-list )
14540 reduction-operator:
14541 One of: + * - & ^ | && ||
14545 reduction-operator:
14546 One of: + * - & ^ | && || max min
14550 reduction-operator:
14551 One of: + * - & ^ | && ||
14555 reduction ( reduction-modifier, reduction-operator : variable-list )
14556 in_reduction ( reduction-operator : variable-list )
14557 task_reduction ( reduction-operator : variable-list ) */
14560 c_parser_omp_clause_reduction (c_parser
*parser
, enum omp_clause_code kind
,
14561 bool is_omp
, tree list
)
14563 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14564 matching_parens parens
;
14565 if (parens
.require_open (parser
))
14568 bool inscan
= false;
14569 enum tree_code code
= ERROR_MARK
;
14570 tree reduc_id
= NULL_TREE
;
14572 if (kind
== OMP_CLAUSE_REDUCTION
&& is_omp
)
14574 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
14575 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
14577 c_parser_consume_token (parser
);
14578 c_parser_consume_token (parser
);
14580 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14581 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
14584 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14585 if (strcmp (p
, "task") == 0)
14587 else if (strcmp (p
, "inscan") == 0)
14589 if (task
|| inscan
)
14591 c_parser_consume_token (parser
);
14592 c_parser_consume_token (parser
);
14597 switch (c_parser_peek_token (parser
)->type
)
14609 code
= BIT_AND_EXPR
;
14612 code
= BIT_XOR_EXPR
;
14615 code
= BIT_IOR_EXPR
;
14618 code
= TRUTH_ANDIF_EXPR
;
14621 code
= TRUTH_ORIF_EXPR
;
14626 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14627 if (strcmp (p
, "min") == 0)
14632 if (strcmp (p
, "max") == 0)
14637 reduc_id
= c_parser_peek_token (parser
)->value
;
14641 c_parser_error (parser
,
14642 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
14643 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
14644 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14647 c_parser_consume_token (parser
);
14648 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
14649 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14653 nl
= c_parser_omp_variable_list (parser
, clause_loc
, kind
, list
);
14654 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
14656 tree d
= OMP_CLAUSE_DECL (c
), type
;
14657 if (TREE_CODE (d
) != TREE_LIST
)
14658 type
= TREE_TYPE (d
);
14663 for (t
= d
; TREE_CODE (t
) == TREE_LIST
; t
= TREE_CHAIN (t
))
14665 type
= TREE_TYPE (t
);
14668 if (TREE_CODE (type
) != POINTER_TYPE
14669 && TREE_CODE (type
) != ARRAY_TYPE
)
14671 type
= TREE_TYPE (type
);
14675 while (TREE_CODE (type
) == ARRAY_TYPE
)
14676 type
= TREE_TYPE (type
);
14677 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
14679 OMP_CLAUSE_REDUCTION_TASK (c
) = 1;
14681 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 1;
14682 if (code
== ERROR_MARK
14683 || !(INTEGRAL_TYPE_P (type
)
14684 || TREE_CODE (type
) == REAL_TYPE
14685 || TREE_CODE (type
) == COMPLEX_TYPE
))
14686 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
14687 = c_omp_reduction_lookup (reduc_id
,
14688 TYPE_MAIN_VARIANT (type
));
14693 parens
.skip_until_found_close (parser
);
14699 schedule ( schedule-kind )
14700 schedule ( schedule-kind , expression )
14703 static | dynamic | guided | runtime | auto
14706 schedule ( schedule-modifier : schedule-kind )
14707 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
14715 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
14718 location_t loc
= c_parser_peek_token (parser
)->location
;
14719 int modifiers
= 0, nmodifiers
= 0;
14721 matching_parens parens
;
14722 if (!parens
.require_open (parser
))
14725 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
14727 while (c_parser_next_token_is (parser
, CPP_NAME
))
14729 tree kind
= c_parser_peek_token (parser
)->value
;
14730 const char *p
= IDENTIFIER_POINTER (kind
);
14731 if (strcmp ("simd", p
) == 0)
14732 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
14733 else if (strcmp ("monotonic", p
) == 0)
14734 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
14735 else if (strcmp ("nonmonotonic", p
) == 0)
14736 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
14739 c_parser_consume_token (parser
);
14740 if (nmodifiers
++ == 0
14741 && c_parser_next_token_is (parser
, CPP_COMMA
))
14742 c_parser_consume_token (parser
);
14745 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
14750 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
14751 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
14752 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
14753 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
14755 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
14760 if (c_parser_next_token_is (parser
, CPP_NAME
))
14762 tree kind
= c_parser_peek_token (parser
)->value
;
14763 const char *p
= IDENTIFIER_POINTER (kind
);
14768 if (strcmp ("dynamic", p
) != 0)
14770 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
14774 if (strcmp ("guided", p
) != 0)
14776 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
14780 if (strcmp ("runtime", p
) != 0)
14782 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
14789 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
14790 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
14791 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
14792 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
14796 c_parser_consume_token (parser
);
14797 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14800 c_parser_consume_token (parser
);
14802 here
= c_parser_peek_token (parser
)->location
;
14803 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14804 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
14806 t
= c_fully_fold (t
, false, NULL
);
14808 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
14809 error_at (here
, "schedule %<runtime%> does not take "
14810 "a %<chunk_size%> parameter");
14811 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
14813 "schedule %<auto%> does not take "
14814 "a %<chunk_size%> parameter");
14815 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
)
14817 /* Attempt to statically determine when the number isn't
14819 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
14820 build_int_cst (TREE_TYPE (t
), 0));
14821 protected_set_expr_location (s
, loc
);
14822 if (s
== boolean_true_node
)
14824 warning_at (loc
, 0,
14825 "chunk size value must be positive");
14826 t
= integer_one_node
;
14828 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
14831 c_parser_error (parser
, "expected integer expression");
14833 parens
.skip_until_found_close (parser
);
14836 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
14837 "expected %<,%> or %<)%>");
14839 OMP_CLAUSE_SCHEDULE_KIND (c
)
14840 = (enum omp_clause_schedule_kind
)
14841 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
14843 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
14844 OMP_CLAUSE_CHAIN (c
) = list
;
14848 c_parser_error (parser
, "invalid schedule kind");
14849 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14854 shared ( variable-list ) */
14857 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
14859 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
14866 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
14870 /* FIXME: Should we allow duplicates? */
14871 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
14873 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
14874 OMP_CLAUSE_UNTIED
);
14875 OMP_CLAUSE_CHAIN (c
) = list
;
14885 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
14886 enum omp_clause_code code
, tree list
)
14888 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14890 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
14891 OMP_CLAUSE_CHAIN (c
) = list
;
14903 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
14904 enum omp_clause_code code
, tree list
)
14906 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
14907 OMP_CLAUSE_CHAIN (c
) = list
;
14916 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
14918 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
14919 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
14920 OMP_CLAUSE_NOGROUP
);
14921 OMP_CLAUSE_CHAIN (c
) = list
;
14930 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
14931 enum omp_clause_code code
, tree list
)
14933 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14934 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
14935 OMP_CLAUSE_CHAIN (c
) = list
;
14940 num_teams ( expression ) */
14943 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
14945 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
14946 matching_parens parens
;
14947 if (parens
.require_open (parser
))
14949 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14950 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14951 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14952 tree c
, t
= expr
.value
;
14953 t
= c_fully_fold (t
, false, NULL
);
14955 parens
.skip_until_found_close (parser
);
14957 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14959 c_parser_error (parser
, "expected integer expression");
14963 /* Attempt to statically determine when the number isn't positive. */
14964 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14965 build_int_cst (TREE_TYPE (t
), 0));
14966 protected_set_expr_location (c
, expr_loc
);
14967 if (c
== boolean_true_node
)
14969 warning_at (expr_loc
, 0, "%<num_teams%> value must be positive");
14970 t
= integer_one_node
;
14973 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
14975 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
14976 OMP_CLAUSE_NUM_TEAMS_EXPR (c
) = t
;
14977 OMP_CLAUSE_CHAIN (c
) = list
;
14985 thread_limit ( expression ) */
14988 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
14990 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
14991 matching_parens parens
;
14992 if (parens
.require_open (parser
))
14994 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14995 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14996 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14997 tree c
, t
= expr
.value
;
14998 t
= c_fully_fold (t
, false, NULL
);
15000 parens
.skip_until_found_close (parser
);
15002 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15004 c_parser_error (parser
, "expected integer expression");
15008 /* Attempt to statically determine when the number isn't positive. */
15009 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
15010 build_int_cst (TREE_TYPE (t
), 0));
15011 protected_set_expr_location (c
, expr_loc
);
15012 if (c
== boolean_true_node
)
15014 warning_at (expr_loc
, 0, "%<thread_limit%> value must be positive");
15015 t
= integer_one_node
;
15018 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
15021 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
15022 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
15023 OMP_CLAUSE_CHAIN (c
) = list
;
15031 aligned ( variable-list )
15032 aligned ( variable-list : constant-expression ) */
15035 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
15037 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15040 matching_parens parens
;
15041 if (!parens
.require_open (parser
))
15044 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15045 OMP_CLAUSE_ALIGNED
, list
);
15047 if (c_parser_next_token_is (parser
, CPP_COLON
))
15049 c_parser_consume_token (parser
);
15050 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15051 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15052 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15053 tree alignment
= expr
.value
;
15054 alignment
= c_fully_fold (alignment
, false, NULL
);
15055 if (TREE_CODE (alignment
) != INTEGER_CST
15056 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
15057 || tree_int_cst_sgn (alignment
) != 1)
15059 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
15060 "be positive constant integer expression");
15061 alignment
= NULL_TREE
;
15064 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15065 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
15068 parens
.skip_until_found_close (parser
);
15073 linear ( variable-list )
15074 linear ( variable-list : expression )
15077 linear ( modifier ( variable-list ) )
15078 linear ( modifier ( variable-list ) : expression ) */
15081 c_parser_omp_clause_linear (c_parser
*parser
, tree list
)
15083 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15085 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15087 matching_parens parens
;
15088 if (!parens
.require_open (parser
))
15091 if (c_parser_next_token_is (parser
, CPP_NAME
))
15093 c_token
*tok
= c_parser_peek_token (parser
);
15094 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15095 if (strcmp ("val", p
) == 0)
15096 kind
= OMP_CLAUSE_LINEAR_VAL
;
15097 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
15098 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15099 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15101 c_parser_consume_token (parser
);
15102 c_parser_consume_token (parser
);
15106 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15107 OMP_CLAUSE_LINEAR
, list
);
15109 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15110 parens
.skip_until_found_close (parser
);
15112 if (c_parser_next_token_is (parser
, CPP_COLON
))
15114 c_parser_consume_token (parser
);
15115 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15116 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15117 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15119 step
= c_fully_fold (step
, false, NULL
);
15120 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
15122 error_at (clause_loc
, "%<linear%> clause step expression must "
15124 step
= integer_one_node
;
15129 step
= integer_one_node
;
15131 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15133 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
15134 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
15137 parens
.skip_until_found_close (parser
);
15142 nontemporal ( variable-list ) */
15145 c_parser_omp_clause_nontemporal (c_parser
*parser
, tree list
)
15147 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_NONTEMPORAL
, list
);
15151 safelen ( constant-expression ) */
15154 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
15156 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15159 matching_parens parens
;
15160 if (!parens
.require_open (parser
))
15163 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15164 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15165 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15167 t
= c_fully_fold (t
, false, NULL
);
15168 if (TREE_CODE (t
) != INTEGER_CST
15169 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
15170 || tree_int_cst_sgn (t
) != 1)
15172 error_at (clause_loc
, "%<safelen%> clause expression must "
15173 "be positive constant integer expression");
15177 parens
.skip_until_found_close (parser
);
15178 if (t
== NULL_TREE
|| t
== error_mark_node
)
15181 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
15183 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
15184 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
15185 OMP_CLAUSE_CHAIN (c
) = list
;
15190 simdlen ( constant-expression ) */
15193 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
15195 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15198 matching_parens parens
;
15199 if (!parens
.require_open (parser
))
15202 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15203 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15204 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15206 t
= c_fully_fold (t
, false, NULL
);
15207 if (TREE_CODE (t
) != INTEGER_CST
15208 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
15209 || tree_int_cst_sgn (t
) != 1)
15211 error_at (clause_loc
, "%<simdlen%> clause expression must "
15212 "be positive constant integer expression");
15216 parens
.skip_until_found_close (parser
);
15217 if (t
== NULL_TREE
|| t
== error_mark_node
)
15220 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
15222 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
15223 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
15224 OMP_CLAUSE_CHAIN (c
) = list
;
15230 identifier [+/- integer]
15231 vec , identifier [+/- integer]
15235 c_parser_omp_clause_depend_sink (c_parser
*parser
, location_t clause_loc
,
15239 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
15240 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
15242 c_parser_error (parser
, "expected identifier");
15246 while (c_parser_next_token_is (parser
, CPP_NAME
)
15247 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
15249 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
15250 tree addend
= NULL
;
15252 if (t
== NULL_TREE
)
15254 undeclared_variable (c_parser_peek_token (parser
)->location
,
15255 c_parser_peek_token (parser
)->value
);
15256 t
= error_mark_node
;
15259 c_parser_consume_token (parser
);
15262 if (c_parser_next_token_is (parser
, CPP_MINUS
))
15264 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
15266 addend
= integer_zero_node
;
15268 goto add_to_vector
;
15270 c_parser_consume_token (parser
);
15272 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
15274 c_parser_error (parser
, "expected integer");
15278 addend
= c_parser_peek_token (parser
)->value
;
15279 if (TREE_CODE (addend
) != INTEGER_CST
)
15281 c_parser_error (parser
, "expected integer");
15284 c_parser_consume_token (parser
);
15287 if (t
!= error_mark_node
)
15289 vec
= tree_cons (addend
, t
, vec
);
15291 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec
) = 1;
15294 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
15297 c_parser_consume_token (parser
);
15300 if (vec
== NULL_TREE
)
15303 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
15304 OMP_CLAUSE_DEPEND_KIND (u
) = OMP_CLAUSE_DEPEND_SINK
;
15305 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
15306 OMP_CLAUSE_CHAIN (u
) = list
;
15311 iterators ( iterators-definition )
15313 iterators-definition:
15315 iterator-specifier , iterators-definition
15317 iterator-specifier:
15318 identifier = range-specification
15319 iterator-type identifier = range-specification
15321 range-specification:
15323 begin : end : step */
15326 c_parser_omp_iterators (c_parser
*parser
)
15328 tree ret
= NULL_TREE
, *last
= &ret
;
15329 c_parser_consume_token (parser
);
15333 matching_parens parens
;
15334 if (!parens
.require_open (parser
))
15335 return error_mark_node
;
15339 tree iter_type
= NULL_TREE
, type_expr
= NULL_TREE
;
15340 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
15342 struct c_type_name
*type
= c_parser_type_name (parser
);
15344 iter_type
= groktypename (type
, &type_expr
, NULL
);
15346 if (iter_type
== NULL_TREE
)
15347 iter_type
= integer_type_node
;
15349 location_t loc
= c_parser_peek_token (parser
)->location
;
15350 if (!c_parser_next_token_is (parser
, CPP_NAME
))
15352 c_parser_error (parser
, "expected identifier");
15356 tree id
= c_parser_peek_token (parser
)->value
;
15357 c_parser_consume_token (parser
);
15359 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
15362 location_t eloc
= c_parser_peek_token (parser
)->location
;
15363 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15364 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15365 tree begin
= expr
.value
;
15367 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15370 eloc
= c_parser_peek_token (parser
)->location
;
15371 expr
= c_parser_expr_no_commas (parser
, NULL
);
15372 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15373 tree end
= expr
.value
;
15375 tree step
= integer_one_node
;
15376 if (c_parser_next_token_is (parser
, CPP_COLON
))
15378 c_parser_consume_token (parser
);
15379 eloc
= c_parser_peek_token (parser
)->location
;
15380 expr
= c_parser_expr_no_commas (parser
, NULL
);
15381 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15385 tree iter_var
= build_decl (loc
, VAR_DECL
, id
, iter_type
);
15386 DECL_ARTIFICIAL (iter_var
) = 1;
15387 DECL_CONTEXT (iter_var
) = current_function_decl
;
15388 pushdecl (iter_var
);
15390 *last
= make_tree_vec (6);
15391 TREE_VEC_ELT (*last
, 0) = iter_var
;
15392 TREE_VEC_ELT (*last
, 1) = begin
;
15393 TREE_VEC_ELT (*last
, 2) = end
;
15394 TREE_VEC_ELT (*last
, 3) = step
;
15395 last
= &TREE_CHAIN (*last
);
15397 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15399 c_parser_consume_token (parser
);
15406 parens
.skip_until_found_close (parser
);
15407 return ret
? ret
: error_mark_node
;
15411 depend ( depend-kind: variable-list )
15419 depend ( sink : vec )
15422 depend ( depend-modifier , depend-kind: variable-list )
15425 in | out | inout | mutexinoutset | depobj
15428 iterator ( iterators-definition ) */
15431 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
15433 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15434 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_LAST
;
15435 tree nl
, c
, iterators
= NULL_TREE
;
15437 matching_parens parens
;
15438 if (!parens
.require_open (parser
))
15443 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
15446 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15447 if (strcmp ("iterator", p
) == 0 && iterators
== NULL_TREE
)
15449 iterators
= c_parser_omp_iterators (parser
);
15450 c_parser_require (parser
, CPP_COMMA
, "expected %<,%>");
15453 if (strcmp ("in", p
) == 0)
15454 kind
= OMP_CLAUSE_DEPEND_IN
;
15455 else if (strcmp ("inout", p
) == 0)
15456 kind
= OMP_CLAUSE_DEPEND_INOUT
;
15457 else if (strcmp ("mutexinoutset", p
) == 0)
15458 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
15459 else if (strcmp ("out", p
) == 0)
15460 kind
= OMP_CLAUSE_DEPEND_OUT
;
15461 else if (strcmp ("depobj", p
) == 0)
15462 kind
= OMP_CLAUSE_DEPEND_DEPOBJ
;
15463 else if (strcmp ("sink", p
) == 0)
15464 kind
= OMP_CLAUSE_DEPEND_SINK
;
15465 else if (strcmp ("source", p
) == 0)
15466 kind
= OMP_CLAUSE_DEPEND_SOURCE
;
15473 c_parser_consume_token (parser
);
15476 && (kind
== OMP_CLAUSE_DEPEND_SOURCE
|| kind
== OMP_CLAUSE_DEPEND_SINK
))
15479 error_at (clause_loc
, "%<iterator%> modifier incompatible with %qs",
15480 kind
== OMP_CLAUSE_DEPEND_SOURCE
? "source" : "sink");
15481 iterators
= NULL_TREE
;
15484 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
15486 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
15487 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
15488 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
15489 OMP_CLAUSE_CHAIN (c
) = list
;
15490 parens
.skip_until_found_close (parser
);
15494 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15497 if (kind
== OMP_CLAUSE_DEPEND_SINK
)
15498 nl
= c_parser_omp_clause_depend_sink (parser
, clause_loc
, list
);
15501 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15502 OMP_CLAUSE_DEPEND
, list
);
15506 tree block
= pop_scope ();
15507 if (iterators
== error_mark_node
)
15508 iterators
= NULL_TREE
;
15510 TREE_VEC_ELT (iterators
, 5) = block
;
15513 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15515 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
15517 OMP_CLAUSE_DECL (c
)
15518 = build_tree_list (iterators
, OMP_CLAUSE_DECL (c
));
15522 parens
.skip_until_found_close (parser
);
15526 c_parser_error (parser
, "invalid depend kind");
15528 parens
.skip_until_found_close (parser
);
15535 map ( map-kind: variable-list )
15536 map ( variable-list )
15539 alloc | to | from | tofrom
15543 alloc | to | from | tofrom | release | delete
15545 map ( always [,] map-kind: variable-list ) */
15548 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
15550 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15551 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
15553 enum c_id_kind always_id_kind
= C_ID_NONE
;
15554 location_t always_loc
= UNKNOWN_LOCATION
;
15555 tree always_id
= NULL_TREE
;
15558 matching_parens parens
;
15559 if (!parens
.require_open (parser
))
15562 if (c_parser_next_token_is (parser
, CPP_NAME
))
15564 c_token
*tok
= c_parser_peek_token (parser
);
15565 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15566 always_id_kind
= tok
->id_kind
;
15567 always_loc
= tok
->location
;
15568 always_id
= tok
->value
;
15569 if (strcmp ("always", p
) == 0)
15571 c_token
*sectok
= c_parser_peek_2nd_token (parser
);
15572 if (sectok
->type
== CPP_COMMA
)
15574 c_parser_consume_token (parser
);
15575 c_parser_consume_token (parser
);
15578 else if (sectok
->type
== CPP_NAME
)
15580 p
= IDENTIFIER_POINTER (sectok
->value
);
15581 if (strcmp ("alloc", p
) == 0
15582 || strcmp ("to", p
) == 0
15583 || strcmp ("from", p
) == 0
15584 || strcmp ("tofrom", p
) == 0
15585 || strcmp ("release", p
) == 0
15586 || strcmp ("delete", p
) == 0)
15588 c_parser_consume_token (parser
);
15595 if (c_parser_next_token_is (parser
, CPP_NAME
)
15596 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
15598 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15599 if (strcmp ("alloc", p
) == 0)
15600 kind
= GOMP_MAP_ALLOC
;
15601 else if (strcmp ("to", p
) == 0)
15602 kind
= always
? GOMP_MAP_ALWAYS_TO
: GOMP_MAP_TO
;
15603 else if (strcmp ("from", p
) == 0)
15604 kind
= always
? GOMP_MAP_ALWAYS_FROM
: GOMP_MAP_FROM
;
15605 else if (strcmp ("tofrom", p
) == 0)
15606 kind
= always
? GOMP_MAP_ALWAYS_TOFROM
: GOMP_MAP_TOFROM
;
15607 else if (strcmp ("release", p
) == 0)
15608 kind
= GOMP_MAP_RELEASE
;
15609 else if (strcmp ("delete", p
) == 0)
15610 kind
= GOMP_MAP_DELETE
;
15613 c_parser_error (parser
, "invalid map kind");
15614 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15618 c_parser_consume_token (parser
);
15619 c_parser_consume_token (parser
);
15623 if (always_id_kind
!= C_ID_ID
)
15625 c_parser_error (parser
, "expected identifier");
15626 parens
.skip_until_found_close (parser
);
15630 tree t
= lookup_name (always_id
);
15631 if (t
== NULL_TREE
)
15633 undeclared_variable (always_loc
, always_id
);
15634 t
= error_mark_node
;
15636 if (t
!= error_mark_node
)
15638 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_MAP
);
15639 OMP_CLAUSE_DECL (u
) = t
;
15640 OMP_CLAUSE_CHAIN (u
) = list
;
15641 OMP_CLAUSE_SET_MAP_KIND (u
, kind
);
15646 parens
.skip_until_found_close (parser
);
15651 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
);
15653 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15654 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
15656 parens
.skip_until_found_close (parser
);
15661 device ( expression ) */
15664 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
15666 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15667 matching_parens parens
;
15668 if (parens
.require_open (parser
))
15670 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15671 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15672 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15673 tree c
, t
= expr
.value
;
15674 t
= c_fully_fold (t
, false, NULL
);
15676 parens
.skip_until_found_close (parser
);
15678 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15680 c_parser_error (parser
, "expected integer expression");
15684 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
15686 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
15687 OMP_CLAUSE_DEVICE_ID (c
) = t
;
15688 OMP_CLAUSE_CHAIN (c
) = list
;
15696 dist_schedule ( static )
15697 dist_schedule ( static , expression ) */
15700 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
15702 tree c
, t
= NULL_TREE
;
15703 location_t loc
= c_parser_peek_token (parser
)->location
;
15705 matching_parens parens
;
15706 if (!parens
.require_open (parser
))
15709 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
15711 c_parser_error (parser
, "invalid dist_schedule kind");
15712 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15717 c_parser_consume_token (parser
);
15718 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15720 c_parser_consume_token (parser
);
15722 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15723 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15724 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15726 t
= c_fully_fold (t
, false, NULL
);
15727 parens
.skip_until_found_close (parser
);
15730 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15731 "expected %<,%> or %<)%>");
15733 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
15734 "dist_schedule"); */
15735 if (omp_find_clause (list
, OMP_CLAUSE_DIST_SCHEDULE
))
15736 warning_at (loc
, 0, "too many %qs clauses", "dist_schedule");
15737 if (t
== error_mark_node
)
15740 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
15741 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
15742 OMP_CLAUSE_CHAIN (c
) = list
;
15747 proc_bind ( proc-bind-kind )
15750 master | close | spread */
15753 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
15755 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15756 enum omp_clause_proc_bind_kind kind
;
15759 matching_parens parens
;
15760 if (!parens
.require_open (parser
))
15763 if (c_parser_next_token_is (parser
, CPP_NAME
))
15765 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15766 if (strcmp ("master", p
) == 0)
15767 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
15768 else if (strcmp ("close", p
) == 0)
15769 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
15770 else if (strcmp ("spread", p
) == 0)
15771 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
15778 check_no_duplicate_clause (list
, OMP_CLAUSE_PROC_BIND
, "proc_bind");
15779 c_parser_consume_token (parser
);
15780 parens
.skip_until_found_close (parser
);
15781 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
15782 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
15783 OMP_CLAUSE_CHAIN (c
) = list
;
15787 c_parser_error (parser
, "invalid proc_bind kind");
15788 parens
.skip_until_found_close (parser
);
15793 device_type ( host | nohost | any ) */
15796 c_parser_omp_clause_device_type (c_parser
*parser
, tree list
)
15798 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15799 enum omp_clause_device_type_kind kind
;
15802 matching_parens parens
;
15803 if (!parens
.require_open (parser
))
15806 if (c_parser_next_token_is (parser
, CPP_NAME
))
15808 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15809 if (strcmp ("host", p
) == 0)
15810 kind
= OMP_CLAUSE_DEVICE_TYPE_HOST
;
15811 else if (strcmp ("nohost", p
) == 0)
15812 kind
= OMP_CLAUSE_DEVICE_TYPE_NOHOST
;
15813 else if (strcmp ("any", p
) == 0)
15814 kind
= OMP_CLAUSE_DEVICE_TYPE_ANY
;
15821 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
15823 c_parser_consume_token (parser
);
15824 parens
.skip_until_found_close (parser
);
15825 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE_TYPE
);
15826 OMP_CLAUSE_DEVICE_TYPE_KIND (c
) = kind
;
15827 OMP_CLAUSE_CHAIN (c
) = list
;
15831 c_parser_error (parser
, "expected %<host%>, %<nohost%> or %<any%>");
15832 parens
.skip_until_found_close (parser
);
15837 to ( variable-list ) */
15840 c_parser_omp_clause_to (c_parser
*parser
, tree list
)
15842 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO
, list
);
15846 from ( variable-list ) */
15849 c_parser_omp_clause_from (c_parser
*parser
, tree list
)
15851 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FROM
, list
);
15855 uniform ( variable-list ) */
15858 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
15860 /* The clauses location. */
15861 location_t loc
= c_parser_peek_token (parser
)->location
;
15863 matching_parens parens
;
15864 if (parens
.require_open (parser
))
15866 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
15868 parens
.skip_until_found_close (parser
);
15873 /* Parse all OpenACC clauses. The set clauses allowed by the directive
15874 is a bitmask in MASK. Return the list of clauses found. */
15877 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
15878 const char *where
, bool finish_p
= true)
15880 tree clauses
= NULL
;
15883 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
15886 pragma_omp_clause c_kind
;
15887 const char *c_name
;
15888 tree prev
= clauses
;
15890 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
15891 c_parser_consume_token (parser
);
15893 here
= c_parser_peek_token (parser
)->location
;
15894 c_kind
= c_parser_omp_clause_name (parser
);
15898 case PRAGMA_OACC_CLAUSE_ASYNC
:
15899 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
15902 case PRAGMA_OACC_CLAUSE_AUTO
:
15903 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_AUTO
,
15907 case PRAGMA_OACC_CLAUSE_ATTACH
:
15908 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15911 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
15912 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
15913 c_name
= "collapse";
15915 case PRAGMA_OACC_CLAUSE_COPY
:
15916 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15919 case PRAGMA_OACC_CLAUSE_COPYIN
:
15920 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15923 case PRAGMA_OACC_CLAUSE_COPYOUT
:
15924 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15925 c_name
= "copyout";
15927 case PRAGMA_OACC_CLAUSE_CREATE
:
15928 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15931 case PRAGMA_OACC_CLAUSE_DELETE
:
15932 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15935 case PRAGMA_OMP_CLAUSE_DEFAULT
:
15936 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
15937 c_name
= "default";
15939 case PRAGMA_OACC_CLAUSE_DETACH
:
15940 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15943 case PRAGMA_OACC_CLAUSE_DEVICE
:
15944 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15947 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
15948 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
15949 c_name
= "deviceptr";
15951 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
15952 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15953 c_name
= "device_resident";
15955 case PRAGMA_OACC_CLAUSE_FINALIZE
:
15956 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_FINALIZE
,
15958 c_name
= "finalize";
15960 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
15961 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
15962 c_name
= "firstprivate";
15964 case PRAGMA_OACC_CLAUSE_GANG
:
15966 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_GANG
,
15969 case PRAGMA_OACC_CLAUSE_HOST
:
15970 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15973 case PRAGMA_OACC_CLAUSE_IF
:
15974 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
15977 case PRAGMA_OACC_CLAUSE_IF_PRESENT
:
15978 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_IF_PRESENT
,
15980 c_name
= "if_present";
15982 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
15983 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_INDEPENDENT
,
15985 c_name
= "independent";
15987 case PRAGMA_OACC_CLAUSE_LINK
:
15988 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15991 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
15992 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15993 c_name
= "no_create";
15995 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
15996 clauses
= c_parser_oacc_single_int_clause (parser
,
15997 OMP_CLAUSE_NUM_GANGS
,
15999 c_name
= "num_gangs";
16001 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
16002 clauses
= c_parser_oacc_single_int_clause (parser
,
16003 OMP_CLAUSE_NUM_WORKERS
,
16005 c_name
= "num_workers";
16007 case PRAGMA_OACC_CLAUSE_PRESENT
:
16008 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16009 c_name
= "present";
16011 case PRAGMA_OACC_CLAUSE_PRIVATE
:
16012 clauses
= c_parser_omp_clause_private (parser
, clauses
);
16013 c_name
= "private";
16015 case PRAGMA_OACC_CLAUSE_REDUCTION
:
16017 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
16019 c_name
= "reduction";
16021 case PRAGMA_OACC_CLAUSE_SEQ
:
16022 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_SEQ
,
16026 case PRAGMA_OACC_CLAUSE_TILE
:
16027 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
16030 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
16031 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
16032 c_name
= "use_device";
16034 case PRAGMA_OACC_CLAUSE_VECTOR
:
16036 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_VECTOR
,
16039 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
16040 clauses
= c_parser_oacc_single_int_clause (parser
,
16041 OMP_CLAUSE_VECTOR_LENGTH
,
16043 c_name
= "vector_length";
16045 case PRAGMA_OACC_CLAUSE_WAIT
:
16046 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
16049 case PRAGMA_OACC_CLAUSE_WORKER
:
16051 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_WORKER
,
16055 c_parser_error (parser
, "expected %<#pragma acc%> clause");
16061 if (((mask
>> c_kind
) & 1) == 0)
16063 /* Remove the invalid clause(s) from the list to avoid
16064 confusing the rest of the compiler. */
16066 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
16071 c_parser_skip_to_pragma_eol (parser
);
16074 return c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16079 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16080 is a bitmask in MASK. Return the list of clauses found.
16081 FINISH_P set if c_finish_omp_clauses should be called.
16082 NESTED non-zero if clauses should be terminated by closing paren instead
16083 of end of pragma. If it is 2, additionally commas are required in between
16087 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
16088 const char *where
, bool finish_p
= true,
16091 tree clauses
= NULL
;
16094 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
16097 pragma_omp_clause c_kind
;
16098 const char *c_name
;
16099 tree prev
= clauses
;
16101 if (nested
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
16106 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16107 c_parser_consume_token (parser
);
16108 else if (nested
== 2)
16109 error_at (c_parser_peek_token (parser
)->location
,
16110 "clauses in %<simd%> trait should be separated "
16114 here
= c_parser_peek_token (parser
)->location
;
16115 c_kind
= c_parser_omp_clause_name (parser
);
16119 case PRAGMA_OMP_CLAUSE_BIND
:
16120 clauses
= c_parser_omp_clause_bind (parser
, clauses
);
16123 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
16124 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
16125 c_name
= "collapse";
16127 case PRAGMA_OMP_CLAUSE_COPYIN
:
16128 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
16131 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
16132 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
16133 c_name
= "copyprivate";
16135 case PRAGMA_OMP_CLAUSE_DEFAULT
:
16136 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
16137 c_name
= "default";
16139 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
16140 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
16141 c_name
= "firstprivate";
16143 case PRAGMA_OMP_CLAUSE_FINAL
:
16144 clauses
= c_parser_omp_clause_final (parser
, clauses
);
16147 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
16148 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
16149 c_name
= "grainsize";
16151 case PRAGMA_OMP_CLAUSE_HINT
:
16152 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
16155 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
16156 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
16157 c_name
= "defaultmap";
16159 case PRAGMA_OMP_CLAUSE_IF
:
16160 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
16163 case PRAGMA_OMP_CLAUSE_IN_REDUCTION
:
16165 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_IN_REDUCTION
,
16167 c_name
= "in_reduction";
16169 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
16170 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
16171 c_name
= "lastprivate";
16173 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
16174 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
16175 c_name
= "mergeable";
16177 case PRAGMA_OMP_CLAUSE_NOWAIT
:
16178 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
16181 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
16182 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
16183 c_name
= "num_tasks";
16185 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
16186 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
16187 c_name
= "num_threads";
16189 case PRAGMA_OMP_CLAUSE_ORDER
:
16190 clauses
= c_parser_omp_clause_order (parser
, clauses
);
16193 case PRAGMA_OMP_CLAUSE_ORDERED
:
16194 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
16195 c_name
= "ordered";
16197 case PRAGMA_OMP_CLAUSE_PRIORITY
:
16198 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
16199 c_name
= "priority";
16201 case PRAGMA_OMP_CLAUSE_PRIVATE
:
16202 clauses
= c_parser_omp_clause_private (parser
, clauses
);
16203 c_name
= "private";
16205 case PRAGMA_OMP_CLAUSE_REDUCTION
:
16207 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
16209 c_name
= "reduction";
16211 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
16212 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
16213 c_name
= "schedule";
16215 case PRAGMA_OMP_CLAUSE_SHARED
:
16216 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
16219 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION
:
16221 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_TASK_REDUCTION
,
16223 c_name
= "task_reduction";
16225 case PRAGMA_OMP_CLAUSE_UNTIED
:
16226 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
16229 case PRAGMA_OMP_CLAUSE_INBRANCH
:
16230 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
16232 c_name
= "inbranch";
16234 case PRAGMA_OMP_CLAUSE_NONTEMPORAL
:
16235 clauses
= c_parser_omp_clause_nontemporal (parser
, clauses
);
16236 c_name
= "nontemporal";
16238 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
16239 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
16241 c_name
= "notinbranch";
16243 case PRAGMA_OMP_CLAUSE_PARALLEL
:
16245 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
16247 c_name
= "parallel";
16251 error_at (here
, "%qs must be the first clause of %qs",
16256 case PRAGMA_OMP_CLAUSE_FOR
:
16258 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
16262 goto clause_not_first
;
16264 case PRAGMA_OMP_CLAUSE_SECTIONS
:
16266 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
16268 c_name
= "sections";
16270 goto clause_not_first
;
16272 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
16274 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
16276 c_name
= "taskgroup";
16278 goto clause_not_first
;
16280 case PRAGMA_OMP_CLAUSE_LINK
:
16282 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
16285 case PRAGMA_OMP_CLAUSE_TO
:
16286 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
16288 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO_DECLARE
,
16291 clauses
= c_parser_omp_clause_to (parser
, clauses
);
16294 case PRAGMA_OMP_CLAUSE_FROM
:
16295 clauses
= c_parser_omp_clause_from (parser
, clauses
);
16298 case PRAGMA_OMP_CLAUSE_UNIFORM
:
16299 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
16300 c_name
= "uniform";
16302 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
16303 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
16304 c_name
= "num_teams";
16306 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
16307 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
16308 c_name
= "thread_limit";
16310 case PRAGMA_OMP_CLAUSE_ALIGNED
:
16311 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
16312 c_name
= "aligned";
16314 case PRAGMA_OMP_CLAUSE_LINEAR
:
16315 clauses
= c_parser_omp_clause_linear (parser
, clauses
);
16318 case PRAGMA_OMP_CLAUSE_DEPEND
:
16319 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
16322 case PRAGMA_OMP_CLAUSE_MAP
:
16323 clauses
= c_parser_omp_clause_map (parser
, clauses
);
16326 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
16327 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
16328 c_name
= "use_device_ptr";
16330 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
:
16331 clauses
= c_parser_omp_clause_use_device_addr (parser
, clauses
);
16332 c_name
= "use_device_addr";
16334 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
16335 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
16336 c_name
= "is_device_ptr";
16338 case PRAGMA_OMP_CLAUSE_DEVICE
:
16339 clauses
= c_parser_omp_clause_device (parser
, clauses
);
16342 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
16343 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
16344 c_name
= "dist_schedule";
16346 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
16347 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
16348 c_name
= "proc_bind";
16350 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE
:
16351 clauses
= c_parser_omp_clause_device_type (parser
, clauses
);
16352 c_name
= "device_type";
16354 case PRAGMA_OMP_CLAUSE_SAFELEN
:
16355 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
16356 c_name
= "safelen";
16358 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
16359 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
16360 c_name
= "simdlen";
16362 case PRAGMA_OMP_CLAUSE_NOGROUP
:
16363 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
16364 c_name
= "nogroup";
16366 case PRAGMA_OMP_CLAUSE_THREADS
:
16368 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
16370 c_name
= "threads";
16372 case PRAGMA_OMP_CLAUSE_SIMD
:
16374 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
16379 c_parser_error (parser
, "expected %<#pragma omp%> clause");
16385 if (((mask
>> c_kind
) & 1) == 0)
16387 /* Remove the invalid clause(s) from the list to avoid
16388 confusing the rest of the compiler. */
16390 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
16396 c_parser_skip_to_pragma_eol (parser
);
16400 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
16401 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
16402 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
16408 /* OpenACC 2.0, OpenMP 2.5:
16412 In practice, we're also interested in adding the statement to an
16413 outer node. So it is convenient if we work around the fact that
16414 c_parser_statement calls add_stmt. */
16417 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
16419 tree stmt
= push_stmt_list ();
16420 c_parser_statement (parser
, if_p
);
16421 return pop_stmt_list (stmt
);
16425 # pragma acc cache (variable-list) new-line
16427 LOC is the location of the #pragma token.
16431 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
16433 tree stmt
, clauses
;
16435 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE__CACHE_
, NULL
);
16436 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16438 c_parser_skip_to_pragma_eol (parser
);
16440 stmt
= make_node (OACC_CACHE
);
16441 TREE_TYPE (stmt
) = void_type_node
;
16442 OACC_CACHE_CLAUSES (stmt
) = clauses
;
16443 SET_EXPR_LOCATION (stmt
, loc
);
16450 # pragma acc data oacc-data-clause[optseq] new-line
16453 LOC is the location of the #pragma token.
16456 #define OACC_DATA_CLAUSE_MASK \
16457 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16458 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16459 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16460 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16461 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16462 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16463 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16464 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16465 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16468 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
16470 tree stmt
, clauses
, block
;
16472 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
16473 "#pragma acc data");
16475 block
= c_begin_omp_parallel ();
16476 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
16478 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
16484 # pragma acc declare oacc-data-clause[optseq] new-line
16487 #define OACC_DECLARE_CLAUSE_MASK \
16488 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16489 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16490 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16491 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16492 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16493 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
16494 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
16495 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16498 c_parser_oacc_declare (c_parser
*parser
)
16500 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
16501 tree clauses
, stmt
, t
, decl
;
16503 bool error
= false;
16505 c_parser_consume_pragma (parser
);
16507 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
16508 "#pragma acc declare");
16511 error_at (pragma_loc
,
16512 "no valid clauses specified in %<#pragma acc declare%>");
16516 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
16518 location_t loc
= OMP_CLAUSE_LOCATION (t
);
16519 decl
= OMP_CLAUSE_DECL (t
);
16520 if (!DECL_P (decl
))
16522 error_at (loc
, "array section in %<#pragma acc declare%>");
16527 switch (OMP_CLAUSE_MAP_KIND (t
))
16529 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
16530 case GOMP_MAP_ALLOC
:
16532 case GOMP_MAP_FORCE_DEVICEPTR
:
16533 case GOMP_MAP_DEVICE_RESIDENT
:
16536 case GOMP_MAP_LINK
:
16537 if (!global_bindings_p ()
16538 && (TREE_STATIC (decl
)
16539 || !DECL_EXTERNAL (decl
)))
16542 "%qD must be a global variable in "
16543 "%<#pragma acc declare link%>",
16551 if (global_bindings_p ())
16553 error_at (loc
, "invalid OpenACC clause at file scope");
16557 if (DECL_EXTERNAL (decl
))
16560 "invalid use of %<extern%> variable %qD "
16561 "in %<#pragma acc declare%>", decl
);
16565 else if (TREE_PUBLIC (decl
))
16568 "invalid use of %<global%> variable %qD "
16569 "in %<#pragma acc declare%>", decl
);
16576 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
16577 || lookup_attribute ("omp declare target link",
16578 DECL_ATTRIBUTES (decl
)))
16580 error_at (loc
, "variable %qD used more than once with "
16581 "%<#pragma acc declare%>", decl
);
16590 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
16591 id
= get_identifier ("omp declare target link");
16593 id
= get_identifier ("omp declare target");
16595 DECL_ATTRIBUTES (decl
)
16596 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
16598 if (global_bindings_p ())
16600 symtab_node
*node
= symtab_node::get (decl
);
16603 node
->offloadable
= 1;
16604 if (ENABLE_OFFLOADING
)
16606 g
->have_offload
= true;
16607 if (is_a
<varpool_node
*> (node
))
16608 vec_safe_push (offload_vars
, decl
);
16615 if (error
|| global_bindings_p ())
16618 stmt
= make_node (OACC_DECLARE
);
16619 TREE_TYPE (stmt
) = void_type_node
;
16620 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
16621 SET_EXPR_LOCATION (stmt
, pragma_loc
);
16629 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
16633 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
16636 LOC is the location of the #pragma token.
16639 #define OACC_ENTER_DATA_CLAUSE_MASK \
16640 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16641 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16642 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16643 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16644 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16645 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16647 #define OACC_EXIT_DATA_CLAUSE_MASK \
16648 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16649 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16650 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16651 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
16652 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
16653 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
16654 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16657 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
16659 location_t loc
= c_parser_peek_token (parser
)->location
;
16660 tree clauses
, stmt
;
16661 const char *p
= "";
16663 c_parser_consume_pragma (parser
);
16665 if (c_parser_next_token_is (parser
, CPP_NAME
))
16667 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16668 c_parser_consume_token (parser
);
16671 if (strcmp (p
, "data") != 0)
16673 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
16674 enter
? "enter" : "exit");
16675 parser
->error
= true;
16676 c_parser_skip_to_pragma_eol (parser
);
16681 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
16682 "#pragma acc enter data");
16684 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
16685 "#pragma acc exit data");
16687 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
16689 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
16690 enter
? "enter" : "exit");
16694 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
16695 TREE_TYPE (stmt
) = void_type_node
;
16696 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
16697 SET_EXPR_LOCATION (stmt
, loc
);
16703 # pragma acc host_data oacc-data-clause[optseq] new-line
16707 #define OACC_HOST_DATA_CLAUSE_MASK \
16708 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
16709 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16710 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
16713 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
16715 tree stmt
, clauses
, block
;
16717 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
16718 "#pragma acc host_data");
16720 block
= c_begin_omp_parallel ();
16721 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
16722 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
16729 # pragma acc loop oacc-loop-clause[optseq] new-line
16732 LOC is the location of the #pragma token.
16735 #define OACC_LOOP_CLAUSE_MASK \
16736 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
16737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16742 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
16743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
16744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
16745 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
16747 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
16748 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
16750 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
16752 strcat (p_name
, " loop");
16753 mask
|= OACC_LOOP_CLAUSE_MASK
;
16755 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
16759 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
16761 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC
);
16763 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16766 tree block
= c_begin_compound_stmt (true);
16767 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
16769 block
= c_end_compound_stmt (loc
, block
, true);
16776 # pragma acc kernels oacc-kernels-clause[optseq] new-line
16781 # pragma acc parallel oacc-parallel-clause[optseq] new-line
16786 # pragma acc serial oacc-serial-clause[optseq] new-line
16789 LOC is the location of the #pragma token.
16792 #define OACC_KERNELS_CLAUSE_MASK \
16793 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16794 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16795 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16796 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16797 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16798 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16799 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16800 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16801 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16802 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16805 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16806 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16807 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16809 #define OACC_PARALLEL_CLAUSE_MASK \
16810 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16815 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16816 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16817 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16818 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16819 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16820 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16821 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
16822 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16823 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16824 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16825 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16827 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16829 #define OACC_SERIAL_CLAUSE_MASK \
16830 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16831 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16832 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16833 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16834 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16835 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16836 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16837 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16838 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16839 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16840 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16841 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
16842 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16843 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16844 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16847 c_parser_oacc_compute (location_t loc
, c_parser
*parser
,
16848 enum pragma_kind p_kind
, char *p_name
, bool *if_p
)
16850 omp_clause_mask mask
;
16851 enum tree_code code
;
16854 case PRAGMA_OACC_KERNELS
:
16855 strcat (p_name
, " kernels");
16856 mask
= OACC_KERNELS_CLAUSE_MASK
;
16857 code
= OACC_KERNELS
;
16859 case PRAGMA_OACC_PARALLEL
:
16860 strcat (p_name
, " parallel");
16861 mask
= OACC_PARALLEL_CLAUSE_MASK
;
16862 code
= OACC_PARALLEL
;
16864 case PRAGMA_OACC_SERIAL
:
16865 strcat (p_name
, " serial");
16866 mask
= OACC_SERIAL_CLAUSE_MASK
;
16867 code
= OACC_SERIAL
;
16870 gcc_unreachable ();
16873 if (c_parser_next_token_is (parser
, CPP_NAME
))
16875 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16876 if (strcmp (p
, "loop") == 0)
16878 c_parser_consume_token (parser
);
16879 tree block
= c_begin_omp_parallel ();
16881 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
16882 return c_finish_omp_construct (loc
, code
, block
, clauses
);
16886 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
);
16888 tree block
= c_begin_omp_parallel ();
16889 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
16891 return c_finish_omp_construct (loc
, code
, block
, clauses
);
16895 # pragma acc routine oacc-routine-clause[optseq] new-line
16896 function-definition
16898 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
16901 #define OACC_ROUTINE_CLAUSE_MASK \
16902 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16904 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16905 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) )
16907 /* Parse an OpenACC routine directive. For named directives, we apply
16908 immediately to the named function. For unnamed ones we then parse
16909 a declaration or definition, which must be for a function. */
16912 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
16914 gcc_checking_assert (context
== pragma_external
);
16916 oacc_routine_data data
;
16917 data
.error_seen
= false;
16918 data
.fndecl_seen
= false;
16919 data
.clauses
= NULL_TREE
;
16920 data
.loc
= c_parser_peek_token (parser
)->location
;
16922 c_parser_consume_pragma (parser
);
16924 /* Look for optional '( name )'. */
16925 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
16927 c_parser_consume_token (parser
); /* '(' */
16929 tree decl
= NULL_TREE
;
16930 c_token
*name_token
= c_parser_peek_token (parser
);
16931 location_t name_loc
= name_token
->location
;
16932 if (name_token
->type
== CPP_NAME
16933 && (name_token
->id_kind
== C_ID_ID
16934 || name_token
->id_kind
== C_ID_TYPENAME
))
16936 decl
= lookup_name (name_token
->value
);
16938 error_at (name_loc
,
16939 "%qE has not been declared", name_token
->value
);
16940 c_parser_consume_token (parser
);
16943 c_parser_error (parser
, "expected function name");
16946 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
16948 c_parser_skip_to_pragma_eol (parser
, false);
16953 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
16954 "#pragma acc routine");
16955 /* The clauses are in reverse order; fix that to make later diagnostic
16956 emission easier. */
16957 data
.clauses
= nreverse (data
.clauses
);
16959 if (TREE_CODE (decl
) != FUNCTION_DECL
)
16961 error_at (name_loc
, "%qD does not refer to a function", decl
);
16965 c_finish_oacc_routine (&data
, decl
, false);
16967 else /* No optional '( name )'. */
16970 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
16971 "#pragma acc routine");
16972 /* The clauses are in reverse order; fix that to make later diagnostic
16973 emission easier. */
16974 data
.clauses
= nreverse (data
.clauses
);
16976 /* Emit a helpful diagnostic if there's another pragma following this
16977 one. Also don't allow a static assertion declaration, as in the
16978 following we'll just parse a *single* "declaration or function
16979 definition", and the static assertion counts an one. */
16980 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
16981 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
16983 error_at (data
.loc
,
16984 "%<#pragma acc routine%> not immediately followed by"
16985 " function declaration or definition");
16986 /* ..., and then just keep going. */
16990 /* We only have to consider the pragma_external case here. */
16991 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
16992 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
16994 int ext
= disable_extension_diagnostics ();
16996 c_parser_consume_token (parser
);
16997 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
16998 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
16999 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
17000 NULL
, vNULL
, false, NULL
, &data
);
17001 restore_extension_diagnostics (ext
);
17004 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
17005 NULL
, vNULL
, false, NULL
, &data
);
17009 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17010 IS_DEFN is true if we're applying it to the definition. */
17013 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
17016 /* Keep going if we're in error reporting mode. */
17017 if (data
->error_seen
17018 || fndecl
== error_mark_node
)
17021 if (data
->fndecl_seen
)
17023 error_at (data
->loc
,
17024 "%<#pragma acc routine%> not immediately followed by"
17025 " a single function declaration or definition");
17026 data
->error_seen
= true;
17029 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
17031 error_at (data
->loc
,
17032 "%<#pragma acc routine%> not immediately followed by"
17033 " function declaration or definition");
17034 data
->error_seen
= true;
17039 = oacc_verify_routine_clauses (fndecl
, &data
->clauses
, data
->loc
,
17040 "#pragma acc routine");
17041 if (compatible
< 0)
17043 data
->error_seen
= true;
17046 if (compatible
> 0)
17051 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
17053 error_at (data
->loc
,
17055 ? G_("%<#pragma acc routine%> must be applied before use")
17056 : G_("%<#pragma acc routine%> must be applied before"
17058 data
->error_seen
= true;
17062 /* Set the routine's level of parallelism. */
17063 tree dims
= oacc_build_routine_dims (data
->clauses
);
17064 oacc_replace_fn_attrib (fndecl
, dims
);
17066 /* Add an "omp declare target" attribute. */
17067 DECL_ATTRIBUTES (fndecl
)
17068 = tree_cons (get_identifier ("omp declare target"),
17069 data
->clauses
, DECL_ATTRIBUTES (fndecl
));
17072 /* Remember that we've used this "#pragma acc routine". */
17073 data
->fndecl_seen
= true;
17077 # pragma acc update oacc-update-clause[optseq] new-line
17080 #define OACC_UPDATE_CLAUSE_MASK \
17081 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17082 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17083 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17084 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17085 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
17086 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17089 c_parser_oacc_update (c_parser
*parser
)
17091 location_t loc
= c_parser_peek_token (parser
)->location
;
17093 c_parser_consume_pragma (parser
);
17095 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
17096 "#pragma acc update");
17097 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
17100 "%<#pragma acc update%> must contain at least one "
17101 "%<device%> or %<host%> or %<self%> clause");
17108 tree stmt
= make_node (OACC_UPDATE
);
17109 TREE_TYPE (stmt
) = void_type_node
;
17110 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
17111 SET_EXPR_LOCATION (stmt
, loc
);
17116 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
17118 LOC is the location of the #pragma token.
17121 #define OACC_WAIT_CLAUSE_MASK \
17122 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
17125 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
17127 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
17129 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
17130 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
17132 strcpy (p_name
, " wait");
17133 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
17134 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
17141 # pragma omp atomic new-line
17145 x binop= expr | x++ | ++x | x-- | --x
17147 +, *, -, /, &, ^, |, <<, >>
17149 where x is an lvalue expression with scalar type.
17152 # pragma omp atomic new-line
17155 # pragma omp atomic read new-line
17158 # pragma omp atomic write new-line
17161 # pragma omp atomic update new-line
17164 # pragma omp atomic capture new-line
17167 # pragma omp atomic capture new-line
17175 expression-stmt | x = x binop expr
17177 v = expression-stmt
17179 { v = x; update-stmt; } | { update-stmt; v = x; }
17183 expression-stmt | x = x binop expr | x = expr binop x
17187 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
17189 where x and v are lvalue expressions with scalar type.
17191 LOC is the location of the #pragma token. */
17194 c_parser_omp_atomic (location_t loc
, c_parser
*parser
)
17196 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
;
17197 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
17198 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
17199 enum tree_code code
= ERROR_MARK
, opcode
= NOP_EXPR
;
17200 enum omp_memory_order memory_order
= OMP_MEMORY_ORDER_UNSPECIFIED
;
17201 struct c_expr expr
;
17203 bool structured_block
= false;
17204 bool swapped
= false;
17207 tree clauses
= NULL_TREE
;
17209 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17211 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
17212 c_parser_consume_token (parser
);
17216 if (c_parser_next_token_is (parser
, CPP_NAME
))
17219 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17220 location_t cloc
= c_parser_peek_token (parser
)->location
;
17221 enum tree_code new_code
= ERROR_MARK
;
17222 enum omp_memory_order new_memory_order
17223 = OMP_MEMORY_ORDER_UNSPECIFIED
;
17225 if (!strcmp (p
, "read"))
17226 new_code
= OMP_ATOMIC_READ
;
17227 else if (!strcmp (p
, "write"))
17228 new_code
= NOP_EXPR
;
17229 else if (!strcmp (p
, "update"))
17230 new_code
= OMP_ATOMIC
;
17231 else if (!strcmp (p
, "capture"))
17232 new_code
= OMP_ATOMIC_CAPTURE_NEW
;
17233 else if (!strcmp (p
, "seq_cst"))
17234 new_memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17235 else if (!strcmp (p
, "acq_rel"))
17236 new_memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
17237 else if (!strcmp (p
, "release"))
17238 new_memory_order
= OMP_MEMORY_ORDER_RELEASE
;
17239 else if (!strcmp (p
, "acquire"))
17240 new_memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
17241 else if (!strcmp (p
, "relaxed"))
17242 new_memory_order
= OMP_MEMORY_ORDER_RELAXED
;
17243 else if (!strcmp (p
, "hint"))
17245 c_parser_consume_token (parser
);
17246 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
17252 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
17253 "%<capture%>, %<seq_cst%>, %<acq_rel%>, "
17254 "%<release%>, %<relaxed%> or %<hint%> clause");
17258 if (new_code
!= ERROR_MARK
)
17260 if (code
!= ERROR_MARK
)
17261 error_at (cloc
, "too many atomic clauses");
17265 else if (new_memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
17267 if (memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
17268 error_at (cloc
, "too many memory order clauses");
17270 memory_order
= new_memory_order
;
17272 c_parser_consume_token (parser
);
17278 c_parser_skip_to_pragma_eol (parser
);
17280 if (code
== ERROR_MARK
)
17282 if (memory_order
== OMP_MEMORY_ORDER_UNSPECIFIED
)
17285 = (enum omp_requires
) (omp_requires_mask
17286 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
);
17287 switch ((enum omp_memory_order
)
17288 (omp_requires_mask
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
))
17290 case OMP_MEMORY_ORDER_UNSPECIFIED
:
17291 case OMP_MEMORY_ORDER_RELAXED
:
17292 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
17294 case OMP_MEMORY_ORDER_SEQ_CST
:
17295 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17297 case OMP_MEMORY_ORDER_ACQ_REL
:
17300 case OMP_ATOMIC_READ
:
17301 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
17303 case NOP_EXPR
: /* atomic write */
17305 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
17308 memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
17313 gcc_unreachable ();
17319 case OMP_ATOMIC_READ
:
17320 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
17321 || memory_order
== OMP_MEMORY_ORDER_RELEASE
)
17323 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
17324 "%<acq_rel%> or %<release%> clauses");
17325 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17328 case NOP_EXPR
: /* atomic write */
17329 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
17330 || memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
17332 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
17333 "%<acq_rel%> or %<acquire%> clauses");
17334 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17338 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
17339 || memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
17341 error_at (loc
, "%<#pragma omp atomic update%> incompatible with "
17342 "%<acq_rel%> or %<acquire%> clauses");
17343 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17352 case OMP_ATOMIC_READ
:
17353 case NOP_EXPR
: /* atomic write */
17354 v
= c_parser_cast_expression (parser
, NULL
).value
;
17355 non_lvalue_p
= !lvalue_p (v
);
17356 v
= c_fully_fold (v
, false, NULL
, true);
17357 if (v
== error_mark_node
)
17360 v
= non_lvalue (v
);
17361 loc
= c_parser_peek_token (parser
)->location
;
17362 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
17364 if (code
== NOP_EXPR
)
17366 lhs
= c_parser_expression (parser
).value
;
17367 lhs
= c_fully_fold (lhs
, false, NULL
);
17368 if (lhs
== error_mark_node
)
17373 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
17374 non_lvalue_p
= !lvalue_p (lhs
);
17375 lhs
= c_fully_fold (lhs
, false, NULL
, true);
17376 if (lhs
== error_mark_node
)
17379 lhs
= non_lvalue (lhs
);
17381 if (code
== NOP_EXPR
)
17383 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
17391 case OMP_ATOMIC_CAPTURE_NEW
:
17392 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
17394 c_parser_consume_token (parser
);
17395 structured_block
= true;
17399 v
= c_parser_cast_expression (parser
, NULL
).value
;
17400 non_lvalue_p
= !lvalue_p (v
);
17401 v
= c_fully_fold (v
, false, NULL
, true);
17402 if (v
== error_mark_node
)
17405 v
= non_lvalue (v
);
17406 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
17414 /* For structured_block case we don't know yet whether
17415 old or new x should be captured. */
17417 eloc
= c_parser_peek_token (parser
)->location
;
17418 expr
= c_parser_cast_expression (parser
, NULL
);
17420 expr
= default_function_array_conversion (eloc
, expr
);
17421 unfolded_lhs
= expr
.value
;
17422 lhs
= c_fully_fold (lhs
, false, NULL
, true);
17424 switch (TREE_CODE (lhs
))
17428 c_parser_skip_to_end_of_block_or_statement (parser
);
17429 if (structured_block
)
17431 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
17432 c_parser_consume_token (parser
);
17433 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
17435 c_parser_skip_to_end_of_block_or_statement (parser
);
17436 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
17437 c_parser_consume_token (parser
);
17442 case POSTINCREMENT_EXPR
:
17443 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
17444 code
= OMP_ATOMIC_CAPTURE_OLD
;
17446 case PREINCREMENT_EXPR
:
17447 lhs
= TREE_OPERAND (lhs
, 0);
17448 unfolded_lhs
= NULL_TREE
;
17449 opcode
= PLUS_EXPR
;
17450 rhs
= integer_one_node
;
17453 case POSTDECREMENT_EXPR
:
17454 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
17455 code
= OMP_ATOMIC_CAPTURE_OLD
;
17457 case PREDECREMENT_EXPR
:
17458 lhs
= TREE_OPERAND (lhs
, 0);
17459 unfolded_lhs
= NULL_TREE
;
17460 opcode
= MINUS_EXPR
;
17461 rhs
= integer_one_node
;
17464 case COMPOUND_EXPR
:
17465 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
17466 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
17467 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
17468 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
17469 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
17470 (TREE_OPERAND (lhs
, 1), 0), 0)))
17472 /* Undo effects of boolean_increment for post {in,de}crement. */
17473 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
17476 if (TREE_CODE (lhs
) == MODIFY_EXPR
17477 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs
, 0))) == BOOLEAN_TYPE
)
17479 /* Undo effects of boolean_increment. */
17480 if (integer_onep (TREE_OPERAND (lhs
, 1)))
17482 /* This is pre or post increment. */
17483 rhs
= TREE_OPERAND (lhs
, 1);
17484 lhs
= TREE_OPERAND (lhs
, 0);
17485 unfolded_lhs
= NULL_TREE
;
17487 if (code
== OMP_ATOMIC_CAPTURE_NEW
17488 && !structured_block
17489 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
17490 code
= OMP_ATOMIC_CAPTURE_OLD
;
17493 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
17494 && TREE_OPERAND (lhs
, 0)
17495 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
17497 /* This is pre or post decrement. */
17498 rhs
= TREE_OPERAND (lhs
, 1);
17499 lhs
= TREE_OPERAND (lhs
, 0);
17500 unfolded_lhs
= NULL_TREE
;
17502 if (code
== OMP_ATOMIC_CAPTURE_NEW
17503 && !structured_block
17504 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
17505 code
= OMP_ATOMIC_CAPTURE_OLD
;
17511 if (!lvalue_p (unfolded_lhs
))
17512 lhs
= non_lvalue (lhs
);
17513 switch (c_parser_peek_token (parser
)->type
)
17516 opcode
= MULT_EXPR
;
17519 opcode
= TRUNC_DIV_EXPR
;
17522 opcode
= PLUS_EXPR
;
17525 opcode
= MINUS_EXPR
;
17527 case CPP_LSHIFT_EQ
:
17528 opcode
= LSHIFT_EXPR
;
17530 case CPP_RSHIFT_EQ
:
17531 opcode
= RSHIFT_EXPR
;
17534 opcode
= BIT_AND_EXPR
;
17537 opcode
= BIT_IOR_EXPR
;
17540 opcode
= BIT_XOR_EXPR
;
17543 c_parser_consume_token (parser
);
17544 eloc
= c_parser_peek_token (parser
)->location
;
17545 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
17547 switch (TREE_CODE (rhs1
))
17550 case TRUNC_DIV_EXPR
:
17559 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
17561 opcode
= TREE_CODE (rhs1
);
17562 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
17564 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
17568 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
17570 opcode
= TREE_CODE (rhs1
);
17571 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
17573 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
17575 swapped
= !commutative_tree_code (opcode
);
17584 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
17586 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
17588 code
= OMP_ATOMIC_CAPTURE_OLD
;
17591 expr
= default_function_array_read_conversion (eloc
, expr
);
17592 unfolded_lhs1
= expr
.value
;
17593 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
17595 c_parser_consume_token (parser
);
17598 if (structured_block
)
17601 expr
= default_function_array_read_conversion (eloc
, expr
);
17602 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
17607 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
17610 c_parser_error (parser
,
17611 "invalid operator for %<#pragma omp atomic%>");
17615 /* Arrange to pass the location of the assignment operator to
17616 c_finish_omp_atomic. */
17617 loc
= c_parser_peek_token (parser
)->location
;
17618 c_parser_consume_token (parser
);
17619 eloc
= c_parser_peek_token (parser
)->location
;
17620 expr
= c_parser_expression (parser
);
17621 expr
= default_function_array_read_conversion (eloc
, expr
);
17623 rhs
= c_fully_fold (rhs
, false, NULL
, true);
17627 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
17629 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
17631 v
= c_parser_cast_expression (parser
, NULL
).value
;
17632 non_lvalue_p
= !lvalue_p (v
);
17633 v
= c_fully_fold (v
, false, NULL
, true);
17634 if (v
== error_mark_node
)
17637 v
= non_lvalue (v
);
17638 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
17640 eloc
= c_parser_peek_token (parser
)->location
;
17641 expr
= c_parser_cast_expression (parser
, NULL
);
17643 expr
= default_function_array_read_conversion (eloc
, expr
);
17644 unfolded_lhs1
= expr
.value
;
17645 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
17646 if (lhs1
== error_mark_node
)
17648 if (!lvalue_p (unfolded_lhs1
))
17649 lhs1
= non_lvalue (lhs1
);
17651 if (structured_block
)
17653 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
17654 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
17657 if (unfolded_lhs
&& unfolded_lhs1
17658 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
17660 error ("%<#pragma omp atomic capture%> uses two different "
17661 "expressions for memory");
17662 stmt
= error_mark_node
;
17665 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
,
17666 swapped
, memory_order
);
17667 if (stmt
!= error_mark_node
)
17670 if (!structured_block
)
17671 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
17676 # pragma omp barrier new-line
17680 c_parser_omp_barrier (c_parser
*parser
)
17682 location_t loc
= c_parser_peek_token (parser
)->location
;
17683 c_parser_consume_pragma (parser
);
17684 c_parser_skip_to_pragma_eol (parser
);
17686 c_finish_omp_barrier (loc
);
17690 # pragma omp critical [(name)] new-line
17694 # pragma omp critical [(name) [hint(expression)]] new-line
17696 LOC is the location of the #pragma itself. */
17698 #define OMP_CRITICAL_CLAUSE_MASK \
17699 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
17702 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
17704 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
17706 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17708 c_parser_consume_token (parser
);
17709 if (c_parser_next_token_is (parser
, CPP_NAME
))
17711 name
= c_parser_peek_token (parser
)->value
;
17712 c_parser_consume_token (parser
);
17713 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
17716 c_parser_error (parser
, "expected identifier");
17718 if (c_parser_next_token_is (parser
, CPP_COMMA
)
17719 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
17720 c_parser_consume_token (parser
);
17722 clauses
= c_parser_omp_all_clauses (parser
,
17723 OMP_CRITICAL_CLAUSE_MASK
,
17724 "#pragma omp critical");
17728 if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17729 c_parser_error (parser
, "expected %<(%> or end of line");
17730 c_parser_skip_to_pragma_eol (parser
);
17733 stmt
= c_parser_omp_structured_block (parser
, if_p
);
17734 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
17738 # pragma omp depobj ( depobj ) depobj-clause new-line
17741 depend (dependence-type : locator)
17743 update (dependence-type)
17752 c_parser_omp_depobj (c_parser
*parser
)
17754 location_t loc
= c_parser_peek_token (parser
)->location
;
17755 c_parser_consume_pragma (parser
);
17756 matching_parens parens
;
17757 if (!parens
.require_open (parser
))
17759 c_parser_skip_to_pragma_eol (parser
);
17763 tree depobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
17764 if (depobj
!= error_mark_node
)
17766 if (!lvalue_p (depobj
))
17768 error_at (EXPR_LOC_OR_LOC (depobj
, loc
),
17769 "%<depobj%> expression is not lvalue expression");
17770 depobj
= error_mark_node
;
17774 tree addr
= build_unary_op (EXPR_LOC_OR_LOC (depobj
, loc
), ADDR_EXPR
,
17776 if (addr
== error_mark_node
)
17777 depobj
= error_mark_node
;
17779 depobj
= build_indirect_ref (EXPR_LOC_OR_LOC (depobj
, loc
),
17780 addr
, RO_UNARY_STAR
);
17784 parens
.skip_until_found_close (parser
);
17785 tree clause
= NULL_TREE
;
17786 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_SOURCE
;
17787 location_t c_loc
= c_parser_peek_token (parser
)->location
;
17788 if (c_parser_next_token_is (parser
, CPP_NAME
))
17790 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17792 c_parser_consume_token (parser
);
17793 if (!strcmp ("depend", p
))
17795 clause
= c_parser_omp_clause_depend (parser
, NULL_TREE
);
17796 clause
= c_finish_omp_clauses (clause
, C_ORT_OMP
);
17798 clause
= error_mark_node
;
17800 else if (!strcmp ("destroy", p
))
17801 kind
= OMP_CLAUSE_DEPEND_LAST
;
17802 else if (!strcmp ("update", p
))
17804 matching_parens c_parens
;
17805 if (c_parens
.require_open (parser
))
17807 location_t c2_loc
= c_parser_peek_token (parser
)->location
;
17808 if (c_parser_next_token_is (parser
, CPP_NAME
))
17811 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17813 c_parser_consume_token (parser
);
17814 if (!strcmp ("in", p2
))
17815 kind
= OMP_CLAUSE_DEPEND_IN
;
17816 else if (!strcmp ("out", p2
))
17817 kind
= OMP_CLAUSE_DEPEND_OUT
;
17818 else if (!strcmp ("inout", p2
))
17819 kind
= OMP_CLAUSE_DEPEND_INOUT
;
17820 else if (!strcmp ("mutexinoutset", p2
))
17821 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
17823 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
17825 clause
= error_mark_node
;
17826 error_at (c2_loc
, "expected %<in%>, %<out%>, %<inout%> or "
17827 "%<mutexinoutset%>");
17829 c_parens
.skip_until_found_close (parser
);
17832 clause
= error_mark_node
;
17835 if (!clause
&& kind
== OMP_CLAUSE_DEPEND_SOURCE
)
17837 clause
= error_mark_node
;
17838 error_at (c_loc
, "expected %<depend%>, %<destroy%> or %<update%> clause");
17840 c_parser_skip_to_pragma_eol (parser
);
17842 c_finish_omp_depobj (loc
, depobj
, kind
, clause
);
17847 # pragma omp flush flush-vars[opt] new-line
17853 # pragma omp flush memory-order-clause new-line */
17856 c_parser_omp_flush (c_parser
*parser
)
17858 location_t loc
= c_parser_peek_token (parser
)->location
;
17859 c_parser_consume_pragma (parser
);
17860 enum memmodel mo
= MEMMODEL_LAST
;
17861 if (c_parser_next_token_is (parser
, CPP_NAME
))
17864 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17866 if (!strcmp (p
, "acq_rel"))
17867 mo
= MEMMODEL_ACQ_REL
;
17868 else if (!strcmp (p
, "release"))
17869 mo
= MEMMODEL_RELEASE
;
17870 else if (!strcmp (p
, "acquire"))
17871 mo
= MEMMODEL_ACQUIRE
;
17873 error_at (c_parser_peek_token (parser
)->location
,
17874 "expected %<acq_rel%>, %<release%> or %<acquire%>");
17875 c_parser_consume_token (parser
);
17877 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17879 if (mo
!= MEMMODEL_LAST
)
17880 error_at (c_parser_peek_token (parser
)->location
,
17881 "%<flush%> list specified together with memory order "
17883 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
17885 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17886 c_parser_error (parser
, "expected %<(%> or end of line");
17887 c_parser_skip_to_pragma_eol (parser
);
17889 c_finish_omp_flush (loc
, mo
);
17895 { structured-block scan-directive structured-block } */
17898 c_parser_omp_scan_loop_body (c_parser
*parser
, bool open_brace_parsed
)
17902 tree clauses
= NULL_TREE
;
17904 loc
= c_parser_peek_token (parser
)->location
;
17905 if (!open_brace_parsed
17906 && !c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
17908 /* Avoid skipping until the end of the block. */
17909 parser
->error
= false;
17913 substmt
= c_parser_omp_structured_block (parser
, NULL
);
17914 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, NULL_TREE
);
17915 SET_EXPR_LOCATION (substmt
, loc
);
17916 add_stmt (substmt
);
17918 loc
= c_parser_peek_token (parser
)->location
;
17919 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SCAN
)
17921 enum omp_clause_code clause
= OMP_CLAUSE_ERROR
;
17923 c_parser_consume_pragma (parser
);
17925 if (c_parser_next_token_is (parser
, CPP_NAME
))
17928 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17929 if (strcmp (p
, "inclusive") == 0)
17930 clause
= OMP_CLAUSE_INCLUSIVE
;
17931 else if (strcmp (p
, "exclusive") == 0)
17932 clause
= OMP_CLAUSE_EXCLUSIVE
;
17934 if (clause
!= OMP_CLAUSE_ERROR
)
17936 c_parser_consume_token (parser
);
17937 clauses
= c_parser_omp_var_list_parens (parser
, clause
, NULL_TREE
);
17940 c_parser_error (parser
, "expected %<inclusive%> or "
17941 "%<exclusive%> clause");
17942 c_parser_skip_to_pragma_eol (parser
);
17945 error ("expected %<#pragma omp scan%>");
17947 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
17948 substmt
= c_parser_omp_structured_block (parser
, NULL
);
17949 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, clauses
);
17950 SET_EXPR_LOCATION (substmt
, loc
);
17951 add_stmt (substmt
);
17953 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
17957 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
17958 The real trick here is to determine the loop control variable early
17959 so that we can push a new decl if necessary to make it private.
17960 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
17964 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
17965 tree clauses
, tree
*cclauses
, bool *if_p
)
17967 tree decl
, cond
, incr
, save_break
, save_cont
, body
, init
, stmt
, cl
;
17968 tree declv
, condv
, incrv
, initv
, ret
= NULL_TREE
;
17969 tree pre_body
= NULL_TREE
, this_pre_body
;
17970 tree ordered_cl
= NULL_TREE
;
17971 bool fail
= false, open_brace_parsed
= false;
17972 int i
, collapse
= 1, ordered
= 0, count
, nbraces
= 0;
17973 location_t for_loc
;
17974 bool tiling
= false;
17975 bool inscan
= false;
17976 vec
<tree
, va_gc
> *for_block
= make_tree_vector ();
17978 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
17979 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
17980 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
17981 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
17984 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
17986 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
17987 && OMP_CLAUSE_ORDERED_EXPR (cl
))
17990 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
17992 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_REDUCTION
17993 && OMP_CLAUSE_REDUCTION_INSCAN (cl
)
17994 && (code
== OMP_SIMD
|| code
== OMP_FOR
))
17997 if (ordered
&& ordered
< collapse
)
17999 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
18000 "%<ordered%> clause parameter is less than %<collapse%>");
18001 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
18002 = build_int_cst (NULL_TREE
, collapse
);
18003 ordered
= collapse
;
18007 for (tree
*pc
= &clauses
; *pc
; )
18008 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LINEAR
)
18010 error_at (OMP_CLAUSE_LOCATION (*pc
),
18011 "%<linear%> clause may not be specified together "
18012 "with %<ordered%> clause with a parameter");
18013 *pc
= OMP_CLAUSE_CHAIN (*pc
);
18016 pc
= &OMP_CLAUSE_CHAIN (*pc
);
18019 gcc_assert (tiling
|| (collapse
>= 1 && ordered
>= 0));
18020 count
= ordered
? ordered
: collapse
;
18022 declv
= make_tree_vec (count
);
18023 initv
= make_tree_vec (count
);
18024 condv
= make_tree_vec (count
);
18025 incrv
= make_tree_vec (count
);
18027 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
))
18029 c_parser_error (parser
, "for statement expected");
18032 for_loc
= c_parser_peek_token (parser
)->location
;
18033 c_parser_consume_token (parser
);
18035 for (i
= 0; i
< count
; i
++)
18037 int bracecount
= 0;
18039 matching_parens parens
;
18040 if (!parens
.require_open (parser
))
18043 /* Parse the initialization declaration or expression. */
18044 if (c_parser_next_tokens_start_declaration (parser
))
18047 vec_safe_push (for_block
, c_begin_compound_stmt (true));
18048 this_pre_body
= push_stmt_list ();
18049 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
18053 this_pre_body
= pop_stmt_list (this_pre_body
);
18057 pre_body
= push_stmt_list ();
18059 add_stmt (this_pre_body
);
18060 pre_body
= pop_stmt_list (pre_body
);
18063 pre_body
= this_pre_body
;
18065 decl
= check_for_loop_decls (for_loc
, flag_isoc99
);
18068 if (DECL_INITIAL (decl
) == error_mark_node
)
18069 decl
= error_mark_node
;
18072 else if (c_parser_next_token_is (parser
, CPP_NAME
)
18073 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
18075 struct c_expr decl_exp
;
18076 struct c_expr init_exp
;
18077 location_t init_loc
;
18079 decl_exp
= c_parser_postfix_expression (parser
);
18080 decl
= decl_exp
.value
;
18082 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
18084 init_loc
= c_parser_peek_token (parser
)->location
;
18085 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
18086 init_exp
= default_function_array_read_conversion (init_loc
,
18088 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
18089 NOP_EXPR
, init_loc
, init_exp
.value
,
18090 init_exp
.original_type
);
18091 init
= c_process_expr_stmt (init_loc
, init
);
18093 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
18098 c_parser_error (parser
,
18099 "expected iteration declaration or initialization");
18100 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
18106 /* Parse the loop condition. */
18108 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
18110 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
18111 struct c_expr cond_expr
18112 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
18114 cond
= cond_expr
.value
;
18115 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
18116 if (COMPARISON_CLASS_P (cond
))
18118 tree op0
= TREE_OPERAND (cond
, 0), op1
= TREE_OPERAND (cond
, 1);
18119 op0
= c_fully_fold (op0
, false, NULL
);
18120 op1
= c_fully_fold (op1
, false, NULL
);
18121 TREE_OPERAND (cond
, 0) = op0
;
18122 TREE_OPERAND (cond
, 1) = op1
;
18124 switch (cond_expr
.original_code
)
18132 if (code
!= OACC_LOOP
)
18136 /* Can't be cond = error_mark_node, because we want to preserve
18137 the location until c_finish_omp_for. */
18138 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
18141 protected_set_expr_location (cond
, cond_loc
);
18143 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
18145 /* Parse the increment expression. */
18147 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
18149 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
18151 incr
= c_process_expr_stmt (incr_loc
,
18152 c_parser_expression (parser
).value
);
18154 parens
.skip_until_found_close (parser
);
18156 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
18160 TREE_VEC_ELT (declv
, i
) = decl
;
18161 TREE_VEC_ELT (initv
, i
) = init
;
18162 TREE_VEC_ELT (condv
, i
) = cond
;
18163 TREE_VEC_ELT (incrv
, i
) = incr
;
18167 if (i
== count
- 1)
18170 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
18171 in between the collapsed for loops to be still considered perfectly
18172 nested. Hopefully the final version clarifies this.
18173 For now handle (multiple) {'s and empty statements. */
18176 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
18178 c_parser_consume_token (parser
);
18181 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
18183 c_parser_consume_token (parser
);
18186 else if (bracecount
18187 && c_parser_next_token_is (parser
, CPP_SEMICOLON
))
18188 c_parser_consume_token (parser
);
18191 c_parser_error (parser
, "not enough perfectly nested loops");
18194 open_brace_parsed
= true;
18204 nbraces
+= bracecount
;
18210 save_break
= c_break_label
;
18211 c_break_label
= size_one_node
;
18212 save_cont
= c_cont_label
;
18213 c_cont_label
= NULL_TREE
;
18214 body
= push_stmt_list ();
18217 c_parser_omp_scan_loop_body (parser
, open_brace_parsed
);
18218 else if (open_brace_parsed
)
18220 location_t here
= c_parser_peek_token (parser
)->location
;
18221 stmt
= c_begin_compound_stmt (true);
18222 c_parser_compound_statement_nostart (parser
);
18223 add_stmt (c_end_compound_stmt (here
, stmt
, true));
18226 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
18229 tree t
= build1 (LABEL_EXPR
, void_type_node
, c_cont_label
);
18230 SET_EXPR_LOCATION (t
, loc
);
18234 body
= pop_stmt_list (body
);
18235 c_break_label
= save_break
;
18236 c_cont_label
= save_cont
;
18240 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18242 c_parser_consume_token (parser
);
18245 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
18246 c_parser_consume_token (parser
);
18249 c_parser_error (parser
, "collapsed loops not perfectly nested");
18252 location_t here
= c_parser_peek_token (parser
)->location
;
18253 stmt
= c_begin_compound_stmt (true);
18255 c_parser_compound_statement_nostart (parser
);
18256 body
= c_end_compound_stmt (here
, stmt
, true);
18263 /* Only bother calling c_finish_omp_for if we haven't already generated
18264 an error from the initialization parsing. */
18267 stmt
= c_finish_omp_for (loc
, code
, declv
, NULL
, initv
, condv
,
18268 incrv
, body
, pre_body
, true);
18270 /* Check for iterators appearing in lb, b or incr expressions. */
18271 if (stmt
&& !c_omp_check_loop_iv (stmt
, declv
, NULL
))
18278 if (cclauses
!= NULL
18279 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
18282 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
18283 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
18284 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
18285 c
= &OMP_CLAUSE_CHAIN (*c
);
18288 for (i
= 0; i
< count
; i
++)
18289 if (TREE_VEC_ELT (declv
, i
) == OMP_CLAUSE_DECL (*c
))
18292 c
= &OMP_CLAUSE_CHAIN (*c
);
18293 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
18296 "iteration variable %qD should not be firstprivate",
18297 OMP_CLAUSE_DECL (*c
));
18298 *c
= OMP_CLAUSE_CHAIN (*c
);
18302 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
18304 *c
= OMP_CLAUSE_CHAIN (*c
);
18305 if (code
== OMP_SIMD
)
18307 OMP_CLAUSE_CHAIN (l
)
18308 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
18309 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
18313 OMP_CLAUSE_CHAIN (l
) = clauses
;
18319 OMP_FOR_CLAUSES (stmt
) = clauses
;
18324 while (!for_block
->is_empty ())
18326 /* FIXME diagnostics: LOC below should be the actual location of
18327 this particular for block. We need to build a list of
18328 locations to go along with FOR_BLOCK. */
18329 stmt
= c_end_compound_stmt (loc
, for_block
->pop (), true);
18332 release_tree_vector (for_block
);
18336 /* Helper function for OpenMP parsing, split clauses and call
18337 finish_omp_clauses on each of the set of clauses afterwards. */
18340 omp_split_clauses (location_t loc
, enum tree_code code
,
18341 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
18344 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
18345 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
18347 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
], C_ORT_OMP
);
18351 #pragma omp loop loop-clause[optseq] new-line
18354 LOC is the location of the #pragma token.
18357 #define OMP_LOOP_CLAUSE_MASK \
18358 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18359 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18360 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18361 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18362 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
18363 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18366 c_parser_omp_loop (location_t loc
, c_parser
*parser
,
18367 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18370 tree block
, clauses
, ret
;
18372 strcat (p_name
, " loop");
18373 mask
|= OMP_LOOP_CLAUSE_MASK
;
18375 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18378 omp_split_clauses (loc
, OMP_LOOP
, mask
, clauses
, cclauses
);
18379 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_LOOP
];
18382 block
= c_begin_compound_stmt (true);
18383 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_LOOP
, clauses
, cclauses
, if_p
);
18384 block
= c_end_compound_stmt (loc
, block
, true);
18391 #pragma omp simd simd-clause[optseq] new-line
18394 LOC is the location of the #pragma token.
18397 #define OMP_SIMD_CLAUSE_MASK \
18398 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
18399 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
18400 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18401 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
18402 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18403 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18404 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18405 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18406 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18407 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
18408 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18411 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
18412 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18415 tree block
, clauses
, ret
;
18417 strcat (p_name
, " simd");
18418 mask
|= OMP_SIMD_CLAUSE_MASK
;
18420 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18423 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
18424 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
18425 tree c
= omp_find_clause (cclauses
[C_OMP_CLAUSE_SPLIT_FOR
],
18426 OMP_CLAUSE_ORDERED
);
18427 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
18429 error_at (OMP_CLAUSE_LOCATION (c
),
18430 "%<ordered%> clause with parameter may not be specified "
18431 "on %qs construct", p_name
);
18432 OMP_CLAUSE_ORDERED_EXPR (c
) = NULL_TREE
;
18436 block
= c_begin_compound_stmt (true);
18437 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
18438 block
= c_end_compound_stmt (loc
, block
, true);
18445 #pragma omp for for-clause[optseq] new-line
18449 #pragma omp for simd for-simd-clause[optseq] new-line
18452 LOC is the location of the #pragma token.
18455 #define OMP_FOR_CLAUSE_MASK \
18456 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18457 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18458 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18459 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18460 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18461 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
18462 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
18463 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18464 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
18465 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18468 c_parser_omp_for (location_t loc
, c_parser
*parser
,
18469 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18472 tree block
, clauses
, ret
;
18474 strcat (p_name
, " for");
18475 mask
|= OMP_FOR_CLAUSE_MASK
;
18476 /* parallel for{, simd} disallows nowait clause, but for
18477 target {teams distribute ,}parallel for{, simd} it should be accepted. */
18478 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
18479 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
18480 /* Composite distribute parallel for{, simd} disallows ordered clause. */
18481 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
18482 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
18484 if (c_parser_next_token_is (parser
, CPP_NAME
))
18486 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18488 if (strcmp (p
, "simd") == 0)
18490 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18491 if (cclauses
== NULL
)
18492 cclauses
= cclauses_buf
;
18494 c_parser_consume_token (parser
);
18495 if (!flag_openmp
) /* flag_openmp_simd */
18496 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
18498 block
= c_begin_compound_stmt (true);
18499 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
18500 block
= c_end_compound_stmt (loc
, block
, true);
18501 if (ret
== NULL_TREE
)
18503 ret
= make_node (OMP_FOR
);
18504 TREE_TYPE (ret
) = void_type_node
;
18505 OMP_FOR_BODY (ret
) = block
;
18506 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
18507 SET_EXPR_LOCATION (ret
, loc
);
18512 if (!flag_openmp
) /* flag_openmp_simd */
18514 c_parser_skip_to_pragma_eol (parser
, false);
18518 /* Composite distribute parallel for disallows linear clause. */
18519 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
18520 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
18522 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18525 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
18526 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
18529 block
= c_begin_compound_stmt (true);
18530 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
18531 block
= c_end_compound_stmt (loc
, block
, true);
18537 static tree
c_parser_omp_taskloop (location_t
, c_parser
*, char *,
18538 omp_clause_mask
, tree
*, bool *);
18541 # pragma omp master new-line
18544 LOC is the location of the #pragma token.
18548 c_parser_omp_master (location_t loc
, c_parser
*parser
,
18549 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18552 tree block
, clauses
, ret
;
18554 strcat (p_name
, " master");
18556 if (c_parser_next_token_is (parser
, CPP_NAME
))
18558 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18560 if (strcmp (p
, "taskloop") == 0)
18562 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18563 if (cclauses
== NULL
)
18564 cclauses
= cclauses_buf
;
18566 c_parser_consume_token (parser
);
18567 if (!flag_openmp
) /* flag_openmp_simd */
18568 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
18570 block
= c_begin_compound_stmt (true);
18571 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
18573 block
= c_end_compound_stmt (loc
, block
, true);
18574 if (ret
== NULL_TREE
)
18576 ret
= c_finish_omp_master (loc
, block
);
18580 if (!flag_openmp
) /* flag_openmp_simd */
18582 c_parser_skip_to_pragma_eol (parser
, false);
18588 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, false);
18589 omp_split_clauses (loc
, OMP_MASTER
, mask
, clauses
, cclauses
);
18592 c_parser_skip_to_pragma_eol (parser
);
18594 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
18599 # pragma omp ordered new-line
18603 # pragma omp ordered ordered-clauses new-line
18606 # pragma omp ordered depend-clauses new-line */
18608 #define OMP_ORDERED_CLAUSE_MASK \
18609 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
18610 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
18612 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
18613 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
18616 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
18619 location_t loc
= c_parser_peek_token (parser
)->location
;
18620 c_parser_consume_pragma (parser
);
18622 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
18624 c_parser_error (parser
, "expected declaration specifiers");
18625 c_parser_skip_to_pragma_eol (parser
, false);
18629 if (c_parser_next_token_is (parser
, CPP_NAME
))
18631 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18633 if (!strcmp ("depend", p
))
18635 if (!flag_openmp
) /* flag_openmp_simd */
18637 c_parser_skip_to_pragma_eol (parser
, false);
18640 if (context
== pragma_stmt
)
18643 "%<#pragma omp ordered%> with %<depend%> clause may "
18644 "only be used in compound statements");
18645 c_parser_skip_to_pragma_eol (parser
, false);
18650 = c_parser_omp_all_clauses (parser
,
18651 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
18652 "#pragma omp ordered");
18653 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
18658 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
18659 "#pragma omp ordered");
18661 if (!flag_openmp
/* flag_openmp_simd */
18662 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
18665 c_finish_omp_ordered (loc
, clauses
,
18666 c_parser_omp_structured_block (parser
, if_p
));
18673 { section-sequence }
18676 section-directive[opt] structured-block
18677 section-sequence section-directive structured-block
18679 SECTIONS_LOC is the location of the #pragma omp sections. */
18682 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
18684 tree stmt
, substmt
;
18685 bool error_suppress
= false;
18688 loc
= c_parser_peek_token (parser
)->location
;
18689 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
18691 /* Avoid skipping until the end of the block. */
18692 parser
->error
= false;
18696 stmt
= push_stmt_list ();
18698 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
)
18700 substmt
= c_parser_omp_structured_block (parser
, NULL
);
18701 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
18702 SET_EXPR_LOCATION (substmt
, loc
);
18703 add_stmt (substmt
);
18708 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18710 if (c_parser_next_token_is (parser
, CPP_EOF
))
18713 loc
= c_parser_peek_token (parser
)->location
;
18714 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
18716 c_parser_consume_pragma (parser
);
18717 c_parser_skip_to_pragma_eol (parser
);
18718 error_suppress
= false;
18720 else if (!error_suppress
)
18722 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
18723 error_suppress
= true;
18726 substmt
= c_parser_omp_structured_block (parser
, NULL
);
18727 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
18728 SET_EXPR_LOCATION (substmt
, loc
);
18729 add_stmt (substmt
);
18731 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
18732 "expected %<#pragma omp section%> or %<}%>");
18734 substmt
= pop_stmt_list (stmt
);
18736 stmt
= make_node (OMP_SECTIONS
);
18737 SET_EXPR_LOCATION (stmt
, sections_loc
);
18738 TREE_TYPE (stmt
) = void_type_node
;
18739 OMP_SECTIONS_BODY (stmt
) = substmt
;
18741 return add_stmt (stmt
);
18745 # pragma omp sections sections-clause[optseq] newline
18748 LOC is the location of the #pragma token.
18751 #define OMP_SECTIONS_CLAUSE_MASK \
18752 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18753 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18754 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18755 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18756 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18759 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
18760 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
18762 tree block
, clauses
, ret
;
18764 strcat (p_name
, " sections");
18765 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
18767 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
18769 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18772 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
18773 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
18776 block
= c_begin_compound_stmt (true);
18777 ret
= c_parser_omp_sections_scope (loc
, parser
);
18779 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
18780 block
= c_end_compound_stmt (loc
, block
, true);
18787 # pragma omp parallel parallel-clause[optseq] new-line
18789 # pragma omp parallel for parallel-for-clause[optseq] new-line
18791 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
18795 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
18798 LOC is the location of the #pragma token.
18801 #define OMP_PARALLEL_CLAUSE_MASK \
18802 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18805 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18806 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18807 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
18808 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18809 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
18810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
18813 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
18814 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18817 tree stmt
, clauses
, block
;
18819 strcat (p_name
, " parallel");
18820 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
18821 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
18822 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
18823 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
18824 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
18826 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
18828 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18829 if (cclauses
== NULL
)
18830 cclauses
= cclauses_buf
;
18832 c_parser_consume_token (parser
);
18833 if (!flag_openmp
) /* flag_openmp_simd */
18834 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
18835 block
= c_begin_omp_parallel ();
18836 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
18838 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
18840 if (ret
== NULL_TREE
)
18842 OMP_PARALLEL_COMBINED (stmt
) = 1;
18845 /* When combined with distribute, parallel has to be followed by for.
18846 #pragma omp target parallel is allowed though. */
18848 && (mask
& (OMP_CLAUSE_MASK_1
18849 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
18851 error_at (loc
, "expected %<for%> after %qs", p_name
);
18852 c_parser_skip_to_pragma_eol (parser
);
18855 else if (c_parser_next_token_is (parser
, CPP_NAME
))
18857 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18858 if (cclauses
== NULL
&& strcmp (p
, "master") == 0)
18860 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18861 cclauses
= cclauses_buf
;
18863 c_parser_consume_token (parser
);
18864 if (!flag_openmp
) /* flag_openmp_simd */
18865 return c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
18867 block
= c_begin_omp_parallel ();
18868 tree ret
= c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
18870 stmt
= c_finish_omp_parallel (loc
,
18871 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
18873 OMP_PARALLEL_COMBINED (stmt
) = 1;
18878 else if (strcmp (p
, "loop") == 0)
18880 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18881 if (cclauses
== NULL
)
18882 cclauses
= cclauses_buf
;
18884 c_parser_consume_token (parser
);
18885 if (!flag_openmp
) /* flag_openmp_simd */
18886 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
18888 block
= c_begin_omp_parallel ();
18889 tree ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
18892 = c_finish_omp_parallel (loc
,
18893 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
18895 if (ret
== NULL_TREE
)
18897 OMP_PARALLEL_COMBINED (stmt
) = 1;
18900 else if (!flag_openmp
) /* flag_openmp_simd */
18902 c_parser_skip_to_pragma_eol (parser
, false);
18905 else if (cclauses
== NULL
&& strcmp (p
, "sections") == 0)
18907 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18908 cclauses
= cclauses_buf
;
18910 c_parser_consume_token (parser
);
18911 block
= c_begin_omp_parallel ();
18912 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
18913 stmt
= c_finish_omp_parallel (loc
,
18914 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
18916 OMP_PARALLEL_COMBINED (stmt
) = 1;
18920 else if (!flag_openmp
) /* flag_openmp_simd */
18922 c_parser_skip_to_pragma_eol (parser
, false);
18926 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18929 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
18930 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
18933 block
= c_begin_omp_parallel ();
18934 c_parser_statement (parser
, if_p
);
18935 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
18941 # pragma omp single single-clause[optseq] new-line
18944 LOC is the location of the #pragma.
18947 #define OMP_SINGLE_CLAUSE_MASK \
18948 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18949 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18950 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
18951 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18954 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
18956 tree stmt
= make_node (OMP_SINGLE
);
18957 SET_EXPR_LOCATION (stmt
, loc
);
18958 TREE_TYPE (stmt
) = void_type_node
;
18960 OMP_SINGLE_CLAUSES (stmt
)
18961 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
18962 "#pragma omp single");
18963 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
18965 return add_stmt (stmt
);
18969 # pragma omp task task-clause[optseq] new-line
18971 LOC is the location of the #pragma.
18974 #define OMP_TASK_CLAUSE_MASK \
18975 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18976 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
18977 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18978 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18979 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18980 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18981 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
18982 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
18983 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
18984 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
18985 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
18988 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
18990 tree clauses
, block
;
18992 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
18993 "#pragma omp task");
18995 block
= c_begin_omp_task ();
18996 c_parser_statement (parser
, if_p
);
18997 return c_finish_omp_task (loc
, clauses
, block
);
19001 # pragma omp taskwait new-line
19004 # pragma omp taskwait taskwait-clause[optseq] new-line
19007 #define OMP_TASKWAIT_CLAUSE_MASK \
19008 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19011 c_parser_omp_taskwait (c_parser
*parser
)
19013 location_t loc
= c_parser_peek_token (parser
)->location
;
19014 c_parser_consume_pragma (parser
);
19017 = c_parser_omp_all_clauses (parser
, OMP_TASKWAIT_CLAUSE_MASK
,
19018 "#pragma omp taskwait");
19022 tree stmt
= make_node (OMP_TASK
);
19023 TREE_TYPE (stmt
) = void_node
;
19024 OMP_TASK_CLAUSES (stmt
) = clauses
;
19025 OMP_TASK_BODY (stmt
) = NULL_TREE
;
19026 SET_EXPR_LOCATION (stmt
, loc
);
19030 c_finish_omp_taskwait (loc
);
19034 # pragma omp taskyield new-line
19038 c_parser_omp_taskyield (c_parser
*parser
)
19040 location_t loc
= c_parser_peek_token (parser
)->location
;
19041 c_parser_consume_pragma (parser
);
19042 c_parser_skip_to_pragma_eol (parser
);
19044 c_finish_omp_taskyield (loc
);
19048 # pragma omp taskgroup new-line
19051 # pragma omp taskgroup taskgroup-clause[optseq] new-line
19054 #define OMP_TASKGROUP_CLAUSE_MASK \
19055 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
19058 c_parser_omp_taskgroup (location_t loc
, c_parser
*parser
, bool *if_p
)
19060 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_TASKGROUP_CLAUSE_MASK
,
19061 "#pragma omp taskgroup");
19063 tree body
= c_parser_omp_structured_block (parser
, if_p
);
19064 return c_finish_omp_taskgroup (loc
, body
, clauses
);
19068 # pragma omp cancel cancel-clause[optseq] new-line
19070 LOC is the location of the #pragma.
19073 #define OMP_CANCEL_CLAUSE_MASK \
19074 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19075 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19076 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19077 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
19078 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
19081 c_parser_omp_cancel (c_parser
*parser
)
19083 location_t loc
= c_parser_peek_token (parser
)->location
;
19085 c_parser_consume_pragma (parser
);
19086 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
19087 "#pragma omp cancel");
19089 c_finish_omp_cancel (loc
, clauses
);
19093 # pragma omp cancellation point cancelpt-clause[optseq] new-line
19095 LOC is the location of the #pragma.
19098 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
19099 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19100 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19101 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19102 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
19105 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
19107 location_t loc
= c_parser_peek_token (parser
)->location
;
19109 bool point_seen
= false;
19111 c_parser_consume_pragma (parser
);
19112 if (c_parser_next_token_is (parser
, CPP_NAME
))
19114 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19115 if (strcmp (p
, "point") == 0)
19117 c_parser_consume_token (parser
);
19123 c_parser_error (parser
, "expected %<point%>");
19124 c_parser_skip_to_pragma_eol (parser
);
19128 if (context
!= pragma_compound
)
19130 if (context
== pragma_stmt
)
19132 "%<#pragma %s%> may only be used in compound statements",
19133 "omp cancellation point");
19135 c_parser_error (parser
, "expected declaration specifiers");
19136 c_parser_skip_to_pragma_eol (parser
, false);
19141 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
19142 "#pragma omp cancellation point");
19144 c_finish_omp_cancellation_point (loc
, clauses
);
19148 #pragma omp distribute distribute-clause[optseq] new-line
19151 #define OMP_DISTRIBUTE_CLAUSE_MASK \
19152 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19154 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19155 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
19156 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
19159 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
19160 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19163 tree clauses
, block
, ret
;
19165 strcat (p_name
, " distribute");
19166 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
19168 if (c_parser_next_token_is (parser
, CPP_NAME
))
19170 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19172 bool parallel
= false;
19174 if (strcmp (p
, "simd") == 0)
19177 parallel
= strcmp (p
, "parallel") == 0;
19178 if (parallel
|| simd
)
19180 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19181 if (cclauses
== NULL
)
19182 cclauses
= cclauses_buf
;
19183 c_parser_consume_token (parser
);
19184 if (!flag_openmp
) /* flag_openmp_simd */
19187 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
19190 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
19193 block
= c_begin_compound_stmt (true);
19195 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
19198 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
19200 block
= c_end_compound_stmt (loc
, block
, true);
19203 ret
= make_node (OMP_DISTRIBUTE
);
19204 TREE_TYPE (ret
) = void_type_node
;
19205 OMP_FOR_BODY (ret
) = block
;
19206 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
19207 SET_EXPR_LOCATION (ret
, loc
);
19212 if (!flag_openmp
) /* flag_openmp_simd */
19214 c_parser_skip_to_pragma_eol (parser
, false);
19218 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19221 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
19222 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
19225 block
= c_begin_compound_stmt (true);
19226 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
19228 block
= c_end_compound_stmt (loc
, block
, true);
19235 # pragma omp teams teams-clause[optseq] new-line
19236 structured-block */
19238 #define OMP_TEAMS_CLAUSE_MASK \
19239 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19240 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19241 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
19242 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19243 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
19244 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
19245 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
19248 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
19249 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19252 tree clauses
, block
, ret
;
19254 strcat (p_name
, " teams");
19255 mask
|= OMP_TEAMS_CLAUSE_MASK
;
19257 if (c_parser_next_token_is (parser
, CPP_NAME
))
19259 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19260 if (strcmp (p
, "distribute") == 0)
19262 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19263 if (cclauses
== NULL
)
19264 cclauses
= cclauses_buf
;
19266 c_parser_consume_token (parser
);
19267 if (!flag_openmp
) /* flag_openmp_simd */
19268 return c_parser_omp_distribute (loc
, parser
, p_name
, mask
,
19270 block
= c_begin_omp_parallel ();
19271 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
19273 block
= c_end_compound_stmt (loc
, block
, true);
19276 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19277 ret
= make_node (OMP_TEAMS
);
19278 TREE_TYPE (ret
) = void_type_node
;
19279 OMP_TEAMS_CLAUSES (ret
) = clauses
;
19280 OMP_TEAMS_BODY (ret
) = block
;
19281 OMP_TEAMS_COMBINED (ret
) = 1;
19282 SET_EXPR_LOCATION (ret
, loc
);
19283 return add_stmt (ret
);
19285 else if (strcmp (p
, "loop") == 0)
19287 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19288 if (cclauses
== NULL
)
19289 cclauses
= cclauses_buf
;
19291 c_parser_consume_token (parser
);
19292 if (!flag_openmp
) /* flag_openmp_simd */
19293 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
19295 block
= c_begin_omp_parallel ();
19296 ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
19297 block
= c_end_compound_stmt (loc
, block
, true);
19300 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19301 ret
= make_node (OMP_TEAMS
);
19302 TREE_TYPE (ret
) = void_type_node
;
19303 OMP_TEAMS_CLAUSES (ret
) = clauses
;
19304 OMP_TEAMS_BODY (ret
) = block
;
19305 OMP_TEAMS_COMBINED (ret
) = 1;
19306 SET_EXPR_LOCATION (ret
, loc
);
19307 return add_stmt (ret
);
19310 if (!flag_openmp
) /* flag_openmp_simd */
19312 c_parser_skip_to_pragma_eol (parser
, false);
19316 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19319 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
19320 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19323 tree stmt
= make_node (OMP_TEAMS
);
19324 TREE_TYPE (stmt
) = void_type_node
;
19325 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
19326 block
= c_begin_omp_parallel ();
19327 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19328 OMP_TEAMS_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
19329 SET_EXPR_LOCATION (stmt
, loc
);
19331 return add_stmt (stmt
);
19335 # pragma omp target data target-data-clause[optseq] new-line
19336 structured-block */
19338 #define OMP_TARGET_DATA_CLAUSE_MASK \
19339 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19340 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19341 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19342 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
19343 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
19346 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
19349 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
19350 "#pragma omp target data");
19352 for (tree
*pc
= &clauses
; *pc
;)
19354 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
19355 switch (OMP_CLAUSE_MAP_KIND (*pc
))
19358 case GOMP_MAP_ALWAYS_TO
:
19359 case GOMP_MAP_FROM
:
19360 case GOMP_MAP_ALWAYS_FROM
:
19361 case GOMP_MAP_TOFROM
:
19362 case GOMP_MAP_ALWAYS_TOFROM
:
19363 case GOMP_MAP_ALLOC
:
19366 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19367 case GOMP_MAP_ALWAYS_POINTER
:
19371 error_at (OMP_CLAUSE_LOCATION (*pc
),
19372 "%<#pragma omp target data%> with map-type other "
19373 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19374 "on %<map%> clause");
19375 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19378 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
19379 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
19381 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19388 "%<#pragma omp target data%> must contain at least "
19389 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
19394 tree stmt
= make_node (OMP_TARGET_DATA
);
19395 TREE_TYPE (stmt
) = void_type_node
;
19396 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
19397 keep_next_level ();
19398 tree block
= c_begin_compound_stmt (true);
19399 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19400 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
19402 SET_EXPR_LOCATION (stmt
, loc
);
19403 return add_stmt (stmt
);
19407 # pragma omp target update target-update-clause[optseq] new-line */
19409 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
19410 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
19411 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
19412 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19413 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19414 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19415 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19418 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
19419 enum pragma_context context
)
19421 if (context
== pragma_stmt
)
19423 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
19424 "omp target update");
19425 c_parser_skip_to_pragma_eol (parser
, false);
19430 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
19431 "#pragma omp target update");
19432 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
19433 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
19436 "%<#pragma omp target update%> must contain at least one "
19437 "%<from%> or %<to%> clauses");
19441 tree stmt
= make_node (OMP_TARGET_UPDATE
);
19442 TREE_TYPE (stmt
) = void_type_node
;
19443 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
19444 SET_EXPR_LOCATION (stmt
, loc
);
19450 # pragma omp target enter data target-data-clause[optseq] new-line */
19452 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
19453 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19454 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19455 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19456 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19457 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19460 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
19461 enum pragma_context context
)
19463 bool data_seen
= false;
19464 if (c_parser_next_token_is (parser
, CPP_NAME
))
19466 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19467 if (strcmp (p
, "data") == 0)
19469 c_parser_consume_token (parser
);
19475 c_parser_error (parser
, "expected %<data%>");
19476 c_parser_skip_to_pragma_eol (parser
);
19480 if (context
== pragma_stmt
)
19482 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
19483 "omp target enter data");
19484 c_parser_skip_to_pragma_eol (parser
, false);
19489 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
19490 "#pragma omp target enter data");
19492 for (tree
*pc
= &clauses
; *pc
;)
19494 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
19495 switch (OMP_CLAUSE_MAP_KIND (*pc
))
19498 case GOMP_MAP_ALWAYS_TO
:
19499 case GOMP_MAP_ALLOC
:
19502 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19503 case GOMP_MAP_ALWAYS_POINTER
:
19507 error_at (OMP_CLAUSE_LOCATION (*pc
),
19508 "%<#pragma omp target enter data%> with map-type other "
19509 "than %<to%> or %<alloc%> on %<map%> clause");
19510 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19513 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19520 "%<#pragma omp target enter data%> must contain at least "
19521 "one %<map%> clause");
19525 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
19526 TREE_TYPE (stmt
) = void_type_node
;
19527 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
19528 SET_EXPR_LOCATION (stmt
, loc
);
19534 # pragma omp target exit data target-data-clause[optseq] new-line */
19536 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
19537 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19538 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19539 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19540 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19544 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
19545 enum pragma_context context
)
19547 bool data_seen
= false;
19548 if (c_parser_next_token_is (parser
, CPP_NAME
))
19550 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19551 if (strcmp (p
, "data") == 0)
19553 c_parser_consume_token (parser
);
19559 c_parser_error (parser
, "expected %<data%>");
19560 c_parser_skip_to_pragma_eol (parser
);
19564 if (context
== pragma_stmt
)
19566 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
19567 "omp target exit data");
19568 c_parser_skip_to_pragma_eol (parser
, false);
19573 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
19574 "#pragma omp target exit data");
19577 for (tree
*pc
= &clauses
; *pc
;)
19579 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
19580 switch (OMP_CLAUSE_MAP_KIND (*pc
))
19582 case GOMP_MAP_FROM
:
19583 case GOMP_MAP_ALWAYS_FROM
:
19584 case GOMP_MAP_RELEASE
:
19585 case GOMP_MAP_DELETE
:
19588 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19589 case GOMP_MAP_ALWAYS_POINTER
:
19593 error_at (OMP_CLAUSE_LOCATION (*pc
),
19594 "%<#pragma omp target exit data%> with map-type other "
19595 "than %<from%>, %<release%> or %<delete%> on %<map%>"
19597 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19600 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19607 "%<#pragma omp target exit data%> must contain at least one "
19612 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
19613 TREE_TYPE (stmt
) = void_type_node
;
19614 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
19615 SET_EXPR_LOCATION (stmt
, loc
);
19621 # pragma omp target target-clause[optseq] new-line
19622 structured-block */
19624 #define OMP_TARGET_CLAUSE_MASK \
19625 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19626 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19627 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19628 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19629 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19630 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19631 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19632 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
19633 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
19636 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
19638 location_t loc
= c_parser_peek_token (parser
)->location
;
19639 c_parser_consume_pragma (parser
);
19640 tree
*pc
= NULL
, stmt
, block
;
19642 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
19644 c_parser_error (parser
, "expected declaration specifiers");
19645 c_parser_skip_to_pragma_eol (parser
);
19651 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
19653 if (c_parser_next_token_is (parser
, CPP_NAME
))
19655 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19656 enum tree_code ccode
= ERROR_MARK
;
19658 if (strcmp (p
, "teams") == 0)
19660 else if (strcmp (p
, "parallel") == 0)
19661 ccode
= OMP_PARALLEL
;
19662 else if (strcmp (p
, "simd") == 0)
19664 if (ccode
!= ERROR_MARK
)
19666 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
19667 char p_name
[sizeof ("#pragma omp target teams distribute "
19668 "parallel for simd")];
19670 c_parser_consume_token (parser
);
19671 strcpy (p_name
, "#pragma omp target");
19672 if (!flag_openmp
) /* flag_openmp_simd */
19678 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
19679 OMP_TARGET_CLAUSE_MASK
,
19683 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
19684 OMP_TARGET_CLAUSE_MASK
,
19688 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
19689 OMP_TARGET_CLAUSE_MASK
,
19693 gcc_unreachable ();
19695 return stmt
!= NULL_TREE
;
19697 keep_next_level ();
19698 tree block
= c_begin_compound_stmt (true), ret
;
19702 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
19703 OMP_TARGET_CLAUSE_MASK
, cclauses
,
19707 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
19708 OMP_TARGET_CLAUSE_MASK
, cclauses
,
19712 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
19713 OMP_TARGET_CLAUSE_MASK
, cclauses
,
19717 gcc_unreachable ();
19719 block
= c_end_compound_stmt (loc
, block
, true);
19720 if (ret
== NULL_TREE
)
19722 if (ccode
== OMP_TEAMS
)
19724 /* For combined target teams, ensure the num_teams and
19725 thread_limit clause expressions are evaluated on the host,
19726 before entering the target construct. */
19728 for (c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19729 c
; c
= OMP_CLAUSE_CHAIN (c
))
19730 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
19731 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
19732 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, 0)) != INTEGER_CST
)
19734 tree expr
= OMP_CLAUSE_OPERAND (c
, 0);
19735 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
19736 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
19737 expr
, NULL_TREE
, NULL_TREE
);
19739 OMP_CLAUSE_OPERAND (c
, 0) = expr
;
19740 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
19741 OMP_CLAUSE_FIRSTPRIVATE
);
19742 OMP_CLAUSE_DECL (tc
) = tmp
;
19743 OMP_CLAUSE_CHAIN (tc
)
19744 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
19745 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
19748 tree stmt
= make_node (OMP_TARGET
);
19749 TREE_TYPE (stmt
) = void_type_node
;
19750 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
19751 OMP_TARGET_BODY (stmt
) = block
;
19752 OMP_TARGET_COMBINED (stmt
) = 1;
19753 SET_EXPR_LOCATION (stmt
, loc
);
19755 pc
= &OMP_TARGET_CLAUSES (stmt
);
19756 goto check_clauses
;
19758 else if (!flag_openmp
) /* flag_openmp_simd */
19760 c_parser_skip_to_pragma_eol (parser
, false);
19763 else if (strcmp (p
, "data") == 0)
19765 c_parser_consume_token (parser
);
19766 c_parser_omp_target_data (loc
, parser
, if_p
);
19769 else if (strcmp (p
, "enter") == 0)
19771 c_parser_consume_token (parser
);
19772 c_parser_omp_target_enter_data (loc
, parser
, context
);
19775 else if (strcmp (p
, "exit") == 0)
19777 c_parser_consume_token (parser
);
19778 c_parser_omp_target_exit_data (loc
, parser
, context
);
19781 else if (strcmp (p
, "update") == 0)
19783 c_parser_consume_token (parser
);
19784 return c_parser_omp_target_update (loc
, parser
, context
);
19787 if (!flag_openmp
) /* flag_openmp_simd */
19789 c_parser_skip_to_pragma_eol (parser
, false);
19793 stmt
= make_node (OMP_TARGET
);
19794 TREE_TYPE (stmt
) = void_type_node
;
19796 OMP_TARGET_CLAUSES (stmt
)
19797 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
19798 "#pragma omp target");
19799 pc
= &OMP_TARGET_CLAUSES (stmt
);
19800 keep_next_level ();
19801 block
= c_begin_compound_stmt (true);
19802 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19803 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
19805 SET_EXPR_LOCATION (stmt
, loc
);
19811 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
19812 switch (OMP_CLAUSE_MAP_KIND (*pc
))
19815 case GOMP_MAP_ALWAYS_TO
:
19816 case GOMP_MAP_FROM
:
19817 case GOMP_MAP_ALWAYS_FROM
:
19818 case GOMP_MAP_TOFROM
:
19819 case GOMP_MAP_ALWAYS_TOFROM
:
19820 case GOMP_MAP_ALLOC
:
19821 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19822 case GOMP_MAP_ALWAYS_POINTER
:
19825 error_at (OMP_CLAUSE_LOCATION (*pc
),
19826 "%<#pragma omp target%> with map-type other "
19827 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19828 "on %<map%> clause");
19829 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19832 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19838 # pragma omp declare simd declare-simd-clauses[optseq] new-line
19841 # pragma omp declare variant (identifier) match(context-selector) new-line
19844 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
19845 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19846 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19847 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19848 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
19849 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
19850 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
19853 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
19855 c_token
*token
= c_parser_peek_token (parser
);
19856 gcc_assert (token
->type
== CPP_NAME
);
19857 tree kind
= token
->value
;
19858 gcc_assert (strcmp (IDENTIFIER_POINTER (kind
), "simd") == 0
19859 || strcmp (IDENTIFIER_POINTER (kind
), "variant") == 0);
19861 auto_vec
<c_token
> clauses
;
19862 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19864 c_token
*token
= c_parser_peek_token (parser
);
19865 if (token
->type
== CPP_EOF
)
19867 c_parser_skip_to_pragma_eol (parser
);
19870 clauses
.safe_push (*token
);
19871 c_parser_consume_token (parser
);
19873 clauses
.safe_push (*c_parser_peek_token (parser
));
19874 c_parser_skip_to_pragma_eol (parser
);
19876 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
19878 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_DECLARE
19879 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
19880 || c_parser_peek_2nd_token (parser
)->value
!= kind
)
19882 error ("%<#pragma omp declare %s%> must be followed by "
19883 "function declaration or definition or another "
19884 "%<#pragma omp declare %s%>",
19885 IDENTIFIER_POINTER (kind
), IDENTIFIER_POINTER (kind
));
19888 c_parser_consume_pragma (parser
);
19889 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19891 c_token
*token
= c_parser_peek_token (parser
);
19892 if (token
->type
== CPP_EOF
)
19894 c_parser_skip_to_pragma_eol (parser
);
19897 clauses
.safe_push (*token
);
19898 c_parser_consume_token (parser
);
19900 clauses
.safe_push (*c_parser_peek_token (parser
));
19901 c_parser_skip_to_pragma_eol (parser
);
19904 /* Make sure nothing tries to read past the end of the tokens. */
19906 memset (&eof_token
, 0, sizeof (eof_token
));
19907 eof_token
.type
= CPP_EOF
;
19908 clauses
.safe_push (eof_token
);
19909 clauses
.safe_push (eof_token
);
19913 case pragma_external
:
19914 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19915 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
19917 int ext
= disable_extension_diagnostics ();
19919 c_parser_consume_token (parser
);
19920 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19921 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
19922 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
19924 restore_extension_diagnostics (ext
);
19927 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
19930 case pragma_struct
:
19933 error ("%<#pragma omp declare %s%> must be followed by "
19934 "function declaration or definition",
19935 IDENTIFIER_POINTER (kind
));
19937 case pragma_compound
:
19938 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19939 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
19941 int ext
= disable_extension_diagnostics ();
19943 c_parser_consume_token (parser
);
19944 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19945 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
19946 if (c_parser_next_tokens_start_declaration (parser
))
19948 c_parser_declaration_or_fndef (parser
, true, true, true, true,
19949 true, NULL
, clauses
);
19950 restore_extension_diagnostics (ext
);
19953 restore_extension_diagnostics (ext
);
19955 else if (c_parser_next_tokens_start_declaration (parser
))
19957 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
19961 error ("%<#pragma omp declare %s%> must be followed by "
19962 "function declaration or definition",
19963 IDENTIFIER_POINTER (kind
));
19966 gcc_unreachable ();
19970 static const char *const omp_construct_selectors
[] = {
19971 "simd", "target", "teams", "parallel", "for", NULL
};
19972 static const char *const omp_device_selectors
[] = {
19973 "kind", "isa", "arch", NULL
};
19974 static const char *const omp_implementation_selectors
[] = {
19975 "vendor", "extension", "atomic_default_mem_order", "unified_address",
19976 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL
};
19977 static const char *const omp_user_selectors
[] = {
19978 "condition", NULL
};
19983 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
19986 score(score-expression) */
19989 c_parser_omp_context_selector (c_parser
*parser
, tree set
, tree parms
)
19991 tree ret
= NULL_TREE
;
19995 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19996 || c_parser_next_token_is (parser
, CPP_NAME
))
19997 selector
= c_parser_peek_token (parser
)->value
;
20000 c_parser_error (parser
, "expected trait selector name");
20001 return error_mark_node
;
20004 tree properties
= NULL_TREE
;
20005 const char *const *selectors
= NULL
;
20006 bool allow_score
= true;
20007 bool allow_user
= false;
20008 int property_limit
= 0;
20009 enum { CTX_PROPERTY_NONE
, CTX_PROPERTY_USER
, CTX_PROPERTY_NAME_LIST
,
20010 CTX_PROPERTY_ID
, CTX_PROPERTY_EXPR
,
20011 CTX_PROPERTY_SIMD
} property_kind
= CTX_PROPERTY_NONE
;
20012 switch (IDENTIFIER_POINTER (set
)[0])
20014 case 'c': /* construct */
20015 selectors
= omp_construct_selectors
;
20016 allow_score
= false;
20017 property_limit
= 1;
20018 property_kind
= CTX_PROPERTY_SIMD
;
20020 case 'd': /* device */
20021 selectors
= omp_device_selectors
;
20022 allow_score
= false;
20024 property_limit
= 3;
20025 property_kind
= CTX_PROPERTY_NAME_LIST
;
20027 case 'i': /* implementation */
20028 selectors
= omp_implementation_selectors
;
20030 property_limit
= 3;
20031 property_kind
= CTX_PROPERTY_NAME_LIST
;
20033 case 'u': /* user */
20034 selectors
= omp_user_selectors
;
20035 property_limit
= 1;
20036 property_kind
= CTX_PROPERTY_EXPR
;
20039 gcc_unreachable ();
20041 for (int i
= 0; ; i
++)
20043 if (selectors
[i
] == NULL
)
20047 property_kind
= CTX_PROPERTY_USER
;
20052 error_at (c_parser_peek_token (parser
)->location
,
20053 "selector %qs not allowed for context selector "
20054 "set %qs", IDENTIFIER_POINTER (selector
),
20055 IDENTIFIER_POINTER (set
));
20056 c_parser_consume_token (parser
);
20057 return error_mark_node
;
20060 if (i
== property_limit
)
20061 property_kind
= CTX_PROPERTY_NONE
;
20062 if (strcmp (selectors
[i
], IDENTIFIER_POINTER (selector
)) == 0)
20065 if (property_kind
== CTX_PROPERTY_NAME_LIST
20066 && IDENTIFIER_POINTER (set
)[0] == 'i'
20067 && strcmp (IDENTIFIER_POINTER (selector
),
20068 "atomic_default_mem_order") == 0)
20069 property_kind
= CTX_PROPERTY_ID
;
20071 c_parser_consume_token (parser
);
20073 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
20075 if (property_kind
== CTX_PROPERTY_NONE
)
20077 error_at (c_parser_peek_token (parser
)->location
,
20078 "selector %qs does not accept any properties",
20079 IDENTIFIER_POINTER (selector
));
20080 return error_mark_node
;
20083 matching_parens parens
;
20084 parens
.require_open (parser
);
20086 c_token
*token
= c_parser_peek_token (parser
);
20088 && c_parser_next_token_is (parser
, CPP_NAME
)
20089 && strcmp (IDENTIFIER_POINTER (token
->value
), "score") == 0
20090 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
20092 c_parser_consume_token (parser
);
20094 matching_parens parens2
;
20095 parens2
.require_open (parser
);
20096 tree score
= c_parser_expr_no_commas (parser
, NULL
).value
;
20097 parens2
.skip_until_found_close (parser
);
20098 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
20099 if (score
!= error_mark_node
)
20101 mark_exp_read (score
);
20102 score
= c_fully_fold (score
, false, NULL
);
20103 if (!INTEGRAL_TYPE_P (TREE_TYPE (score
))
20104 || TREE_CODE (score
) != INTEGER_CST
)
20105 error_at (token
->location
, "score argument must be "
20106 "constant integer expression");
20107 else if (tree_int_cst_sgn (score
) < 0)
20108 error_at (token
->location
, "score argument must be "
20111 properties
= tree_cons (get_identifier (" score"),
20112 score
, properties
);
20114 token
= c_parser_peek_token (parser
);
20117 switch (property_kind
)
20120 case CTX_PROPERTY_USER
:
20123 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
20124 if (TREE_CODE (t
) == STRING_CST
)
20125 properties
= tree_cons (NULL_TREE
, t
, properties
);
20126 else if (t
!= error_mark_node
)
20129 t
= c_fully_fold (t
, false, NULL
);
20130 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
20131 || !tree_fits_shwi_p (t
))
20132 error_at (token
->location
, "property must be "
20133 "constant integer expression or string "
20136 properties
= tree_cons (NULL_TREE
, t
, properties
);
20139 return error_mark_node
;
20141 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20142 c_parser_consume_token (parser
);
20148 case CTX_PROPERTY_ID
:
20149 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20150 || c_parser_next_token_is (parser
, CPP_NAME
))
20152 tree prop
= c_parser_peek_token (parser
)->value
;
20153 c_parser_consume_token (parser
);
20154 properties
= tree_cons (prop
, NULL_TREE
, properties
);
20158 c_parser_error (parser
, "expected identifier");
20159 return error_mark_node
;
20162 case CTX_PROPERTY_NAME_LIST
:
20165 tree prop
= NULL_TREE
, value
= NULL_TREE
;
20166 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20167 || c_parser_next_token_is (parser
, CPP_NAME
))
20169 prop
= c_parser_peek_token (parser
)->value
;
20170 c_parser_consume_token (parser
);
20172 else if (c_parser_next_token_is (parser
, CPP_STRING
))
20173 value
= c_parser_string_literal (parser
, false,
20177 c_parser_error (parser
, "expected identifier or "
20179 return error_mark_node
;
20182 properties
= tree_cons (prop
, value
, properties
);
20184 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20185 c_parser_consume_token (parser
);
20191 case CTX_PROPERTY_EXPR
:
20192 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
20193 if (t
!= error_mark_node
)
20196 t
= c_fully_fold (t
, false, NULL
);
20197 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
20198 || !tree_fits_shwi_p (t
))
20199 error_at (token
->location
, "property must be "
20200 "constant integer expression");
20202 properties
= tree_cons (NULL_TREE
, t
, properties
);
20205 return error_mark_node
;
20207 case CTX_PROPERTY_SIMD
:
20208 if (parms
== NULL_TREE
)
20210 error_at (token
->location
, "properties for %<simd%> "
20211 "selector may not be specified in "
20212 "%<metadirective%>");
20213 return error_mark_node
;
20216 c
= c_parser_omp_all_clauses (parser
,
20217 OMP_DECLARE_SIMD_CLAUSE_MASK
,
20219 c
= c_omp_declare_simd_clauses_to_numbers (parms
20221 ? NULL_TREE
: parms
,
20226 gcc_unreachable ();
20229 parens
.skip_until_found_close (parser
);
20230 properties
= nreverse (properties
);
20232 else if (property_kind
== CTX_PROPERTY_NAME_LIST
20233 || property_kind
== CTX_PROPERTY_ID
20234 || property_kind
== CTX_PROPERTY_EXPR
)
20236 c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>");
20237 return error_mark_node
;
20240 ret
= tree_cons (selector
, properties
, ret
);
20242 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20243 c_parser_consume_token (parser
);
20249 return nreverse (ret
);
20254 trait-set-selector[,trait-set-selector[,...]]
20256 trait-set-selector:
20257 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
20259 trait-set-selector-name:
20266 c_parser_omp_context_selector_specification (c_parser
*parser
, tree parms
)
20268 tree ret
= NULL_TREE
;
20271 const char *setp
= "";
20272 if (c_parser_next_token_is (parser
, CPP_NAME
))
20273 setp
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20277 if (strcmp (setp
, "construct") == 0)
20281 if (strcmp (setp
, "device") == 0)
20285 if (strcmp (setp
, "implementation") == 0)
20289 if (strcmp (setp
, "user") == 0)
20297 c_parser_error (parser
, "expected %<construct%>, %<device%>, "
20298 "%<implementation%> or %<user%>");
20299 return error_mark_node
;
20302 tree set
= c_parser_peek_token (parser
)->value
;
20303 c_parser_consume_token (parser
);
20305 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
20306 return error_mark_node
;
20308 matching_braces braces
;
20309 if (!braces
.require_open (parser
))
20310 return error_mark_node
;
20312 tree selectors
= c_parser_omp_context_selector (parser
, set
, parms
);
20313 if (selectors
== error_mark_node
)
20314 ret
= error_mark_node
;
20315 else if (ret
!= error_mark_node
)
20316 ret
= tree_cons (set
, selectors
, ret
);
20318 braces
.skip_until_found_close (parser
);
20320 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20321 c_parser_consume_token (parser
);
20327 if (ret
== error_mark_node
)
20329 return nreverse (ret
);
20332 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
20333 that into "omp declare variant base" attribute. */
20336 c_finish_omp_declare_variant (c_parser
*parser
, tree fndecl
, tree parms
)
20338 matching_parens parens
;
20339 if (!parens
.require_open (parser
))
20342 c_parser_skip_to_pragma_eol (parser
, false);
20346 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
20347 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
20349 c_parser_error (parser
, "expected identifier");
20353 c_token
*token
= c_parser_peek_token (parser
);
20354 tree variant
= lookup_name (token
->value
);
20356 if (variant
== NULL_TREE
)
20358 undeclared_variable (token
->location
, token
->value
);
20359 variant
= error_mark_node
;
20362 c_parser_consume_token (parser
);
20364 parens
.require_close (parser
);
20366 const char *clause
= "";
20367 location_t match_loc
= c_parser_peek_token (parser
)->location
;
20368 if (c_parser_next_token_is (parser
, CPP_NAME
))
20369 clause
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20370 if (strcmp (clause
, "match"))
20372 c_parser_error (parser
, "expected %<match%>");
20376 c_parser_consume_token (parser
);
20378 if (!parens
.require_open (parser
))
20381 if (parms
== NULL_TREE
)
20382 parms
= error_mark_node
;
20384 tree ctx
= c_parser_omp_context_selector_specification (parser
, parms
);
20385 if (ctx
== error_mark_node
)
20387 ctx
= c_omp_check_context_selector (match_loc
, ctx
);
20388 if (ctx
!= error_mark_node
&& variant
!= error_mark_node
)
20390 if (TREE_CODE (variant
) != FUNCTION_DECL
)
20392 error_at (token
->location
, "variant %qD is not a function", variant
);
20393 variant
= error_mark_node
;
20395 else if (omp_get_context_selector (ctx
, "construct", "simd") == NULL_TREE
20396 && !comptypes (TREE_TYPE (fndecl
), TREE_TYPE (variant
)))
20398 error_at (token
->location
, "variant %qD and base %qD have "
20399 "incompatible types", variant
, fndecl
);
20400 variant
= error_mark_node
;
20402 else if (fndecl_built_in_p (variant
)
20403 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
20404 "__builtin_", strlen ("__builtin_")) == 0
20405 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
20406 "__sync_", strlen ("__sync_")) == 0
20407 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
20408 "__atomic_", strlen ("__atomic_")) == 0))
20410 error_at (token
->location
, "variant %qD is a built-in", variant
);
20411 variant
= error_mark_node
;
20413 if (variant
!= error_mark_node
)
20415 C_DECL_USED (variant
) = 1;
20416 tree construct
= omp_get_context_selector (ctx
, "construct", NULL
);
20417 c_omp_mark_declare_variant (match_loc
, variant
, construct
);
20418 if (omp_context_selector_matches (ctx
))
20421 = tree_cons (get_identifier ("omp declare variant base"),
20422 build_tree_list (variant
, ctx
),
20423 DECL_ATTRIBUTES (fndecl
));
20424 DECL_ATTRIBUTES (fndecl
) = attr
;
20429 parens
.require_close (parser
);
20430 c_parser_skip_to_pragma_eol (parser
);
20433 /* Finalize #pragma omp declare simd or #pragma omp declare variant
20434 clauses after FNDECL has been parsed, and put that into "omp declare simd"
20435 or "omp declare variant base" attribute. */
20438 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
20439 vec
<c_token
> clauses
)
20441 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
20442 indicates error has been reported and CPP_PRAGMA that
20443 c_finish_omp_declare_simd has already processed the tokens. */
20444 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
20446 const char *kind
= "simd";
20447 if (clauses
.exists ()
20448 && (clauses
[0].type
== CPP_NAME
|| clauses
[0].type
== CPP_PRAGMA
))
20449 kind
= IDENTIFIER_POINTER (clauses
[0].value
);
20450 gcc_assert (strcmp (kind
, "simd") == 0 || strcmp (kind
, "variant") == 0);
20451 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
20453 error ("%<#pragma omp declare %s%> not immediately followed by "
20454 "a function declaration or definition", kind
);
20455 clauses
[0].type
= CPP_EOF
;
20458 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
20460 error_at (DECL_SOURCE_LOCATION (fndecl
),
20461 "%<#pragma omp declare %s%> not immediately followed by "
20462 "a single function declaration or definition", kind
);
20463 clauses
[0].type
= CPP_EOF
;
20467 if (parms
== NULL_TREE
)
20468 parms
= DECL_ARGUMENTS (fndecl
);
20470 unsigned int tokens_avail
= parser
->tokens_avail
;
20471 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
20473 parser
->tokens
= clauses
.address ();
20474 parser
->tokens_avail
= clauses
.length ();
20476 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
20477 while (parser
->tokens_avail
> 3)
20479 c_token
*token
= c_parser_peek_token (parser
);
20480 gcc_assert (token
->type
== CPP_NAME
20481 && strcmp (IDENTIFIER_POINTER (token
->value
), kind
) == 0);
20482 c_parser_consume_token (parser
);
20483 parser
->in_pragma
= true;
20485 if (strcmp (kind
, "simd") == 0)
20488 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
20489 "#pragma omp declare simd");
20490 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
20491 if (c
!= NULL_TREE
)
20492 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
20493 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
20494 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
20495 DECL_ATTRIBUTES (fndecl
) = c
;
20499 gcc_assert (strcmp (kind
, "variant") == 0);
20500 c_finish_omp_declare_variant (parser
, fndecl
, parms
);
20504 parser
->tokens
= &parser
->tokens_buf
[0];
20505 parser
->tokens_avail
= tokens_avail
;
20506 if (clauses
.exists ())
20507 clauses
[0].type
= CPP_PRAGMA
;
20512 # pragma omp declare target new-line
20513 declarations and definitions
20514 # pragma omp end declare target new-line
20517 # pragma omp declare target ( extended-list ) new-line
20519 # pragma omp declare target declare-target-clauses[seq] new-line */
20521 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
20522 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
20523 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
20524 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
20527 c_parser_omp_declare_target (c_parser
*parser
)
20529 tree clauses
= NULL_TREE
;
20530 int device_type
= 0;
20531 bool only_device_type
= true;
20532 if (c_parser_next_token_is (parser
, CPP_NAME
))
20533 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
20534 "#pragma omp declare target");
20535 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
20537 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO_DECLARE
,
20539 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
20540 c_parser_skip_to_pragma_eol (parser
);
20544 c_parser_skip_to_pragma_eol (parser
);
20545 current_omp_declare_target_attribute
++;
20548 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
20549 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
20550 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
20551 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
20553 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
20555 tree t
= OMP_CLAUSE_DECL (c
), id
;
20556 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
20557 tree at2
= lookup_attribute ("omp declare target link",
20558 DECL_ATTRIBUTES (t
));
20559 only_device_type
= false;
20560 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
20562 id
= get_identifier ("omp declare target link");
20563 std::swap (at1
, at2
);
20566 id
= get_identifier ("omp declare target");
20569 error_at (OMP_CLAUSE_LOCATION (c
),
20570 "%qD specified both in declare target %<link%> and %<to%>"
20576 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
20577 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
20580 symtab_node
*node
= symtab_node::get (t
);
20583 node
->offloadable
= 1;
20584 if (ENABLE_OFFLOADING
)
20586 g
->have_offload
= true;
20587 if (is_a
<varpool_node
*> (node
))
20588 vec_safe_push (offload_vars
, t
);
20592 if (TREE_CODE (t
) != FUNCTION_DECL
)
20594 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_HOST
) != 0)
20596 tree at3
= lookup_attribute ("omp declare target host",
20597 DECL_ATTRIBUTES (t
));
20598 if (at3
== NULL_TREE
)
20600 id
= get_identifier ("omp declare target host");
20601 DECL_ATTRIBUTES (t
)
20602 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
20605 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_NOHOST
) != 0)
20607 tree at3
= lookup_attribute ("omp declare target nohost",
20608 DECL_ATTRIBUTES (t
));
20609 if (at3
== NULL_TREE
)
20611 id
= get_identifier ("omp declare target nohost");
20612 DECL_ATTRIBUTES (t
)
20613 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
20617 if (device_type
&& only_device_type
)
20618 warning_at (OMP_CLAUSE_LOCATION (clauses
), 0,
20619 "directive with only %<device_type%> clauses ignored");
20623 c_parser_omp_end_declare_target (c_parser
*parser
)
20625 location_t loc
= c_parser_peek_token (parser
)->location
;
20626 c_parser_consume_pragma (parser
);
20627 if (c_parser_next_token_is (parser
, CPP_NAME
)
20628 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
20631 c_parser_consume_token (parser
);
20632 if (c_parser_next_token_is (parser
, CPP_NAME
)
20633 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
20635 c_parser_consume_token (parser
);
20638 c_parser_error (parser
, "expected %<target%>");
20639 c_parser_skip_to_pragma_eol (parser
);
20645 c_parser_error (parser
, "expected %<declare%>");
20646 c_parser_skip_to_pragma_eol (parser
);
20649 c_parser_skip_to_pragma_eol (parser
);
20650 if (!current_omp_declare_target_attribute
)
20651 error_at (loc
, "%<#pragma omp end declare target%> without corresponding "
20652 "%<#pragma omp declare target%>");
20654 current_omp_declare_target_attribute
--;
20659 #pragma omp declare reduction (reduction-id : typename-list : expression) \
20660 initializer-clause[opt] new-line
20662 initializer-clause:
20663 initializer (omp_priv = initializer)
20664 initializer (function-name (argument-list)) */
20667 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
20669 unsigned int tokens_avail
= 0, i
;
20670 vec
<tree
> types
= vNULL
;
20671 vec
<c_token
> clauses
= vNULL
;
20672 enum tree_code reduc_code
= ERROR_MARK
;
20673 tree reduc_id
= NULL_TREE
;
20675 location_t rloc
= c_parser_peek_token (parser
)->location
;
20677 if (context
== pragma_struct
|| context
== pragma_param
)
20679 error ("%<#pragma omp declare reduction%> not at file or block scope");
20683 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
20686 switch (c_parser_peek_token (parser
)->type
)
20689 reduc_code
= PLUS_EXPR
;
20692 reduc_code
= MULT_EXPR
;
20695 reduc_code
= MINUS_EXPR
;
20698 reduc_code
= BIT_AND_EXPR
;
20701 reduc_code
= BIT_XOR_EXPR
;
20704 reduc_code
= BIT_IOR_EXPR
;
20707 reduc_code
= TRUTH_ANDIF_EXPR
;
20710 reduc_code
= TRUTH_ORIF_EXPR
;
20714 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20715 if (strcmp (p
, "min") == 0)
20717 reduc_code
= MIN_EXPR
;
20720 if (strcmp (p
, "max") == 0)
20722 reduc_code
= MAX_EXPR
;
20725 reduc_id
= c_parser_peek_token (parser
)->value
;
20728 c_parser_error (parser
,
20729 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
20730 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
20734 tree orig_reduc_id
, reduc_decl
;
20735 orig_reduc_id
= reduc_id
;
20736 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
20737 reduc_decl
= c_omp_reduction_decl (reduc_id
);
20738 c_parser_consume_token (parser
);
20740 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
20745 location_t loc
= c_parser_peek_token (parser
)->location
;
20746 struct c_type_name
*ctype
= c_parser_type_name (parser
);
20749 type
= groktypename (ctype
, NULL
, NULL
);
20750 if (type
== error_mark_node
)
20752 else if ((INTEGRAL_TYPE_P (type
)
20753 || TREE_CODE (type
) == REAL_TYPE
20754 || TREE_CODE (type
) == COMPLEX_TYPE
)
20755 && orig_reduc_id
== NULL_TREE
)
20756 error_at (loc
, "predeclared arithmetic type in "
20757 "%<#pragma omp declare reduction%>");
20758 else if (TREE_CODE (type
) == FUNCTION_TYPE
20759 || TREE_CODE (type
) == ARRAY_TYPE
)
20760 error_at (loc
, "function or array type in "
20761 "%<#pragma omp declare reduction%>");
20762 else if (TYPE_ATOMIC (type
))
20763 error_at (loc
, "%<_Atomic%> qualified type in "
20764 "%<#pragma omp declare reduction%>");
20765 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
20766 error_at (loc
, "const, volatile or restrict qualified type in "
20767 "%<#pragma omp declare reduction%>");
20771 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
20772 if (comptypes (TREE_PURPOSE (t
), type
))
20774 error_at (loc
, "redeclaration of %qs "
20775 "%<#pragma omp declare reduction%> for "
20777 IDENTIFIER_POINTER (reduc_id
)
20778 + sizeof ("omp declare reduction ") - 1,
20781 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
20783 error_at (ploc
, "previous %<#pragma omp declare "
20787 if (t
== NULL_TREE
)
20788 types
.safe_push (type
);
20790 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20791 c_parser_consume_token (parser
);
20799 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
20800 || types
.is_empty ())
20803 clauses
.release ();
20807 c_token
*token
= c_parser_peek_token (parser
);
20808 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
20810 c_parser_consume_token (parser
);
20812 c_parser_skip_to_pragma_eol (parser
);
20816 if (types
.length () > 1)
20818 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
20820 c_token
*token
= c_parser_peek_token (parser
);
20821 if (token
->type
== CPP_EOF
)
20823 clauses
.safe_push (*token
);
20824 c_parser_consume_token (parser
);
20826 clauses
.safe_push (*c_parser_peek_token (parser
));
20827 c_parser_skip_to_pragma_eol (parser
);
20829 /* Make sure nothing tries to read past the end of the tokens. */
20831 memset (&eof_token
, 0, sizeof (eof_token
));
20832 eof_token
.type
= CPP_EOF
;
20833 clauses
.safe_push (eof_token
);
20834 clauses
.safe_push (eof_token
);
20837 int errs
= errorcount
;
20838 FOR_EACH_VEC_ELT (types
, i
, type
)
20840 tokens_avail
= parser
->tokens_avail
;
20841 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
20842 if (!clauses
.is_empty ())
20844 parser
->tokens
= clauses
.address ();
20845 parser
->tokens_avail
= clauses
.length ();
20846 parser
->in_pragma
= true;
20849 bool nested
= current_function_decl
!= NULL_TREE
;
20851 c_push_function_context ();
20852 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
20853 reduc_id
, default_function_type
);
20854 current_function_decl
= fndecl
;
20855 allocate_struct_function (fndecl
, true);
20857 tree stmt
= push_stmt_list ();
20858 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
20859 warn about these. */
20860 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20861 get_identifier ("omp_out"), type
);
20862 DECL_ARTIFICIAL (omp_out
) = 1;
20863 DECL_CONTEXT (omp_out
) = fndecl
;
20864 pushdecl (omp_out
);
20865 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20866 get_identifier ("omp_in"), type
);
20867 DECL_ARTIFICIAL (omp_in
) = 1;
20868 DECL_CONTEXT (omp_in
) = fndecl
;
20870 struct c_expr combiner
= c_parser_expression (parser
);
20871 struct c_expr initializer
;
20872 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
20874 initializer
.set_error ();
20875 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
20877 else if (c_parser_next_token_is (parser
, CPP_NAME
)
20878 && strcmp (IDENTIFIER_POINTER
20879 (c_parser_peek_token (parser
)->value
),
20880 "initializer") == 0)
20882 c_parser_consume_token (parser
);
20885 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20886 get_identifier ("omp_priv"), type
);
20887 DECL_ARTIFICIAL (omp_priv
) = 1;
20888 DECL_INITIAL (omp_priv
) = error_mark_node
;
20889 DECL_CONTEXT (omp_priv
) = fndecl
;
20890 pushdecl (omp_priv
);
20891 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20892 get_identifier ("omp_orig"), type
);
20893 DECL_ARTIFICIAL (omp_orig
) = 1;
20894 DECL_CONTEXT (omp_orig
) = fndecl
;
20895 pushdecl (omp_orig
);
20896 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
20898 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
20900 c_parser_error (parser
, "expected %<omp_priv%> or "
20904 else if (strcmp (IDENTIFIER_POINTER
20905 (c_parser_peek_token (parser
)->value
),
20908 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
20909 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
20911 c_parser_error (parser
, "expected function-name %<(%>");
20915 initializer
= c_parser_postfix_expression (parser
);
20916 if (initializer
.value
20917 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
20920 tree c
= initializer
.value
;
20921 for (j
= 0; j
< call_expr_nargs (c
); j
++)
20923 tree a
= CALL_EXPR_ARG (c
, j
);
20925 if (TREE_CODE (a
) == ADDR_EXPR
20926 && TREE_OPERAND (a
, 0) == omp_priv
)
20929 if (j
== call_expr_nargs (c
))
20930 error ("one of the initializer call arguments should be "
20936 c_parser_consume_token (parser
);
20937 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
20941 tree st
= push_stmt_list ();
20942 location_t loc
= c_parser_peek_token (parser
)->location
;
20943 rich_location
richloc (line_table
, loc
);
20944 start_init (omp_priv
, NULL_TREE
, 0, &richloc
);
20945 struct c_expr init
= c_parser_initializer (parser
);
20947 finish_decl (omp_priv
, loc
, init
.value
,
20948 init
.original_type
, NULL_TREE
);
20949 pop_stmt_list (st
);
20953 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
20959 c_parser_skip_to_pragma_eol (parser
);
20961 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
20962 DECL_INITIAL (reduc_decl
));
20963 DECL_INITIAL (reduc_decl
) = t
;
20964 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
20965 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
20966 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
20967 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
20968 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
20969 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
20972 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
20973 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
20974 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
20975 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
20976 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
20977 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
20978 walk_tree (&DECL_INITIAL (omp_priv
),
20979 c_check_omp_declare_reduction_r
,
20980 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
20984 pop_stmt_list (stmt
);
20986 if (cfun
->language
!= NULL
)
20988 ggc_free (cfun
->language
);
20989 cfun
->language
= NULL
;
20992 current_function_decl
= NULL_TREE
;
20994 c_pop_function_context ();
20996 if (!clauses
.is_empty ())
20998 parser
->tokens
= &parser
->tokens_buf
[0];
20999 parser
->tokens_avail
= tokens_avail
;
21003 if (errs
!= errorcount
)
21007 clauses
.release ();
21013 #pragma omp declare simd declare-simd-clauses[optseq] new-line
21014 #pragma omp declare reduction (reduction-id : typename-list : expression) \
21015 initializer-clause[opt] new-line
21016 #pragma omp declare target new-line
21019 #pragma omp declare variant (identifier) match (context-selector) */
21022 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
21024 c_parser_consume_pragma (parser
);
21025 if (c_parser_next_token_is (parser
, CPP_NAME
))
21027 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21028 if (strcmp (p
, "simd") == 0)
21030 /* c_parser_consume_token (parser); done in
21031 c_parser_omp_declare_simd. */
21032 c_parser_omp_declare_simd (parser
, context
);
21035 if (strcmp (p
, "reduction") == 0)
21037 c_parser_consume_token (parser
);
21038 c_parser_omp_declare_reduction (parser
, context
);
21041 if (!flag_openmp
) /* flag_openmp_simd */
21043 c_parser_skip_to_pragma_eol (parser
, false);
21046 if (strcmp (p
, "target") == 0)
21048 c_parser_consume_token (parser
);
21049 c_parser_omp_declare_target (parser
);
21052 if (strcmp (p
, "variant") == 0)
21054 /* c_parser_consume_token (parser); done in
21055 c_parser_omp_declare_simd. */
21056 c_parser_omp_declare_simd (parser
, context
);
21061 c_parser_error (parser
, "expected %<simd%>, %<reduction%>, "
21062 "%<target%> or %<variant%>");
21063 c_parser_skip_to_pragma_eol (parser
);
21067 #pragma omp requires clauses[optseq] new-line */
21070 c_parser_omp_requires (c_parser
*parser
)
21073 enum omp_requires new_req
= (enum omp_requires
) 0;
21075 c_parser_consume_pragma (parser
);
21077 location_t loc
= c_parser_peek_token (parser
)->location
;
21078 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21080 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
21081 c_parser_consume_token (parser
);
21085 if (c_parser_next_token_is (parser
, CPP_NAME
))
21088 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21089 location_t cloc
= c_parser_peek_token (parser
)->location
;
21090 enum omp_requires this_req
= (enum omp_requires
) 0;
21092 if (!strcmp (p
, "unified_address"))
21093 this_req
= OMP_REQUIRES_UNIFIED_ADDRESS
;
21094 else if (!strcmp (p
, "unified_shared_memory"))
21095 this_req
= OMP_REQUIRES_UNIFIED_SHARED_MEMORY
;
21096 else if (!strcmp (p
, "dynamic_allocators"))
21097 this_req
= OMP_REQUIRES_DYNAMIC_ALLOCATORS
;
21098 else if (!strcmp (p
, "reverse_offload"))
21099 this_req
= OMP_REQUIRES_REVERSE_OFFLOAD
;
21100 else if (!strcmp (p
, "atomic_default_mem_order"))
21102 c_parser_consume_token (parser
);
21104 matching_parens parens
;
21105 if (parens
.require_open (parser
))
21107 if (c_parser_next_token_is (parser
, CPP_NAME
))
21109 tree v
= c_parser_peek_token (parser
)->value
;
21110 p
= IDENTIFIER_POINTER (v
);
21112 if (!strcmp (p
, "seq_cst"))
21114 = (enum omp_requires
) OMP_MEMORY_ORDER_SEQ_CST
;
21115 else if (!strcmp (p
, "relaxed"))
21117 = (enum omp_requires
) OMP_MEMORY_ORDER_RELAXED
;
21118 else if (!strcmp (p
, "acq_rel"))
21120 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQ_REL
;
21124 error_at (c_parser_peek_token (parser
)->location
,
21125 "expected %<seq_cst%>, %<relaxed%> or "
21127 if (c_parser_peek_2nd_token (parser
)->type
21128 == CPP_CLOSE_PAREN
)
21129 c_parser_consume_token (parser
);
21132 c_parser_consume_token (parser
);
21134 parens
.skip_until_found_close (parser
);
21137 c_parser_skip_to_pragma_eol (parser
, false);
21145 error_at (cloc
, "expected %<unified_address%>, "
21146 "%<unified_shared_memory%>, "
21147 "%<dynamic_allocators%>, "
21148 "%<reverse_offload%> "
21149 "or %<atomic_default_mem_order%> clause");
21150 c_parser_skip_to_pragma_eol (parser
, false);
21154 sorry_at (cloc
, "%qs clause on %<requires%> directive not "
21155 "supported yet", p
);
21157 c_parser_consume_token (parser
);
21160 if ((this_req
& ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
21162 if ((this_req
& new_req
) != 0)
21163 error_at (cloc
, "too many %qs clauses", p
);
21164 if (this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
21165 && (omp_requires_mask
& OMP_REQUIRES_TARGET_USED
) != 0)
21166 error_at (cloc
, "%qs clause used lexically after first "
21167 "target construct or offloading API", p
);
21169 else if ((new_req
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
21171 error_at (cloc
, "too many %qs clauses",
21172 "atomic_default_mem_order");
21173 this_req
= (enum omp_requires
) 0;
21175 else if ((omp_requires_mask
21176 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
21178 error_at (cloc
, "more than one %<atomic_default_mem_order%>"
21179 " clause in a single compilation unit");
21181 = (enum omp_requires
)
21183 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
);
21185 else if ((omp_requires_mask
21186 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
) != 0)
21187 error_at (cloc
, "%<atomic_default_mem_order%> clause used "
21188 "lexically after first %<atomic%> construct "
21189 "without memory order clause");
21190 new_req
= (enum omp_requires
) (new_req
| this_req
);
21192 = (enum omp_requires
) (omp_requires_mask
| this_req
);
21198 c_parser_skip_to_pragma_eol (parser
);
21201 error_at (loc
, "%<pragma omp requires%> requires at least one clause");
21204 /* Helper function for c_parser_omp_taskloop.
21205 Disallow zero sized or potentially zero sized task reductions. */
21208 c_finish_taskloop_clauses (tree clauses
)
21210 tree
*pc
= &clauses
;
21211 for (tree c
= clauses
; c
; c
= *pc
)
21213 bool remove
= false;
21214 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
21216 tree type
= strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
21217 if (integer_zerop (TYPE_SIZE_UNIT (type
)))
21219 error_at (OMP_CLAUSE_LOCATION (c
),
21220 "zero sized type %qT in %<reduction%> clause", type
);
21223 else if (TREE_CODE (TYPE_SIZE_UNIT (type
)) != INTEGER_CST
)
21225 error_at (OMP_CLAUSE_LOCATION (c
),
21226 "variable sized type %qT in %<reduction%> clause",
21232 *pc
= OMP_CLAUSE_CHAIN (c
);
21234 pc
= &OMP_CLAUSE_CHAIN (c
);
21240 #pragma omp taskloop taskloop-clause[optseq] new-line
21243 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
21246 #define OMP_TASKLOOP_CLAUSE_MASK \
21247 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21249 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21250 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
21251 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
21252 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
21253 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
21254 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
21255 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
21256 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21257 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
21258 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
21259 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
21260 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
21261 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21262 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
21265 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
21266 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
21269 tree clauses
, block
, ret
;
21271 strcat (p_name
, " taskloop");
21272 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
21273 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
21275 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
)) != 0)
21276 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_IN_REDUCTION
);
21278 if (c_parser_next_token_is (parser
, CPP_NAME
))
21280 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21282 if (strcmp (p
, "simd") == 0)
21284 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
21285 if (cclauses
== NULL
)
21286 cclauses
= cclauses_buf
;
21287 c_parser_consume_token (parser
);
21288 if (!flag_openmp
) /* flag_openmp_simd */
21289 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
21291 block
= c_begin_compound_stmt (true);
21292 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
21293 block
= c_end_compound_stmt (loc
, block
, true);
21296 ret
= make_node (OMP_TASKLOOP
);
21297 TREE_TYPE (ret
) = void_type_node
;
21298 OMP_FOR_BODY (ret
) = block
;
21299 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
21300 OMP_FOR_CLAUSES (ret
)
21301 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret
));
21302 SET_EXPR_LOCATION (ret
, loc
);
21307 if (!flag_openmp
) /* flag_openmp_simd */
21309 c_parser_skip_to_pragma_eol (parser
, false);
21313 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
21316 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
21317 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
21320 clauses
= c_finish_taskloop_clauses (clauses
);
21321 block
= c_begin_compound_stmt (true);
21322 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
21323 block
= c_end_compound_stmt (loc
, block
, true);
21329 /* Main entry point to parsing most OpenMP pragmas. */
21332 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
21334 enum pragma_kind p_kind
;
21337 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
21338 omp_clause_mask
mask (0);
21340 loc
= c_parser_peek_token (parser
)->location
;
21341 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
21342 c_parser_consume_pragma (parser
);
21346 case PRAGMA_OACC_ATOMIC
:
21347 c_parser_omp_atomic (loc
, parser
);
21349 case PRAGMA_OACC_CACHE
:
21350 strcpy (p_name
, "#pragma acc");
21351 stmt
= c_parser_oacc_cache (loc
, parser
);
21353 case PRAGMA_OACC_DATA
:
21354 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
21356 case PRAGMA_OACC_HOST_DATA
:
21357 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
21359 case PRAGMA_OACC_KERNELS
:
21360 case PRAGMA_OACC_PARALLEL
:
21361 case PRAGMA_OACC_SERIAL
:
21362 strcpy (p_name
, "#pragma acc");
21363 stmt
= c_parser_oacc_compute (loc
, parser
, p_kind
, p_name
, if_p
);
21365 case PRAGMA_OACC_LOOP
:
21366 strcpy (p_name
, "#pragma acc");
21367 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21369 case PRAGMA_OACC_WAIT
:
21370 strcpy (p_name
, "#pragma wait");
21371 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
21373 case PRAGMA_OMP_ATOMIC
:
21374 c_parser_omp_atomic (loc
, parser
);
21376 case PRAGMA_OMP_CRITICAL
:
21377 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
21379 case PRAGMA_OMP_DISTRIBUTE
:
21380 strcpy (p_name
, "#pragma omp");
21381 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21383 case PRAGMA_OMP_FOR
:
21384 strcpy (p_name
, "#pragma omp");
21385 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21387 case PRAGMA_OMP_LOOP
:
21388 strcpy (p_name
, "#pragma omp");
21389 stmt
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21391 case PRAGMA_OMP_MASTER
:
21392 strcpy (p_name
, "#pragma omp");
21393 stmt
= c_parser_omp_master (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21395 case PRAGMA_OMP_PARALLEL
:
21396 strcpy (p_name
, "#pragma omp");
21397 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21399 case PRAGMA_OMP_SECTIONS
:
21400 strcpy (p_name
, "#pragma omp");
21401 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
21403 case PRAGMA_OMP_SIMD
:
21404 strcpy (p_name
, "#pragma omp");
21405 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21407 case PRAGMA_OMP_SINGLE
:
21408 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
21410 case PRAGMA_OMP_TASK
:
21411 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
21413 case PRAGMA_OMP_TASKGROUP
:
21414 stmt
= c_parser_omp_taskgroup (loc
, parser
, if_p
);
21416 case PRAGMA_OMP_TASKLOOP
:
21417 strcpy (p_name
, "#pragma omp");
21418 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21420 case PRAGMA_OMP_TEAMS
:
21421 strcpy (p_name
, "#pragma omp");
21422 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21425 gcc_unreachable ();
21429 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
21434 # pragma omp threadprivate (variable-list) */
21437 c_parser_omp_threadprivate (c_parser
*parser
)
21442 c_parser_consume_pragma (parser
);
21443 loc
= c_parser_peek_token (parser
)->location
;
21444 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
21446 /* Mark every variable in VARS to be assigned thread local storage. */
21447 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
21449 tree v
= TREE_PURPOSE (t
);
21451 /* FIXME diagnostics: Ideally we should keep individual
21452 locations for all the variables in the var list to make the
21453 following errors more precise. Perhaps
21454 c_parser_omp_var_list_parens() should construct a list of
21455 locations to go along with the var list. */
21457 /* If V had already been marked threadprivate, it doesn't matter
21458 whether it had been used prior to this point. */
21460 error_at (loc
, "%qD is not a variable", v
);
21461 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
21462 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
21463 else if (! is_global_var (v
))
21464 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
21465 else if (TREE_TYPE (v
) == error_mark_node
)
21467 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
21468 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
21471 if (! DECL_THREAD_LOCAL_P (v
))
21473 set_decl_tls_model (v
, decl_default_tls_model (v
));
21474 /* If rtl has been already set for this var, call
21475 make_decl_rtl once again, so that encode_section_info
21476 has a chance to look at the new decl flags. */
21477 if (DECL_RTL_SET_P (v
))
21480 C_DECL_THREADPRIVATE_P (v
) = 1;
21484 c_parser_skip_to_pragma_eol (parser
);
21487 /* Parse a transaction attribute (GCC Extension).
21489 transaction-attribute:
21491 attribute-specifier
21495 c_parser_transaction_attributes (c_parser
*parser
)
21497 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
21498 return c_parser_gnu_attributes (parser
);
21500 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
21502 return c_parser_std_attribute_specifier (parser
, true);
21505 /* Parse a __transaction_atomic or __transaction_relaxed statement
21508 transaction-statement:
21509 __transaction_atomic transaction-attribute[opt] compound-statement
21510 __transaction_relaxed compound-statement
21512 Note that the only valid attribute is: "outer".
21516 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
21518 unsigned int old_in
= parser
->in_transaction
;
21519 unsigned int this_in
= 1, new_in
;
21520 location_t loc
= c_parser_peek_token (parser
)->location
;
21523 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
21524 || keyword
== RID_TRANSACTION_RELAXED
)
21525 && c_parser_next_token_is_keyword (parser
, keyword
));
21526 c_parser_consume_token (parser
);
21528 if (keyword
== RID_TRANSACTION_RELAXED
)
21529 this_in
|= TM_STMT_ATTR_RELAXED
;
21532 attrs
= c_parser_transaction_attributes (parser
);
21534 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
21537 /* Keep track if we're in the lexical scope of an outer transaction. */
21538 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
21540 parser
->in_transaction
= new_in
;
21541 stmt
= c_parser_compound_statement (parser
);
21542 parser
->in_transaction
= old_in
;
21545 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
21547 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
21548 "%<__transaction_atomic%> without transactional memory support enabled"
21549 : "%<__transaction_relaxed %> "
21550 "without transactional memory support enabled"));
21555 /* Parse a __transaction_atomic or __transaction_relaxed expression
21558 transaction-expression:
21559 __transaction_atomic ( expression )
21560 __transaction_relaxed ( expression )
21563 static struct c_expr
21564 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
21567 unsigned int old_in
= parser
->in_transaction
;
21568 unsigned int this_in
= 1;
21569 location_t loc
= c_parser_peek_token (parser
)->location
;
21572 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
21573 || keyword
== RID_TRANSACTION_RELAXED
)
21574 && c_parser_next_token_is_keyword (parser
, keyword
));
21575 c_parser_consume_token (parser
);
21577 if (keyword
== RID_TRANSACTION_RELAXED
)
21578 this_in
|= TM_STMT_ATTR_RELAXED
;
21581 attrs
= c_parser_transaction_attributes (parser
);
21583 this_in
|= parse_tm_stmt_attr (attrs
, 0);
21586 parser
->in_transaction
= this_in
;
21587 matching_parens parens
;
21588 if (parens
.require_open (parser
))
21590 tree expr
= c_parser_expression (parser
).value
;
21591 ret
.original_type
= TREE_TYPE (expr
);
21592 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
21593 if (this_in
& TM_STMT_ATTR_RELAXED
)
21594 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
21595 SET_EXPR_LOCATION (ret
.value
, loc
);
21596 ret
.original_code
= TRANSACTION_EXPR
;
21597 if (!parens
.require_close (parser
))
21599 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
21607 ret
.original_code
= ERROR_MARK
;
21608 ret
.original_type
= NULL
;
21610 parser
->in_transaction
= old_in
;
21613 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
21614 "%<__transaction_atomic%> without transactional memory support enabled"
21615 : "%<__transaction_relaxed %> "
21616 "without transactional memory support enabled"));
21618 set_c_expr_source_range (&ret
, loc
, loc
);
21623 /* Parse a __transaction_cancel statement (GCC Extension).
21625 transaction-cancel-statement:
21626 __transaction_cancel transaction-attribute[opt] ;
21628 Note that the only valid attribute is "outer".
21632 c_parser_transaction_cancel (c_parser
*parser
)
21634 location_t loc
= c_parser_peek_token (parser
)->location
;
21636 bool is_outer
= false;
21638 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
21639 c_parser_consume_token (parser
);
21641 attrs
= c_parser_transaction_attributes (parser
);
21643 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
21647 error_at (loc
, "%<__transaction_cancel%> without "
21648 "transactional memory support enabled");
21651 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
21653 error_at (loc
, "%<__transaction_cancel%> within a "
21654 "%<__transaction_relaxed%>");
21659 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
21660 && !is_tm_may_cancel_outer (current_function_decl
))
21662 error_at (loc
, "outer %<__transaction_cancel%> not "
21663 "within outer %<__transaction_atomic%> or "
21664 "a %<transaction_may_cancel_outer%> function");
21668 else if (parser
->in_transaction
== 0)
21670 error_at (loc
, "%<__transaction_cancel%> not within "
21671 "%<__transaction_atomic%>");
21675 return add_stmt (build_tm_abort_call (loc
, is_outer
));
21678 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
21681 /* Parse a single source file. */
21684 c_parse_file (void)
21686 /* Use local storage to begin. If the first token is a pragma, parse it.
21687 If it is #pragma GCC pch_preprocess, then this will load a PCH file
21688 which will cause garbage collection. */
21691 memset (&tparser
, 0, sizeof tparser
);
21692 tparser
.translate_strings_p
= true;
21693 tparser
.tokens
= &tparser
.tokens_buf
[0];
21694 the_parser
= &tparser
;
21696 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
21697 c_parser_pragma_pch_preprocess (&tparser
);
21699 c_common_no_more_pch ();
21701 the_parser
= ggc_alloc
<c_parser
> ();
21702 *the_parser
= tparser
;
21703 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
21704 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
21706 /* Initialize EH, if we've been told to do so. */
21707 if (flag_exceptions
)
21708 using_eh_for_cleanups ();
21710 c_parser_translation_unit (the_parser
);
21714 /* Parse the body of a function declaration marked with "__RTL".
21716 The RTL parser works on the level of characters read from a
21717 FILE *, whereas c_parser works at the level of tokens.
21718 Square this circle by consuming all of the tokens up to and
21719 including the closing brace, recording the start/end of the RTL
21720 fragment, and reopening the file and re-reading the relevant
21721 lines within the RTL parser.
21723 This requires the opening and closing braces of the C function
21724 to be on separate lines from the RTL they wrap.
21726 Take ownership of START_WITH_PASS, if non-NULL. */
21729 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
21731 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
21733 free (start_with_pass
);
21737 location_t start_loc
= c_parser_peek_token (parser
)->location
;
21739 /* Consume all tokens, up to the closing brace, handling
21740 matching pairs of braces in the rtl dump. */
21741 int num_open_braces
= 1;
21744 switch (c_parser_peek_token (parser
)->type
)
21746 case CPP_OPEN_BRACE
:
21749 case CPP_CLOSE_BRACE
:
21750 if (--num_open_braces
== 0)
21751 goto found_closing_brace
;
21754 error_at (start_loc
, "no closing brace");
21755 free (start_with_pass
);
21760 c_parser_consume_token (parser
);
21763 found_closing_brace
:
21764 /* At the closing brace; record its location. */
21765 location_t end_loc
= c_parser_peek_token (parser
)->location
;
21767 /* Consume the closing brace. */
21768 c_parser_consume_token (parser
);
21770 /* Invoke the RTL parser. */
21771 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
21773 free (start_with_pass
);
21777 /* Run the backend on the cfun created above, transferring ownership of
21778 START_WITH_PASS. */
21779 run_rtl_passes (start_with_pass
);
21782 #include "gt-c-c-parser.h"