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"
72 #include "c-family/known-headers.h"
74 /* We need to walk over decls with incomplete struct/union/enum types
75 after parsing the whole translation unit.
76 In finish_decl(), if the decl is static, has incomplete
77 struct/union/enum type, it is appended to incomplete_record_decls.
78 In c_parser_translation_unit(), we iterate over incomplete_record_decls
79 and report error if any of the decls are still incomplete. */
81 vec
<tree
> incomplete_record_decls
;
84 set_c_expr_source_range (c_expr
*expr
,
85 location_t start
, location_t finish
)
87 expr
->src_range
.m_start
= start
;
88 expr
->src_range
.m_finish
= finish
;
90 set_source_range (expr
->value
, start
, finish
);
94 set_c_expr_source_range (c_expr
*expr
,
95 source_range src_range
)
97 expr
->src_range
= src_range
;
99 set_source_range (expr
->value
, src_range
);
103 /* Initialization routine for this file. */
108 /* The only initialization required is of the reserved word
114 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
115 the c_token structure. */
116 gcc_assert (RID_MAX
<= 255);
123 mask
|= D_ASM
| D_EXT
;
127 if (!c_dialect_objc ())
128 mask
|= D_OBJC
| D_CXX_OBJC
;
130 ridpointers
= ggc_cleared_vec_alloc
<tree
> ((int) RID_MAX
);
131 for (i
= 0; i
< num_c_common_reswords
; i
++)
133 /* If a keyword is disabled, do not enter it into the table
134 and so create a canonical spelling that isn't a keyword. */
135 if (c_common_reswords
[i
].disable
& mask
)
138 && (c_common_reswords
[i
].disable
& D_CXXWARN
))
140 id
= get_identifier (c_common_reswords
[i
].word
);
141 C_SET_RID_CODE (id
, RID_CXX_COMPAT_WARN
);
142 C_IS_RESERVED_WORD (id
) = 1;
147 id
= get_identifier (c_common_reswords
[i
].word
);
148 C_SET_RID_CODE (id
, c_common_reswords
[i
].rid
);
149 C_IS_RESERVED_WORD (id
) = 1;
150 ridpointers
[(int) c_common_reswords
[i
].rid
] = id
;
153 for (i
= 0; i
< NUM_INT_N_ENTS
; i
++)
155 /* We always create the symbols but they aren't always supported. */
157 sprintf (name
, "__int%d", int_n_data
[i
].bitsize
);
158 id
= get_identifier (name
);
159 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
160 C_IS_RESERVED_WORD (id
) = 1;
162 sprintf (name
, "__int%d__", int_n_data
[i
].bitsize
);
163 id
= get_identifier (name
);
164 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
165 C_IS_RESERVED_WORD (id
) = 1;
169 /* A parser structure recording information about the state and
170 context of parsing. Includes lexer information with up to two
171 tokens of look-ahead; more are not needed for C. */
172 struct GTY(()) c_parser
{
173 /* The look-ahead tokens. */
174 c_token
* GTY((skip
)) tokens
;
175 /* Buffer for look-ahead tokens. */
176 c_token tokens_buf
[4];
177 /* How many look-ahead tokens are available (0 - 4, or
178 more if parsing from pre-lexed tokens). */
179 unsigned int tokens_avail
;
180 /* Raw look-ahead tokens, used only for checking in Objective-C
181 whether '[[' starts attributes. */
182 vec
<c_token
, va_gc
> *raw_tokens
;
183 /* The number of raw look-ahead tokens that have since been fully
185 unsigned int raw_tokens_used
;
186 /* True if a syntax error is being recovered from; false otherwise.
187 c_parser_error sets this flag. It should clear this flag when
188 enough tokens have been consumed to recover from the error. */
189 BOOL_BITFIELD error
: 1;
190 /* True if we're processing a pragma, and shouldn't automatically
191 consume CPP_PRAGMA_EOL. */
192 BOOL_BITFIELD in_pragma
: 1;
193 /* True if we're parsing the outermost block of an if statement. */
194 BOOL_BITFIELD in_if_block
: 1;
195 /* True if we want to lex a translated, joined string (for an
196 initial #pragma pch_preprocess). Otherwise the parser is
197 responsible for concatenating strings and translating to the
198 execution character set as needed. */
199 BOOL_BITFIELD lex_joined_string
: 1;
200 /* True if, when the parser is concatenating string literals, it
201 should translate them to the execution character set (false
202 inside attributes). */
203 BOOL_BITFIELD translate_strings_p
: 1;
205 /* Objective-C specific parser/lexer information. */
207 /* True if we are in a context where the Objective-C "PQ" keywords
208 are considered keywords. */
209 BOOL_BITFIELD objc_pq_context
: 1;
210 /* True if we are parsing a (potential) Objective-C foreach
211 statement. This is set to true after we parsed 'for (' and while
212 we wait for 'in' or ';' to decide if it's a standard C for loop or an
213 Objective-C foreach loop. */
214 BOOL_BITFIELD objc_could_be_foreach_context
: 1;
215 /* The following flag is needed to contextualize Objective-C lexical
216 analysis. In some cases (e.g., 'int NSObject;'), it is
217 undesirable to bind an identifier to an Objective-C class, even
218 if a class with that name exists. */
219 BOOL_BITFIELD objc_need_raw_identifier
: 1;
220 /* Nonzero if we're processing a __transaction statement. The value
221 is 1 | TM_STMT_ATTR_*. */
222 unsigned int in_transaction
: 4;
223 /* True if we are in a context where the Objective-C "Property attribute"
224 keywords are valid. */
225 BOOL_BITFIELD objc_property_attr_context
: 1;
227 /* Whether we have just seen/constructed a string-literal. Set when
228 returning a string-literal from c_parser_string_literal. Reset
229 in consume_token. Useful when we get a parse error and see an
230 unknown token, which could have been a string-literal constant
232 BOOL_BITFIELD seen_string_literal
: 1;
234 /* Location of the last consumed token. */
235 location_t last_token_location
;
238 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
241 c_parser_tokens_buf (c_parser
*parser
, unsigned n
)
243 return &parser
->tokens_buf
[n
];
246 /* Return the error state of PARSER. */
249 c_parser_error (c_parser
*parser
)
251 return parser
->error
;
254 /* Set the error state of PARSER to ERR. */
257 c_parser_set_error (c_parser
*parser
, bool err
)
263 /* The actual parser and external interface. ??? Does this need to be
264 garbage-collected? */
266 static GTY (()) c_parser
*the_parser
;
268 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
269 context-sensitive postprocessing of the token is not done. */
272 c_lex_one_token (c_parser
*parser
, c_token
*token
, bool raw
= false)
274 timevar_push (TV_LEX
);
276 if (raw
|| vec_safe_length (parser
->raw_tokens
) == 0)
278 token
->type
= c_lex_with_flags (&token
->value
, &token
->location
,
280 (parser
->lex_joined_string
281 ? 0 : C_LEX_STRING_NO_JOIN
));
282 token
->id_kind
= C_ID_NONE
;
283 token
->keyword
= RID_MAX
;
284 token
->pragma_kind
= PRAGMA_NONE
;
288 /* Use a token previously lexed as a raw look-ahead token, and
289 complete the processing on it. */
290 *token
= (*parser
->raw_tokens
)[parser
->raw_tokens_used
];
291 ++parser
->raw_tokens_used
;
292 if (parser
->raw_tokens_used
== vec_safe_length (parser
->raw_tokens
))
294 vec_free (parser
->raw_tokens
);
295 parser
->raw_tokens_used
= 0;
308 bool objc_force_identifier
= parser
->objc_need_raw_identifier
;
309 if (c_dialect_objc ())
310 parser
->objc_need_raw_identifier
= false;
312 if (C_IS_RESERVED_WORD (token
->value
))
314 enum rid rid_code
= C_RID_CODE (token
->value
);
316 if (rid_code
== RID_CXX_COMPAT_WARN
)
318 warning_at (token
->location
,
320 "identifier %qE conflicts with C++ keyword",
323 else if (rid_code
>= RID_FIRST_ADDR_SPACE
324 && rid_code
<= RID_LAST_ADDR_SPACE
)
327 as
= (addr_space_t
) (rid_code
- RID_FIRST_ADDR_SPACE
);
328 targetm
.addr_space
.diagnose_usage (as
, token
->location
);
329 token
->id_kind
= C_ID_ADDRSPACE
;
330 token
->keyword
= rid_code
;
333 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code
))
335 /* We found an Objective-C "pq" keyword (in, out,
336 inout, bycopy, byref, oneway). They need special
337 care because the interpretation depends on the
339 if (parser
->objc_pq_context
)
341 token
->type
= CPP_KEYWORD
;
342 token
->keyword
= rid_code
;
345 else if (parser
->objc_could_be_foreach_context
346 && rid_code
== RID_IN
)
348 /* We are in Objective-C, inside a (potential)
349 foreach context (which means after having
350 parsed 'for (', but before having parsed ';'),
351 and we found 'in'. We consider it the keyword
352 which terminates the declaration at the
353 beginning of a foreach-statement. Note that
354 this means you can't use 'in' for anything else
355 in that context; in particular, in Objective-C
356 you can't use 'in' as the name of the running
357 variable in a C for loop. We could potentially
358 try to add code here to disambiguate, but it
359 seems a reasonable limitation. */
360 token
->type
= CPP_KEYWORD
;
361 token
->keyword
= rid_code
;
364 /* Else, "pq" keywords outside of the "pq" context are
365 not keywords, and we fall through to the code for
368 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code
))
370 /* We found an Objective-C "property attribute"
371 keyword (getter, setter, readonly, etc). These are
372 only valid in the property context. */
373 if (parser
->objc_property_attr_context
)
375 token
->type
= CPP_KEYWORD
;
376 token
->keyword
= rid_code
;
379 /* Else they are not special keywords.
382 else if (c_dialect_objc ()
383 && (OBJC_IS_AT_KEYWORD (rid_code
)
384 || OBJC_IS_CXX_KEYWORD (rid_code
)))
386 /* We found one of the Objective-C "@" keywords (defs,
387 selector, synchronized, etc) or one of the
388 Objective-C "cxx" keywords (class, private,
389 protected, public, try, catch, throw) without a
390 preceding '@' sign. Do nothing and fall through to
391 the code for normal tokens (in C++ we would still
392 consider the CXX ones keywords, but not in C). */
397 token
->type
= CPP_KEYWORD
;
398 token
->keyword
= rid_code
;
403 decl
= lookup_name (token
->value
);
406 if (TREE_CODE (decl
) == TYPE_DECL
)
408 token
->id_kind
= C_ID_TYPENAME
;
412 else if (c_dialect_objc ())
414 tree objc_interface_decl
= objc_is_class_name (token
->value
);
415 /* Objective-C class names are in the same namespace as
416 variables and typedefs, and hence are shadowed by local
418 if (objc_interface_decl
419 && (!objc_force_identifier
|| global_bindings_p ()))
421 token
->value
= objc_interface_decl
;
422 token
->id_kind
= C_ID_CLASSNAME
;
426 token
->id_kind
= C_ID_ID
;
430 /* This only happens in Objective-C; it must be a keyword. */
431 token
->type
= CPP_KEYWORD
;
432 switch (C_RID_CODE (token
->value
))
434 /* Replace 'class' with '@class', 'private' with '@private',
435 etc. This prevents confusion with the C++ keyword
436 'class', and makes the tokens consistent with other
437 Objective-C 'AT' keywords. For example '@class' is
438 reported as RID_AT_CLASS which is consistent with
439 '@synchronized', which is reported as
442 case RID_CLASS
: token
->keyword
= RID_AT_CLASS
; break;
443 case RID_PRIVATE
: token
->keyword
= RID_AT_PRIVATE
; break;
444 case RID_PROTECTED
: token
->keyword
= RID_AT_PROTECTED
; break;
445 case RID_PUBLIC
: token
->keyword
= RID_AT_PUBLIC
; break;
446 case RID_THROW
: token
->keyword
= RID_AT_THROW
; break;
447 case RID_TRY
: token
->keyword
= RID_AT_TRY
; break;
448 case RID_CATCH
: token
->keyword
= RID_AT_CATCH
; break;
449 case RID_SYNCHRONIZED
: token
->keyword
= RID_AT_SYNCHRONIZED
; break;
450 default: token
->keyword
= C_RID_CODE (token
->value
);
455 case CPP_CLOSE_PAREN
:
457 /* These tokens may affect the interpretation of any identifiers
458 following, if doing Objective-C. */
459 if (c_dialect_objc ())
460 parser
->objc_need_raw_identifier
= false;
463 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
464 token
->pragma_kind
= (enum pragma_kind
) TREE_INT_CST_LOW (token
->value
);
471 timevar_pop (TV_LEX
);
474 /* Return a pointer to the next token from PARSER, reading it in if
478 c_parser_peek_token (c_parser
*parser
)
480 if (parser
->tokens_avail
== 0)
482 c_lex_one_token (parser
, &parser
->tokens
[0]);
483 parser
->tokens_avail
= 1;
485 return &parser
->tokens
[0];
488 /* Return a pointer to the next-but-one token from PARSER, reading it
489 in if necessary. The next token is already read in. */
492 c_parser_peek_2nd_token (c_parser
*parser
)
494 if (parser
->tokens_avail
>= 2)
495 return &parser
->tokens
[1];
496 gcc_assert (parser
->tokens_avail
== 1);
497 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
498 gcc_assert (parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
499 c_lex_one_token (parser
, &parser
->tokens
[1]);
500 parser
->tokens_avail
= 2;
501 return &parser
->tokens
[1];
504 /* Return a pointer to the Nth token from PARSER, reading it
505 in if necessary. The N-1th token is already read in. */
508 c_parser_peek_nth_token (c_parser
*parser
, unsigned int n
)
510 /* N is 1-based, not zero-based. */
513 if (parser
->tokens_avail
>= n
)
514 return &parser
->tokens
[n
- 1];
515 gcc_assert (parser
->tokens_avail
== n
- 1);
516 c_lex_one_token (parser
, &parser
->tokens
[n
- 1]);
517 parser
->tokens_avail
= n
;
518 return &parser
->tokens
[n
- 1];
521 /* Return a pointer to the Nth token from PARSER, reading it in as a
522 raw look-ahead token if necessary. The N-1th token is already read
523 in. Raw look-ahead tokens remain available for when the non-raw
524 functions above are called. */
527 c_parser_peek_nth_token_raw (c_parser
*parser
, unsigned int n
)
529 /* N is 1-based, not zero-based. */
532 if (parser
->tokens_avail
>= n
)
533 return &parser
->tokens
[n
- 1];
534 unsigned int raw_len
= vec_safe_length (parser
->raw_tokens
);
535 unsigned int raw_avail
536 = parser
->tokens_avail
+ raw_len
- parser
->raw_tokens_used
;
537 gcc_assert (raw_avail
>= n
- 1);
539 return &(*parser
->raw_tokens
)[parser
->raw_tokens_used
540 + n
- 1 - parser
->tokens_avail
];
541 vec_safe_reserve (parser
->raw_tokens
, 1);
542 parser
->raw_tokens
->quick_grow (raw_len
+ 1);
543 c_lex_one_token (parser
, &(*parser
->raw_tokens
)[raw_len
], true);
544 return &(*parser
->raw_tokens
)[raw_len
];
548 c_keyword_starts_typename (enum rid keyword
)
583 if (keyword
>= RID_FIRST_INT_N
584 && keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
585 && int_n_enabled_p
[keyword
- RID_FIRST_INT_N
])
591 /* Return true if TOKEN can start a type name,
594 c_token_starts_typename (c_token
*token
)
599 switch (token
->id_kind
)
608 gcc_assert (c_dialect_objc ());
614 return c_keyword_starts_typename (token
->keyword
);
616 if (c_dialect_objc ())
624 /* Return true if the next token from PARSER can start a type name,
625 false otherwise. LA specifies how to do lookahead in order to
626 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
629 c_parser_next_tokens_start_typename (c_parser
*parser
, enum c_lookahead_kind la
)
631 c_token
*token
= c_parser_peek_token (parser
);
632 if (c_token_starts_typename (token
))
635 /* Try a bit harder to detect an unknown typename. */
636 if (la
!= cla_prefer_id
637 && token
->type
== CPP_NAME
638 && token
->id_kind
== C_ID_ID
640 /* Do not try too hard when we could have "object in array". */
641 && !parser
->objc_could_be_foreach_context
643 && (la
== cla_prefer_type
644 || c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
645 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
647 /* Only unknown identifiers. */
648 && !lookup_name (token
->value
))
654 /* Return true if TOKEN is a type qualifier, false otherwise. */
656 c_token_is_qualifier (c_token
*token
)
661 switch (token
->id_kind
)
669 switch (token
->keyword
)
687 /* Return true if the next token from PARSER is a type qualifier,
690 c_parser_next_token_is_qualifier (c_parser
*parser
)
692 c_token
*token
= c_parser_peek_token (parser
);
693 return c_token_is_qualifier (token
);
696 /* Return true if TOKEN can start declaration specifiers (not
697 including standard attributes), false otherwise. */
699 c_token_starts_declspecs (c_token
*token
)
704 switch (token
->id_kind
)
713 gcc_assert (c_dialect_objc ());
719 switch (token
->keyword
)
760 if (token
->keyword
>= RID_FIRST_INT_N
761 && token
->keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
762 && int_n_enabled_p
[token
->keyword
- RID_FIRST_INT_N
])
767 if (c_dialect_objc ())
776 /* Return true if TOKEN can start declaration specifiers (not
777 including standard attributes) or a static assertion, false
780 c_token_starts_declaration (c_token
*token
)
782 if (c_token_starts_declspecs (token
)
783 || token
->keyword
== RID_STATIC_ASSERT
)
789 /* Return true if the next token from PARSER can start declaration
790 specifiers (not including standard attributes), false
793 c_parser_next_token_starts_declspecs (c_parser
*parser
)
795 c_token
*token
= c_parser_peek_token (parser
);
797 /* In Objective-C, a classname normally starts a declspecs unless it
798 is immediately followed by a dot. In that case, it is the
799 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
800 setter/getter on the class. c_token_starts_declspecs() can't
801 differentiate between the two cases because it only checks the
802 current token, so we have a special check here. */
803 if (c_dialect_objc ()
804 && token
->type
== CPP_NAME
805 && token
->id_kind
== C_ID_CLASSNAME
806 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
809 return c_token_starts_declspecs (token
);
812 /* Return true if the next tokens from PARSER can start declaration
813 specifiers (not including standard attributes) or a static
814 assertion, false otherwise. */
816 c_parser_next_tokens_start_declaration (c_parser
*parser
)
818 c_token
*token
= c_parser_peek_token (parser
);
821 if (c_dialect_objc ()
822 && token
->type
== CPP_NAME
823 && token
->id_kind
== C_ID_CLASSNAME
824 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
827 /* Labels do not start declarations. */
828 if (token
->type
== CPP_NAME
829 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
832 if (c_token_starts_declaration (token
))
835 if (c_parser_next_tokens_start_typename (parser
, cla_nonabstract_decl
))
841 /* Consume the next token from PARSER. */
844 c_parser_consume_token (c_parser
*parser
)
846 gcc_assert (parser
->tokens_avail
>= 1);
847 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
848 gcc_assert (!parser
->in_pragma
|| parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
849 gcc_assert (parser
->error
|| parser
->tokens
[0].type
!= CPP_PRAGMA
);
850 parser
->last_token_location
= parser
->tokens
[0].location
;
851 if (parser
->tokens
!= &parser
->tokens_buf
[0])
853 else if (parser
->tokens_avail
>= 2)
855 parser
->tokens
[0] = parser
->tokens
[1];
856 if (parser
->tokens_avail
>= 3)
858 parser
->tokens
[1] = parser
->tokens
[2];
859 if (parser
->tokens_avail
>= 4)
860 parser
->tokens
[2] = parser
->tokens
[3];
863 parser
->tokens_avail
--;
864 parser
->seen_string_literal
= false;
867 /* Expect the current token to be a #pragma. Consume it and remember
868 that we've begun parsing a pragma. */
871 c_parser_consume_pragma (c_parser
*parser
)
873 gcc_assert (!parser
->in_pragma
);
874 gcc_assert (parser
->tokens_avail
>= 1);
875 gcc_assert (parser
->tokens
[0].type
== CPP_PRAGMA
);
876 if (parser
->tokens
!= &parser
->tokens_buf
[0])
878 else if (parser
->tokens_avail
>= 2)
880 parser
->tokens
[0] = parser
->tokens
[1];
881 if (parser
->tokens_avail
>= 3)
882 parser
->tokens
[1] = parser
->tokens
[2];
884 parser
->tokens_avail
--;
885 parser
->in_pragma
= true;
888 /* Update the global input_location from TOKEN. */
890 c_parser_set_source_position_from_token (c_token
*token
)
892 if (token
->type
!= CPP_EOF
)
894 input_location
= token
->location
;
898 /* Helper function for c_parser_error.
899 Having peeked a token of kind TOK1_KIND that might signify
900 a conflict marker, peek successor tokens to determine
901 if we actually do have a conflict marker.
902 Specifically, we consider a run of 7 '<', '=' or '>' characters
903 at the start of a line as a conflict marker.
904 These come through the lexer as three pairs and a single,
905 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
906 If it returns true, *OUT_LOC is written to with the location/range
910 c_parser_peek_conflict_marker (c_parser
*parser
, enum cpp_ttype tok1_kind
,
913 c_token
*token2
= c_parser_peek_2nd_token (parser
);
914 if (token2
->type
!= tok1_kind
)
916 c_token
*token3
= c_parser_peek_nth_token (parser
, 3);
917 if (token3
->type
!= tok1_kind
)
919 c_token
*token4
= c_parser_peek_nth_token (parser
, 4);
920 if (token4
->type
!= conflict_marker_get_final_tok_kind (tok1_kind
))
923 /* It must be at the start of the line. */
924 location_t start_loc
= c_parser_peek_token (parser
)->location
;
925 if (LOCATION_COLUMN (start_loc
) != 1)
928 /* We have a conflict marker. Construct a location of the form:
931 with start == caret, finishing at the end of the marker. */
932 location_t finish_loc
= get_finish (token4
->location
);
933 *out_loc
= make_location (start_loc
, start_loc
, finish_loc
);
938 /* Issue a diagnostic of the form
939 FILE:LINE: MESSAGE before TOKEN
940 where TOKEN is the next token in the input stream of PARSER.
941 MESSAGE (specified by the caller) is usually of the form "expected
944 Use RICHLOC as the location of the diagnostic.
946 Do not issue a diagnostic if still recovering from an error.
948 Return true iff an error was actually emitted.
950 ??? This is taken from the C++ parser, but building up messages in
951 this way is not i18n-friendly and some other approach should be
955 c_parser_error_richloc (c_parser
*parser
, const char *gmsgid
,
956 rich_location
*richloc
)
958 c_token
*token
= c_parser_peek_token (parser
);
961 parser
->error
= true;
965 /* If this is actually a conflict marker, report it as such. */
966 if (token
->type
== CPP_LSHIFT
967 || token
->type
== CPP_RSHIFT
968 || token
->type
== CPP_EQ_EQ
)
971 if (c_parser_peek_conflict_marker (parser
, token
->type
, &loc
))
973 error_at (loc
, "version control conflict marker in file");
978 /* If we were parsing a string-literal and there is an unknown name
979 token right after, then check to see if that could also have been
980 a literal string by checking the name against a list of known
981 standard string literal constants defined in header files. If
982 there is one, then add that as an hint to the error message. */
983 auto_diagnostic_group d
;
985 if (parser
->seen_string_literal
&& token
->type
== CPP_NAME
)
987 tree name
= token
->value
;
988 const char *token_name
= IDENTIFIER_POINTER (name
);
989 const char *header_hint
990 = get_c_stdlib_header_for_string_macro_name (token_name
);
991 if (header_hint
!= NULL
)
992 h
= name_hint (NULL
, new suggest_missing_header (token
->location
,
997 c_parse_error (gmsgid
,
998 /* Because c_parse_error does not understand
999 CPP_KEYWORD, keywords are treated like
1001 (token
->type
== CPP_KEYWORD
? CPP_NAME
: token
->type
),
1002 /* ??? The C parser does not save the cpp flags of a
1003 token, we need to pass 0 here and we will not get
1004 the source spelling of some tokens but rather the
1005 canonical spelling. */
1006 token
->value
, /*flags=*/0, richloc
);
1010 /* As c_parser_error_richloc, but issue the message at the
1011 location of PARSER's next token, or at input_location
1012 if the next token is EOF. */
1015 c_parser_error (c_parser
*parser
, const char *gmsgid
)
1017 c_token
*token
= c_parser_peek_token (parser
);
1018 c_parser_set_source_position_from_token (token
);
1019 rich_location
richloc (line_table
, input_location
);
1020 return c_parser_error_richloc (parser
, gmsgid
, &richloc
);
1023 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1024 This class is for tracking such a matching pair of symbols.
1025 In particular, it tracks the location of the first token,
1026 so that if the second token is missing, we can highlight the
1027 location of the first token when notifying the user about the
1030 template <typename traits_t
>
1034 /* token_pair's ctor. */
1035 token_pair () : m_open_loc (UNKNOWN_LOCATION
) {}
1037 /* If the next token is the opening symbol for this pair, consume it and
1039 Otherwise, issue an error and return false.
1040 In either case, record the location of the opening token. */
1042 bool require_open (c_parser
*parser
)
1044 c_token
*token
= c_parser_peek_token (parser
);
1046 m_open_loc
= token
->location
;
1048 return c_parser_require (parser
, traits_t::open_token_type
,
1049 traits_t::open_gmsgid
);
1052 /* Consume the next token from PARSER, recording its location as
1053 that of the opening token within the pair. */
1055 void consume_open (c_parser
*parser
)
1057 c_token
*token
= c_parser_peek_token (parser
);
1058 gcc_assert (token
->type
== traits_t::open_token_type
);
1059 m_open_loc
= token
->location
;
1060 c_parser_consume_token (parser
);
1063 /* If the next token is the closing symbol for this pair, consume it
1065 Otherwise, issue an error, highlighting the location of the
1066 corresponding opening token, and return false. */
1068 bool require_close (c_parser
*parser
) const
1070 return c_parser_require (parser
, traits_t::close_token_type
,
1071 traits_t::close_gmsgid
, m_open_loc
);
1074 /* Like token_pair::require_close, except that tokens will be skipped
1075 until the desired token is found. An error message is still produced
1076 if the next token is not as expected. */
1078 void skip_until_found_close (c_parser
*parser
) const
1080 c_parser_skip_until_found (parser
, traits_t::close_token_type
,
1081 traits_t::close_gmsgid
, m_open_loc
);
1085 location_t m_open_loc
;
1088 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1090 struct matching_paren_traits
1092 static const enum cpp_ttype open_token_type
= CPP_OPEN_PAREN
;
1093 static const char * const open_gmsgid
;
1094 static const enum cpp_ttype close_token_type
= CPP_CLOSE_PAREN
;
1095 static const char * const close_gmsgid
;
1098 const char * const matching_paren_traits::open_gmsgid
= "expected %<(%>";
1099 const char * const matching_paren_traits::close_gmsgid
= "expected %<)%>";
1101 /* "matching_parens" is a token_pair<T> class for tracking matching
1102 pairs of parentheses. */
1104 typedef token_pair
<matching_paren_traits
> matching_parens
;
1106 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1108 struct matching_brace_traits
1110 static const enum cpp_ttype open_token_type
= CPP_OPEN_BRACE
;
1111 static const char * const open_gmsgid
;
1112 static const enum cpp_ttype close_token_type
= CPP_CLOSE_BRACE
;
1113 static const char * const close_gmsgid
;
1116 const char * const matching_brace_traits::open_gmsgid
= "expected %<{%>";
1117 const char * const matching_brace_traits::close_gmsgid
= "expected %<}%>";
1119 /* "matching_braces" is a token_pair<T> class for tracking matching
1122 typedef token_pair
<matching_brace_traits
> matching_braces
;
1124 /* Get a description of the matching symbol to TYPE e.g. "(" for
1128 get_matching_symbol (enum cpp_ttype type
)
1135 case CPP_CLOSE_PAREN
:
1137 case CPP_CLOSE_BRACE
:
1142 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1143 issue the error MSGID. If MSGID is NULL then a message has already
1144 been produced and no message will be produced this time. Returns
1145 true if found, false otherwise.
1147 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1148 within any error as the location of an "opening" token matching
1149 the close token TYPE (e.g. the location of the '(' when TYPE is
1152 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1153 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1154 attempt to generate a fix-it hint for the problem.
1155 Otherwise msgid describes multiple token types (e.g.
1156 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1157 generate a fix-it hint. */
1160 c_parser_require (c_parser
*parser
,
1161 enum cpp_ttype type
,
1163 location_t matching_location
,
1164 bool type_is_unique
)
1166 if (c_parser_next_token_is (parser
, type
))
1168 c_parser_consume_token (parser
);
1173 location_t next_token_loc
= c_parser_peek_token (parser
)->location
;
1174 gcc_rich_location
richloc (next_token_loc
);
1176 /* Potentially supply a fix-it hint, suggesting to add the
1177 missing token immediately after the *previous* token.
1178 This may move the primary location within richloc. */
1179 if (!parser
->error
&& type_is_unique
)
1180 maybe_suggest_missing_token_insertion (&richloc
, type
,
1181 parser
->last_token_location
);
1183 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1184 Attempt to consolidate diagnostics by printing it as a
1185 secondary range within the main diagnostic. */
1186 bool added_matching_location
= false;
1187 if (matching_location
!= UNKNOWN_LOCATION
)
1188 added_matching_location
1189 = richloc
.add_location_if_nearby (matching_location
);
1191 if (c_parser_error_richloc (parser
, msgid
, &richloc
))
1192 /* If we weren't able to consolidate matching_location, then
1193 print it as a secondary diagnostic. */
1194 if (matching_location
!= UNKNOWN_LOCATION
&& !added_matching_location
)
1195 inform (matching_location
, "to match this %qs",
1196 get_matching_symbol (type
));
1202 /* If the next token is the indicated keyword, consume it. Otherwise,
1203 issue the error MSGID. Returns true if found, false otherwise. */
1206 c_parser_require_keyword (c_parser
*parser
,
1210 if (c_parser_next_token_is_keyword (parser
, keyword
))
1212 c_parser_consume_token (parser
);
1217 c_parser_error (parser
, msgid
);
1222 /* Like c_parser_require, except that tokens will be skipped until the
1223 desired token is found. An error message is still produced if the
1224 next token is not as expected. If MSGID is NULL then a message has
1225 already been produced and no message will be produced this
1228 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1229 within any error as the location of an "opening" token matching
1230 the close token TYPE (e.g. the location of the '(' when TYPE is
1231 CPP_CLOSE_PAREN). */
1234 c_parser_skip_until_found (c_parser
*parser
,
1235 enum cpp_ttype type
,
1237 location_t matching_location
)
1239 unsigned nesting_depth
= 0;
1241 if (c_parser_require (parser
, type
, msgid
, matching_location
))
1244 /* Skip tokens until the desired token is found. */
1247 /* Peek at the next token. */
1248 c_token
*token
= c_parser_peek_token (parser
);
1249 /* If we've reached the token we want, consume it and stop. */
1250 if (token
->type
== type
&& !nesting_depth
)
1252 c_parser_consume_token (parser
);
1256 /* If we've run out of tokens, stop. */
1257 if (token
->type
== CPP_EOF
)
1259 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1261 if (token
->type
== CPP_OPEN_BRACE
1262 || token
->type
== CPP_OPEN_PAREN
1263 || token
->type
== CPP_OPEN_SQUARE
)
1265 else if (token
->type
== CPP_CLOSE_BRACE
1266 || token
->type
== CPP_CLOSE_PAREN
1267 || token
->type
== CPP_CLOSE_SQUARE
)
1269 if (nesting_depth
-- == 0)
1272 /* Consume this token. */
1273 c_parser_consume_token (parser
);
1275 parser
->error
= false;
1278 /* Skip tokens until the end of a parameter is found, but do not
1279 consume the comma, semicolon or closing delimiter. */
1282 c_parser_skip_to_end_of_parameter (c_parser
*parser
)
1284 unsigned nesting_depth
= 0;
1288 c_token
*token
= c_parser_peek_token (parser
);
1289 if ((token
->type
== CPP_COMMA
|| token
->type
== CPP_SEMICOLON
)
1292 /* If we've run out of tokens, stop. */
1293 if (token
->type
== CPP_EOF
)
1295 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1297 if (token
->type
== CPP_OPEN_BRACE
1298 || token
->type
== CPP_OPEN_PAREN
1299 || token
->type
== CPP_OPEN_SQUARE
)
1301 else if (token
->type
== CPP_CLOSE_BRACE
1302 || token
->type
== CPP_CLOSE_PAREN
1303 || token
->type
== CPP_CLOSE_SQUARE
)
1305 if (nesting_depth
-- == 0)
1308 /* Consume this token. */
1309 c_parser_consume_token (parser
);
1311 parser
->error
= false;
1314 /* Expect to be at the end of the pragma directive and consume an
1315 end of line marker. */
1318 c_parser_skip_to_pragma_eol (c_parser
*parser
, bool error_if_not_eol
= true)
1320 gcc_assert (parser
->in_pragma
);
1321 parser
->in_pragma
= false;
1323 if (error_if_not_eol
&& c_parser_peek_token (parser
)->type
!= CPP_PRAGMA_EOL
)
1324 c_parser_error (parser
, "expected end of line");
1326 cpp_ttype token_type
;
1329 c_token
*token
= c_parser_peek_token (parser
);
1330 token_type
= token
->type
;
1331 if (token_type
== CPP_EOF
)
1333 c_parser_consume_token (parser
);
1335 while (token_type
!= CPP_PRAGMA_EOL
);
1337 parser
->error
= false;
1340 /* Skip tokens until we have consumed an entire block, or until we
1341 have consumed a non-nested ';'. */
1344 c_parser_skip_to_end_of_block_or_statement (c_parser
*parser
)
1346 unsigned nesting_depth
= 0;
1347 bool save_error
= parser
->error
;
1353 /* Peek at the next token. */
1354 token
= c_parser_peek_token (parser
);
1356 switch (token
->type
)
1361 case CPP_PRAGMA_EOL
:
1362 if (parser
->in_pragma
)
1367 /* If the next token is a ';', we have reached the
1368 end of the statement. */
1371 /* Consume the ';'. */
1372 c_parser_consume_token (parser
);
1377 case CPP_CLOSE_BRACE
:
1378 /* If the next token is a non-nested '}', then we have
1379 reached the end of the current block. */
1380 if (nesting_depth
== 0 || --nesting_depth
== 0)
1382 c_parser_consume_token (parser
);
1387 case CPP_OPEN_BRACE
:
1388 /* If it the next token is a '{', then we are entering a new
1389 block. Consume the entire block. */
1394 /* If we see a pragma, consume the whole thing at once. We
1395 have some safeguards against consuming pragmas willy-nilly.
1396 Normally, we'd expect to be here with parser->error set,
1397 which disables these safeguards. But it's possible to get
1398 here for secondary error recovery, after parser->error has
1400 c_parser_consume_pragma (parser
);
1401 c_parser_skip_to_pragma_eol (parser
);
1402 parser
->error
= save_error
;
1409 c_parser_consume_token (parser
);
1413 parser
->error
= false;
1416 /* CPP's options (initialized by c-opts.c). */
1417 extern cpp_options
*cpp_opts
;
1419 /* Save the warning flags which are controlled by __extension__. */
1422 disable_extension_diagnostics (void)
1425 | (warn_pointer_arith
<< 1)
1426 | (warn_traditional
<< 2)
1428 | (warn_long_long
<< 4)
1429 | (warn_cxx_compat
<< 5)
1430 | (warn_overlength_strings
<< 6)
1431 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1432 play tricks to properly restore it. */
1433 | ((warn_c90_c99_compat
== 1) << 7)
1434 | ((warn_c90_c99_compat
== -1) << 8)
1435 /* Similarly for warn_c99_c11_compat. */
1436 | ((warn_c99_c11_compat
== 1) << 9)
1437 | ((warn_c99_c11_compat
== -1) << 10)
1438 /* Similarly for warn_c11_c2x_compat. */
1439 | ((warn_c11_c2x_compat
== 1) << 11)
1440 | ((warn_c11_c2x_compat
== -1) << 12)
1442 cpp_opts
->cpp_pedantic
= pedantic
= 0;
1443 warn_pointer_arith
= 0;
1444 cpp_opts
->cpp_warn_traditional
= warn_traditional
= 0;
1446 cpp_opts
->cpp_warn_long_long
= warn_long_long
= 0;
1447 warn_cxx_compat
= 0;
1448 warn_overlength_strings
= 0;
1449 warn_c90_c99_compat
= 0;
1450 warn_c99_c11_compat
= 0;
1451 warn_c11_c2x_compat
= 0;
1455 /* Restore the warning flags which are controlled by __extension__.
1456 FLAGS is the return value from disable_extension_diagnostics. */
1459 restore_extension_diagnostics (int flags
)
1461 cpp_opts
->cpp_pedantic
= pedantic
= flags
& 1;
1462 warn_pointer_arith
= (flags
>> 1) & 1;
1463 cpp_opts
->cpp_warn_traditional
= warn_traditional
= (flags
>> 2) & 1;
1464 flag_iso
= (flags
>> 3) & 1;
1465 cpp_opts
->cpp_warn_long_long
= warn_long_long
= (flags
>> 4) & 1;
1466 warn_cxx_compat
= (flags
>> 5) & 1;
1467 warn_overlength_strings
= (flags
>> 6) & 1;
1468 /* See above for why is this needed. */
1469 warn_c90_c99_compat
= (flags
>> 7) & 1 ? 1 : ((flags
>> 8) & 1 ? -1 : 0);
1470 warn_c99_c11_compat
= (flags
>> 9) & 1 ? 1 : ((flags
>> 10) & 1 ? -1 : 0);
1471 warn_c11_c2x_compat
= (flags
>> 11) & 1 ? 1 : ((flags
>> 12) & 1 ? -1 : 0);
1474 /* Helper data structure for parsing #pragma acc routine. */
1475 struct oacc_routine_data
{
1476 bool error_seen
; /* Set if error has been reported. */
1477 bool fndecl_seen
; /* Set if one fn decl/definition has been seen already. */
1482 static bool c_parser_nth_token_starts_std_attributes (c_parser
*,
1484 static tree
c_parser_std_attribute_specifier_sequence (c_parser
*);
1485 static void c_parser_external_declaration (c_parser
*);
1486 static void c_parser_asm_definition (c_parser
*);
1487 static void c_parser_declaration_or_fndef (c_parser
*, bool, bool, bool,
1488 bool, bool, tree
*, vec
<c_token
>,
1489 bool have_attrs
= false,
1491 struct oacc_routine_data
* = NULL
,
1493 static void c_parser_static_assert_declaration_no_semi (c_parser
*);
1494 static void c_parser_static_assert_declaration (c_parser
*);
1495 static struct c_typespec
c_parser_enum_specifier (c_parser
*);
1496 static struct c_typespec
c_parser_struct_or_union_specifier (c_parser
*);
1497 static tree
c_parser_struct_declaration (c_parser
*);
1498 static struct c_typespec
c_parser_typeof_specifier (c_parser
*);
1499 static tree
c_parser_alignas_specifier (c_parser
*);
1500 static struct c_declarator
*c_parser_direct_declarator (c_parser
*, bool,
1502 static struct c_declarator
*c_parser_direct_declarator_inner (c_parser
*,
1504 struct c_declarator
*);
1505 static struct c_arg_info
*c_parser_parms_declarator (c_parser
*, bool, tree
,
1507 static struct c_arg_info
*c_parser_parms_list_declarator (c_parser
*, tree
,
1509 static struct c_parm
*c_parser_parameter_declaration (c_parser
*, tree
, bool);
1510 static tree
c_parser_simple_asm_expr (c_parser
*);
1511 static tree
c_parser_gnu_attributes (c_parser
*);
1512 static struct c_expr
c_parser_initializer (c_parser
*);
1513 static struct c_expr
c_parser_braced_init (c_parser
*, tree
, bool,
1515 static void c_parser_initelt (c_parser
*, struct obstack
*);
1516 static void c_parser_initval (c_parser
*, struct c_expr
*,
1518 static tree
c_parser_compound_statement (c_parser
*, location_t
* = NULL
);
1519 static location_t
c_parser_compound_statement_nostart (c_parser
*);
1520 static void c_parser_label (c_parser
*);
1521 static void c_parser_statement (c_parser
*, bool *, location_t
* = NULL
);
1522 static void c_parser_statement_after_labels (c_parser
*, bool *,
1523 vec
<tree
> * = NULL
);
1524 static tree
c_parser_c99_block_statement (c_parser
*, bool *,
1525 location_t
* = NULL
);
1526 static void c_parser_if_statement (c_parser
*, bool *, vec
<tree
> *);
1527 static void c_parser_switch_statement (c_parser
*, bool *);
1528 static void c_parser_while_statement (c_parser
*, bool, unsigned short, bool *);
1529 static void c_parser_do_statement (c_parser
*, bool, unsigned short);
1530 static void c_parser_for_statement (c_parser
*, bool, unsigned short, bool *);
1531 static tree
c_parser_asm_statement (c_parser
*);
1532 static tree
c_parser_asm_operands (c_parser
*);
1533 static tree
c_parser_asm_goto_operands (c_parser
*);
1534 static tree
c_parser_asm_clobbers (c_parser
*);
1535 static struct c_expr
c_parser_expr_no_commas (c_parser
*, struct c_expr
*,
1537 static struct c_expr
c_parser_conditional_expression (c_parser
*,
1538 struct c_expr
*, tree
);
1539 static struct c_expr
c_parser_binary_expression (c_parser
*, struct c_expr
*,
1541 static struct c_expr
c_parser_cast_expression (c_parser
*, struct c_expr
*);
1542 static struct c_expr
c_parser_unary_expression (c_parser
*);
1543 static struct c_expr
c_parser_sizeof_expression (c_parser
*);
1544 static struct c_expr
c_parser_alignof_expression (c_parser
*);
1545 static struct c_expr
c_parser_postfix_expression (c_parser
*);
1546 static struct c_expr
c_parser_postfix_expression_after_paren_type (c_parser
*,
1547 struct c_type_name
*,
1549 static struct c_expr
c_parser_postfix_expression_after_primary (c_parser
*,
1552 static tree
c_parser_transaction (c_parser
*, enum rid
);
1553 static struct c_expr
c_parser_transaction_expression (c_parser
*, enum rid
);
1554 static tree
c_parser_transaction_cancel (c_parser
*);
1555 static struct c_expr
c_parser_expression (c_parser
*);
1556 static struct c_expr
c_parser_expression_conv (c_parser
*);
1557 static vec
<tree
, va_gc
> *c_parser_expr_list (c_parser
*, bool, bool,
1558 vec
<tree
, va_gc
> **, location_t
*,
1559 tree
*, vec
<location_t
> *,
1560 unsigned int * = NULL
);
1561 static struct c_expr
c_parser_has_attribute_expression (c_parser
*);
1563 static void c_parser_oacc_declare (c_parser
*);
1564 static void c_parser_oacc_enter_exit_data (c_parser
*, bool);
1565 static void c_parser_oacc_update (c_parser
*);
1566 static void c_parser_omp_construct (c_parser
*, bool *);
1567 static void c_parser_omp_threadprivate (c_parser
*);
1568 static void c_parser_omp_barrier (c_parser
*);
1569 static void c_parser_omp_depobj (c_parser
*);
1570 static void c_parser_omp_flush (c_parser
*);
1571 static tree
c_parser_omp_for_loop (location_t
, c_parser
*, enum tree_code
,
1572 tree
, tree
*, bool *);
1573 static void c_parser_omp_taskwait (c_parser
*);
1574 static void c_parser_omp_taskyield (c_parser
*);
1575 static void c_parser_omp_cancel (c_parser
*);
1577 enum pragma_context
{ pragma_external
, pragma_struct
, pragma_param
,
1578 pragma_stmt
, pragma_compound
};
1579 static bool c_parser_pragma (c_parser
*, enum pragma_context
, bool *);
1580 static void c_parser_omp_cancellation_point (c_parser
*, enum pragma_context
);
1581 static bool c_parser_omp_target (c_parser
*, enum pragma_context
, bool *);
1582 static void c_parser_omp_end_declare_target (c_parser
*);
1583 static void c_parser_omp_declare (c_parser
*, enum pragma_context
);
1584 static void c_parser_omp_requires (c_parser
*);
1585 static bool c_parser_omp_ordered (c_parser
*, enum pragma_context
, bool *);
1586 static void c_parser_oacc_routine (c_parser
*, enum pragma_context
);
1588 /* These Objective-C parser functions are only ever called when
1589 compiling Objective-C. */
1590 static void c_parser_objc_class_definition (c_parser
*, tree
);
1591 static void c_parser_objc_class_instance_variables (c_parser
*);
1592 static void c_parser_objc_class_declaration (c_parser
*);
1593 static void c_parser_objc_alias_declaration (c_parser
*);
1594 static void c_parser_objc_protocol_definition (c_parser
*, tree
);
1595 static bool c_parser_objc_method_type (c_parser
*);
1596 static void c_parser_objc_method_definition (c_parser
*);
1597 static void c_parser_objc_methodprotolist (c_parser
*);
1598 static void c_parser_objc_methodproto (c_parser
*);
1599 static tree
c_parser_objc_method_decl (c_parser
*, bool, tree
*, tree
*);
1600 static tree
c_parser_objc_type_name (c_parser
*);
1601 static tree
c_parser_objc_protocol_refs (c_parser
*);
1602 static void c_parser_objc_try_catch_finally_statement (c_parser
*);
1603 static void c_parser_objc_synchronized_statement (c_parser
*);
1604 static tree
c_parser_objc_selector (c_parser
*);
1605 static tree
c_parser_objc_selector_arg (c_parser
*);
1606 static tree
c_parser_objc_receiver (c_parser
*);
1607 static tree
c_parser_objc_message_args (c_parser
*);
1608 static tree
c_parser_objc_keywordexpr (c_parser
*);
1609 static void c_parser_objc_at_property_declaration (c_parser
*);
1610 static void c_parser_objc_at_synthesize_declaration (c_parser
*);
1611 static void c_parser_objc_at_dynamic_declaration (c_parser
*);
1612 static bool c_parser_objc_diagnose_bad_element_prefix
1613 (c_parser
*, struct c_declspecs
*);
1614 static location_t
c_parser_parse_rtl_body (c_parser
*, char *);
1616 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1619 external-declarations
1621 external-declarations:
1622 external-declaration
1623 external-declarations external-declaration
1632 c_parser_translation_unit (c_parser
*parser
)
1634 if (c_parser_next_token_is (parser
, CPP_EOF
))
1636 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1637 "ISO C forbids an empty translation unit");
1641 void *obstack_position
= obstack_alloc (&parser_obstack
, 0);
1642 mark_valid_location_for_stdc_pragma (false);
1646 c_parser_external_declaration (parser
);
1647 obstack_free (&parser_obstack
, obstack_position
);
1649 while (c_parser_next_token_is_not (parser
, CPP_EOF
));
1654 FOR_EACH_VEC_ELT (incomplete_record_decls
, i
, decl
)
1655 if (DECL_SIZE (decl
) == NULL_TREE
&& TREE_TYPE (decl
) != error_mark_node
)
1656 error ("storage size of %q+D isn%'t known", decl
);
1658 if (current_omp_declare_target_attribute
)
1661 error ("%<#pragma omp declare target%> without corresponding "
1662 "%<#pragma omp end declare target%>");
1663 current_omp_declare_target_attribute
= 0;
1667 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1669 external-declaration:
1675 external-declaration:
1678 __extension__ external-declaration
1682 external-declaration:
1683 objc-class-definition
1684 objc-class-declaration
1685 objc-alias-declaration
1686 objc-protocol-definition
1687 objc-method-definition
1692 c_parser_external_declaration (c_parser
*parser
)
1695 switch (c_parser_peek_token (parser
)->type
)
1698 switch (c_parser_peek_token (parser
)->keyword
)
1701 ext
= disable_extension_diagnostics ();
1702 c_parser_consume_token (parser
);
1703 c_parser_external_declaration (parser
);
1704 restore_extension_diagnostics (ext
);
1707 c_parser_asm_definition (parser
);
1709 case RID_AT_INTERFACE
:
1710 case RID_AT_IMPLEMENTATION
:
1711 gcc_assert (c_dialect_objc ());
1712 c_parser_objc_class_definition (parser
, NULL_TREE
);
1715 gcc_assert (c_dialect_objc ());
1716 c_parser_objc_class_declaration (parser
);
1719 gcc_assert (c_dialect_objc ());
1720 c_parser_objc_alias_declaration (parser
);
1722 case RID_AT_PROTOCOL
:
1723 gcc_assert (c_dialect_objc ());
1724 c_parser_objc_protocol_definition (parser
, NULL_TREE
);
1726 case RID_AT_PROPERTY
:
1727 gcc_assert (c_dialect_objc ());
1728 c_parser_objc_at_property_declaration (parser
);
1730 case RID_AT_SYNTHESIZE
:
1731 gcc_assert (c_dialect_objc ());
1732 c_parser_objc_at_synthesize_declaration (parser
);
1734 case RID_AT_DYNAMIC
:
1735 gcc_assert (c_dialect_objc ());
1736 c_parser_objc_at_dynamic_declaration (parser
);
1739 gcc_assert (c_dialect_objc ());
1740 c_parser_consume_token (parser
);
1741 objc_finish_implementation ();
1748 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1749 "ISO C does not allow extra %<;%> outside of a function");
1750 c_parser_consume_token (parser
);
1753 mark_valid_location_for_stdc_pragma (true);
1754 c_parser_pragma (parser
, pragma_external
, NULL
);
1755 mark_valid_location_for_stdc_pragma (false);
1759 if (c_dialect_objc ())
1761 c_parser_objc_method_definition (parser
);
1764 /* Else fall through, and yield a syntax error trying to parse
1765 as a declaration or function definition. */
1769 /* A declaration or a function definition (or, in Objective-C,
1770 an @interface or @protocol with prefix attributes). We can
1771 only tell which after parsing the declaration specifiers, if
1772 any, and the first declarator. */
1773 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
1779 static void c_finish_omp_declare_simd (c_parser
*, tree
, tree
, vec
<c_token
>);
1780 static void c_finish_oacc_routine (struct oacc_routine_data
*, tree
, bool);
1782 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1785 add_debug_begin_stmt (location_t loc
)
1787 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1788 if (!MAY_HAVE_DEBUG_MARKER_STMTS
|| !building_stmt_list_p ())
1791 tree stmt
= build0 (DEBUG_BEGIN_STMT
, void_type_node
);
1792 SET_EXPR_LOCATION (stmt
, loc
);
1796 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1797 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1798 is accepted; otherwise (old-style parameter declarations) only other
1799 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1800 assertion is accepted; otherwise (old-style parameter declarations)
1801 it is not. If NESTED is true, we are inside a function or parsing
1802 old-style parameter declarations; any functions encountered are
1803 nested functions and declaration specifiers are required; otherwise
1804 we are at top level and functions are normal functions and
1805 declaration specifiers may be optional. If EMPTY_OK is true, empty
1806 declarations are OK (subject to all other constraints); otherwise
1807 (old-style parameter declarations) they are diagnosed. If
1808 START_ATTR_OK is true, the declaration specifiers may start with
1809 attributes (GNU or standard); otherwise they may not.
1810 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1811 declaration when parsing an Objective-C foreach statement.
1812 FALLTHRU_ATTR_P is used to signal whether this function parsed
1813 "__attribute__((fallthrough));". ATTRS are any standard attributes
1814 parsed in the caller (in contexts where such attributes had to be
1815 parsed to determine whether what follows is a declaration or a
1816 statement); HAVE_ATTRS says whether there were any such attributes
1820 declaration-specifiers init-declarator-list[opt] ;
1821 static_assert-declaration
1823 function-definition:
1824 declaration-specifiers[opt] declarator declaration-list[opt]
1829 declaration-list declaration
1831 init-declarator-list:
1833 init-declarator-list , init-declarator
1836 declarator simple-asm-expr[opt] gnu-attributes[opt]
1837 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1841 nested-function-definition:
1842 declaration-specifiers declarator declaration-list[opt]
1848 gnu-attributes objc-class-definition
1849 gnu-attributes objc-category-definition
1850 gnu-attributes objc-protocol-definition
1852 The simple-asm-expr and gnu-attributes are GNU extensions.
1854 This function does not handle __extension__; that is handled in its
1855 callers. ??? Following the old parser, __extension__ may start
1856 external declarations, declarations in functions and declarations
1857 at the start of "for" loops, but not old-style parameter
1860 C99 requires declaration specifiers in a function definition; the
1861 absence is diagnosed through the diagnosis of implicit int. In GNU
1862 C we also allow but diagnose declarations without declaration
1863 specifiers, but only at top level (elsewhere they conflict with
1866 In Objective-C, declarations of the looping variable in a foreach
1867 statement are exceptionally terminated by 'in' (for example, 'for
1868 (NSObject *object in array) { ... }').
1873 threadprivate-directive
1877 gimple-function-definition:
1878 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1879 declaration-list[opt] compound-statement
1881 rtl-function-definition:
1882 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1883 declaration-list[opt] compound-statement */
1886 c_parser_declaration_or_fndef (c_parser
*parser
, bool fndef_ok
,
1887 bool static_assert_ok
, bool empty_ok
,
1888 bool nested
, bool start_attr_ok
,
1889 tree
*objc_foreach_object_declaration
,
1890 vec
<c_token
> omp_declare_simd_clauses
,
1891 bool have_attrs
, tree attrs
,
1892 struct oacc_routine_data
*oacc_routine_data
,
1893 bool *fallthru_attr_p
)
1895 struct c_declspecs
*specs
;
1897 tree all_prefix_attrs
;
1898 bool diagnosed_no_specs
= false;
1899 location_t here
= c_parser_peek_token (parser
)->location
;
1901 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
1903 if (static_assert_ok
1904 && c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
1906 c_parser_static_assert_declaration (parser
);
1909 specs
= build_null_declspecs ();
1911 /* Handle any standard attributes parsed in the caller. */
1914 declspecs_add_attrs (here
, specs
, attrs
);
1915 specs
->non_std_attrs_seen_p
= false;
1918 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1919 if (c_parser_peek_token (parser
)->type
== CPP_NAME
1920 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
1921 && (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
1922 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
1923 && (!nested
|| !lookup_name (c_parser_peek_token (parser
)->value
)))
1925 tree name
= c_parser_peek_token (parser
)->value
;
1927 /* Issue a warning about NAME being an unknown type name, perhaps
1928 with some kind of hint.
1929 If the user forgot a "struct" etc, suggest inserting
1930 it. Otherwise, attempt to look for misspellings. */
1931 gcc_rich_location
richloc (here
);
1932 if (tag_exists_p (RECORD_TYPE
, name
))
1934 /* This is not C++ with its implicit typedef. */
1935 richloc
.add_fixit_insert_before ("struct ");
1937 "unknown type name %qE;"
1938 " use %<struct%> keyword to refer to the type",
1941 else if (tag_exists_p (UNION_TYPE
, name
))
1943 richloc
.add_fixit_insert_before ("union ");
1945 "unknown type name %qE;"
1946 " use %<union%> keyword to refer to the type",
1949 else if (tag_exists_p (ENUMERAL_TYPE
, name
))
1951 richloc
.add_fixit_insert_before ("enum ");
1953 "unknown type name %qE;"
1954 " use %<enum%> keyword to refer to the type",
1959 auto_diagnostic_group d
;
1960 name_hint hint
= lookup_name_fuzzy (name
, FUZZY_LOOKUP_TYPENAME
,
1962 if (const char *suggestion
= hint
.suggestion ())
1964 richloc
.add_fixit_replace (suggestion
);
1966 "unknown type name %qE; did you mean %qs?",
1970 error_at (here
, "unknown type name %qE", name
);
1973 /* Parse declspecs normally to get a correct pointer type, but avoid
1974 a further "fails to be a type name" error. Refuse nested functions
1975 since it is not how the user likely wants us to recover. */
1976 c_parser_peek_token (parser
)->type
= CPP_KEYWORD
;
1977 c_parser_peek_token (parser
)->keyword
= RID_VOID
;
1978 c_parser_peek_token (parser
)->value
= error_mark_node
;
1982 /* When there are standard attributes at the start of the
1983 declaration (to apply to the entity being declared), an
1984 init-declarator-list or function definition must be present. */
1985 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
1988 c_parser_declspecs (parser
, specs
, true, true, start_attr_ok
,
1989 true, true, start_attr_ok
, true, cla_nonabstract_decl
);
1992 c_parser_skip_to_end_of_block_or_statement (parser
);
1995 if (nested
&& !specs
->declspecs_seen_p
)
1997 c_parser_error (parser
, "expected declaration specifiers");
1998 c_parser_skip_to_end_of_block_or_statement (parser
);
2002 finish_declspecs (specs
);
2003 bool auto_type_p
= specs
->typespec_word
== cts_auto_type
;
2004 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2007 error_at (here
, "%<__auto_type%> in empty declaration");
2008 else if (specs
->typespec_kind
== ctsk_none
2009 && attribute_fallthrough_p (specs
->attrs
))
2011 if (fallthru_attr_p
!= NULL
)
2012 *fallthru_attr_p
= true;
2015 tree fn
= build_call_expr_internal_loc (here
, IFN_FALLTHROUGH
,
2020 pedwarn (here
, OPT_Wattributes
,
2021 "%<fallthrough%> attribute at top level");
2023 else if (empty_ok
&& !(have_attrs
2024 && specs
->non_std_attrs_seen_p
))
2028 shadow_tag_warned (specs
, 1);
2029 pedwarn (here
, 0, "empty declaration");
2031 c_parser_consume_token (parser
);
2032 if (oacc_routine_data
)
2033 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2037 /* Provide better error recovery. Note that a type name here is usually
2038 better diagnosed as a redeclaration. */
2040 && specs
->typespec_kind
== ctsk_tagdef
2041 && c_parser_next_token_starts_declspecs (parser
)
2042 && !c_parser_next_token_is (parser
, CPP_NAME
))
2044 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
2045 parser
->error
= false;
2046 shadow_tag_warned (specs
, 1);
2049 else if (c_dialect_objc () && !auto_type_p
)
2051 /* Prefix attributes are an error on method decls. */
2052 switch (c_parser_peek_token (parser
)->type
)
2056 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2060 warning_at (c_parser_peek_token (parser
)->location
,
2062 "prefix attributes are ignored for methods");
2063 specs
->attrs
= NULL_TREE
;
2066 c_parser_objc_method_definition (parser
);
2068 c_parser_objc_methodproto (parser
);
2074 /* This is where we parse 'attributes @interface ...',
2075 'attributes @implementation ...', 'attributes @protocol ...'
2076 (where attributes could be, for example, __attribute__
2079 switch (c_parser_peek_token (parser
)->keyword
)
2081 case RID_AT_INTERFACE
:
2083 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2085 c_parser_objc_class_definition (parser
, specs
->attrs
);
2089 case RID_AT_IMPLEMENTATION
:
2091 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2095 warning_at (c_parser_peek_token (parser
)->location
,
2097 "prefix attributes are ignored for implementations");
2098 specs
->attrs
= NULL_TREE
;
2100 c_parser_objc_class_definition (parser
, NULL_TREE
);
2104 case RID_AT_PROTOCOL
:
2106 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2108 c_parser_objc_protocol_definition (parser
, specs
->attrs
);
2115 case RID_AT_PROPERTY
:
2118 c_parser_error (parser
, "unexpected attribute");
2119 specs
->attrs
= NULL
;
2126 else if (attribute_fallthrough_p (specs
->attrs
))
2127 warning_at (here
, OPT_Wattributes
,
2128 "%<fallthrough%> attribute not followed by %<;%>");
2130 pending_xref_error ();
2131 prefix_attrs
= specs
->attrs
;
2132 all_prefix_attrs
= prefix_attrs
;
2133 specs
->attrs
= NULL_TREE
;
2136 struct c_declarator
*declarator
;
2139 tree fnbody
= NULL_TREE
;
2140 /* Declaring either one or more declarators (in which case we
2141 should diagnose if there were no declaration specifiers) or a
2142 function definition (in which case the diagnostic for
2143 implicit int suffices). */
2144 declarator
= c_parser_declarator (parser
,
2145 specs
->typespec_kind
!= ctsk_none
,
2146 C_DTR_NORMAL
, &dummy
);
2147 if (declarator
== NULL
)
2149 if (omp_declare_simd_clauses
.exists ())
2150 c_finish_omp_declare_simd (parser
, NULL_TREE
, NULL_TREE
,
2151 omp_declare_simd_clauses
);
2152 if (oacc_routine_data
)
2153 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2154 c_parser_skip_to_end_of_block_or_statement (parser
);
2157 if (auto_type_p
&& declarator
->kind
!= cdk_id
)
2160 "%<__auto_type%> requires a plain identifier"
2162 c_parser_skip_to_end_of_block_or_statement (parser
);
2165 if (c_parser_next_token_is (parser
, CPP_EQ
)
2166 || c_parser_next_token_is (parser
, CPP_COMMA
)
2167 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
2168 || c_parser_next_token_is_keyword (parser
, RID_ASM
)
2169 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
)
2170 || c_parser_next_token_is_keyword (parser
, RID_IN
))
2172 tree asm_name
= NULL_TREE
;
2173 tree postfix_attrs
= NULL_TREE
;
2174 if (!diagnosed_no_specs
&& !specs
->declspecs_seen_p
)
2176 diagnosed_no_specs
= true;
2177 pedwarn (here
, 0, "data definition has no type or storage class");
2179 /* Having seen a data definition, there cannot now be a
2180 function definition. */
2182 if (c_parser_next_token_is_keyword (parser
, RID_ASM
))
2183 asm_name
= c_parser_simple_asm_expr (parser
);
2184 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2186 postfix_attrs
= c_parser_gnu_attributes (parser
);
2187 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2189 /* This means there is an attribute specifier after
2190 the declarator in a function definition. Provide
2191 some more information for the user. */
2192 error_at (here
, "attributes should be specified before the "
2193 "declarator in a function definition");
2194 c_parser_skip_to_end_of_block_or_statement (parser
);
2198 if (c_parser_next_token_is (parser
, CPP_EQ
))
2202 location_t init_loc
;
2203 c_parser_consume_token (parser
);
2206 init_loc
= c_parser_peek_token (parser
)->location
;
2207 rich_location
richloc (line_table
, init_loc
);
2208 start_init (NULL_TREE
, asm_name
, global_bindings_p (), &richloc
);
2209 /* A parameter is initialized, which is invalid. Don't
2210 attempt to instrument the initializer. */
2211 int flag_sanitize_save
= flag_sanitize
;
2212 if (nested
&& !empty_ok
)
2214 init
= c_parser_expr_no_commas (parser
, NULL
);
2215 flag_sanitize
= flag_sanitize_save
;
2216 if (TREE_CODE (init
.value
) == COMPONENT_REF
2217 && DECL_C_BIT_FIELD (TREE_OPERAND (init
.value
, 1)))
2219 "%<__auto_type%> used with a bit-field"
2221 init
= convert_lvalue_to_rvalue (init_loc
, init
, true, true);
2222 tree init_type
= TREE_TYPE (init
.value
);
2223 /* As with typeof, remove all qualifiers from atomic types. */
2224 if (init_type
!= error_mark_node
&& TYPE_ATOMIC (init_type
))
2226 = c_build_qualified_type (init_type
, TYPE_UNQUALIFIED
);
2227 bool vm_type
= variably_modified_type_p (init_type
,
2230 init
.value
= save_expr (init
.value
);
2232 specs
->typespec_kind
= ctsk_typeof
;
2233 specs
->locations
[cdw_typedef
] = init_loc
;
2234 specs
->typedef_p
= true;
2235 specs
->type
= init_type
;
2238 bool maybe_const
= true;
2239 tree type_expr
= c_fully_fold (init
.value
, false,
2241 specs
->expr_const_operands
&= maybe_const
;
2243 specs
->expr
= build2 (COMPOUND_EXPR
,
2244 TREE_TYPE (type_expr
),
2245 specs
->expr
, type_expr
);
2247 specs
->expr
= type_expr
;
2249 d
= start_decl (declarator
, specs
, true,
2250 chainon (postfix_attrs
, all_prefix_attrs
));
2252 d
= error_mark_node
;
2253 if (omp_declare_simd_clauses
.exists ())
2254 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2255 omp_declare_simd_clauses
);
2259 /* The declaration of the variable is in effect while
2260 its initializer is parsed. */
2261 d
= start_decl (declarator
, specs
, true,
2262 chainon (postfix_attrs
, all_prefix_attrs
));
2264 d
= error_mark_node
;
2265 if (omp_declare_simd_clauses
.exists ())
2266 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2267 omp_declare_simd_clauses
);
2268 init_loc
= c_parser_peek_token (parser
)->location
;
2269 rich_location
richloc (line_table
, init_loc
);
2270 start_init (d
, asm_name
, global_bindings_p (), &richloc
);
2271 /* A parameter is initialized, which is invalid. Don't
2272 attempt to instrument the initializer. */
2273 int flag_sanitize_save
= flag_sanitize
;
2274 if (TREE_CODE (d
) == PARM_DECL
)
2276 init
= c_parser_initializer (parser
);
2277 flag_sanitize
= flag_sanitize_save
;
2280 if (oacc_routine_data
)
2281 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2282 if (d
!= error_mark_node
)
2284 maybe_warn_string_init (init_loc
, TREE_TYPE (d
), init
);
2285 finish_decl (d
, init_loc
, init
.value
,
2286 init
.original_type
, asm_name
);
2294 "%<__auto_type%> requires an initialized "
2295 "data declaration");
2296 c_parser_skip_to_end_of_block_or_statement (parser
);
2299 tree d
= start_decl (declarator
, specs
, false,
2300 chainon (postfix_attrs
,
2303 && TREE_CODE (d
) == FUNCTION_DECL
2304 && DECL_ARGUMENTS (d
) == NULL_TREE
2305 && DECL_INITIAL (d
) == NULL_TREE
)
2307 /* Find the innermost declarator that is neither cdk_id
2309 const struct c_declarator
*decl
= declarator
;
2310 const struct c_declarator
*last_non_id_attrs
= NULL
;
2318 last_non_id_attrs
= decl
;
2319 decl
= decl
->declarator
;
2323 decl
= decl
->declarator
;
2334 /* If it exists and is cdk_function, use its parameters. */
2335 if (last_non_id_attrs
2336 && last_non_id_attrs
->kind
== cdk_function
)
2337 DECL_ARGUMENTS (d
) = last_non_id_attrs
->u
.arg_info
->parms
;
2339 if (omp_declare_simd_clauses
.exists ())
2341 tree parms
= NULL_TREE
;
2342 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2344 struct c_declarator
*ce
= declarator
;
2346 if (ce
->kind
== cdk_function
)
2348 parms
= ce
->u
.arg_info
->parms
;
2352 ce
= ce
->declarator
;
2355 temp_store_parm_decls (d
, parms
);
2356 c_finish_omp_declare_simd (parser
, d
, parms
,
2357 omp_declare_simd_clauses
);
2359 temp_pop_parm_decls ();
2361 if (oacc_routine_data
)
2362 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2364 finish_decl (d
, UNKNOWN_LOCATION
, NULL_TREE
,
2365 NULL_TREE
, asm_name
);
2367 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2370 *objc_foreach_object_declaration
= d
;
2372 *objc_foreach_object_declaration
= error_mark_node
;
2375 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2380 "%<__auto_type%> may only be used with"
2381 " a single declarator");
2382 c_parser_skip_to_end_of_block_or_statement (parser
);
2385 c_parser_consume_token (parser
);
2386 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2387 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
2390 all_prefix_attrs
= prefix_attrs
;
2393 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2395 c_parser_consume_token (parser
);
2398 else if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2400 /* This can only happen in Objective-C: we found the
2401 'in' that terminates the declaration inside an
2402 Objective-C foreach statement. Do not consume the
2403 token, so that the caller can use it to determine
2404 that this indeed is a foreach context. */
2409 c_parser_error (parser
, "expected %<,%> or %<;%>");
2410 c_parser_skip_to_end_of_block_or_statement (parser
);
2414 else if (auto_type_p
)
2417 "%<__auto_type%> requires an initialized data declaration");
2418 c_parser_skip_to_end_of_block_or_statement (parser
);
2423 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, "
2424 "%<asm%> or %<__attribute__%>");
2425 c_parser_skip_to_end_of_block_or_statement (parser
);
2428 /* Function definition (nested or otherwise). */
2431 pedwarn (here
, OPT_Wpedantic
, "ISO C forbids nested functions");
2432 c_push_function_context ();
2434 if (!start_function (specs
, declarator
, all_prefix_attrs
))
2436 /* At this point we've consumed:
2437 declaration-specifiers declarator
2438 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2439 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2441 declaration-specifiers declarator
2442 aren't grokkable as a function definition, so we have
2444 gcc_assert (!c_parser_next_token_is (parser
, CPP_SEMICOLON
));
2445 if (c_parser_next_token_starts_declspecs (parser
))
2448 declaration-specifiers declarator decl-specs
2449 then assume we have a missing semicolon, which would
2451 declaration-specifiers declarator decl-specs
2454 <~~~~~~~~~ declaration ~~~~~~~~~~>
2455 Use c_parser_require to get an error with a fix-it hint. */
2456 c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>");
2457 parser
->error
= false;
2461 /* This can appear in many cases looking nothing like a
2462 function definition, so we don't give a more specific
2463 error suggesting there was one. */
2464 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2465 "or %<__attribute__%>");
2468 c_pop_function_context ();
2472 if (DECL_DECLARED_INLINE_P (current_function_decl
))
2473 tv
= TV_PARSE_INLINE
;
2476 auto_timevar
at (g_timer
, tv
);
2478 /* Parse old-style parameter declarations. ??? Attributes are
2479 not allowed to start declaration specifiers here because of a
2480 syntax conflict between a function declaration with attribute
2481 suffix and a function definition with an attribute prefix on
2482 first old-style parameter declaration. Following the old
2483 parser, they are not accepted on subsequent old-style
2484 parameter declarations either. However, there is no
2485 ambiguity after the first declaration, nor indeed on the
2486 first as long as we don't allow postfix attributes after a
2487 declarator with a nonempty identifier list in a definition;
2488 and postfix attributes have never been accepted here in
2489 function definitions either. */
2490 while (c_parser_next_token_is_not (parser
, CPP_EOF
)
2491 && c_parser_next_token_is_not (parser
, CPP_OPEN_BRACE
))
2492 c_parser_declaration_or_fndef (parser
, false, false, false,
2493 true, false, NULL
, vNULL
);
2494 store_parm_decls ();
2495 if (omp_declare_simd_clauses
.exists ())
2496 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2497 omp_declare_simd_clauses
);
2498 if (oacc_routine_data
)
2499 c_finish_oacc_routine (oacc_routine_data
, current_function_decl
, true);
2500 location_t startloc
= c_parser_peek_token (parser
)->location
;
2501 DECL_STRUCT_FUNCTION (current_function_decl
)->function_start_locus
2503 location_t endloc
= startloc
;
2505 /* If the definition was marked with __RTL, use the RTL parser now,
2506 consuming the function body. */
2507 if (specs
->declspec_il
== cdil_rtl
)
2509 endloc
= c_parser_parse_rtl_body (parser
, specs
->gimple_or_rtl_pass
);
2511 /* Normally, store_parm_decls sets next_is_function_body,
2512 anticipating a function body. We need a push_scope/pop_scope
2513 pair to flush out this state, or subsequent function parsing
2518 finish_function (endloc
);
2521 /* If the definition was marked with __GIMPLE then parse the
2522 function body as GIMPLE. */
2523 else if (specs
->declspec_il
!= cdil_none
)
2525 bool saved
= in_late_binary_op
;
2526 in_late_binary_op
= true;
2527 c_parser_parse_gimple_body (parser
, specs
->gimple_or_rtl_pass
,
2529 specs
->entry_bb_count
);
2530 in_late_binary_op
= saved
;
2533 fnbody
= c_parser_compound_statement (parser
, &endloc
);
2534 tree fndecl
= current_function_decl
;
2537 tree decl
= current_function_decl
;
2538 /* Mark nested functions as needing static-chain initially.
2539 lower_nested_functions will recompute it but the
2540 DECL_STATIC_CHAIN flag is also used before that happens,
2541 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2542 DECL_STATIC_CHAIN (decl
) = 1;
2544 finish_function (endloc
);
2545 c_pop_function_context ();
2546 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl
), DECL_EXPR
, decl
));
2552 finish_function (endloc
);
2554 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2555 if (specs
->declspec_il
!= cdil_none
)
2556 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
2562 /* Parse an asm-definition (asm() outside a function body). This is a
2570 c_parser_asm_definition (c_parser
*parser
)
2572 tree asm_str
= c_parser_simple_asm_expr (parser
);
2574 symtab
->finalize_toplevel_asm (asm_str
);
2575 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
2578 /* Parse a static assertion (C11 6.7.10).
2580 static_assert-declaration:
2581 static_assert-declaration-no-semi ;
2585 c_parser_static_assert_declaration (c_parser
*parser
)
2587 c_parser_static_assert_declaration_no_semi (parser
);
2589 || !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
2590 c_parser_skip_to_end_of_block_or_statement (parser
);
2593 /* Parse a static assertion (C11 6.7.10), without the trailing
2596 static_assert-declaration-no-semi:
2597 _Static_assert ( constant-expression , string-literal )
2600 static_assert-declaration-no-semi:
2601 _Static_assert ( constant-expression )
2605 c_parser_static_assert_declaration_no_semi (c_parser
*parser
)
2607 location_t assert_loc
, value_loc
;
2609 tree string
= NULL_TREE
;
2611 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
));
2612 assert_loc
= c_parser_peek_token (parser
)->location
;
2614 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2615 "ISO C99 does not support %<_Static_assert%>");
2617 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2618 "ISO C90 does not support %<_Static_assert%>");
2619 c_parser_consume_token (parser
);
2620 matching_parens parens
;
2621 if (!parens
.require_open (parser
))
2623 location_t value_tok_loc
= c_parser_peek_token (parser
)->location
;
2624 value
= c_parser_expr_no_commas (parser
, NULL
).value
;
2625 value_loc
= EXPR_LOC_OR_LOC (value
, value_tok_loc
);
2626 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2628 c_parser_consume_token (parser
);
2629 switch (c_parser_peek_token (parser
)->type
)
2635 case CPP_UTF8STRING
:
2636 string
= c_parser_string_literal (parser
, false, true).value
;
2639 c_parser_error (parser
, "expected string literal");
2643 else if (flag_isoc11
)
2644 /* If pedantic for pre-C11, the use of _Static_assert itself will
2645 have been diagnosed, so do not also diagnose the use of this
2646 new C2X feature of _Static_assert. */
2647 pedwarn_c11 (assert_loc
, OPT_Wpedantic
,
2648 "ISO C11 does not support omitting the string in "
2649 "%<_Static_assert%>");
2650 parens
.require_close (parser
);
2652 if (!INTEGRAL_TYPE_P (TREE_TYPE (value
)))
2654 error_at (value_loc
, "expression in static assertion is not an integer");
2657 if (TREE_CODE (value
) != INTEGER_CST
)
2659 value
= c_fully_fold (value
, false, NULL
);
2660 /* Strip no-op conversions. */
2661 STRIP_TYPE_NOPS (value
);
2662 if (TREE_CODE (value
) == INTEGER_CST
)
2663 pedwarn (value_loc
, OPT_Wpedantic
, "expression in static assertion "
2664 "is not an integer constant expression");
2666 if (TREE_CODE (value
) != INTEGER_CST
)
2668 error_at (value_loc
, "expression in static assertion is not constant");
2671 constant_expression_warning (value
);
2672 if (integer_zerop (value
))
2675 error_at (assert_loc
, "static assertion failed: %E", string
);
2677 error_at (assert_loc
, "static assertion failed");
2681 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2682 6.7, C11 6.7), adding them to SPECS (which may already include some).
2683 Storage class specifiers are accepted iff SCSPEC_OK; type
2684 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2685 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2686 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2687 addition to the syntax shown, standard attributes are accepted at
2688 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2689 unlike gnu-attributes, they are not accepted in the middle of the
2690 list. (This combines various different syntax productions in the C
2691 standard, and in some cases gnu-attributes and standard attributes
2692 at the start may already have been parsed before this function is
2695 declaration-specifiers:
2696 storage-class-specifier declaration-specifiers[opt]
2697 type-specifier declaration-specifiers[opt]
2698 type-qualifier declaration-specifiers[opt]
2699 function-specifier declaration-specifiers[opt]
2700 alignment-specifier declaration-specifiers[opt]
2702 Function specifiers (inline) are from C99, and are currently
2703 handled as storage class specifiers, as is __thread. Alignment
2704 specifiers are from C11.
2706 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2707 storage-class-specifier:
2715 (_Thread_local is new in C11.)
2717 C99 6.7.4, C11 6.7.4:
2722 (_Noreturn is new in C11.)
2724 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2737 [_Imaginary removed in C99 TC2]
2738 struct-or-union-specifier
2741 atomic-type-specifier
2743 (_Bool and _Complex are new in C99.)
2744 (atomic-type-specifier is new in C11.)
2746 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2752 address-space-qualifier
2755 (restrict is new in C99.)
2756 (_Atomic is new in C11.)
2760 declaration-specifiers:
2761 gnu-attributes declaration-specifiers[opt]
2767 identifier recognized by the target
2769 storage-class-specifier:
2783 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2784 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2786 atomic-type-specifier
2787 _Atomic ( type-name )
2792 class-name objc-protocol-refs[opt]
2793 typedef-name objc-protocol-refs
2798 c_parser_declspecs (c_parser
*parser
, struct c_declspecs
*specs
,
2799 bool scspec_ok
, bool typespec_ok
, bool start_attr_ok
,
2800 bool alignspec_ok
, bool auto_type_ok
,
2801 bool start_std_attr_ok
, bool end_std_attr_ok
,
2802 enum c_lookahead_kind la
)
2804 bool attrs_ok
= start_attr_ok
;
2805 bool seen_type
= specs
->typespec_kind
!= ctsk_none
;
2808 gcc_assert (la
== cla_prefer_id
);
2810 if (start_std_attr_ok
2811 && c_parser_nth_token_starts_std_attributes (parser
, 1))
2813 gcc_assert (!specs
->non_std_attrs_seen_p
);
2814 location_t loc
= c_parser_peek_token (parser
)->location
;
2815 tree attrs
= c_parser_std_attribute_specifier_sequence (parser
);
2816 declspecs_add_attrs (loc
, specs
, attrs
);
2817 specs
->non_std_attrs_seen_p
= false;
2820 while (c_parser_next_token_is (parser
, CPP_NAME
)
2821 || c_parser_next_token_is (parser
, CPP_KEYWORD
)
2822 || (c_dialect_objc () && c_parser_next_token_is (parser
, CPP_LESS
)))
2824 struct c_typespec t
;
2827 location_t loc
= c_parser_peek_token (parser
)->location
;
2829 /* If we cannot accept a type, exit if the next token must start
2830 one. Also, if we already have seen a tagged definition,
2831 a typename would be an error anyway and likely the user
2832 has simply forgotten a semicolon, so we exit. */
2833 if ((!typespec_ok
|| specs
->typespec_kind
== ctsk_tagdef
)
2834 && c_parser_next_tokens_start_typename (parser
, la
)
2835 && !c_parser_next_token_is_qualifier (parser
)
2836 && !c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
))
2839 if (c_parser_next_token_is (parser
, CPP_NAME
))
2841 c_token
*name_token
= c_parser_peek_token (parser
);
2842 tree value
= name_token
->value
;
2843 c_id_kind kind
= name_token
->id_kind
;
2845 if (kind
== C_ID_ADDRSPACE
)
2848 = name_token
->keyword
- RID_FIRST_ADDR_SPACE
;
2849 declspecs_add_addrspace (name_token
->location
, specs
, as
);
2850 c_parser_consume_token (parser
);
2855 gcc_assert (!c_parser_next_token_is_qualifier (parser
));
2857 /* If we cannot accept a type, and the next token must start one,
2858 exit. Do the same if we already have seen a tagged definition,
2859 since it would be an error anyway and likely the user has simply
2860 forgotten a semicolon. */
2861 if (seen_type
|| !c_parser_next_tokens_start_typename (parser
, la
))
2864 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2865 a C_ID_CLASSNAME. */
2866 c_parser_consume_token (parser
);
2869 if (kind
== C_ID_ID
)
2871 error_at (loc
, "unknown type name %qE", value
);
2872 t
.kind
= ctsk_typedef
;
2873 t
.spec
= error_mark_node
;
2875 else if (kind
== C_ID_TYPENAME
2876 && (!c_dialect_objc ()
2877 || c_parser_next_token_is_not (parser
, CPP_LESS
)))
2879 t
.kind
= ctsk_typedef
;
2880 /* For a typedef name, record the meaning, not the name.
2881 In case of 'foo foo, bar;'. */
2882 t
.spec
= lookup_name (value
);
2886 tree proto
= NULL_TREE
;
2887 gcc_assert (c_dialect_objc ());
2889 if (c_parser_next_token_is (parser
, CPP_LESS
))
2890 proto
= c_parser_objc_protocol_refs (parser
);
2891 t
.spec
= objc_get_protocol_qualified_type (value
, proto
);
2894 t
.expr_const_operands
= true;
2895 declspecs_add_type (name_token
->location
, specs
, t
);
2898 if (c_parser_next_token_is (parser
, CPP_LESS
))
2900 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2901 nisse@lysator.liu.se. */
2903 gcc_assert (c_dialect_objc ());
2904 if (!typespec_ok
|| seen_type
)
2906 proto
= c_parser_objc_protocol_refs (parser
);
2908 t
.spec
= objc_get_protocol_qualified_type (NULL_TREE
, proto
);
2910 t
.expr_const_operands
= true;
2911 declspecs_add_type (loc
, specs
, t
);
2914 gcc_assert (c_parser_next_token_is (parser
, CPP_KEYWORD
));
2915 switch (c_parser_peek_token (parser
)->keyword
)
2928 /* TODO: Distinguish between function specifiers (inline, noreturn)
2929 and storage class specifiers, either here or in
2930 declspecs_add_scspec. */
2931 declspecs_add_scspec (loc
, specs
,
2932 c_parser_peek_token (parser
)->value
);
2933 c_parser_consume_token (parser
);
2965 if (c_dialect_objc ())
2966 parser
->objc_need_raw_identifier
= true;
2967 t
.kind
= ctsk_resword
;
2968 t
.spec
= c_parser_peek_token (parser
)->value
;
2970 t
.expr_const_operands
= true;
2971 declspecs_add_type (loc
, specs
, t
);
2972 c_parser_consume_token (parser
);
2979 t
= c_parser_enum_specifier (parser
);
2980 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
2981 declspecs_add_type (loc
, specs
, t
);
2989 t
= c_parser_struct_or_union_specifier (parser
);
2990 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
2991 declspecs_add_type (loc
, specs
, t
);
2994 /* ??? The old parser rejected typeof after other type
2995 specifiers, but is a syntax error the best way of
2997 if (!typespec_ok
|| seen_type
)
3001 t
= c_parser_typeof_specifier (parser
);
3002 declspecs_add_type (loc
, specs
, t
);
3005 /* C parser handling of Objective-C constructs needs
3006 checking for correct lvalue-to-rvalue conversions, and
3007 the code in build_modify_expr handling various
3008 Objective-C cases, and that in build_unary_op handling
3009 Objective-C cases for increment / decrement, also needs
3010 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3011 and objc_types_are_equivalent may also need updates. */
3012 if (c_dialect_objc ())
3013 sorry ("%<_Atomic%> in Objective-C");
3015 pedwarn_c99 (loc
, OPT_Wpedantic
,
3016 "ISO C99 does not support the %<_Atomic%> qualifier");
3018 pedwarn_c99 (loc
, OPT_Wpedantic
,
3019 "ISO C90 does not support the %<_Atomic%> qualifier");
3022 value
= c_parser_peek_token (parser
)->value
;
3023 c_parser_consume_token (parser
);
3024 if (typespec_ok
&& c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3026 /* _Atomic ( type-name ). */
3028 c_parser_consume_token (parser
);
3029 struct c_type_name
*type
= c_parser_type_name (parser
);
3030 t
.kind
= ctsk_typeof
;
3031 t
.spec
= error_mark_node
;
3033 t
.expr_const_operands
= true;
3035 t
.spec
= groktypename (type
, &t
.expr
,
3036 &t
.expr_const_operands
);
3037 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3039 if (t
.spec
!= error_mark_node
)
3041 if (TREE_CODE (t
.spec
) == ARRAY_TYPE
)
3042 error_at (loc
, "%<_Atomic%>-qualified array type");
3043 else if (TREE_CODE (t
.spec
) == FUNCTION_TYPE
)
3044 error_at (loc
, "%<_Atomic%>-qualified function type");
3045 else if (TYPE_QUALS (t
.spec
) != TYPE_UNQUALIFIED
)
3046 error_at (loc
, "%<_Atomic%> applied to a qualified type");
3048 t
.spec
= c_build_qualified_type (t
.spec
, TYPE_QUAL_ATOMIC
);
3050 declspecs_add_type (loc
, specs
, t
);
3053 declspecs_add_qual (loc
, specs
, value
);
3059 declspecs_add_qual (loc
, specs
, c_parser_peek_token (parser
)->value
);
3060 c_parser_consume_token (parser
);
3065 attrs
= c_parser_gnu_attributes (parser
);
3066 declspecs_add_attrs (loc
, specs
, attrs
);
3071 align
= c_parser_alignas_specifier (parser
);
3072 declspecs_add_alignas (loc
, specs
, align
);
3076 error_at (loc
, "%<__GIMPLE%> only valid with %<-fgimple%>");
3077 c_parser_consume_token (parser
);
3078 specs
->declspec_il
= cdil_gimple
;
3079 specs
->locations
[cdw_gimple
] = loc
;
3080 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3083 c_parser_consume_token (parser
);
3084 specs
->declspec_il
= cdil_rtl
;
3085 specs
->locations
[cdw_rtl
] = loc
;
3086 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3094 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3095 specs
->postfix_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3098 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3101 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3103 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3105 enum gnu-attributes[opt] identifier
3107 The form with trailing comma is new in C99. The forms with
3108 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3109 without commas in the syntax (assignment expressions, not just
3110 conditional expressions); assignment expressions will be diagnosed
3115 enumerator-list , enumerator
3118 enumeration-constant attribute-specifier-sequence[opt]
3119 enumeration-constant attribute-specifier-sequence[opt]
3120 = constant-expression
3125 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3126 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3127 = constant-expression
3131 static struct c_typespec
3132 c_parser_enum_specifier (c_parser
*parser
)
3134 struct c_typespec ret
;
3135 bool have_std_attrs
;
3136 tree std_attrs
= NULL_TREE
;
3138 tree ident
= NULL_TREE
;
3139 location_t enum_loc
;
3140 location_t ident_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3141 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ENUM
));
3142 c_parser_consume_token (parser
);
3143 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3145 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3146 attrs
= c_parser_gnu_attributes (parser
);
3147 enum_loc
= c_parser_peek_token (parser
)->location
;
3148 /* Set the location in case we create a decl now. */
3149 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3150 if (c_parser_next_token_is (parser
, CPP_NAME
))
3152 ident
= c_parser_peek_token (parser
)->value
;
3153 ident_loc
= c_parser_peek_token (parser
)->location
;
3154 enum_loc
= ident_loc
;
3155 c_parser_consume_token (parser
);
3157 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3159 /* Parse an enum definition. */
3160 struct c_enum_contents the_enum
;
3163 /* We chain the enumerators in reverse order, then put them in
3164 forward order at the end. */
3166 timevar_push (TV_PARSE_ENUM
);
3167 type
= start_enum (enum_loc
, &the_enum
, ident
);
3169 c_parser_consume_token (parser
);
3177 location_t comma_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3178 location_t decl_loc
, value_loc
;
3179 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
3181 /* Give a nicer error for "enum {}". */
3182 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3185 error_at (c_parser_peek_token (parser
)->location
,
3186 "empty enum is invalid");
3187 parser
->error
= true;
3190 c_parser_error (parser
, "expected identifier");
3191 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3192 values
= error_mark_node
;
3195 token
= c_parser_peek_token (parser
);
3196 enum_id
= token
->value
;
3197 /* Set the location in case we create a decl now. */
3198 c_parser_set_source_position_from_token (token
);
3199 decl_loc
= value_loc
= token
->location
;
3200 c_parser_consume_token (parser
);
3201 /* Parse any specified attributes. */
3202 tree std_attrs
= NULL_TREE
;
3203 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3204 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3205 tree enum_attrs
= chainon (std_attrs
,
3206 c_parser_gnu_attributes (parser
));
3207 if (c_parser_next_token_is (parser
, CPP_EQ
))
3209 c_parser_consume_token (parser
);
3210 value_loc
= c_parser_peek_token (parser
)->location
;
3211 enum_value
= c_parser_expr_no_commas (parser
, NULL
).value
;
3214 enum_value
= NULL_TREE
;
3215 enum_decl
= build_enumerator (decl_loc
, value_loc
,
3216 &the_enum
, enum_id
, enum_value
);
3218 decl_attributes (&TREE_PURPOSE (enum_decl
), enum_attrs
, 0);
3219 TREE_CHAIN (enum_decl
) = values
;
3222 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3224 comma_loc
= c_parser_peek_token (parser
)->location
;
3226 c_parser_consume_token (parser
);
3228 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3231 pedwarn_c90 (comma_loc
, OPT_Wpedantic
,
3232 "comma at end of enumerator list");
3233 c_parser_consume_token (parser
);
3238 c_parser_error (parser
, "expected %<,%> or %<}%>");
3239 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3240 values
= error_mark_node
;
3244 postfix_attrs
= c_parser_gnu_attributes (parser
);
3245 ret
.spec
= finish_enum (type
, nreverse (values
),
3247 chainon (attrs
, postfix_attrs
)));
3248 ret
.kind
= ctsk_tagdef
;
3249 ret
.expr
= NULL_TREE
;
3250 ret
.expr_const_operands
= true;
3251 timevar_pop (TV_PARSE_ENUM
);
3256 c_parser_error (parser
, "expected %<{%>");
3257 ret
.spec
= error_mark_node
;
3258 ret
.kind
= ctsk_tagref
;
3259 ret
.expr
= NULL_TREE
;
3260 ret
.expr_const_operands
= true;
3263 /* Attributes may only appear when the members are defined or in
3264 certain forward declarations (treat enum forward declarations in
3265 GNU C analogously to struct and union forward declarations in
3267 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3268 c_parser_error (parser
, "expected %<;%>");
3269 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
, have_std_attrs
,
3271 /* In ISO C, enumerated types can be referred to only if already
3273 if (pedantic
&& !COMPLETE_TYPE_P (ret
.spec
))
3276 pedwarn (enum_loc
, OPT_Wpedantic
,
3277 "ISO C forbids forward references to %<enum%> types");
3282 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3284 struct-or-union-specifier:
3285 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3286 identifier[opt] { struct-contents } gnu-attributes[opt]
3287 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3291 struct-declaration-list
3293 struct-declaration-list:
3294 struct-declaration ;
3295 struct-declaration-list struct-declaration ;
3302 struct-declaration-list struct-declaration
3304 struct-declaration-list:
3305 struct-declaration-list ;
3308 (Note that in the syntax here, unlike that in ISO C, the semicolons
3309 are included here rather than in struct-declaration, in order to
3310 describe the syntax with extra semicolons and missing semicolon at
3315 struct-declaration-list:
3316 @defs ( class-name )
3318 (Note this does not include a trailing semicolon, but can be
3319 followed by further declarations, and gets a pedwarn-if-pedantic
3320 when followed by a semicolon.) */
3322 static struct c_typespec
3323 c_parser_struct_or_union_specifier (c_parser
*parser
)
3325 struct c_typespec ret
;
3326 bool have_std_attrs
;
3327 tree std_attrs
= NULL_TREE
;
3329 tree ident
= NULL_TREE
;
3330 location_t struct_loc
;
3331 location_t ident_loc
= UNKNOWN_LOCATION
;
3332 enum tree_code code
;
3333 switch (c_parser_peek_token (parser
)->keyword
)
3344 struct_loc
= c_parser_peek_token (parser
)->location
;
3345 c_parser_consume_token (parser
);
3346 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3348 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3349 attrs
= c_parser_gnu_attributes (parser
);
3351 /* Set the location in case we create a decl now. */
3352 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3354 if (c_parser_next_token_is (parser
, CPP_NAME
))
3356 ident
= c_parser_peek_token (parser
)->value
;
3357 ident_loc
= c_parser_peek_token (parser
)->location
;
3358 struct_loc
= ident_loc
;
3359 c_parser_consume_token (parser
);
3361 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3363 /* Parse a struct or union definition. Start the scope of the
3364 tag before parsing components. */
3365 class c_struct_parse_info
*struct_info
;
3366 tree type
= start_struct (struct_loc
, code
, ident
, &struct_info
);
3368 /* We chain the components in reverse order, then put them in
3369 forward order at the end. Each struct-declaration may
3370 declare multiple components (comma-separated), so we must use
3371 chainon to join them, although when parsing each
3372 struct-declaration we can use TREE_CHAIN directly.
3374 The theory behind all this is that there will be more
3375 semicolon separated fields than comma separated fields, and
3376 so we'll be minimizing the number of node traversals required
3379 timevar_push (TV_PARSE_STRUCT
);
3380 contents
= NULL_TREE
;
3381 c_parser_consume_token (parser
);
3382 /* Handle the Objective-C @defs construct,
3383 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3384 if (c_parser_next_token_is_keyword (parser
, RID_AT_DEFS
))
3387 gcc_assert (c_dialect_objc ());
3388 c_parser_consume_token (parser
);
3389 matching_parens parens
;
3390 if (!parens
.require_open (parser
))
3392 if (c_parser_next_token_is (parser
, CPP_NAME
)
3393 && c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
)
3395 name
= c_parser_peek_token (parser
)->value
;
3396 c_parser_consume_token (parser
);
3400 c_parser_error (parser
, "expected class name");
3401 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
3404 parens
.skip_until_found_close (parser
);
3405 contents
= nreverse (objc_get_class_ivars (name
));
3408 /* Parse the struct-declarations and semicolons. Problems with
3409 semicolons are diagnosed here; empty structures are diagnosed
3414 /* Parse any stray semicolon. */
3415 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3417 location_t semicolon_loc
3418 = c_parser_peek_token (parser
)->location
;
3419 gcc_rich_location
richloc (semicolon_loc
);
3420 richloc
.add_fixit_remove ();
3421 pedwarn (&richloc
, OPT_Wpedantic
,
3422 "extra semicolon in struct or union specified");
3423 c_parser_consume_token (parser
);
3426 /* Stop if at the end of the struct or union contents. */
3427 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3429 c_parser_consume_token (parser
);
3432 /* Accept #pragmas at struct scope. */
3433 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
3435 c_parser_pragma (parser
, pragma_struct
, NULL
);
3438 /* Parse some comma-separated declarations, but not the
3439 trailing semicolon if any. */
3440 decls
= c_parser_struct_declaration (parser
);
3441 contents
= chainon (decls
, contents
);
3442 /* If no semicolon follows, either we have a parse error or
3443 are at the end of the struct or union and should
3445 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3446 c_parser_consume_token (parser
);
3449 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3450 pedwarn (c_parser_peek_token (parser
)->location
, 0,
3451 "no semicolon at end of struct or union");
3452 else if (parser
->error
3453 || !c_parser_next_token_starts_declspecs (parser
))
3455 c_parser_error (parser
, "expected %<;%>");
3456 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3460 /* If we come here, we have already emitted an error
3461 for an expected `;', identifier or `(', and we also
3462 recovered already. Go on with the next field. */
3465 postfix_attrs
= c_parser_gnu_attributes (parser
);
3466 ret
.spec
= finish_struct (struct_loc
, type
, nreverse (contents
),
3468 chainon (attrs
, postfix_attrs
)),
3470 ret
.kind
= ctsk_tagdef
;
3471 ret
.expr
= NULL_TREE
;
3472 ret
.expr_const_operands
= true;
3473 timevar_pop (TV_PARSE_STRUCT
);
3478 c_parser_error (parser
, "expected %<{%>");
3479 ret
.spec
= error_mark_node
;
3480 ret
.kind
= ctsk_tagref
;
3481 ret
.expr
= NULL_TREE
;
3482 ret
.expr_const_operands
= true;
3485 /* Attributes may only appear when the members are defined or in
3486 certain forward declarations. */
3487 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3488 c_parser_error (parser
, "expected %<;%>");
3489 /* ??? Existing practice is that GNU attributes are ignored after
3490 the struct or union keyword when not defining the members. */
3491 ret
= parser_xref_tag (ident_loc
, code
, ident
, have_std_attrs
, std_attrs
);
3495 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3496 *without* the trailing semicolon.
3499 attribute-specifier-sequence[opt] specifier-qualifier-list
3500 attribute-specifier-sequence[opt] struct-declarator-list
3501 static_assert-declaration-no-semi
3503 specifier-qualifier-list:
3504 type-specifier specifier-qualifier-list[opt]
3505 type-qualifier specifier-qualifier-list[opt]
3506 alignment-specifier specifier-qualifier-list[opt]
3507 gnu-attributes specifier-qualifier-list[opt]
3509 struct-declarator-list:
3511 struct-declarator-list , gnu-attributes[opt] struct-declarator
3514 declarator gnu-attributes[opt]
3515 declarator[opt] : constant-expression gnu-attributes[opt]
3520 __extension__ struct-declaration
3521 specifier-qualifier-list
3523 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3524 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3525 any expression without commas in the syntax (assignment
3526 expressions, not just conditional expressions); assignment
3527 expressions will be diagnosed as non-constant. */
3530 c_parser_struct_declaration (c_parser
*parser
)
3532 struct c_declspecs
*specs
;
3534 tree all_prefix_attrs
;
3536 location_t decl_loc
;
3537 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
3541 ext
= disable_extension_diagnostics ();
3542 c_parser_consume_token (parser
);
3543 decl
= c_parser_struct_declaration (parser
);
3544 restore_extension_diagnostics (ext
);
3547 if (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
3549 c_parser_static_assert_declaration_no_semi (parser
);
3552 specs
= build_null_declspecs ();
3553 decl_loc
= c_parser_peek_token (parser
)->location
;
3554 /* Strictly by the standard, we shouldn't allow _Alignas here,
3555 but it appears to have been intended to allow it there, so
3556 we're keeping it as it is until WG14 reaches a conclusion
3558 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3559 c_parser_declspecs (parser
, specs
, false, true, true,
3560 true, false, true, true, cla_nonabstract_decl
);
3563 if (!specs
->declspecs_seen_p
)
3565 c_parser_error (parser
, "expected specifier-qualifier-list");
3568 finish_declspecs (specs
);
3569 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3570 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3573 if (specs
->typespec_kind
== ctsk_none
)
3575 pedwarn (decl_loc
, OPT_Wpedantic
,
3576 "ISO C forbids member declarations with no members");
3577 shadow_tag_warned (specs
, pedantic
);
3582 /* Support for unnamed structs or unions as members of
3583 structs or unions (which is [a] useful and [b] supports
3587 ret
= grokfield (c_parser_peek_token (parser
)->location
,
3588 build_id_declarator (NULL_TREE
), specs
,
3591 decl_attributes (&ret
, attrs
, 0);
3596 /* Provide better error recovery. Note that a type name here is valid,
3597 and will be treated as a field name. */
3598 if (specs
->typespec_kind
== ctsk_tagdef
3599 && TREE_CODE (specs
->type
) != ENUMERAL_TYPE
3600 && c_parser_next_token_starts_declspecs (parser
)
3601 && !c_parser_next_token_is (parser
, CPP_NAME
))
3603 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
3604 parser
->error
= false;
3608 pending_xref_error ();
3609 prefix_attrs
= specs
->attrs
;
3610 all_prefix_attrs
= prefix_attrs
;
3611 specs
->attrs
= NULL_TREE
;
3615 /* Declaring one or more declarators or un-named bit-fields. */
3616 struct c_declarator
*declarator
;
3618 if (c_parser_next_token_is (parser
, CPP_COLON
))
3619 declarator
= build_id_declarator (NULL_TREE
);
3621 declarator
= c_parser_declarator (parser
,
3622 specs
->typespec_kind
!= ctsk_none
,
3623 C_DTR_NORMAL
, &dummy
);
3624 if (declarator
== NULL
)
3626 c_parser_skip_to_end_of_block_or_statement (parser
);
3629 if (c_parser_next_token_is (parser
, CPP_COLON
)
3630 || c_parser_next_token_is (parser
, CPP_COMMA
)
3631 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3632 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3633 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3635 tree postfix_attrs
= NULL_TREE
;
3636 tree width
= NULL_TREE
;
3638 if (c_parser_next_token_is (parser
, CPP_COLON
))
3640 c_parser_consume_token (parser
);
3641 width
= c_parser_expr_no_commas (parser
, NULL
).value
;
3643 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3644 postfix_attrs
= c_parser_gnu_attributes (parser
);
3645 d
= grokfield (c_parser_peek_token (parser
)->location
,
3646 declarator
, specs
, width
, &all_prefix_attrs
);
3647 decl_attributes (&d
, chainon (postfix_attrs
,
3648 all_prefix_attrs
), 0);
3649 DECL_CHAIN (d
) = decls
;
3651 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3652 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
3655 all_prefix_attrs
= prefix_attrs
;
3656 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3657 c_parser_consume_token (parser
);
3658 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3659 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3661 /* Semicolon consumed in caller. */
3666 c_parser_error (parser
, "expected %<,%>, %<;%> or %<}%>");
3672 c_parser_error (parser
,
3673 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3674 "%<__attribute__%>");
3681 /* Parse a typeof specifier (a GNU extension).
3684 typeof ( expression )
3685 typeof ( type-name )
3688 static struct c_typespec
3689 c_parser_typeof_specifier (c_parser
*parser
)
3691 struct c_typespec ret
;
3692 ret
.kind
= ctsk_typeof
;
3693 ret
.spec
= error_mark_node
;
3694 ret
.expr
= NULL_TREE
;
3695 ret
.expr_const_operands
= true;
3696 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TYPEOF
));
3697 c_parser_consume_token (parser
);
3698 c_inhibit_evaluation_warnings
++;
3700 matching_parens parens
;
3701 if (!parens
.require_open (parser
))
3703 c_inhibit_evaluation_warnings
--;
3707 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3709 struct c_type_name
*type
= c_parser_type_name (parser
);
3710 c_inhibit_evaluation_warnings
--;
3714 ret
.spec
= groktypename (type
, &ret
.expr
, &ret
.expr_const_operands
);
3715 pop_maybe_used (variably_modified_type_p (ret
.spec
, NULL_TREE
));
3721 location_t here
= c_parser_peek_token (parser
)->location
;
3722 struct c_expr expr
= c_parser_expression (parser
);
3723 c_inhibit_evaluation_warnings
--;
3725 if (TREE_CODE (expr
.value
) == COMPONENT_REF
3726 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
3727 error_at (here
, "%<typeof%> applied to a bit-field");
3728 mark_exp_read (expr
.value
);
3729 ret
.spec
= TREE_TYPE (expr
.value
);
3730 was_vm
= variably_modified_type_p (ret
.spec
, NULL_TREE
);
3731 /* This is returned with the type so that when the type is
3732 evaluated, this can be evaluated. */
3734 ret
.expr
= c_fully_fold (expr
.value
, false, &ret
.expr_const_operands
);
3735 pop_maybe_used (was_vm
);
3736 /* For use in macros such as those in <stdatomic.h>, remove all
3737 qualifiers from atomic types. (const can be an issue for more macros
3738 using typeof than just the <stdatomic.h> ones.) */
3739 if (ret
.spec
!= error_mark_node
&& TYPE_ATOMIC (ret
.spec
))
3740 ret
.spec
= c_build_qualified_type (ret
.spec
, TYPE_UNQUALIFIED
);
3742 parens
.skip_until_found_close (parser
);
3746 /* Parse an alignment-specifier.
3750 alignment-specifier:
3751 _Alignas ( type-name )
3752 _Alignas ( constant-expression )
3756 c_parser_alignas_specifier (c_parser
* parser
)
3758 tree ret
= error_mark_node
;
3759 location_t loc
= c_parser_peek_token (parser
)->location
;
3760 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
));
3761 c_parser_consume_token (parser
);
3763 pedwarn_c99 (loc
, OPT_Wpedantic
,
3764 "ISO C99 does not support %<_Alignas%>");
3766 pedwarn_c99 (loc
, OPT_Wpedantic
,
3767 "ISO C90 does not support %<_Alignas%>");
3768 matching_parens parens
;
3769 if (!parens
.require_open (parser
))
3771 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3773 struct c_type_name
*type
= c_parser_type_name (parser
);
3775 ret
= c_sizeof_or_alignof_type (loc
, groktypename (type
, NULL
, NULL
),
3779 ret
= c_parser_expr_no_commas (parser
, NULL
).value
;
3780 parens
.skip_until_found_close (parser
);
3784 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3785 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3786 a typedef name may be redeclared; otherwise it may not. KIND
3787 indicates which kind of declarator is wanted. Returns a valid
3788 declarator except in the case of a syntax error in which case NULL is
3789 returned. *SEEN_ID is set to true if an identifier being declared is
3790 seen; this is used to diagnose bad forms of abstract array declarators
3791 and to determine whether an identifier list is syntactically permitted.
3794 pointer[opt] direct-declarator
3798 ( gnu-attributes[opt] declarator )
3799 direct-declarator array-declarator
3800 direct-declarator ( parameter-type-list )
3801 direct-declarator ( identifier-list[opt] )
3804 * type-qualifier-list[opt]
3805 * type-qualifier-list[opt] pointer
3807 type-qualifier-list:
3810 type-qualifier-list type-qualifier
3811 type-qualifier-list gnu-attributes
3814 [ type-qualifier-list[opt] assignment-expression[opt] ]
3815 [ static type-qualifier-list[opt] assignment-expression ]
3816 [ type-qualifier-list static assignment-expression ]
3817 [ type-qualifier-list[opt] * ]
3819 parameter-type-list:
3821 parameter-list , ...
3824 parameter-declaration
3825 parameter-list , parameter-declaration
3827 parameter-declaration:
3828 declaration-specifiers declarator gnu-attributes[opt]
3829 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3833 identifier-list , identifier
3835 abstract-declarator:
3837 pointer[opt] direct-abstract-declarator
3839 direct-abstract-declarator:
3840 ( gnu-attributes[opt] abstract-declarator )
3841 direct-abstract-declarator[opt] array-declarator
3842 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3847 direct-declarator ( parameter-forward-declarations
3848 parameter-type-list[opt] )
3850 direct-abstract-declarator:
3851 direct-abstract-declarator[opt] ( parameter-forward-declarations
3852 parameter-type-list[opt] )
3854 parameter-forward-declarations:
3856 parameter-forward-declarations parameter-list ;
3858 The uses of gnu-attributes shown above are GNU extensions.
3860 Some forms of array declarator are not included in C99 in the
3861 syntax for abstract declarators; these are disallowed elsewhere.
3862 This may be a defect (DR#289).
3864 This function also accepts an omitted abstract declarator as being
3865 an abstract declarator, although not part of the formal syntax. */
3867 struct c_declarator
*
3868 c_parser_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3871 /* Parse any initial pointer part. */
3872 if (c_parser_next_token_is (parser
, CPP_MULT
))
3874 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
3875 struct c_declarator
*inner
;
3876 c_parser_consume_token (parser
);
3877 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
3878 false, false, true, false, cla_prefer_id
);
3879 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
3883 return make_pointer_declarator (quals_attrs
, inner
);
3885 /* Now we have a direct declarator, direct abstract declarator or
3886 nothing (which counts as a direct abstract declarator here). */
3887 return c_parser_direct_declarator (parser
, type_seen_p
, kind
, seen_id
);
3890 /* Parse a direct declarator or direct abstract declarator; arguments
3891 as c_parser_declarator. */
3893 static struct c_declarator
*
3894 c_parser_direct_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3897 /* The direct declarator must start with an identifier (possibly
3898 omitted) or a parenthesized declarator (possibly abstract). In
3899 an ordinary declarator, initial parentheses must start a
3900 parenthesized declarator. In an abstract declarator or parameter
3901 declarator, they could start a parenthesized declarator or a
3902 parameter list. To tell which, the open parenthesis and any
3903 following gnu-attributes must be read. If a declaration
3904 specifier or standard attributes follow, then it is a parameter
3905 list; if the specifier is a typedef name, there might be an
3906 ambiguity about redeclaring it, which is resolved in the
3907 direction of treating it as a typedef name. If a close
3908 parenthesis follows, it is also an empty parameter list, as the
3909 syntax does not permit empty abstract declarators. Otherwise, it
3910 is a parenthesized declarator (in which case the analysis may be
3911 repeated inside it, recursively).
3913 ??? There is an ambiguity in a parameter declaration "int
3914 (__attribute__((foo)) x)", where x is not a typedef name: it
3915 could be an abstract declarator for a function, or declare x with
3916 parentheses. The proper resolution of this ambiguity needs
3917 documenting. At present we follow an accident of the old
3918 parser's implementation, whereby the first parameter must have
3919 some declaration specifiers other than just gnu-attributes. Thus as
3920 a parameter declaration it is treated as a parenthesized
3921 parameter named x, and as an abstract declarator it is
3924 ??? Also following the old parser, gnu-attributes inside an empty
3925 parameter list are ignored, making it a list not yielding a
3926 prototype, rather than giving an error or making it have one
3927 parameter with implicit type int.
3929 ??? Also following the old parser, typedef names may be
3930 redeclared in declarators, but not Objective-C class names. */
3932 if (kind
!= C_DTR_ABSTRACT
3933 && c_parser_next_token_is (parser
, CPP_NAME
)
3935 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
3936 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
3937 || c_parser_peek_token (parser
)->id_kind
== C_ID_ID
))
3939 struct c_declarator
*inner
3940 = build_id_declarator (c_parser_peek_token (parser
)->value
);
3942 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3943 c_parser_consume_token (parser
);
3944 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3945 inner
->u
.id
.attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3946 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3949 if (kind
!= C_DTR_NORMAL
3950 && c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
3951 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
3953 struct c_declarator
*inner
= build_id_declarator (NULL_TREE
);
3954 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3955 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3958 /* Either we are at the end of an abstract declarator, or we have
3961 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3964 struct c_declarator
*inner
;
3965 c_parser_consume_token (parser
);
3966 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
3968 attrs
= c_parser_gnu_attributes (parser
);
3969 if (kind
!= C_DTR_NORMAL
3970 && (c_parser_next_token_starts_declspecs (parser
)
3972 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3973 || c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
)))
3975 struct c_arg_info
*args
3976 = c_parser_parms_declarator (parser
, kind
== C_DTR_NORMAL
,
3977 attrs
, have_gnu_attrs
);
3982 inner
= build_id_declarator (NULL_TREE
);
3984 && args
->types
!= error_mark_node
3985 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
3986 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3989 = c_parser_std_attribute_specifier_sequence (parser
);
3991 inner
= build_attrs_declarator (std_attrs
, inner
);
3993 inner
= build_function_declarator (args
, inner
);
3994 return c_parser_direct_declarator_inner (parser
, *seen_id
,
3998 /* A parenthesized declarator. */
3999 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4000 if (inner
!= NULL
&& attrs
!= NULL
)
4001 inner
= build_attrs_declarator (attrs
, inner
);
4002 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4004 c_parser_consume_token (parser
);
4008 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4012 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4019 if (kind
== C_DTR_NORMAL
)
4021 c_parser_error (parser
, "expected identifier or %<(%>");
4025 return build_id_declarator (NULL_TREE
);
4029 /* Parse part of a direct declarator or direct abstract declarator,
4030 given that some (in INNER) has already been parsed; ID_PRESENT is
4031 true if an identifier is present, false for an abstract
4034 static struct c_declarator
*
4035 c_parser_direct_declarator_inner (c_parser
*parser
, bool id_present
,
4036 struct c_declarator
*inner
)
4038 /* Parse a sequence of array declarators and parameter lists. */
4039 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4040 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4042 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
4043 struct c_declarator
*declarator
;
4044 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4047 struct c_expr dimen
;
4048 dimen
.value
= NULL_TREE
;
4049 dimen
.original_code
= ERROR_MARK
;
4050 dimen
.original_type
= NULL_TREE
;
4051 c_parser_consume_token (parser
);
4052 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4053 false, false, false, false, cla_prefer_id
);
4054 static_seen
= c_parser_next_token_is_keyword (parser
, RID_STATIC
);
4056 c_parser_consume_token (parser
);
4057 if (static_seen
&& !quals_attrs
->declspecs_seen_p
)
4058 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4059 false, false, false, false, cla_prefer_id
);
4060 if (!quals_attrs
->declspecs_seen_p
)
4062 /* If "static" is present, there must be an array dimension.
4063 Otherwise, there may be a dimension, "*", or no
4068 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4072 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4074 dimen
.value
= NULL_TREE
;
4077 else if (c_parser_next_token_is (parser
, CPP_MULT
))
4079 if (c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_SQUARE
)
4081 dimen
.value
= NULL_TREE
;
4083 c_parser_consume_token (parser
);
4088 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4094 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4097 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4098 c_parser_consume_token (parser
);
4101 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4106 dimen
= convert_lvalue_to_rvalue (brace_loc
, dimen
, true, true);
4107 declarator
= build_array_declarator (brace_loc
, dimen
.value
, quals_attrs
,
4108 static_seen
, star_seen
);
4109 if (declarator
== NULL
)
4111 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4114 = c_parser_std_attribute_specifier_sequence (parser
);
4116 inner
= build_attrs_declarator (std_attrs
, inner
);
4118 inner
= set_array_declarator_inner (declarator
, inner
);
4119 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4121 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4124 struct c_arg_info
*args
;
4125 c_parser_consume_token (parser
);
4126 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4128 attrs
= c_parser_gnu_attributes (parser
);
4129 args
= c_parser_parms_declarator (parser
, id_present
, attrs
,
4136 && args
->types
!= error_mark_node
4137 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4138 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4141 = c_parser_std_attribute_specifier_sequence (parser
);
4143 inner
= build_attrs_declarator (std_attrs
, inner
);
4145 inner
= build_function_declarator (args
, inner
);
4146 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4152 /* Parse a parameter list or identifier list, including the closing
4153 parenthesis but not the opening one. ATTRS are the gnu-attributes
4154 at the start of the list. ID_LIST_OK is true if an identifier list
4155 is acceptable; such a list must not have attributes at the start.
4156 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4157 attributes) were present (in which case standard attributes cannot
4160 static struct c_arg_info
*
4161 c_parser_parms_declarator (c_parser
*parser
, bool id_list_ok
, tree attrs
,
4162 bool have_gnu_attrs
)
4165 declare_parm_level ();
4166 /* If the list starts with an identifier, it is an identifier list.
4167 Otherwise, it is either a prototype list or an empty list. */
4170 && c_parser_next_token_is (parser
, CPP_NAME
)
4171 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4173 /* Look ahead to detect typos in type names. */
4174 && c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
4175 && c_parser_peek_2nd_token (parser
)->type
!= CPP_MULT
4176 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
4177 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_SQUARE
4178 && c_parser_peek_2nd_token (parser
)->type
!= CPP_KEYWORD
)
4180 tree list
= NULL_TREE
, *nextp
= &list
;
4181 while (c_parser_next_token_is (parser
, CPP_NAME
)
4182 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
4184 *nextp
= build_tree_list (NULL_TREE
,
4185 c_parser_peek_token (parser
)->value
);
4186 nextp
= & TREE_CHAIN (*nextp
);
4187 c_parser_consume_token (parser
);
4188 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
4190 c_parser_consume_token (parser
);
4191 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4193 c_parser_error (parser
, "expected identifier");
4197 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4199 struct c_arg_info
*ret
= build_arg_info ();
4201 c_parser_consume_token (parser
);
4207 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4215 struct c_arg_info
*ret
4216 = c_parser_parms_list_declarator (parser
, attrs
, NULL
, have_gnu_attrs
);
4222 /* Parse a parameter list (possibly empty), including the closing
4223 parenthesis but not the opening one. ATTRS are the gnu-attributes
4224 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4225 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4226 which means standard attributes cannot start the list. EXPR is
4227 NULL or an expression that needs to be evaluated for the side
4228 effects of array size expressions in the parameters. */
4230 static struct c_arg_info
*
4231 c_parser_parms_list_declarator (c_parser
*parser
, tree attrs
, tree expr
,
4232 bool have_gnu_attrs
)
4234 bool bad_parm
= false;
4236 /* ??? Following the old parser, forward parameter declarations may
4237 use abstract declarators, and if no real parameter declarations
4238 follow the forward declarations then this is not diagnosed. Also
4239 note as above that gnu-attributes are ignored as the only contents of
4240 the parentheses, or as the only contents after forward
4242 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4244 struct c_arg_info
*ret
= build_arg_info ();
4245 c_parser_consume_token (parser
);
4248 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4250 struct c_arg_info
*ret
= build_arg_info ();
4252 if (flag_allow_parameterless_variadic_functions
)
4254 /* F (...) is allowed. */
4255 ret
->types
= NULL_TREE
;
4259 /* Suppress -Wold-style-definition for this case. */
4260 ret
->types
= error_mark_node
;
4261 error_at (c_parser_peek_token (parser
)->location
,
4262 "ISO C requires a named argument before %<...%>");
4264 c_parser_consume_token (parser
);
4265 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4267 c_parser_consume_token (parser
);
4272 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4277 /* Nonempty list of parameters, either terminated with semicolon
4278 (forward declarations; recurse) or with close parenthesis (normal
4279 function) or with ", ... )" (variadic function). */
4282 /* Parse a parameter. */
4283 struct c_parm
*parm
= c_parser_parameter_declaration (parser
, attrs
,
4286 have_gnu_attrs
= false;
4290 push_parm_decl (parm
, &expr
);
4291 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4294 c_parser_consume_token (parser
);
4295 mark_forward_parm_decls ();
4296 bool new_have_gnu_attrs
4297 = c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
);
4298 new_attrs
= c_parser_gnu_attributes (parser
);
4299 return c_parser_parms_list_declarator (parser
, new_attrs
, expr
,
4300 new_have_gnu_attrs
);
4302 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4304 c_parser_consume_token (parser
);
4308 return get_parm_info (false, expr
);
4310 if (!c_parser_require (parser
, CPP_COMMA
,
4311 "expected %<;%>, %<,%> or %<)%>",
4312 UNKNOWN_LOCATION
, false))
4314 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4317 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4319 c_parser_consume_token (parser
);
4320 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4322 c_parser_consume_token (parser
);
4326 return get_parm_info (true, expr
);
4330 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4338 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4339 start of the declaration if it is the first parameter;
4340 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4343 static struct c_parm
*
4344 c_parser_parameter_declaration (c_parser
*parser
, tree attrs
,
4345 bool have_gnu_attrs
)
4347 struct c_declspecs
*specs
;
4348 struct c_declarator
*declarator
;
4350 tree postfix_attrs
= NULL_TREE
;
4353 /* Accept #pragmas between parameter declarations. */
4354 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
4355 c_parser_pragma (parser
, pragma_param
, NULL
);
4357 if (!c_parser_next_token_starts_declspecs (parser
)
4358 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4360 c_token
*token
= c_parser_peek_token (parser
);
4363 c_parser_set_source_position_from_token (token
);
4364 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
4366 auto_diagnostic_group d
;
4367 name_hint hint
= lookup_name_fuzzy (token
->value
,
4368 FUZZY_LOOKUP_TYPENAME
,
4370 if (const char *suggestion
= hint
.suggestion ())
4372 gcc_rich_location
richloc (token
->location
);
4373 richloc
.add_fixit_replace (suggestion
);
4375 "unknown type name %qE; did you mean %qs?",
4376 token
->value
, suggestion
);
4379 error_at (token
->location
, "unknown type name %qE", token
->value
);
4380 parser
->error
= true;
4382 /* ??? In some Objective-C cases '...' isn't applicable so there
4383 should be a different message. */
4385 c_parser_error (parser
,
4386 "expected declaration specifiers or %<...%>");
4387 c_parser_skip_to_end_of_parameter (parser
);
4391 location_t start_loc
= c_parser_peek_token (parser
)->location
;
4393 specs
= build_null_declspecs ();
4396 declspecs_add_attrs (input_location
, specs
, attrs
);
4399 c_parser_declspecs (parser
, specs
, true, true, true, true, false,
4400 !have_gnu_attrs
, true, cla_nonabstract_decl
);
4401 finish_declspecs (specs
);
4402 pending_xref_error ();
4403 prefix_attrs
= specs
->attrs
;
4404 specs
->attrs
= NULL_TREE
;
4405 declarator
= c_parser_declarator (parser
,
4406 specs
->typespec_kind
!= ctsk_none
,
4407 C_DTR_PARM
, &dummy
);
4408 if (declarator
== NULL
)
4410 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
4413 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4414 postfix_attrs
= c_parser_gnu_attributes (parser
);
4416 /* Generate a location for the parameter, ranging from the start of the
4417 initial token to the end of the final token.
4419 If we have a identifier, then use it for the caret location, e.g.
4421 extern int callee (int one, int (*two)(int, int), float three);
4422 ~~~~~~^~~~~~~~~~~~~~
4424 otherwise, reuse the start location for the caret location e.g.:
4426 extern int callee (int one, int (*)(int, int), float three);
4429 location_t end_loc
= parser
->last_token_location
;
4431 /* Find any cdk_id declarator; determine if we have an identifier. */
4432 c_declarator
*id_declarator
= declarator
;
4433 while (id_declarator
&& id_declarator
->kind
!= cdk_id
)
4434 id_declarator
= id_declarator
->declarator
;
4435 location_t caret_loc
= (id_declarator
->u
.id
.id
4436 ? id_declarator
->id_loc
4438 location_t param_loc
= make_location (caret_loc
, start_loc
, end_loc
);
4440 return build_c_parm (specs
, chainon (postfix_attrs
, prefix_attrs
),
4441 declarator
, param_loc
);
4444 /* Parse a string literal in an asm expression. It should not be
4445 translated, and wide string literals are an error although
4446 permitted by the syntax. This is a GNU extension.
4453 c_parser_asm_string_literal (c_parser
*parser
)
4456 int save_flag
= warn_overlength_strings
;
4457 warn_overlength_strings
= 0;
4458 str
= c_parser_string_literal (parser
, false, false).value
;
4459 warn_overlength_strings
= save_flag
;
4463 /* Parse a simple asm expression. This is used in restricted
4464 contexts, where a full expression with inputs and outputs does not
4465 make sense. This is a GNU extension.
4468 asm ( asm-string-literal )
4472 c_parser_simple_asm_expr (c_parser
*parser
)
4475 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
4476 c_parser_consume_token (parser
);
4477 matching_parens parens
;
4478 if (!parens
.require_open (parser
))
4480 str
= c_parser_asm_string_literal (parser
);
4481 if (!parens
.require_close (parser
))
4483 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4490 c_parser_gnu_attribute_any_word (c_parser
*parser
)
4492 tree attr_name
= NULL_TREE
;
4494 if (c_parser_next_token_is (parser
, CPP_KEYWORD
))
4496 /* ??? See comment above about what keywords are accepted here. */
4498 switch (c_parser_peek_token (parser
)->keyword
)
4529 case RID_TRANSACTION_ATOMIC
:
4530 case RID_TRANSACTION_CANCEL
:
4546 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4547 attr_name
= ridpointers
[(int) c_parser_peek_token (parser
)->keyword
];
4549 else if (c_parser_next_token_is (parser
, CPP_NAME
))
4550 attr_name
= c_parser_peek_token (parser
)->value
;
4555 /* Parse attribute arguments. This is a common form of syntax
4556 covering all currently valid GNU and standard attributes.
4558 gnu-attribute-arguments:
4560 identifier , nonempty-expr-list
4563 where the "identifier" must not be declared as a type. ??? Why not
4564 allow identifiers declared as types to start the arguments? */
4567 c_parser_attribute_arguments (c_parser
*parser
, bool takes_identifier
,
4568 bool require_string
, bool allow_empty_args
)
4570 vec
<tree
, va_gc
> *expr_list
;
4572 /* Parse the attribute contents. If they start with an
4573 identifier which is followed by a comma or close
4574 parenthesis, then the arguments start with that
4575 identifier; otherwise they are an expression list.
4576 In objective-c the identifier may be a classname. */
4577 if (c_parser_next_token_is (parser
, CPP_NAME
)
4578 && (c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4579 || (c_dialect_objc ()
4580 && c_parser_peek_token (parser
)->id_kind
4582 && ((c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
4583 || (c_parser_peek_2nd_token (parser
)->type
4584 == CPP_CLOSE_PAREN
))
4585 && (takes_identifier
4586 || (c_dialect_objc ()
4587 && c_parser_peek_token (parser
)->id_kind
4588 == C_ID_CLASSNAME
)))
4590 tree arg1
= c_parser_peek_token (parser
)->value
;
4591 c_parser_consume_token (parser
);
4592 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4593 attr_args
= build_tree_list (NULL_TREE
, arg1
);
4597 c_parser_consume_token (parser
);
4598 expr_list
= c_parser_expr_list (parser
, false, true,
4599 NULL
, NULL
, NULL
, NULL
);
4600 tree_list
= build_tree_list_vec (expr_list
);
4601 attr_args
= tree_cons (NULL_TREE
, arg1
, tree_list
);
4602 release_tree_vector (expr_list
);
4607 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4609 if (!allow_empty_args
)
4610 error_at (c_parser_peek_token (parser
)->location
,
4611 "parentheses must be omitted if "
4612 "attribute argument list is empty");
4613 attr_args
= NULL_TREE
;
4615 else if (require_string
)
4617 /* The only valid argument for this attribute is a string
4618 literal. Handle this specially here to avoid accepting
4619 string literals with excess parentheses. */
4620 tree string
= c_parser_string_literal (parser
, false, true).value
;
4621 attr_args
= build_tree_list (NULL_TREE
, string
);
4625 expr_list
= c_parser_expr_list (parser
, false, true,
4626 NULL
, NULL
, NULL
, NULL
);
4627 attr_args
= build_tree_list_vec (expr_list
);
4628 release_tree_vector (expr_list
);
4634 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4638 gnu-attributes gnu-attribute
4641 __attribute__ ( ( gnu-attribute-list ) )
4645 gnu-attribute_list , gnu-attrib
4650 any-word ( gnu-attribute-arguments )
4652 where "any-word" may be any identifier (including one declared as a
4653 type), a reserved word storage class specifier, type specifier or
4654 type qualifier. ??? This still leaves out most reserved keywords
4655 (following the old parser), shouldn't we include them?
4656 When EXPECT_COMMA is true, expect the attribute to be preceded
4657 by a comma and fail if it isn't.
4658 When EMPTY_OK is true, allow and consume any number of consecutive
4659 commas with no attributes in between. */
4662 c_parser_gnu_attribute (c_parser
*parser
, tree attrs
,
4663 bool expect_comma
= false, bool empty_ok
= true)
4665 bool comma_first
= c_parser_next_token_is (parser
, CPP_COMMA
);
4667 && !c_parser_next_token_is (parser
, CPP_NAME
)
4668 && !c_parser_next_token_is (parser
, CPP_KEYWORD
))
4671 while (c_parser_next_token_is (parser
, CPP_COMMA
))
4673 c_parser_consume_token (parser
);
4678 tree attr_name
= c_parser_gnu_attribute_any_word (parser
);
4679 if (attr_name
== NULL_TREE
)
4682 attr_name
= canonicalize_attr_name (attr_name
);
4683 c_parser_consume_token (parser
);
4686 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4688 if (expect_comma
&& !comma_first
)
4690 /* A comma is missing between the last attribute on the chain
4692 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4694 return error_mark_node
;
4696 attr
= build_tree_list (attr_name
, NULL_TREE
);
4697 /* Add this attribute to the list. */
4698 attrs
= chainon (attrs
, attr
);
4701 c_parser_consume_token (parser
);
4704 = c_parser_attribute_arguments (parser
,
4705 attribute_takes_identifier_p (attr_name
),
4708 attr
= build_tree_list (attr_name
, attr_args
);
4709 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4710 c_parser_consume_token (parser
);
4713 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4715 return error_mark_node
;
4718 if (expect_comma
&& !comma_first
)
4720 /* A comma is missing between the last attribute on the chain
4722 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4724 return error_mark_node
;
4727 /* Add this attribute to the list. */
4728 attrs
= chainon (attrs
, attr
);
4733 c_parser_gnu_attributes (c_parser
*parser
)
4735 tree attrs
= NULL_TREE
;
4736 while (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4738 bool save_translate_strings_p
= parser
->translate_strings_p
;
4739 parser
->translate_strings_p
= false;
4740 /* Consume the `__attribute__' keyword. */
4741 c_parser_consume_token (parser
);
4742 /* Look for the two `(' tokens. */
4743 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4745 parser
->translate_strings_p
= save_translate_strings_p
;
4748 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4750 parser
->translate_strings_p
= save_translate_strings_p
;
4751 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4754 /* Parse the attribute list. Require a comma between successive
4755 (possibly empty) attributes. */
4756 for (bool expect_comma
= false; ; expect_comma
= true)
4758 /* Parse a single attribute. */
4759 tree attr
= c_parser_gnu_attribute (parser
, attrs
, expect_comma
);
4760 if (attr
== error_mark_node
)
4767 /* Look for the two `)' tokens. */
4768 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4769 c_parser_consume_token (parser
);
4772 parser
->translate_strings_p
= save_translate_strings_p
;
4773 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4777 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4778 c_parser_consume_token (parser
);
4781 parser
->translate_strings_p
= save_translate_strings_p
;
4782 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4786 parser
->translate_strings_p
= save_translate_strings_p
;
4792 /* Parse an optional balanced token sequence.
4794 balanced-token-sequence:
4796 balanced-token-sequence balanced-token
4799 ( balanced-token-sequence[opt] )
4800 [ balanced-token-sequence[opt] ]
4801 { balanced-token-sequence[opt] }
4802 any token other than ()[]{}
4806 c_parser_balanced_token_sequence (c_parser
*parser
)
4810 c_token
*token
= c_parser_peek_token (parser
);
4811 switch (token
->type
)
4813 case CPP_OPEN_BRACE
:
4815 matching_braces braces
;
4816 braces
.consume_open (parser
);
4817 c_parser_balanced_token_sequence (parser
);
4818 braces
.require_close (parser
);
4822 case CPP_OPEN_PAREN
:
4824 matching_parens parens
;
4825 parens
.consume_open (parser
);
4826 c_parser_balanced_token_sequence (parser
);
4827 parens
.require_close (parser
);
4831 case CPP_OPEN_SQUARE
:
4832 c_parser_consume_token (parser
);
4833 c_parser_balanced_token_sequence (parser
);
4834 c_parser_require (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
4837 case CPP_CLOSE_BRACE
:
4838 case CPP_CLOSE_PAREN
:
4839 case CPP_CLOSE_SQUARE
:
4844 c_parser_consume_token (parser
);
4850 /* Parse standard (C2X) attributes (including GNU attributes in the
4853 attribute-specifier-sequence:
4854 attribute-specifier-sequence[opt] attribute-specifier
4856 attribute-specifier:
4857 [ [ attribute-list ] ]
4861 attribute-list, attribute[opt]
4864 attribute-token attribute-argument-clause[opt]
4868 attribute-prefixed-token
4873 attribute-prefixed-token:
4874 attribute-prefix :: identifier
4879 attribute-argument-clause:
4880 ( balanced-token-sequence[opt] )
4882 Keywords are accepted as identifiers for this purpose.
4886 c_parser_std_attribute (c_parser
*parser
, bool for_tm
)
4888 c_token
*token
= c_parser_peek_token (parser
);
4889 tree ns
, name
, attribute
;
4891 /* Parse the attribute-token. */
4892 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
4894 c_parser_error (parser
, "expected identifier");
4895 return error_mark_node
;
4897 name
= canonicalize_attr_name (token
->value
);
4898 c_parser_consume_token (parser
);
4899 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
4902 c_parser_consume_token (parser
);
4903 token
= c_parser_peek_token (parser
);
4904 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
4906 c_parser_error (parser
, "expected identifier");
4907 return error_mark_node
;
4909 name
= canonicalize_attr_name (token
->value
);
4910 c_parser_consume_token (parser
);
4914 attribute
= build_tree_list (build_tree_list (ns
, name
), NULL_TREE
);
4916 /* Parse the arguments, if any. */
4917 const attribute_spec
*as
= lookup_attribute_spec (TREE_PURPOSE (attribute
));
4918 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4921 location_t open_loc
= c_parser_peek_token (parser
)->location
;
4922 matching_parens parens
;
4923 parens
.consume_open (parser
);
4924 if ((as
&& as
->max_length
== 0)
4925 /* Special-case the transactional-memory attribute "outer",
4926 which is specially handled but not registered as an
4927 attribute, to avoid allowing arbitrary balanced token
4928 sequences as arguments. */
4929 || is_attribute_p ("outer", name
))
4931 error_at (open_loc
, "%qE attribute does not take any arguments", name
);
4932 parens
.skip_until_found_close (parser
);
4933 return error_mark_node
;
4937 bool takes_identifier
4939 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
4940 && attribute_takes_identifier_p (name
));
4943 && strcmp (IDENTIFIER_POINTER (name
), "deprecated") == 0);
4944 TREE_VALUE (attribute
)
4945 = c_parser_attribute_arguments (parser
, takes_identifier
,
4946 require_string
, false);
4949 c_parser_balanced_token_sequence (parser
);
4950 parens
.require_close (parser
);
4953 if (ns
== NULL_TREE
&& !for_tm
&& !as
&& !is_attribute_p ("nodiscard", name
))
4955 /* An attribute with standard syntax and no namespace specified
4956 is a constraint violation if it is not one of the known
4957 standard attributes (of which nodiscard is the only one
4958 without a handler in GCC). Diagnose it here with a pedwarn
4959 and then discard it to prevent a duplicate warning later. */
4960 pedwarn (input_location
, OPT_Wattributes
, "%qE attribute ignored",
4962 return error_mark_node
;
4968 c_parser_std_attribute_specifier (c_parser
*parser
, bool for_tm
)
4970 bool seen_deprecated
= false;
4971 bool seen_fallthrough
= false;
4972 bool seen_maybe_unused
= false;
4973 location_t loc
= c_parser_peek_token (parser
)->location
;
4974 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
4976 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
4978 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
4982 pedwarn_c11 (loc
, OPT_Wpedantic
,
4983 "ISO C does not support %<[[]]%> attributes before C2X");
4984 tree attributes
= NULL_TREE
;
4987 c_token
*token
= c_parser_peek_token (parser
);
4988 if (token
->type
== CPP_CLOSE_SQUARE
)
4990 if (token
->type
== CPP_COMMA
)
4992 c_parser_consume_token (parser
);
4995 tree attribute
= c_parser_std_attribute (parser
, for_tm
);
4996 if (attribute
!= error_mark_node
)
4998 bool duplicate
= false;
4999 tree name
= get_attribute_name (attribute
);
5000 tree ns
= get_attribute_namespace (attribute
);
5001 if (ns
== NULL_TREE
)
5003 /* Some standard attributes may appear at most once in
5004 each attribute list. Diagnose duplicates and remove
5005 them from the list to avoid subsequent diagnostics
5006 such as the more general one for multiple
5007 "fallthrough" attributes in the same place (including
5008 in separate attribute lists in the same attribute
5009 specifier sequence, which is not a constraint
5011 if (is_attribute_p ("deprecated", name
))
5013 if (seen_deprecated
)
5015 error ("attribute %<deprecated%> can appear at most "
5016 "once in an attribute-list");
5019 seen_deprecated
= true;
5021 else if (is_attribute_p ("fallthrough", name
))
5023 if (seen_fallthrough
)
5025 error ("attribute %<fallthrough%> can appear at most "
5026 "once in an attribute-list");
5029 seen_fallthrough
= true;
5031 else if (is_attribute_p ("maybe_unused", name
))
5033 if (seen_maybe_unused
)
5035 error ("attribute %<maybe_unused%> can appear at most "
5036 "once in an attribute-list");
5039 seen_maybe_unused
= true;
5044 TREE_CHAIN (attribute
) = attributes
;
5045 attributes
= attribute
;
5048 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5051 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5052 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5053 return nreverse (attributes
);
5056 /* Look past an optional balanced token sequence of raw look-ahead
5057 tokens starting with the *Nth token. *N is updated to point to the
5058 following token. Return true if such a sequence was found, false
5059 if the tokens parsed were not balanced. */
5062 c_parser_check_balanced_raw_token_sequence (c_parser
*parser
, unsigned int *n
)
5066 c_token
*token
= c_parser_peek_nth_token_raw (parser
, *n
);
5067 switch (token
->type
)
5069 case CPP_OPEN_BRACE
:
5072 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5074 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5075 if (token
->type
== CPP_CLOSE_BRACE
)
5085 case CPP_OPEN_PAREN
:
5088 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5090 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5091 if (token
->type
== CPP_CLOSE_PAREN
)
5101 case CPP_OPEN_SQUARE
:
5104 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5106 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5107 if (token
->type
== CPP_CLOSE_SQUARE
)
5117 case CPP_CLOSE_BRACE
:
5118 case CPP_CLOSE_PAREN
:
5119 case CPP_CLOSE_SQUARE
:
5130 /* Return whether standard attributes start with the Nth token. */
5133 c_parser_nth_token_starts_std_attributes (c_parser
*parser
, unsigned int n
)
5135 if (!(c_parser_peek_nth_token (parser
, n
)->type
== CPP_OPEN_SQUARE
5136 && c_parser_peek_nth_token (parser
, n
+ 1)->type
== CPP_OPEN_SQUARE
))
5138 /* In C, '[[' must start attributes. In Objective-C, we need to
5139 check whether '[[' is matched by ']]'. */
5140 if (!c_dialect_objc ())
5143 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
5145 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
5146 if (token
->type
!= CPP_CLOSE_SQUARE
)
5148 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
5149 return token
->type
== CPP_CLOSE_SQUARE
;
5153 c_parser_std_attribute_specifier_sequence (c_parser
*parser
)
5155 tree attributes
= NULL_TREE
;
5158 tree attrs
= c_parser_std_attribute_specifier (parser
, false);
5159 attributes
= chainon (attributes
, attrs
);
5161 while (c_parser_nth_token_starts_std_attributes (parser
, 1));
5165 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5166 says whether alignment specifiers are OK (only in cases that might
5167 be the type name of a compound literal).
5170 specifier-qualifier-list abstract-declarator[opt]
5173 struct c_type_name
*
5174 c_parser_type_name (c_parser
*parser
, bool alignas_ok
)
5176 struct c_declspecs
*specs
= build_null_declspecs ();
5177 struct c_declarator
*declarator
;
5178 struct c_type_name
*ret
;
5180 c_parser_declspecs (parser
, specs
, false, true, true, alignas_ok
, false,
5181 false, true, cla_prefer_type
);
5182 if (!specs
->declspecs_seen_p
)
5184 c_parser_error (parser
, "expected specifier-qualifier-list");
5187 if (specs
->type
!= error_mark_node
)
5189 pending_xref_error ();
5190 finish_declspecs (specs
);
5192 declarator
= c_parser_declarator (parser
,
5193 specs
->typespec_kind
!= ctsk_none
,
5194 C_DTR_ABSTRACT
, &dummy
);
5195 if (declarator
== NULL
)
5197 ret
= XOBNEW (&parser_obstack
, struct c_type_name
);
5199 ret
->declarator
= declarator
;
5203 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5206 assignment-expression
5207 { initializer-list }
5208 { initializer-list , }
5211 designation[opt] initializer
5212 initializer-list , designation[opt] initializer
5219 designator-list designator
5226 [ constant-expression ]
5238 [ constant-expression ... constant-expression ]
5240 Any expression without commas is accepted in the syntax for the
5241 constant-expressions, with non-constant expressions rejected later.
5243 This function is only used for top-level initializers; for nested
5244 ones, see c_parser_initval. */
5246 static struct c_expr
5247 c_parser_initializer (c_parser
*parser
)
5249 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
5250 return c_parser_braced_init (parser
, NULL_TREE
, false, NULL
);
5254 location_t loc
= c_parser_peek_token (parser
)->location
;
5255 ret
= c_parser_expr_no_commas (parser
, NULL
);
5256 if (TREE_CODE (ret
.value
) != STRING_CST
5257 && TREE_CODE (ret
.value
) != COMPOUND_LITERAL_EXPR
)
5258 ret
= convert_lvalue_to_rvalue (loc
, ret
, true, true);
5263 /* The location of the last comma within the current initializer list,
5264 or UNKNOWN_LOCATION if not within one. */
5266 location_t last_init_list_comma
;
5268 /* Parse a braced initializer list. TYPE is the type specified for a
5269 compound literal, and NULL_TREE for other initializers and for
5270 nested braced lists. NESTED_P is true for nested braced lists,
5271 false for the list of a compound literal or the list that is the
5272 top-level initializer in a declaration. */
5274 static struct c_expr
5275 c_parser_braced_init (c_parser
*parser
, tree type
, bool nested_p
,
5276 struct obstack
*outer_obstack
)
5279 struct obstack braced_init_obstack
;
5280 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
5281 gcc_obstack_init (&braced_init_obstack
);
5282 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
5283 matching_braces braces
;
5284 braces
.consume_open (parser
);
5287 finish_implicit_inits (brace_loc
, outer_obstack
);
5288 push_init_level (brace_loc
, 0, &braced_init_obstack
);
5291 really_start_incremental_init (type
);
5292 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5294 pedwarn (brace_loc
, OPT_Wpedantic
, "ISO C forbids empty initializer braces");
5298 /* Parse a non-empty initializer list, possibly with a trailing
5302 c_parser_initelt (parser
, &braced_init_obstack
);
5305 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5307 last_init_list_comma
= c_parser_peek_token (parser
)->location
;
5308 c_parser_consume_token (parser
);
5312 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5316 c_token
*next_tok
= c_parser_peek_token (parser
);
5317 if (next_tok
->type
!= CPP_CLOSE_BRACE
)
5320 ret
.original_code
= ERROR_MARK
;
5321 ret
.original_type
= NULL
;
5322 braces
.skip_until_found_close (parser
);
5323 pop_init_level (brace_loc
, 0, &braced_init_obstack
, last_init_list_comma
);
5324 obstack_free (&braced_init_obstack
, NULL
);
5327 location_t close_loc
= next_tok
->location
;
5328 c_parser_consume_token (parser
);
5329 ret
= pop_init_level (brace_loc
, 0, &braced_init_obstack
, close_loc
);
5330 obstack_free (&braced_init_obstack
, NULL
);
5331 set_c_expr_source_range (&ret
, brace_loc
, close_loc
);
5335 /* Parse a nested initializer, including designators. */
5338 c_parser_initelt (c_parser
*parser
, struct obstack
* braced_init_obstack
)
5340 /* Parse any designator or designator list. A single array
5341 designator may have the subsequent "=" omitted in GNU C, but a
5342 longer list or a structure member designator may not. */
5343 if (c_parser_next_token_is (parser
, CPP_NAME
)
5344 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
5346 /* Old-style structure member designator. */
5347 set_init_label (c_parser_peek_token (parser
)->location
,
5348 c_parser_peek_token (parser
)->value
,
5349 c_parser_peek_token (parser
)->location
,
5350 braced_init_obstack
);
5351 /* Use the colon as the error location. */
5352 pedwarn (c_parser_peek_2nd_token (parser
)->location
, OPT_Wpedantic
,
5353 "obsolete use of designated initializer with %<:%>");
5354 c_parser_consume_token (parser
);
5355 c_parser_consume_token (parser
);
5359 /* des_seen is 0 if there have been no designators, 1 if there
5360 has been a single array designator and 2 otherwise. */
5362 /* Location of a designator. */
5363 location_t des_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5364 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
5365 || c_parser_next_token_is (parser
, CPP_DOT
))
5367 int des_prev
= des_seen
;
5369 des_loc
= c_parser_peek_token (parser
)->location
;
5372 if (c_parser_next_token_is (parser
, CPP_DOT
))
5375 c_parser_consume_token (parser
);
5376 if (c_parser_next_token_is (parser
, CPP_NAME
))
5378 set_init_label (des_loc
, c_parser_peek_token (parser
)->value
,
5379 c_parser_peek_token (parser
)->location
,
5380 braced_init_obstack
);
5381 c_parser_consume_token (parser
);
5387 init
.original_code
= ERROR_MARK
;
5388 init
.original_type
= NULL
;
5389 c_parser_error (parser
, "expected identifier");
5390 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5391 process_init_element (input_location
, init
, false,
5392 braced_init_obstack
);
5399 location_t ellipsis_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5400 location_t array_index_loc
= UNKNOWN_LOCATION
;
5401 /* ??? Following the old parser, [ objc-receiver
5402 objc-message-args ] is accepted as an initializer,
5403 being distinguished from a designator by what follows
5404 the first assignment expression inside the square
5405 brackets, but after a first array designator a
5406 subsequent square bracket is for Objective-C taken to
5407 start an expression, using the obsolete form of
5408 designated initializer without '=', rather than
5409 possibly being a second level of designation: in LALR
5410 terms, the '[' is shifted rather than reducing
5411 designator to designator-list. */
5412 if (des_prev
== 1 && c_dialect_objc ())
5414 des_seen
= des_prev
;
5417 if (des_prev
== 0 && c_dialect_objc ())
5419 /* This might be an array designator or an
5420 Objective-C message expression. If the former,
5421 continue parsing here; if the latter, parse the
5422 remainder of the initializer given the starting
5423 primary-expression. ??? It might make sense to
5424 distinguish when des_prev == 1 as well; see
5425 previous comment. */
5427 struct c_expr mexpr
;
5428 c_parser_consume_token (parser
);
5429 if (c_parser_peek_token (parser
)->type
== CPP_NAME
5430 && ((c_parser_peek_token (parser
)->id_kind
5432 || (c_parser_peek_token (parser
)->id_kind
5433 == C_ID_CLASSNAME
)))
5435 /* Type name receiver. */
5436 tree id
= c_parser_peek_token (parser
)->value
;
5437 c_parser_consume_token (parser
);
5438 rec
= objc_get_class_reference (id
);
5439 goto parse_message_args
;
5441 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
5442 mark_exp_read (first
);
5443 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
)
5444 || c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5445 goto array_desig_after_first
;
5446 /* Expression receiver. So far only one part
5447 without commas has been parsed; there might be
5448 more of the expression. */
5450 while (c_parser_next_token_is (parser
, CPP_COMMA
))
5453 location_t comma_loc
, exp_loc
;
5454 comma_loc
= c_parser_peek_token (parser
)->location
;
5455 c_parser_consume_token (parser
);
5456 exp_loc
= c_parser_peek_token (parser
)->location
;
5457 next
= c_parser_expr_no_commas (parser
, NULL
);
5458 next
= convert_lvalue_to_rvalue (exp_loc
, next
,
5460 rec
= build_compound_expr (comma_loc
, rec
, next
.value
);
5463 /* Now parse the objc-message-args. */
5464 args
= c_parser_objc_message_args (parser
);
5465 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5468 = objc_build_message_expr (rec
, args
);
5469 mexpr
.original_code
= ERROR_MARK
;
5470 mexpr
.original_type
= NULL
;
5471 /* Now parse and process the remainder of the
5472 initializer, starting with this message
5473 expression as a primary-expression. */
5474 c_parser_initval (parser
, &mexpr
, braced_init_obstack
);
5477 c_parser_consume_token (parser
);
5478 array_index_loc
= c_parser_peek_token (parser
)->location
;
5479 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
5480 mark_exp_read (first
);
5481 array_desig_after_first
:
5482 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5484 ellipsis_loc
= c_parser_peek_token (parser
)->location
;
5485 c_parser_consume_token (parser
);
5486 second
= c_parser_expr_no_commas (parser
, NULL
).value
;
5487 mark_exp_read (second
);
5491 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5493 c_parser_consume_token (parser
);
5494 set_init_index (array_index_loc
, first
, second
,
5495 braced_init_obstack
);
5497 pedwarn (ellipsis_loc
, OPT_Wpedantic
,
5498 "ISO C forbids specifying range of elements to initialize");
5501 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5507 if (c_parser_next_token_is (parser
, CPP_EQ
))
5509 pedwarn_c90 (des_loc
, OPT_Wpedantic
,
5510 "ISO C90 forbids specifying subobject "
5512 c_parser_consume_token (parser
);
5517 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
5518 "obsolete use of designated initializer without %<=%>");
5523 init
.original_code
= ERROR_MARK
;
5524 init
.original_type
= NULL
;
5525 c_parser_error (parser
, "expected %<=%>");
5526 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5527 process_init_element (input_location
, init
, false,
5528 braced_init_obstack
);
5534 c_parser_initval (parser
, NULL
, braced_init_obstack
);
5537 /* Parse a nested initializer; as c_parser_initializer but parses
5538 initializers within braced lists, after any designators have been
5539 applied. If AFTER is not NULL then it is an Objective-C message
5540 expression which is the primary-expression starting the
5544 c_parser_initval (c_parser
*parser
, struct c_expr
*after
,
5545 struct obstack
* braced_init_obstack
)
5548 gcc_assert (!after
|| c_dialect_objc ());
5549 location_t loc
= c_parser_peek_token (parser
)->location
;
5551 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
) && !after
)
5552 init
= c_parser_braced_init (parser
, NULL_TREE
, true,
5553 braced_init_obstack
);
5556 init
= c_parser_expr_no_commas (parser
, after
);
5557 if (init
.value
!= NULL_TREE
5558 && TREE_CODE (init
.value
) != STRING_CST
5559 && TREE_CODE (init
.value
) != COMPOUND_LITERAL_EXPR
)
5560 init
= convert_lvalue_to_rvalue (loc
, init
, true, true);
5562 process_init_element (loc
, init
, false, braced_init_obstack
);
5565 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5566 C99 6.8.2, C11 6.8.2).
5569 { block-item-list[opt] }
5570 { label-declarations block-item-list }
5574 block-item-list block-item
5586 { label-declarations block-item-list }
5589 __extension__ nested-declaration
5590 nested-function-definition
5594 label-declarations label-declaration
5597 __label__ identifier-list ;
5599 Allowing the mixing of declarations and code is new in C99. The
5600 GNU syntax also permits (not shown above) labels at the end of
5601 compound statements, which yield an error. We don't allow labels
5602 on declarations; this might seem like a natural extension, but
5603 there would be a conflict between gnu-attributes on the label and
5604 prefix gnu-attributes on the declaration. ??? The syntax follows the
5605 old parser in requiring something after label declarations.
5606 Although they are erroneous if the labels declared aren't defined,
5607 is it useful for the syntax to be this way?
5628 cancellation-point-directive */
5631 c_parser_compound_statement (c_parser
*parser
, location_t
*endlocp
)
5634 location_t brace_loc
;
5635 brace_loc
= c_parser_peek_token (parser
)->location
;
5636 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
5638 /* Ensure a scope is entered and left anyway to avoid confusion
5639 if we have just prepared to enter a function body. */
5640 stmt
= c_begin_compound_stmt (true);
5641 c_end_compound_stmt (brace_loc
, stmt
, true);
5642 return error_mark_node
;
5644 stmt
= c_begin_compound_stmt (true);
5645 location_t end_loc
= c_parser_compound_statement_nostart (parser
);
5649 return c_end_compound_stmt (brace_loc
, stmt
, true);
5652 /* Parse a compound statement except for the opening brace. This is
5653 used for parsing both compound statements and statement expressions
5654 (which follow different paths to handling the opening). */
5657 c_parser_compound_statement_nostart (c_parser
*parser
)
5659 bool last_stmt
= false;
5660 bool last_label
= false;
5661 bool save_valid_for_pragma
= valid_location_for_stdc_pragma_p ();
5662 location_t label_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5663 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5665 location_t endloc
= c_parser_peek_token (parser
)->location
;
5666 add_debug_begin_stmt (endloc
);
5667 c_parser_consume_token (parser
);
5670 mark_valid_location_for_stdc_pragma (true);
5671 if (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5673 /* Read zero or more forward-declarations for labels that nested
5674 functions can jump to. */
5675 mark_valid_location_for_stdc_pragma (false);
5676 while (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5678 label_loc
= c_parser_peek_token (parser
)->location
;
5679 c_parser_consume_token (parser
);
5680 /* Any identifiers, including those declared as type names,
5685 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
5687 c_parser_error (parser
, "expected identifier");
5691 = declare_label (c_parser_peek_token (parser
)->value
);
5692 C_DECLARED_LABEL_FLAG (label
) = 1;
5693 add_stmt (build_stmt (label_loc
, DECL_EXPR
, label
));
5694 c_parser_consume_token (parser
);
5695 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5696 c_parser_consume_token (parser
);
5700 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
5702 pedwarn (label_loc
, OPT_Wpedantic
, "ISO C forbids label declarations");
5704 /* We must now have at least one statement, label or declaration. */
5705 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5707 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5708 c_parser_error (parser
, "expected declaration or statement");
5709 location_t endloc
= c_parser_peek_token (parser
)->location
;
5710 c_parser_consume_token (parser
);
5713 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_BRACE
))
5715 location_t loc
= c_parser_peek_token (parser
)->location
;
5716 loc
= expansion_point_location_if_in_system_header (loc
);
5717 /* Standard attributes may start a statement or a declaration. */
5719 = c_parser_nth_token_starts_std_attributes (parser
, 1);
5720 tree std_attrs
= NULL_TREE
;
5722 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5723 if (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5724 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5725 || (c_parser_next_token_is (parser
, CPP_NAME
)
5726 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5728 c_warn_unused_attributes (std_attrs
);
5729 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5730 label_loc
= c_parser_peek_2nd_token (parser
)->location
;
5732 label_loc
= c_parser_peek_token (parser
)->location
;
5735 mark_valid_location_for_stdc_pragma (false);
5736 c_parser_label (parser
);
5738 else if (!last_label
5739 && (c_parser_next_tokens_start_declaration (parser
)
5741 && c_parser_next_token_is (parser
, CPP_SEMICOLON
))))
5744 mark_valid_location_for_stdc_pragma (false);
5745 bool fallthru_attr_p
= false;
5746 c_parser_declaration_or_fndef (parser
, true, !have_std_attrs
,
5747 true, true, true, NULL
,
5748 vNULL
, have_std_attrs
, std_attrs
,
5749 NULL
, &fallthru_attr_p
);
5750 if (last_stmt
&& !fallthru_attr_p
)
5751 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5752 "ISO C90 forbids mixed declarations and code");
5753 last_stmt
= fallthru_attr_p
;
5755 else if (!last_label
5756 && c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
5758 /* __extension__ can start a declaration, but is also an
5759 unary operator that can start an expression. Consume all
5760 but the last of a possible series of __extension__ to
5761 determine which. If standard attributes have already
5762 been seen, it must start a statement, not a declaration,
5763 but standard attributes starting a declaration may appear
5764 after __extension__. */
5765 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
5766 && (c_parser_peek_2nd_token (parser
)->keyword
5768 c_parser_consume_token (parser
);
5770 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
5771 || c_parser_nth_token_starts_std_attributes (parser
, 2)))
5774 ext
= disable_extension_diagnostics ();
5775 c_parser_consume_token (parser
);
5777 mark_valid_location_for_stdc_pragma (false);
5778 c_parser_declaration_or_fndef (parser
, true, true, true, true,
5780 /* Following the old parser, __extension__ does not
5781 disable this diagnostic. */
5782 restore_extension_diagnostics (ext
);
5784 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5785 "ISO C90 forbids mixed declarations and code");
5791 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
5794 c_parser_error (parser
, "expected declaration or statement");
5795 /* External pragmas, and some omp pragmas, are not associated
5796 with regular c code, and so are not to be considered statements
5797 syntactically. This ensures that the user doesn't put them
5798 places that would turn into syntax errors if the directive
5800 if (c_parser_pragma (parser
,
5801 last_label
? pragma_stmt
: pragma_compound
,
5803 last_label
= false, last_stmt
= true;
5805 else if (c_parser_next_token_is (parser
, CPP_EOF
))
5807 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5808 c_parser_error (parser
, "expected declaration or statement");
5809 return c_parser_peek_token (parser
)->location
;
5811 else if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
5813 if (parser
->in_if_block
)
5815 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5816 error_at (loc
, "expected %<}%> before %<else%>");
5817 return c_parser_peek_token (parser
)->location
;
5821 error_at (loc
, "%<else%> without a previous %<if%>");
5822 c_parser_consume_token (parser
);
5829 c_warn_unused_attributes (std_attrs
);
5832 mark_valid_location_for_stdc_pragma (false);
5833 c_parser_statement_after_labels (parser
, NULL
);
5836 parser
->error
= false;
5839 error_at (label_loc
, "label at end of compound statement");
5840 location_t endloc
= c_parser_peek_token (parser
)->location
;
5841 c_parser_consume_token (parser
);
5842 /* Restore the value we started with. */
5843 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5847 /* Parse all consecutive labels, possibly preceded by standard
5848 attributes. In this context, a statement is required, not a
5849 declaration, so attributes must be followed by a statement that is
5850 not just a semicolon. */
5853 c_parser_all_labels (c_parser
*parser
)
5855 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
5857 tree std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5858 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5859 c_parser_error (parser
, "expected statement");
5861 c_warn_unused_attributes (std_attrs
);
5863 while (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5864 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5865 || (c_parser_next_token_is (parser
, CPP_NAME
)
5866 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5867 c_parser_label (parser
);
5870 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5873 identifier : gnu-attributes[opt]
5874 case constant-expression :
5880 case constant-expression ... constant-expression :
5882 The use of gnu-attributes on labels is a GNU extension. The syntax in
5883 GNU C accepts any expressions without commas, non-constant
5884 expressions being rejected later. Any standard
5885 attribute-specifier-sequence before the first label has been parsed
5886 in the caller, to distinguish statements from declarations. Any
5887 attribute-specifier-sequence after the label is parsed in this
5891 c_parser_label (c_parser
*parser
)
5893 location_t loc1
= c_parser_peek_token (parser
)->location
;
5894 tree label
= NULL_TREE
;
5896 /* Remember whether this case or a user-defined label is allowed to fall
5898 bool fallthrough_p
= c_parser_peek_token (parser
)->flags
& PREV_FALLTHROUGH
;
5900 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5903 c_parser_consume_token (parser
);
5904 exp1
= c_parser_expr_no_commas (parser
, NULL
).value
;
5905 if (c_parser_next_token_is (parser
, CPP_COLON
))
5907 c_parser_consume_token (parser
);
5908 label
= do_case (loc1
, exp1
, NULL_TREE
);
5910 else if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5912 c_parser_consume_token (parser
);
5913 exp2
= c_parser_expr_no_commas (parser
, NULL
).value
;
5914 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5915 label
= do_case (loc1
, exp1
, exp2
);
5918 c_parser_error (parser
, "expected %<:%> or %<...%>");
5920 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
5922 c_parser_consume_token (parser
);
5923 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5924 label
= do_case (loc1
, NULL_TREE
, NULL_TREE
);
5928 tree name
= c_parser_peek_token (parser
)->value
;
5931 location_t loc2
= c_parser_peek_token (parser
)->location
;
5932 gcc_assert (c_parser_next_token_is (parser
, CPP_NAME
));
5933 c_parser_consume_token (parser
);
5934 gcc_assert (c_parser_next_token_is (parser
, CPP_COLON
));
5935 c_parser_consume_token (parser
);
5936 attrs
= c_parser_gnu_attributes (parser
);
5937 tlab
= define_label (loc2
, name
);
5940 decl_attributes (&tlab
, attrs
, 0);
5941 label
= add_stmt (build_stmt (loc1
, LABEL_EXPR
, tlab
));
5946 if (TREE_CODE (label
) == LABEL_EXPR
)
5947 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label
)) = fallthrough_p
;
5949 FALLTHROUGH_LABEL_P (CASE_LABEL (label
)) = fallthrough_p
;
5951 /* Standard attributes are only allowed here if they start a
5952 statement, not a declaration (including the case of an
5953 attribute-declaration with only attributes). */
5955 = c_parser_nth_token_starts_std_attributes (parser
, 1);
5956 tree std_attrs
= NULL_TREE
;
5958 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5960 /* Allow '__attribute__((fallthrough));'. */
5962 && c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
5964 location_t loc
= c_parser_peek_token (parser
)->location
;
5965 tree attrs
= c_parser_gnu_attributes (parser
);
5966 if (attribute_fallthrough_p (attrs
))
5968 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5970 tree fn
= build_call_expr_internal_loc (loc
,
5976 warning_at (loc
, OPT_Wattributes
, "%<fallthrough%> attribute "
5977 "not followed by %<;%>");
5979 else if (attrs
!= NULL_TREE
)
5980 warning_at (loc
, OPT_Wattributes
, "only attribute %<fallthrough%>"
5981 " can be applied to a null statement");
5983 if (c_parser_next_tokens_start_declaration (parser
)
5985 && c_parser_next_token_is (parser
, CPP_SEMICOLON
)))
5987 error_at (c_parser_peek_token (parser
)->location
,
5988 "a label can only be part of a statement and "
5989 "a declaration is not a statement");
5990 c_parser_declaration_or_fndef (parser
, /*fndef_ok*/ false,
5991 /*static_assert_ok*/ true,
5992 /*empty_ok*/ true, /*nested*/ true,
5993 /*start_attr_ok*/ true, NULL
,
5994 vNULL
, have_std_attrs
, std_attrs
);
5997 /* Nonempty attributes on the following statement are ignored. */
5998 c_warn_unused_attributes (std_attrs
);
6002 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
6006 attribute-specifier-sequence[opt] compound-statement
6007 expression-statement
6008 attribute-specifier-sequence[opt] selection-statement
6009 attribute-specifier-sequence[opt] iteration-statement
6010 attribute-specifier-sequence[opt] jump-statement
6013 attribute-specifier-sequence[opt] label statement
6015 expression-statement:
6017 attribute-specifier-sequence expression ;
6019 selection-statement:
6023 iteration-statement:
6032 return expression[opt] ;
6037 attribute-specifier-sequence[opt] asm-statement
6042 expression-statement:
6048 attribute-specifier-sequence[opt] objc-throw-statement
6049 attribute-specifier-sequence[opt] objc-try-catch-statement
6050 attribute-specifier-sequence[opt] objc-synchronized-statement
6052 objc-throw-statement:
6059 attribute-specifier-sequence[opt] openacc-construct
6068 parallel-directive structured-block
6071 kernels-directive structured-block
6074 data-directive structured-block
6077 loop-directive structured-block
6082 attribute-specifier-sequence[opt] openmp-construct
6091 parallel-for-construct
6092 parallel-for-simd-construct
6093 parallel-sections-construct
6100 parallel-directive structured-block
6103 for-directive iteration-statement
6106 simd-directive iteration-statements
6109 for-simd-directive iteration-statements
6112 sections-directive section-scope
6115 single-directive structured-block
6117 parallel-for-construct:
6118 parallel-for-directive iteration-statement
6120 parallel-for-simd-construct:
6121 parallel-for-simd-directive iteration-statement
6123 parallel-sections-construct:
6124 parallel-sections-directive section-scope
6127 master-directive structured-block
6130 critical-directive structured-block
6133 atomic-directive expression-statement
6136 ordered-directive structured-block
6138 Transactional Memory:
6141 attribute-specifier-sequence[opt] transaction-statement
6142 attribute-specifier-sequence[opt] transaction-cancel-statement
6144 IF_P is used to track whether there's a (possibly labeled) if statement
6145 which is not enclosed in braces and has an else clause. This is used to
6146 implement -Wparentheses. */
6149 c_parser_statement (c_parser
*parser
, bool *if_p
, location_t
*loc_after_labels
)
6151 c_parser_all_labels (parser
);
6152 if (loc_after_labels
)
6153 *loc_after_labels
= c_parser_peek_token (parser
)->location
;
6154 c_parser_statement_after_labels (parser
, if_p
, NULL
);
6157 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6158 of if-else-if conditions. All labels and standard attributes have
6159 been parsed in the caller.
6161 IF_P is used to track whether there's a (possibly labeled) if statement
6162 which is not enclosed in braces and has an else clause. This is used to
6163 implement -Wparentheses. */
6166 c_parser_statement_after_labels (c_parser
*parser
, bool *if_p
,
6169 location_t loc
= c_parser_peek_token (parser
)->location
;
6170 tree stmt
= NULL_TREE
;
6171 bool in_if_block
= parser
->in_if_block
;
6172 parser
->in_if_block
= false;
6176 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_BRACE
)
6177 add_debug_begin_stmt (loc
);
6179 switch (c_parser_peek_token (parser
)->type
)
6181 case CPP_OPEN_BRACE
:
6182 add_stmt (c_parser_compound_statement (parser
));
6185 switch (c_parser_peek_token (parser
)->keyword
)
6188 c_parser_if_statement (parser
, if_p
, chain
);
6191 c_parser_switch_statement (parser
, if_p
);
6194 c_parser_while_statement (parser
, false, 0, if_p
);
6197 c_parser_do_statement (parser
, false, 0);
6200 c_parser_for_statement (parser
, false, 0, if_p
);
6203 c_parser_consume_token (parser
);
6204 if (c_parser_next_token_is (parser
, CPP_NAME
))
6206 stmt
= c_finish_goto_label (loc
,
6207 c_parser_peek_token (parser
)->value
);
6208 c_parser_consume_token (parser
);
6210 else if (c_parser_next_token_is (parser
, CPP_MULT
))
6214 c_parser_consume_token (parser
);
6215 val
= c_parser_expression (parser
);
6216 val
= convert_lvalue_to_rvalue (loc
, val
, false, true);
6217 stmt
= c_finish_goto_ptr (loc
, val
.value
);
6220 c_parser_error (parser
, "expected identifier or %<*%>");
6221 goto expect_semicolon
;
6223 c_parser_consume_token (parser
);
6224 stmt
= c_finish_bc_stmt (loc
, &c_cont_label
, false);
6225 goto expect_semicolon
;
6227 c_parser_consume_token (parser
);
6228 stmt
= c_finish_bc_stmt (loc
, &c_break_label
, true);
6229 goto expect_semicolon
;
6231 c_parser_consume_token (parser
);
6232 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6234 stmt
= c_finish_return (loc
, NULL_TREE
, NULL_TREE
);
6235 c_parser_consume_token (parser
);
6239 location_t xloc
= c_parser_peek_token (parser
)->location
;
6240 struct c_expr expr
= c_parser_expression_conv (parser
);
6241 mark_exp_read (expr
.value
);
6242 stmt
= c_finish_return (EXPR_LOC_OR_LOC (expr
.value
, xloc
),
6243 expr
.value
, expr
.original_type
);
6244 goto expect_semicolon
;
6248 stmt
= c_parser_asm_statement (parser
);
6250 case RID_TRANSACTION_ATOMIC
:
6251 case RID_TRANSACTION_RELAXED
:
6252 stmt
= c_parser_transaction (parser
,
6253 c_parser_peek_token (parser
)->keyword
);
6255 case RID_TRANSACTION_CANCEL
:
6256 stmt
= c_parser_transaction_cancel (parser
);
6257 goto expect_semicolon
;
6259 gcc_assert (c_dialect_objc ());
6260 c_parser_consume_token (parser
);
6261 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6263 stmt
= objc_build_throw_stmt (loc
, NULL_TREE
);
6264 c_parser_consume_token (parser
);
6268 struct c_expr expr
= c_parser_expression (parser
);
6269 expr
= convert_lvalue_to_rvalue (loc
, expr
, false, false);
6270 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
6271 stmt
= objc_build_throw_stmt (loc
, expr
.value
);
6272 goto expect_semicolon
;
6276 gcc_assert (c_dialect_objc ());
6277 c_parser_objc_try_catch_finally_statement (parser
);
6279 case RID_AT_SYNCHRONIZED
:
6280 gcc_assert (c_dialect_objc ());
6281 c_parser_objc_synchronized_statement (parser
);
6285 /* Allow '__attribute__((fallthrough));'. */
6286 tree attrs
= c_parser_gnu_attributes (parser
);
6287 if (attribute_fallthrough_p (attrs
))
6289 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6291 tree fn
= build_call_expr_internal_loc (loc
,
6296 c_parser_consume_token (parser
);
6299 warning_at (loc
, OPT_Wattributes
,
6300 "%<fallthrough%> attribute not followed "
6303 else if (attrs
!= NULL_TREE
)
6304 warning_at (loc
, OPT_Wattributes
, "only attribute %<fallthrough%>"
6305 " can be applied to a null statement");
6313 c_parser_consume_token (parser
);
6315 case CPP_CLOSE_PAREN
:
6316 case CPP_CLOSE_SQUARE
:
6317 /* Avoid infinite loop in error recovery:
6318 c_parser_skip_until_found stops at a closing nesting
6319 delimiter without consuming it, but here we need to consume
6320 it to proceed further. */
6321 c_parser_error (parser
, "expected statement");
6322 c_parser_consume_token (parser
);
6325 c_parser_pragma (parser
, pragma_stmt
, if_p
);
6329 stmt
= c_finish_expr_stmt (loc
, c_parser_expression_conv (parser
).value
);
6331 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
6334 /* Two cases cannot and do not have line numbers associated: If stmt
6335 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6336 cannot hold line numbers. But that's OK because the statement
6337 will either be changed to a MODIFY_EXPR during gimplification of
6338 the statement expr, or discarded. If stmt was compound, but
6339 without new variables, we will have skipped the creation of a
6340 BIND and will have a bare STATEMENT_LIST. But that's OK because
6341 (recursively) all of the component statements should already have
6342 line numbers assigned. ??? Can we discard no-op statements
6344 if (EXPR_LOCATION (stmt
) == UNKNOWN_LOCATION
)
6345 protected_set_expr_location (stmt
, loc
);
6347 parser
->in_if_block
= in_if_block
;
6350 /* Parse the condition from an if, do, while or for statements. */
6353 c_parser_condition (c_parser
*parser
)
6355 location_t loc
= c_parser_peek_token (parser
)->location
;
6357 cond
= c_parser_expression_conv (parser
).value
;
6358 cond
= c_objc_common_truthvalue_conversion (loc
, cond
);
6359 cond
= c_fully_fold (cond
, false, NULL
);
6360 if (warn_sequence_point
)
6361 verify_sequence_points (cond
);
6365 /* Parse a parenthesized condition from an if, do or while statement.
6371 c_parser_paren_condition (c_parser
*parser
)
6374 matching_parens parens
;
6375 if (!parens
.require_open (parser
))
6376 return error_mark_node
;
6377 cond
= c_parser_condition (parser
);
6378 parens
.skip_until_found_close (parser
);
6382 /* Parse a statement which is a block in C99.
6384 IF_P is used to track whether there's a (possibly labeled) if statement
6385 which is not enclosed in braces and has an else clause. This is used to
6386 implement -Wparentheses. */
6389 c_parser_c99_block_statement (c_parser
*parser
, bool *if_p
,
6390 location_t
*loc_after_labels
)
6392 tree block
= c_begin_compound_stmt (flag_isoc99
);
6393 location_t loc
= c_parser_peek_token (parser
)->location
;
6394 c_parser_statement (parser
, if_p
, loc_after_labels
);
6395 return c_end_compound_stmt (loc
, block
, flag_isoc99
);
6398 /* Parse the body of an if statement. This is just parsing a
6399 statement but (a) it is a block in C99, (b) we track whether the
6400 body is an if statement for the sake of -Wparentheses warnings, (c)
6401 we handle an empty body specially for the sake of -Wempty-body
6402 warnings, and (d) we call parser_compound_statement directly
6403 because c_parser_statement_after_labels resets
6404 parser->in_if_block.
6406 IF_P is used to track whether there's a (possibly labeled) if statement
6407 which is not enclosed in braces and has an else clause. This is used to
6408 implement -Wparentheses. */
6411 c_parser_if_body (c_parser
*parser
, bool *if_p
,
6412 const token_indent_info
&if_tinfo
)
6414 tree block
= c_begin_compound_stmt (flag_isoc99
);
6415 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6416 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6417 token_indent_info body_tinfo
6418 = get_token_indent_info (c_parser_peek_token (parser
));
6420 c_parser_all_labels (parser
);
6421 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6423 location_t loc
= c_parser_peek_token (parser
)->location
;
6424 add_stmt (build_empty_stmt (loc
));
6425 c_parser_consume_token (parser
);
6426 if (!c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6427 warning_at (loc
, OPT_Wempty_body
,
6428 "suggest braces around empty body in an %<if%> statement");
6430 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6431 add_stmt (c_parser_compound_statement (parser
));
6434 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6435 c_parser_statement_after_labels (parser
, if_p
);
6438 token_indent_info next_tinfo
6439 = get_token_indent_info (c_parser_peek_token (parser
));
6440 warn_for_misleading_indentation (if_tinfo
, body_tinfo
, next_tinfo
);
6441 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6442 && next_tinfo
.type
!= CPP_SEMICOLON
)
6443 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6444 if_tinfo
.location
, RID_IF
);
6446 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6449 /* Parse the else body of an if statement. This is just parsing a
6450 statement but (a) it is a block in C99, (b) we handle an empty body
6451 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6452 of if-else-if conditions. */
6455 c_parser_else_body (c_parser
*parser
, const token_indent_info
&else_tinfo
,
6458 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6459 tree block
= c_begin_compound_stmt (flag_isoc99
);
6460 token_indent_info body_tinfo
6461 = get_token_indent_info (c_parser_peek_token (parser
));
6462 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6464 c_parser_all_labels (parser
);
6465 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6467 location_t loc
= c_parser_peek_token (parser
)->location
;
6470 "suggest braces around empty body in an %<else%> statement");
6471 add_stmt (build_empty_stmt (loc
));
6472 c_parser_consume_token (parser
);
6476 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6477 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6478 c_parser_statement_after_labels (parser
, NULL
, chain
);
6481 token_indent_info next_tinfo
6482 = get_token_indent_info (c_parser_peek_token (parser
));
6483 warn_for_misleading_indentation (else_tinfo
, body_tinfo
, next_tinfo
);
6484 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6485 && next_tinfo
.type
!= CPP_SEMICOLON
)
6486 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6487 else_tinfo
.location
, RID_ELSE
);
6489 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6492 /* We might need to reclassify any previously-lexed identifier, e.g.
6493 when we've left a for loop with an if-statement without else in the
6494 body - we might have used a wrong scope for the token. See PR67784. */
6497 c_parser_maybe_reclassify_token (c_parser
*parser
)
6499 if (c_parser_next_token_is (parser
, CPP_NAME
))
6501 c_token
*token
= c_parser_peek_token (parser
);
6503 if (token
->id_kind
!= C_ID_CLASSNAME
)
6505 tree decl
= lookup_name (token
->value
);
6507 token
->id_kind
= C_ID_ID
;
6510 if (TREE_CODE (decl
) == TYPE_DECL
)
6511 token
->id_kind
= C_ID_TYPENAME
;
6513 else if (c_dialect_objc ())
6515 tree objc_interface_decl
= objc_is_class_name (token
->value
);
6516 /* Objective-C class names are in the same namespace as
6517 variables and typedefs, and hence are shadowed by local
6519 if (objc_interface_decl
)
6521 token
->value
= objc_interface_decl
;
6522 token
->id_kind
= C_ID_CLASSNAME
;
6529 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6532 if ( expression ) statement
6533 if ( expression ) statement else statement
6535 CHAIN is a vector of if-else-if conditions.
6536 IF_P is used to track whether there's a (possibly labeled) if statement
6537 which is not enclosed in braces and has an else clause. This is used to
6538 implement -Wparentheses. */
6541 c_parser_if_statement (c_parser
*parser
, bool *if_p
, vec
<tree
> *chain
)
6546 bool nested_if
= false;
6547 tree first_body
, second_body
;
6550 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_IF
));
6551 token_indent_info if_tinfo
6552 = get_token_indent_info (c_parser_peek_token (parser
));
6553 c_parser_consume_token (parser
);
6554 block
= c_begin_compound_stmt (flag_isoc99
);
6555 loc
= c_parser_peek_token (parser
)->location
;
6556 cond
= c_parser_paren_condition (parser
);
6557 in_if_block
= parser
->in_if_block
;
6558 parser
->in_if_block
= true;
6559 first_body
= c_parser_if_body (parser
, &nested_if
, if_tinfo
);
6560 parser
->in_if_block
= in_if_block
;
6562 if (warn_duplicated_cond
)
6563 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond
), cond
, &chain
);
6565 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6567 token_indent_info else_tinfo
6568 = get_token_indent_info (c_parser_peek_token (parser
));
6569 c_parser_consume_token (parser
);
6570 if (warn_duplicated_cond
)
6572 if (c_parser_next_token_is_keyword (parser
, RID_IF
)
6575 /* We've got "if (COND) else if (COND2)". Start the
6576 condition chain and add COND as the first element. */
6577 chain
= new vec
<tree
> ();
6578 if (!CONSTANT_CLASS_P (cond
) && !TREE_SIDE_EFFECTS (cond
))
6579 chain
->safe_push (cond
);
6581 else if (!c_parser_next_token_is_keyword (parser
, RID_IF
))
6583 /* This is if-else without subsequent if. Zap the condition
6584 chain; we would have already warned at this point. */
6589 second_body
= c_parser_else_body (parser
, else_tinfo
, chain
);
6590 /* Set IF_P to true to indicate that this if statement has an
6591 else clause. This may trigger the Wparentheses warning
6592 below when we get back up to the parent if statement. */
6598 second_body
= NULL_TREE
;
6600 /* Diagnose an ambiguous else if if-then-else is nested inside
6603 warning_at (loc
, OPT_Wdangling_else
,
6604 "suggest explicit braces to avoid ambiguous %<else%>");
6606 if (warn_duplicated_cond
)
6608 /* This if statement does not have an else clause. We don't
6609 need the condition chain anymore. */
6614 c_finish_if_stmt (loc
, cond
, first_body
, second_body
);
6615 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6617 c_parser_maybe_reclassify_token (parser
);
6620 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6623 switch (expression) statement
6627 c_parser_switch_statement (c_parser
*parser
, bool *if_p
)
6630 tree block
, expr
, body
, save_break
;
6631 location_t switch_loc
= c_parser_peek_token (parser
)->location
;
6632 location_t switch_cond_loc
;
6633 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SWITCH
));
6634 c_parser_consume_token (parser
);
6635 block
= c_begin_compound_stmt (flag_isoc99
);
6636 bool explicit_cast_p
= false;
6637 matching_parens parens
;
6638 if (parens
.require_open (parser
))
6640 switch_cond_loc
= c_parser_peek_token (parser
)->location
;
6641 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
6642 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
6643 explicit_cast_p
= true;
6644 ce
= c_parser_expression (parser
);
6645 ce
= convert_lvalue_to_rvalue (switch_cond_loc
, ce
, true, true);
6647 /* ??? expr has no valid location? */
6648 parens
.skip_until_found_close (parser
);
6652 switch_cond_loc
= UNKNOWN_LOCATION
;
6653 expr
= error_mark_node
;
6654 ce
.original_type
= error_mark_node
;
6656 c_start_case (switch_loc
, switch_cond_loc
, expr
, explicit_cast_p
);
6657 save_break
= c_break_label
;
6658 c_break_label
= NULL_TREE
;
6659 location_t loc_after_labels
;
6660 bool open_brace_p
= c_parser_peek_token (parser
)->type
== CPP_OPEN_BRACE
;
6661 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6662 location_t next_loc
= c_parser_peek_token (parser
)->location
;
6663 if (!open_brace_p
&& c_parser_peek_token (parser
)->type
!= CPP_SEMICOLON
)
6664 warn_for_multistatement_macros (loc_after_labels
, next_loc
, switch_loc
,
6668 location_t here
= c_parser_peek_token (parser
)->location
;
6669 tree t
= build1 (LABEL_EXPR
, void_type_node
, c_break_label
);
6670 SET_EXPR_LOCATION (t
, here
);
6671 SWITCH_BREAK_LABEL_P (c_break_label
) = 1;
6672 append_to_statement_list_force (t
, &body
);
6674 c_finish_case (body
, ce
.original_type
);
6675 c_break_label
= save_break
;
6676 add_stmt (c_end_compound_stmt (switch_loc
, block
, flag_isoc99
));
6677 c_parser_maybe_reclassify_token (parser
);
6680 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6683 while (expression) statement
6685 IF_P is used to track whether there's a (possibly labeled) if statement
6686 which is not enclosed in braces and has an else clause. This is used to
6687 implement -Wparentheses. */
6690 c_parser_while_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6693 tree block
, cond
, body
, save_break
, save_cont
;
6695 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_WHILE
));
6696 token_indent_info while_tinfo
6697 = get_token_indent_info (c_parser_peek_token (parser
));
6698 c_parser_consume_token (parser
);
6699 block
= c_begin_compound_stmt (flag_isoc99
);
6700 loc
= c_parser_peek_token (parser
)->location
;
6701 cond
= c_parser_paren_condition (parser
);
6702 if (ivdep
&& cond
!= error_mark_node
)
6703 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6704 build_int_cst (integer_type_node
,
6705 annot_expr_ivdep_kind
),
6707 if (unroll
&& cond
!= error_mark_node
)
6708 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6709 build_int_cst (integer_type_node
,
6710 annot_expr_unroll_kind
),
6711 build_int_cst (integer_type_node
, unroll
));
6712 save_break
= c_break_label
;
6713 c_break_label
= NULL_TREE
;
6714 save_cont
= c_cont_label
;
6715 c_cont_label
= NULL_TREE
;
6717 token_indent_info body_tinfo
6718 = get_token_indent_info (c_parser_peek_token (parser
));
6720 location_t loc_after_labels
;
6721 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
6722 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6723 c_finish_loop (loc
, loc
, cond
, UNKNOWN_LOCATION
, NULL
, body
,
6724 c_break_label
, c_cont_label
, true);
6725 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6726 c_parser_maybe_reclassify_token (parser
);
6728 token_indent_info next_tinfo
6729 = get_token_indent_info (c_parser_peek_token (parser
));
6730 warn_for_misleading_indentation (while_tinfo
, body_tinfo
, next_tinfo
);
6732 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
6733 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
6734 while_tinfo
.location
, RID_WHILE
);
6736 c_break_label
= save_break
;
6737 c_cont_label
= save_cont
;
6740 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6743 do statement while ( expression ) ;
6747 c_parser_do_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
)
6749 tree block
, cond
, body
, save_break
, save_cont
, new_break
, new_cont
;
6751 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_DO
));
6752 c_parser_consume_token (parser
);
6753 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6754 warning_at (c_parser_peek_token (parser
)->location
,
6756 "suggest braces around empty body in %<do%> statement");
6757 block
= c_begin_compound_stmt (flag_isoc99
);
6758 loc
= c_parser_peek_token (parser
)->location
;
6759 save_break
= c_break_label
;
6760 c_break_label
= NULL_TREE
;
6761 save_cont
= c_cont_label
;
6762 c_cont_label
= NULL_TREE
;
6763 body
= c_parser_c99_block_statement (parser
, NULL
);
6764 c_parser_require_keyword (parser
, RID_WHILE
, "expected %<while%>");
6765 new_break
= c_break_label
;
6766 c_break_label
= save_break
;
6767 new_cont
= c_cont_label
;
6768 c_cont_label
= save_cont
;
6769 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
6770 cond
= c_parser_paren_condition (parser
);
6771 if (ivdep
&& cond
!= error_mark_node
)
6772 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6773 build_int_cst (integer_type_node
,
6774 annot_expr_ivdep_kind
),
6776 if (unroll
&& cond
!= error_mark_node
)
6777 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6778 build_int_cst (integer_type_node
,
6779 annot_expr_unroll_kind
),
6780 build_int_cst (integer_type_node
, unroll
));
6781 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
6782 c_parser_skip_to_end_of_block_or_statement (parser
);
6783 c_finish_loop (loc
, cond_loc
, cond
, UNKNOWN_LOCATION
, NULL
, body
,
6784 new_break
, new_cont
, false);
6785 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6788 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6791 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6792 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6794 The form with a declaration is new in C99.
6796 ??? In accordance with the old parser, the declaration may be a
6797 nested function, which is then rejected in check_for_loop_decls,
6798 but does it make any sense for this to be included in the grammar?
6799 Note in particular that the nested function does not include a
6800 trailing ';', whereas the "declaration" production includes one.
6801 Also, can we reject bad declarations earlier and cheaper than
6802 check_for_loop_decls?
6804 In Objective-C, there are two additional variants:
6807 for ( expression in expresssion ) statement
6808 for ( declaration in expression ) statement
6810 This is inconsistent with C, because the second variant is allowed
6811 even if c99 is not enabled.
6813 The rest of the comment documents these Objective-C foreach-statement.
6815 Here is the canonical example of the first variant:
6816 for (object in array) { do something with object }
6817 we call the first expression ("object") the "object_expression" and
6818 the second expression ("array") the "collection_expression".
6819 object_expression must be an lvalue of type "id" (a generic Objective-C
6820 object) because the loop works by assigning to object_expression the
6821 various objects from the collection_expression. collection_expression
6822 must evaluate to something of type "id" which responds to the method
6823 countByEnumeratingWithState:objects:count:.
6825 The canonical example of the second variant is:
6826 for (id object in array) { do something with object }
6827 which is completely equivalent to
6830 for (object in array) { do something with object }
6832 Note that initizializing 'object' in some way (eg, "for ((object =
6833 xxx) in array) { do something with object }") is possibly
6834 technically valid, but completely pointless as 'object' will be
6835 assigned to something else as soon as the loop starts. We should
6836 most likely reject it (TODO).
6838 The beginning of the Objective-C foreach-statement looks exactly
6839 like the beginning of the for-statement, and we can tell it is a
6840 foreach-statement only because the initial declaration or
6841 expression is terminated by 'in' instead of ';'.
6843 IF_P is used to track whether there's a (possibly labeled) if statement
6844 which is not enclosed in braces and has an else clause. This is used to
6845 implement -Wparentheses. */
6848 c_parser_for_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6851 tree block
, cond
, incr
, save_break
, save_cont
, body
;
6852 /* The following are only used when parsing an ObjC foreach statement. */
6853 tree object_expression
;
6854 /* Silence the bogus uninitialized warning. */
6855 tree collection_expression
= NULL
;
6856 location_t loc
= c_parser_peek_token (parser
)->location
;
6857 location_t for_loc
= loc
;
6858 location_t cond_loc
= UNKNOWN_LOCATION
;
6859 location_t incr_loc
= UNKNOWN_LOCATION
;
6860 bool is_foreach_statement
= false;
6861 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
6862 token_indent_info for_tinfo
6863 = get_token_indent_info (c_parser_peek_token (parser
));
6864 c_parser_consume_token (parser
);
6865 /* Open a compound statement in Objective-C as well, just in case this is
6866 as foreach expression. */
6867 block
= c_begin_compound_stmt (flag_isoc99
|| c_dialect_objc ());
6868 cond
= error_mark_node
;
6869 incr
= error_mark_node
;
6870 matching_parens parens
;
6871 if (parens
.require_open (parser
))
6873 /* Parse the initialization declaration or expression. */
6874 object_expression
= error_mark_node
;
6875 parser
->objc_could_be_foreach_context
= c_dialect_objc ();
6876 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6878 parser
->objc_could_be_foreach_context
= false;
6879 c_parser_consume_token (parser
);
6880 c_finish_expr_stmt (loc
, NULL_TREE
);
6882 else if (c_parser_next_tokens_start_declaration (parser
)
6883 || c_parser_nth_token_starts_std_attributes (parser
, 1))
6885 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
6886 &object_expression
, vNULL
);
6887 parser
->objc_could_be_foreach_context
= false;
6889 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6891 c_parser_consume_token (parser
);
6892 is_foreach_statement
= true;
6893 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6894 c_parser_error (parser
, "multiple iterating variables in "
6895 "fast enumeration");
6898 check_for_loop_decls (for_loc
, flag_isoc99
);
6900 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
6902 /* __extension__ can start a declaration, but is also an
6903 unary operator that can start an expression. Consume all
6904 but the last of a possible series of __extension__ to
6906 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
6907 && (c_parser_peek_2nd_token (parser
)->keyword
6909 c_parser_consume_token (parser
);
6910 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
6911 || c_parser_nth_token_starts_std_attributes (parser
, 2))
6914 ext
= disable_extension_diagnostics ();
6915 c_parser_consume_token (parser
);
6916 c_parser_declaration_or_fndef (parser
, true, true, true, true,
6917 true, &object_expression
, vNULL
);
6918 parser
->objc_could_be_foreach_context
= false;
6920 restore_extension_diagnostics (ext
);
6921 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6923 c_parser_consume_token (parser
);
6924 is_foreach_statement
= true;
6925 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6926 c_parser_error (parser
, "multiple iterating variables in "
6927 "fast enumeration");
6930 check_for_loop_decls (for_loc
, flag_isoc99
);
6940 tree init_expression
;
6941 ce
= c_parser_expression (parser
);
6942 init_expression
= ce
.value
;
6943 parser
->objc_could_be_foreach_context
= false;
6944 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6946 c_parser_consume_token (parser
);
6947 is_foreach_statement
= true;
6948 if (! lvalue_p (init_expression
))
6949 c_parser_error (parser
, "invalid iterating variable in "
6950 "fast enumeration");
6952 = c_fully_fold (init_expression
, false, NULL
);
6956 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6957 init_expression
= ce
.value
;
6958 c_finish_expr_stmt (loc
, init_expression
);
6959 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6964 /* Parse the loop condition. In the case of a foreach
6965 statement, there is no loop condition. */
6966 gcc_assert (!parser
->objc_could_be_foreach_context
);
6967 if (!is_foreach_statement
)
6969 cond_loc
= c_parser_peek_token (parser
)->location
;
6970 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6974 c_parser_error (parser
, "missing loop condition in loop "
6975 "with %<GCC ivdep%> pragma");
6976 cond
= error_mark_node
;
6980 c_parser_error (parser
, "missing loop condition in loop "
6981 "with %<GCC unroll%> pragma");
6982 cond
= error_mark_node
;
6986 c_parser_consume_token (parser
);
6992 cond
= c_parser_condition (parser
);
6993 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6996 if (ivdep
&& cond
!= error_mark_node
)
6997 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6998 build_int_cst (integer_type_node
,
6999 annot_expr_ivdep_kind
),
7001 if (unroll
&& cond
!= error_mark_node
)
7002 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
7003 build_int_cst (integer_type_node
,
7004 annot_expr_unroll_kind
),
7005 build_int_cst (integer_type_node
, unroll
));
7007 /* Parse the increment expression (the third expression in a
7008 for-statement). In the case of a foreach-statement, this is
7009 the expression that follows the 'in'. */
7010 loc
= incr_loc
= c_parser_peek_token (parser
)->location
;
7011 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7013 if (is_foreach_statement
)
7015 c_parser_error (parser
,
7016 "missing collection in fast enumeration");
7017 collection_expression
= error_mark_node
;
7020 incr
= c_process_expr_stmt (loc
, NULL_TREE
);
7024 if (is_foreach_statement
)
7025 collection_expression
7026 = c_fully_fold (c_parser_expression (parser
).value
, false, NULL
);
7029 struct c_expr ce
= c_parser_expression (parser
);
7030 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
7031 incr
= c_process_expr_stmt (loc
, ce
.value
);
7034 parens
.skip_until_found_close (parser
);
7036 save_break
= c_break_label
;
7037 c_break_label
= NULL_TREE
;
7038 save_cont
= c_cont_label
;
7039 c_cont_label
= NULL_TREE
;
7041 token_indent_info body_tinfo
7042 = get_token_indent_info (c_parser_peek_token (parser
));
7044 location_t loc_after_labels
;
7045 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
7046 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
7048 if (is_foreach_statement
)
7049 objc_finish_foreach_loop (for_loc
, object_expression
,
7050 collection_expression
, body
, c_break_label
,
7053 c_finish_loop (for_loc
, cond_loc
, cond
, incr_loc
, incr
, body
,
7054 c_break_label
, c_cont_label
, true);
7055 add_stmt (c_end_compound_stmt (for_loc
, block
,
7056 flag_isoc99
|| c_dialect_objc ()));
7057 c_parser_maybe_reclassify_token (parser
);
7059 token_indent_info next_tinfo
7060 = get_token_indent_info (c_parser_peek_token (parser
));
7061 warn_for_misleading_indentation (for_tinfo
, body_tinfo
, next_tinfo
);
7063 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
7064 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
7065 for_tinfo
.location
, RID_FOR
);
7067 c_break_label
= save_break
;
7068 c_cont_label
= save_cont
;
7071 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7072 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7081 asm-qualifier-list asm-qualifier
7085 asm asm-qualifier-list[opt] ( asm-argument ) ;
7089 asm-string-literal : asm-operands[opt]
7090 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7091 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7093 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7096 The form with asm-goto-operands is valid if and only if the
7097 asm-qualifier-list contains goto, and is the only allowed form in that case.
7098 Duplicate asm-qualifiers are not allowed.
7100 The :: token is considered equivalent to two consecutive : tokens. */
7103 c_parser_asm_statement (c_parser
*parser
)
7105 tree str
, outputs
, inputs
, clobbers
, labels
, ret
;
7107 location_t asm_loc
= c_parser_peek_token (parser
)->location
;
7108 int section
, nsections
;
7110 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
7111 c_parser_consume_token (parser
);
7113 /* Handle the asm-qualifier-list. */
7114 location_t volatile_loc
= UNKNOWN_LOCATION
;
7115 location_t inline_loc
= UNKNOWN_LOCATION
;
7116 location_t goto_loc
= UNKNOWN_LOCATION
;
7119 c_token
*token
= c_parser_peek_token (parser
);
7120 location_t loc
= token
->location
;
7121 switch (token
->keyword
)
7126 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7127 inform (volatile_loc
, "first seen here");
7131 c_parser_consume_token (parser
);
7137 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7138 inform (inline_loc
, "first seen here");
7142 c_parser_consume_token (parser
);
7148 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7149 inform (goto_loc
, "first seen here");
7153 c_parser_consume_token (parser
);
7158 error_at (loc
, "%qE is not a valid %<asm%> qualifier", token
->value
);
7159 c_parser_consume_token (parser
);
7168 bool is_volatile
= (volatile_loc
!= UNKNOWN_LOCATION
);
7169 bool is_inline
= (inline_loc
!= UNKNOWN_LOCATION
);
7170 bool is_goto
= (goto_loc
!= UNKNOWN_LOCATION
);
7174 matching_parens parens
;
7175 if (!parens
.require_open (parser
))
7178 str
= c_parser_asm_string_literal (parser
);
7179 if (str
== NULL_TREE
)
7180 goto error_close_paren
;
7183 outputs
= NULL_TREE
;
7185 clobbers
= NULL_TREE
;
7188 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7191 /* Parse each colon-delimited section of operands. */
7192 nsections
= 3 + is_goto
;
7193 for (section
= 0; section
< nsections
; ++section
)
7195 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
7198 if (section
== nsections
)
7200 c_parser_error (parser
, "expected %<)%>");
7201 goto error_close_paren
;
7203 c_parser_consume_token (parser
);
7205 else if (!c_parser_require (parser
, CPP_COLON
,
7207 ? G_("expected %<:%>")
7208 : G_("expected %<:%> or %<)%>"),
7209 UNKNOWN_LOCATION
, is_goto
))
7210 goto error_close_paren
;
7212 /* Once past any colon, we're no longer a simple asm. */
7215 if ((!c_parser_next_token_is (parser
, CPP_COLON
)
7216 && !c_parser_next_token_is (parser
, CPP_SCOPE
)
7217 && !c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7222 /* For asm goto, we don't allow output operands, but reserve
7223 the slot for a future extension that does allow them. */
7225 outputs
= c_parser_asm_operands (parser
);
7228 inputs
= c_parser_asm_operands (parser
);
7231 clobbers
= c_parser_asm_clobbers (parser
);
7234 labels
= c_parser_asm_goto_operands (parser
);
7240 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7245 if (!parens
.require_close (parser
))
7247 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7251 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
7252 c_parser_skip_to_end_of_block_or_statement (parser
);
7254 ret
= build_asm_stmt (is_volatile
,
7255 build_asm_expr (asm_loc
, str
, outputs
, inputs
,
7256 clobbers
, labels
, simple
, is_inline
));
7262 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7266 /* Parse asm operands, a GNU extension.
7270 asm-operands , asm-operand
7273 asm-string-literal ( expression )
7274 [ identifier ] asm-string-literal ( expression )
7278 c_parser_asm_operands (c_parser
*parser
)
7280 tree list
= NULL_TREE
;
7285 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
7287 c_parser_consume_token (parser
);
7288 if (c_parser_next_token_is (parser
, CPP_NAME
))
7290 tree id
= c_parser_peek_token (parser
)->value
;
7291 c_parser_consume_token (parser
);
7292 name
= build_string (IDENTIFIER_LENGTH (id
),
7293 IDENTIFIER_POINTER (id
));
7297 c_parser_error (parser
, "expected identifier");
7298 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
7301 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
7306 str
= c_parser_asm_string_literal (parser
);
7307 if (str
== NULL_TREE
)
7309 matching_parens parens
;
7310 if (!parens
.require_open (parser
))
7312 expr
= c_parser_expression (parser
);
7313 mark_exp_read (expr
.value
);
7314 if (!parens
.require_close (parser
))
7316 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7319 list
= chainon (list
, build_tree_list (build_tree_list (name
, str
),
7321 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7322 c_parser_consume_token (parser
);
7329 /* Parse asm clobbers, a GNU extension.
7333 asm-clobbers , asm-string-literal
7337 c_parser_asm_clobbers (c_parser
*parser
)
7339 tree list
= NULL_TREE
;
7342 tree str
= c_parser_asm_string_literal (parser
);
7344 list
= tree_cons (NULL_TREE
, str
, list
);
7347 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7348 c_parser_consume_token (parser
);
7355 /* Parse asm goto labels, a GNU extension.
7359 asm-goto-operands , identifier
7363 c_parser_asm_goto_operands (c_parser
*parser
)
7365 tree list
= NULL_TREE
;
7370 if (c_parser_next_token_is (parser
, CPP_NAME
))
7372 c_token
*tok
= c_parser_peek_token (parser
);
7374 label
= lookup_label_for_goto (tok
->location
, name
);
7375 c_parser_consume_token (parser
);
7376 TREE_USED (label
) = 1;
7380 c_parser_error (parser
, "expected identifier");
7384 name
= build_string (IDENTIFIER_LENGTH (name
),
7385 IDENTIFIER_POINTER (name
));
7386 list
= tree_cons (name
, label
, list
);
7387 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7388 c_parser_consume_token (parser
);
7390 return nreverse (list
);
7394 /* Parse a possibly concatenated sequence of string literals.
7395 TRANSLATE says whether to translate them to the execution character
7396 set; WIDE_OK says whether any kind of prefixed string literal is
7397 permitted in this context. This code is based on that in
7401 c_parser_string_literal (c_parser
*parser
, bool translate
, bool wide_ok
)
7405 struct obstack str_ob
;
7406 struct obstack loc_ob
;
7407 cpp_string str
, istr
, *strs
;
7409 location_t loc
, last_tok_loc
;
7410 enum cpp_ttype type
;
7411 tree value
, string_tree
;
7413 tok
= c_parser_peek_token (parser
);
7414 loc
= tok
->location
;
7415 last_tok_loc
= linemap_resolve_location (line_table
, loc
,
7416 LRK_MACRO_DEFINITION_LOCATION
,
7425 case CPP_UTF8STRING
:
7426 string_tree
= tok
->value
;
7430 c_parser_error (parser
, "expected string literal");
7432 ret
.value
= NULL_TREE
;
7433 ret
.original_code
= ERROR_MARK
;
7434 ret
.original_type
= NULL_TREE
;
7438 /* Try to avoid the overhead of creating and destroying an obstack
7439 for the common case of just one string. */
7440 switch (c_parser_peek_2nd_token (parser
)->type
)
7443 c_parser_consume_token (parser
);
7444 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7445 str
.len
= TREE_STRING_LENGTH (string_tree
);
7454 case CPP_UTF8STRING
:
7455 gcc_obstack_init (&str_ob
);
7456 gcc_obstack_init (&loc_ob
);
7460 c_parser_consume_token (parser
);
7462 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7463 str
.len
= TREE_STRING_LENGTH (string_tree
);
7464 if (type
!= tok
->type
)
7466 if (type
== CPP_STRING
)
7468 else if (tok
->type
!= CPP_STRING
)
7469 error ("unsupported non-standard concatenation "
7470 "of string literals");
7472 obstack_grow (&str_ob
, &str
, sizeof (cpp_string
));
7473 obstack_grow (&loc_ob
, &last_tok_loc
, sizeof (location_t
));
7474 tok
= c_parser_peek_token (parser
);
7475 string_tree
= tok
->value
;
7477 = linemap_resolve_location (line_table
, tok
->location
,
7478 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
7480 while (tok
->type
== CPP_STRING
7481 || tok
->type
== CPP_WSTRING
7482 || tok
->type
== CPP_STRING16
7483 || tok
->type
== CPP_STRING32
7484 || tok
->type
== CPP_UTF8STRING
);
7485 strs
= (cpp_string
*) obstack_finish (&str_ob
);
7488 if (count
> 1 && !in_system_header_at (input_location
))
7489 warning (OPT_Wtraditional
,
7490 "traditional C rejects string constant concatenation");
7492 if ((type
== CPP_STRING
|| wide_ok
)
7494 ? cpp_interpret_string
: cpp_interpret_string_notranslate
)
7495 (parse_in
, strs
, count
, &istr
, type
)))
7497 value
= build_string (istr
.len
, (const char *) istr
.text
);
7498 free (CONST_CAST (unsigned char *, istr
.text
));
7501 location_t
*locs
= (location_t
*) obstack_finish (&loc_ob
);
7502 gcc_assert (g_string_concat_db
);
7503 g_string_concat_db
->record_string_concatenation (count
, locs
);
7508 if (type
!= CPP_STRING
&& !wide_ok
)
7510 error_at (loc
, "a wide string is invalid in this context");
7513 /* Callers cannot generally handle error_mark_node in this
7514 context, so return the empty string instead. An error has
7515 been issued, either above or from cpp_interpret_string. */
7520 case CPP_UTF8STRING
:
7521 value
= build_string (1, "");
7524 value
= build_string (TYPE_PRECISION (char16_type_node
)
7525 / TYPE_PRECISION (char_type_node
),
7526 "\0"); /* char16_t is 16 bits */
7529 value
= build_string (TYPE_PRECISION (char32_type_node
)
7530 / TYPE_PRECISION (char_type_node
),
7531 "\0\0\0"); /* char32_t is 32 bits */
7534 value
= build_string (TYPE_PRECISION (wchar_type_node
)
7535 / TYPE_PRECISION (char_type_node
),
7536 "\0\0\0"); /* widest supported wchar_t
7546 case CPP_UTF8STRING
:
7547 TREE_TYPE (value
) = char_array_type_node
;
7550 TREE_TYPE (value
) = char16_array_type_node
;
7553 TREE_TYPE (value
) = char32_array_type_node
;
7556 TREE_TYPE (value
) = wchar_array_type_node
;
7558 value
= fix_string_type (value
);
7562 obstack_free (&str_ob
, 0);
7563 obstack_free (&loc_ob
, 0);
7567 ret
.original_code
= STRING_CST
;
7568 ret
.original_type
= NULL_TREE
;
7569 set_c_expr_source_range (&ret
, get_range_from_loc (line_table
, loc
));
7570 parser
->seen_string_literal
= true;
7574 /* Parse an expression other than a compound expression; that is, an
7575 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7576 AFTER is not NULL then it is an Objective-C message expression which
7577 is the primary-expression starting the expression as an initializer.
7579 assignment-expression:
7580 conditional-expression
7581 unary-expression assignment-operator assignment-expression
7583 assignment-operator: one of
7584 = *= /= %= += -= <<= >>= &= ^= |=
7586 In GNU C we accept any conditional expression on the LHS and
7587 diagnose the invalid lvalue rather than producing a syntax
7590 static struct c_expr
7591 c_parser_expr_no_commas (c_parser
*parser
, struct c_expr
*after
,
7592 tree omp_atomic_lhs
)
7594 struct c_expr lhs
, rhs
, ret
;
7595 enum tree_code code
;
7596 location_t op_location
, exp_location
;
7597 bool save_in_omp_for
= c_in_omp_for
;
7598 c_in_omp_for
= false;
7599 gcc_assert (!after
|| c_dialect_objc ());
7600 lhs
= c_parser_conditional_expression (parser
, after
, omp_atomic_lhs
);
7601 op_location
= c_parser_peek_token (parser
)->location
;
7602 switch (c_parser_peek_token (parser
)->type
)
7611 code
= TRUNC_DIV_EXPR
;
7614 code
= TRUNC_MOD_EXPR
;
7629 code
= BIT_AND_EXPR
;
7632 code
= BIT_XOR_EXPR
;
7635 code
= BIT_IOR_EXPR
;
7638 c_in_omp_for
= save_in_omp_for
;
7641 c_parser_consume_token (parser
);
7642 exp_location
= c_parser_peek_token (parser
)->location
;
7643 rhs
= c_parser_expr_no_commas (parser
, NULL
);
7644 rhs
= convert_lvalue_to_rvalue (exp_location
, rhs
, true, true);
7646 ret
.value
= build_modify_expr (op_location
, lhs
.value
, lhs
.original_type
,
7647 code
, exp_location
, rhs
.value
,
7649 set_c_expr_source_range (&ret
, lhs
.get_start (), rhs
.get_finish ());
7650 if (code
== NOP_EXPR
)
7651 ret
.original_code
= MODIFY_EXPR
;
7654 TREE_NO_WARNING (ret
.value
) = 1;
7655 ret
.original_code
= ERROR_MARK
;
7657 ret
.original_type
= NULL
;
7658 c_in_omp_for
= save_in_omp_for
;
7662 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7663 AFTER is not NULL then it is an Objective-C message expression which is
7664 the primary-expression starting the expression as an initializer.
7666 conditional-expression:
7667 logical-OR-expression
7668 logical-OR-expression ? expression : conditional-expression
7672 conditional-expression:
7673 logical-OR-expression ? : conditional-expression
7676 static struct c_expr
7677 c_parser_conditional_expression (c_parser
*parser
, struct c_expr
*after
,
7678 tree omp_atomic_lhs
)
7680 struct c_expr cond
, exp1
, exp2
, ret
;
7681 location_t start
, cond_loc
, colon_loc
;
7683 gcc_assert (!after
|| c_dialect_objc ());
7685 cond
= c_parser_binary_expression (parser
, after
, omp_atomic_lhs
);
7687 if (c_parser_next_token_is_not (parser
, CPP_QUERY
))
7689 if (cond
.value
!= error_mark_node
)
7690 start
= cond
.get_start ();
7692 start
= UNKNOWN_LOCATION
;
7693 cond_loc
= c_parser_peek_token (parser
)->location
;
7694 cond
= convert_lvalue_to_rvalue (cond_loc
, cond
, true, true);
7695 c_parser_consume_token (parser
);
7696 if (c_parser_next_token_is (parser
, CPP_COLON
))
7698 tree eptype
= NULL_TREE
;
7700 location_t middle_loc
= c_parser_peek_token (parser
)->location
;
7701 pedwarn (middle_loc
, OPT_Wpedantic
,
7702 "ISO C forbids omitting the middle term of a %<?:%> expression");
7703 if (TREE_CODE (cond
.value
) == EXCESS_PRECISION_EXPR
)
7705 eptype
= TREE_TYPE (cond
.value
);
7706 cond
.value
= TREE_OPERAND (cond
.value
, 0);
7708 tree e
= cond
.value
;
7709 while (TREE_CODE (e
) == COMPOUND_EXPR
)
7710 e
= TREE_OPERAND (e
, 1);
7711 warn_for_omitted_condop (middle_loc
, e
);
7712 /* Make sure first operand is calculated only once. */
7713 exp1
.value
= save_expr (default_conversion (cond
.value
));
7715 exp1
.value
= build1 (EXCESS_PRECISION_EXPR
, eptype
, exp1
.value
);
7716 exp1
.original_type
= NULL
;
7717 exp1
.src_range
= cond
.src_range
;
7718 cond
.value
= c_objc_common_truthvalue_conversion (cond_loc
, exp1
.value
);
7719 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_true_node
;
7724 = c_objc_common_truthvalue_conversion
7725 (cond_loc
, default_conversion (cond
.value
));
7726 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_false_node
;
7727 exp1
= c_parser_expression_conv (parser
);
7728 mark_exp_read (exp1
.value
);
7729 c_inhibit_evaluation_warnings
+=
7730 ((cond
.value
== truthvalue_true_node
)
7731 - (cond
.value
== truthvalue_false_node
));
7734 colon_loc
= c_parser_peek_token (parser
)->location
;
7735 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7737 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7739 ret
.original_code
= ERROR_MARK
;
7740 ret
.original_type
= NULL
;
7744 location_t exp2_loc
= c_parser_peek_token (parser
)->location
;
7745 exp2
= c_parser_conditional_expression (parser
, NULL
, NULL_TREE
);
7746 exp2
= convert_lvalue_to_rvalue (exp2_loc
, exp2
, true, true);
7748 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7749 location_t loc1
= make_location (exp1
.get_start (), exp1
.src_range
);
7750 location_t loc2
= make_location (exp2
.get_start (), exp2
.src_range
);
7751 ret
.value
= build_conditional_expr (colon_loc
, cond
.value
,
7752 cond
.original_code
== C_MAYBE_CONST_EXPR
,
7753 exp1
.value
, exp1
.original_type
, loc1
,
7754 exp2
.value
, exp2
.original_type
, loc2
);
7755 ret
.original_code
= ERROR_MARK
;
7756 if (exp1
.value
== error_mark_node
|| exp2
.value
== error_mark_node
)
7757 ret
.original_type
= NULL
;
7762 /* If both sides are enum type, the default conversion will have
7763 made the type of the result be an integer type. We want to
7764 remember the enum types we started with. */
7765 t1
= exp1
.original_type
? exp1
.original_type
: TREE_TYPE (exp1
.value
);
7766 t2
= exp2
.original_type
? exp2
.original_type
: TREE_TYPE (exp2
.value
);
7767 ret
.original_type
= ((t1
!= error_mark_node
7768 && t2
!= error_mark_node
7769 && (TYPE_MAIN_VARIANT (t1
)
7770 == TYPE_MAIN_VARIANT (t2
)))
7774 set_c_expr_source_range (&ret
, start
, exp2
.get_finish ());
7778 /* Parse a binary expression; that is, a logical-OR-expression (C90
7779 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7780 NULL then it is an Objective-C message expression which is the
7781 primary-expression starting the expression as an initializer.
7783 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7784 when it should be the unfolded lhs. In a valid OpenMP source,
7785 one of the operands of the toplevel binary expression must be equal
7786 to it. In that case, just return a build2 created binary operation
7787 rather than result of parser_build_binary_op.
7789 multiplicative-expression:
7791 multiplicative-expression * cast-expression
7792 multiplicative-expression / cast-expression
7793 multiplicative-expression % cast-expression
7795 additive-expression:
7796 multiplicative-expression
7797 additive-expression + multiplicative-expression
7798 additive-expression - multiplicative-expression
7802 shift-expression << additive-expression
7803 shift-expression >> additive-expression
7805 relational-expression:
7807 relational-expression < shift-expression
7808 relational-expression > shift-expression
7809 relational-expression <= shift-expression
7810 relational-expression >= shift-expression
7812 equality-expression:
7813 relational-expression
7814 equality-expression == relational-expression
7815 equality-expression != relational-expression
7819 AND-expression & equality-expression
7821 exclusive-OR-expression:
7823 exclusive-OR-expression ^ AND-expression
7825 inclusive-OR-expression:
7826 exclusive-OR-expression
7827 inclusive-OR-expression | exclusive-OR-expression
7829 logical-AND-expression:
7830 inclusive-OR-expression
7831 logical-AND-expression && inclusive-OR-expression
7833 logical-OR-expression:
7834 logical-AND-expression
7835 logical-OR-expression || logical-AND-expression
7838 static struct c_expr
7839 c_parser_binary_expression (c_parser
*parser
, struct c_expr
*after
,
7840 tree omp_atomic_lhs
)
7842 /* A binary expression is parsed using operator-precedence parsing,
7843 with the operands being cast expressions. All the binary
7844 operators are left-associative. Thus a binary expression is of
7847 E0 op1 E1 op2 E2 ...
7849 which we represent on a stack. On the stack, the precedence
7850 levels are strictly increasing. When a new operator is
7851 encountered of higher precedence than that at the top of the
7852 stack, it is pushed; its LHS is the top expression, and its RHS
7853 is everything parsed until it is popped. When a new operator is
7854 encountered with precedence less than or equal to that at the top
7855 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7856 by the result of the operation until the operator at the top of
7857 the stack has lower precedence than the new operator or there is
7858 only one element on the stack; then the top expression is the LHS
7859 of the new operator. In the case of logical AND and OR
7860 expressions, we also need to adjust c_inhibit_evaluation_warnings
7861 as appropriate when the operators are pushed and popped. */
7864 /* The expression at this stack level. */
7866 /* The precedence of the operator on its left, PREC_NONE at the
7867 bottom of the stack. */
7868 enum c_parser_prec prec
;
7869 /* The operation on its left. */
7871 /* The source location of this operation. */
7873 /* The sizeof argument if expr.original_code == SIZEOF_EXPR. */
7877 /* Location of the binary operator. */
7878 location_t binary_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
7881 switch (stack[sp].op) \
7883 case TRUTH_ANDIF_EXPR: \
7884 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7885 == truthvalue_false_node); \
7887 case TRUTH_ORIF_EXPR: \
7888 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7889 == truthvalue_true_node); \
7891 case TRUNC_DIV_EXPR: \
7892 if (stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7893 && stack[sp].expr.original_code == SIZEOF_EXPR) \
7895 tree type0 = stack[sp - 1].sizeof_arg; \
7896 tree type1 = stack[sp].sizeof_arg; \
7897 tree first_arg = type0; \
7898 if (!TYPE_P (type0)) \
7899 type0 = TREE_TYPE (type0); \
7900 if (!TYPE_P (type1)) \
7901 type1 = TREE_TYPE (type1); \
7902 if (POINTER_TYPE_P (type0) \
7903 && comptypes (TREE_TYPE (type0), type1) \
7904 && !(TREE_CODE (first_arg) == PARM_DECL \
7905 && C_ARRAY_PARAMETER (first_arg) \
7906 && warn_sizeof_array_argument)) \
7908 auto_diagnostic_group d; \
7909 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7910 "division %<sizeof (%T) / sizeof (%T)%> " \
7911 "does not compute the number of array " \
7914 if (DECL_P (first_arg)) \
7915 inform (DECL_SOURCE_LOCATION (first_arg), \
7916 "first %<sizeof%> operand was declared here"); \
7923 stack[sp - 1].expr \
7924 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7925 stack[sp - 1].expr, true, true); \
7927 = convert_lvalue_to_rvalue (stack[sp].loc, \
7928 stack[sp].expr, true, true); \
7929 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
7930 && c_parser_peek_token (parser)->type == CPP_SEMICOLON \
7931 && ((1 << stack[sp].prec) \
7932 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \
7933 | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \
7934 && stack[sp].op != TRUNC_MOD_EXPR \
7935 && stack[0].expr.value != error_mark_node \
7936 && stack[1].expr.value != error_mark_node \
7937 && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7938 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \
7939 stack[0].expr.value \
7940 = build2 (stack[1].op, TREE_TYPE (stack[0].expr.value), \
7941 stack[0].expr.value, stack[1].expr.value); \
7943 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7945 stack[sp - 1].expr, \
7949 gcc_assert (!after
|| c_dialect_objc ());
7950 stack
[0].loc
= c_parser_peek_token (parser
)->location
;
7951 stack
[0].expr
= c_parser_cast_expression (parser
, after
);
7952 stack
[0].prec
= PREC_NONE
;
7953 stack
[0].sizeof_arg
= c_last_sizeof_arg
;
7957 enum c_parser_prec oprec
;
7958 enum tree_code ocode
;
7959 source_range src_range
;
7962 switch (c_parser_peek_token (parser
)->type
)
7970 ocode
= TRUNC_DIV_EXPR
;
7974 ocode
= TRUNC_MOD_EXPR
;
7986 ocode
= LSHIFT_EXPR
;
7990 ocode
= RSHIFT_EXPR
;
8004 case CPP_GREATER_EQ
:
8017 oprec
= PREC_BITAND
;
8018 ocode
= BIT_AND_EXPR
;
8021 oprec
= PREC_BITXOR
;
8022 ocode
= BIT_XOR_EXPR
;
8026 ocode
= BIT_IOR_EXPR
;
8029 oprec
= PREC_LOGAND
;
8030 ocode
= TRUTH_ANDIF_EXPR
;
8034 ocode
= TRUTH_ORIF_EXPR
;
8037 /* Not a binary operator, so end of the binary
8041 binary_loc
= c_parser_peek_token (parser
)->location
;
8042 while (oprec
<= stack
[sp
].prec
)
8044 c_parser_consume_token (parser
);
8047 case TRUTH_ANDIF_EXPR
:
8048 src_range
= stack
[sp
].expr
.src_range
;
8050 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
8051 stack
[sp
].expr
, true, true);
8052 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
8053 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
8054 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
8055 == truthvalue_false_node
);
8056 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
8058 case TRUTH_ORIF_EXPR
:
8059 src_range
= stack
[sp
].expr
.src_range
;
8061 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
8062 stack
[sp
].expr
, true, true);
8063 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
8064 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
8065 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
8066 == truthvalue_true_node
);
8067 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
8073 stack
[sp
].loc
= binary_loc
;
8074 stack
[sp
].expr
= c_parser_cast_expression (parser
, NULL
);
8075 stack
[sp
].prec
= oprec
;
8076 stack
[sp
].op
= ocode
;
8077 stack
[sp
].sizeof_arg
= c_last_sizeof_arg
;
8082 return stack
[0].expr
;
8086 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8087 is not NULL then it is an Objective-C message expression which is the
8088 primary-expression starting the expression as an initializer.
8092 ( type-name ) unary-expression
8095 static struct c_expr
8096 c_parser_cast_expression (c_parser
*parser
, struct c_expr
*after
)
8098 location_t cast_loc
= c_parser_peek_token (parser
)->location
;
8099 gcc_assert (!after
|| c_dialect_objc ());
8101 return c_parser_postfix_expression_after_primary (parser
,
8103 /* If the expression begins with a parenthesized type name, it may
8104 be either a cast or a compound literal; we need to see whether
8105 the next character is '{' to tell the difference. If not, it is
8106 an unary expression. Full detection of unknown typenames here
8107 would require a 3-token lookahead. */
8108 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8109 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8111 struct c_type_name
*type_name
;
8114 matching_parens parens
;
8115 parens
.consume_open (parser
);
8116 type_name
= c_parser_type_name (parser
, true);
8117 parens
.skip_until_found_close (parser
);
8118 if (type_name
== NULL
)
8121 ret
.original_code
= ERROR_MARK
;
8122 ret
.original_type
= NULL
;
8126 /* Save casted types in the function's used types hash table. */
8127 used_types_insert (type_name
->specs
->type
);
8129 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8130 return c_parser_postfix_expression_after_paren_type (parser
, type_name
,
8132 if (type_name
->specs
->alignas_p
)
8133 error_at (type_name
->specs
->locations
[cdw_alignas
],
8134 "alignment specified for type name in cast");
8136 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
8137 expr
= c_parser_cast_expression (parser
, NULL
);
8138 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
8140 ret
.value
= c_cast_expr (cast_loc
, type_name
, expr
.value
);
8141 if (ret
.value
&& expr
.value
)
8142 set_c_expr_source_range (&ret
, cast_loc
, expr
.get_finish ());
8143 ret
.original_code
= ERROR_MARK
;
8144 ret
.original_type
= NULL
;
8148 return c_parser_unary_expression (parser
);
8151 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8157 unary-operator cast-expression
8158 sizeof unary-expression
8159 sizeof ( type-name )
8161 unary-operator: one of
8167 __alignof__ unary-expression
8168 __alignof__ ( type-name )
8171 (C11 permits _Alignof with type names only.)
8173 unary-operator: one of
8174 __extension__ __real__ __imag__
8176 Transactional Memory:
8179 transaction-expression
8181 In addition, the GNU syntax treats ++ and -- as unary operators, so
8182 they may be applied to cast expressions with errors for non-lvalues
8185 static struct c_expr
8186 c_parser_unary_expression (c_parser
*parser
)
8189 struct c_expr ret
, op
;
8190 location_t op_loc
= c_parser_peek_token (parser
)->location
;
8193 ret
.original_code
= ERROR_MARK
;
8194 ret
.original_type
= NULL
;
8195 switch (c_parser_peek_token (parser
)->type
)
8198 c_parser_consume_token (parser
);
8199 exp_loc
= c_parser_peek_token (parser
)->location
;
8200 op
= c_parser_cast_expression (parser
, NULL
);
8202 op
= default_function_array_read_conversion (exp_loc
, op
);
8203 return parser_build_unary_op (op_loc
, PREINCREMENT_EXPR
, op
);
8204 case CPP_MINUS_MINUS
:
8205 c_parser_consume_token (parser
);
8206 exp_loc
= c_parser_peek_token (parser
)->location
;
8207 op
= c_parser_cast_expression (parser
, NULL
);
8209 op
= default_function_array_read_conversion (exp_loc
, op
);
8210 return parser_build_unary_op (op_loc
, PREDECREMENT_EXPR
, op
);
8212 c_parser_consume_token (parser
);
8213 op
= c_parser_cast_expression (parser
, NULL
);
8214 mark_exp_read (op
.value
);
8215 return parser_build_unary_op (op_loc
, ADDR_EXPR
, op
);
8218 c_parser_consume_token (parser
);
8219 exp_loc
= c_parser_peek_token (parser
)->location
;
8220 op
= c_parser_cast_expression (parser
, NULL
);
8221 finish
= op
.get_finish ();
8222 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8223 location_t combined_loc
= make_location (op_loc
, op_loc
, finish
);
8224 ret
.value
= build_indirect_ref (combined_loc
, op
.value
, RO_UNARY_STAR
);
8225 ret
.src_range
.m_start
= op_loc
;
8226 ret
.src_range
.m_finish
= finish
;
8230 if (!c_dialect_objc () && !in_system_header_at (input_location
))
8233 "traditional C rejects the unary plus operator");
8234 c_parser_consume_token (parser
);
8235 exp_loc
= c_parser_peek_token (parser
)->location
;
8236 op
= c_parser_cast_expression (parser
, NULL
);
8237 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8238 return parser_build_unary_op (op_loc
, CONVERT_EXPR
, op
);
8240 c_parser_consume_token (parser
);
8241 exp_loc
= c_parser_peek_token (parser
)->location
;
8242 op
= c_parser_cast_expression (parser
, NULL
);
8243 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8244 return parser_build_unary_op (op_loc
, NEGATE_EXPR
, op
);
8246 c_parser_consume_token (parser
);
8247 exp_loc
= c_parser_peek_token (parser
)->location
;
8248 op
= c_parser_cast_expression (parser
, NULL
);
8249 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8250 return parser_build_unary_op (op_loc
, BIT_NOT_EXPR
, op
);
8252 c_parser_consume_token (parser
);
8253 exp_loc
= c_parser_peek_token (parser
)->location
;
8254 op
= c_parser_cast_expression (parser
, NULL
);
8255 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8256 return parser_build_unary_op (op_loc
, TRUTH_NOT_EXPR
, op
);
8258 /* Refer to the address of a label as a pointer. */
8259 c_parser_consume_token (parser
);
8260 if (c_parser_next_token_is (parser
, CPP_NAME
))
8262 ret
.value
= finish_label_address_expr
8263 (c_parser_peek_token (parser
)->value
, op_loc
);
8264 set_c_expr_source_range (&ret
, op_loc
,
8265 c_parser_peek_token (parser
)->get_finish ());
8266 c_parser_consume_token (parser
);
8270 c_parser_error (parser
, "expected identifier");
8275 switch (c_parser_peek_token (parser
)->keyword
)
8278 return c_parser_sizeof_expression (parser
);
8280 return c_parser_alignof_expression (parser
);
8281 case RID_BUILTIN_HAS_ATTRIBUTE
:
8282 return c_parser_has_attribute_expression (parser
);
8284 c_parser_consume_token (parser
);
8285 ext
= disable_extension_diagnostics ();
8286 ret
= c_parser_cast_expression (parser
, NULL
);
8287 restore_extension_diagnostics (ext
);
8290 c_parser_consume_token (parser
);
8291 exp_loc
= c_parser_peek_token (parser
)->location
;
8292 op
= c_parser_cast_expression (parser
, NULL
);
8293 op
= default_function_array_conversion (exp_loc
, op
);
8294 return parser_build_unary_op (op_loc
, REALPART_EXPR
, op
);
8296 c_parser_consume_token (parser
);
8297 exp_loc
= c_parser_peek_token (parser
)->location
;
8298 op
= c_parser_cast_expression (parser
, NULL
);
8299 op
= default_function_array_conversion (exp_loc
, op
);
8300 return parser_build_unary_op (op_loc
, IMAGPART_EXPR
, op
);
8301 case RID_TRANSACTION_ATOMIC
:
8302 case RID_TRANSACTION_RELAXED
:
8303 return c_parser_transaction_expression (parser
,
8304 c_parser_peek_token (parser
)->keyword
);
8306 return c_parser_postfix_expression (parser
);
8309 return c_parser_postfix_expression (parser
);
8313 /* Parse a sizeof expression. */
8315 static struct c_expr
8316 c_parser_sizeof_expression (c_parser
*parser
)
8319 struct c_expr result
;
8320 location_t expr_loc
;
8321 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SIZEOF
));
8324 location_t finish
= UNKNOWN_LOCATION
;
8326 start
= c_parser_peek_token (parser
)->location
;
8328 c_parser_consume_token (parser
);
8329 c_inhibit_evaluation_warnings
++;
8331 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8332 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8334 /* Either sizeof ( type-name ) or sizeof unary-expression
8335 starting with a compound literal. */
8336 struct c_type_name
*type_name
;
8337 matching_parens parens
;
8338 parens
.consume_open (parser
);
8339 expr_loc
= c_parser_peek_token (parser
)->location
;
8340 type_name
= c_parser_type_name (parser
, true);
8341 parens
.skip_until_found_close (parser
);
8342 finish
= parser
->tokens_buf
[0].location
;
8343 if (type_name
== NULL
)
8346 c_inhibit_evaluation_warnings
--;
8349 ret
.original_code
= ERROR_MARK
;
8350 ret
.original_type
= NULL
;
8353 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8355 expr
= c_parser_postfix_expression_after_paren_type (parser
,
8358 finish
= expr
.get_finish ();
8361 /* sizeof ( type-name ). */
8362 if (type_name
->specs
->alignas_p
)
8363 error_at (type_name
->specs
->locations
[cdw_alignas
],
8364 "alignment specified for type name in %<sizeof%>");
8365 c_inhibit_evaluation_warnings
--;
8367 result
= c_expr_sizeof_type (expr_loc
, type_name
);
8371 expr_loc
= c_parser_peek_token (parser
)->location
;
8372 expr
= c_parser_unary_expression (parser
);
8373 finish
= expr
.get_finish ();
8375 c_inhibit_evaluation_warnings
--;
8377 mark_exp_read (expr
.value
);
8378 if (TREE_CODE (expr
.value
) == COMPONENT_REF
8379 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
8380 error_at (expr_loc
, "%<sizeof%> applied to a bit-field");
8381 result
= c_expr_sizeof_expr (expr_loc
, expr
);
8383 if (finish
== UNKNOWN_LOCATION
)
8385 set_c_expr_source_range (&result
, start
, finish
);
8389 /* Parse an alignof expression. */
8391 static struct c_expr
8392 c_parser_alignof_expression (c_parser
*parser
)
8395 location_t start_loc
= c_parser_peek_token (parser
)->location
;
8397 tree alignof_spelling
= c_parser_peek_token (parser
)->value
;
8398 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNOF
));
8399 bool is_c11_alignof
= strcmp (IDENTIFIER_POINTER (alignof_spelling
),
8401 /* A diagnostic is not required for the use of this identifier in
8402 the implementation namespace; only diagnose it for the C11
8403 spelling because of existing code using the other spellings. */
8407 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C99 does not support %qE",
8410 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C90 does not support %qE",
8413 c_parser_consume_token (parser
);
8414 c_inhibit_evaluation_warnings
++;
8416 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8417 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8419 /* Either __alignof__ ( type-name ) or __alignof__
8420 unary-expression starting with a compound literal. */
8422 struct c_type_name
*type_name
;
8424 matching_parens parens
;
8425 parens
.consume_open (parser
);
8426 loc
= c_parser_peek_token (parser
)->location
;
8427 type_name
= c_parser_type_name (parser
, true);
8428 end_loc
= c_parser_peek_token (parser
)->location
;
8429 parens
.skip_until_found_close (parser
);
8430 if (type_name
== NULL
)
8433 c_inhibit_evaluation_warnings
--;
8436 ret
.original_code
= ERROR_MARK
;
8437 ret
.original_type
= NULL
;
8440 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8442 expr
= c_parser_postfix_expression_after_paren_type (parser
,
8447 /* alignof ( type-name ). */
8448 if (type_name
->specs
->alignas_p
)
8449 error_at (type_name
->specs
->locations
[cdw_alignas
],
8450 "alignment specified for type name in %qE",
8452 c_inhibit_evaluation_warnings
--;
8454 ret
.value
= c_sizeof_or_alignof_type (loc
, groktypename (type_name
,
8456 false, is_c11_alignof
, 1);
8457 ret
.original_code
= ERROR_MARK
;
8458 ret
.original_type
= NULL
;
8459 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
8465 expr
= c_parser_unary_expression (parser
);
8466 end_loc
= expr
.src_range
.m_finish
;
8468 mark_exp_read (expr
.value
);
8469 c_inhibit_evaluation_warnings
--;
8473 OPT_Wpedantic
, "ISO C does not allow %<%E (expression)%>",
8475 ret
.value
= c_alignof_expr (start_loc
, expr
.value
);
8476 ret
.original_code
= ERROR_MARK
;
8477 ret
.original_type
= NULL
;
8478 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
8483 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8486 static struct c_expr
8487 c_parser_has_attribute_expression (c_parser
*parser
)
8489 gcc_assert (c_parser_next_token_is_keyword (parser
,
8490 RID_BUILTIN_HAS_ATTRIBUTE
));
8491 c_parser_consume_token (parser
);
8493 c_inhibit_evaluation_warnings
++;
8495 matching_parens parens
;
8496 if (!parens
.require_open (parser
))
8498 c_inhibit_evaluation_warnings
--;
8501 struct c_expr result
;
8502 result
.set_error ();
8503 result
.original_code
= ERROR_MARK
;
8504 result
.original_type
= NULL
;
8508 /* Treat the type argument the same way as in typeof for the purposes
8509 of warnings. FIXME: Generalize this so the warning refers to
8510 __builtin_has_attribute rather than typeof. */
8513 /* The first operand: one of DECL, EXPR, or TYPE. */
8514 tree oper
= NULL_TREE
;
8515 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
8517 struct c_type_name
*tname
= c_parser_type_name (parser
);
8521 oper
= groktypename (tname
, NULL
, NULL
);
8522 pop_maybe_used (variably_modified_type_p (oper
, NULL_TREE
));
8527 struct c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
8528 c_inhibit_evaluation_warnings
--;
8530 if (cexpr
.value
!= error_mark_node
)
8532 mark_exp_read (cexpr
.value
);
8534 tree etype
= TREE_TYPE (oper
);
8535 bool was_vm
= variably_modified_type_p (etype
, NULL_TREE
);
8536 /* This is returned with the type so that when the type is
8537 evaluated, this can be evaluated. */
8539 oper
= c_fully_fold (oper
, false, NULL
);
8540 pop_maybe_used (was_vm
);
8544 struct c_expr result
;
8545 result
.original_code
= ERROR_MARK
;
8546 result
.original_type
= NULL
;
8548 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8550 /* Consume the closing parenthesis if that's the next token
8551 in the likely case the built-in was invoked with fewer
8552 than two arguments. */
8553 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8554 c_parser_consume_token (parser
);
8555 c_inhibit_evaluation_warnings
--;
8556 result
.set_error ();
8560 bool save_translate_strings_p
= parser
->translate_strings_p
;
8562 location_t atloc
= c_parser_peek_token (parser
)->location
;
8563 /* Parse a single attribute. Require no leading comma and do not
8564 allow empty attributes. */
8565 tree attr
= c_parser_gnu_attribute (parser
, NULL_TREE
, false, false);
8567 parser
->translate_strings_p
= save_translate_strings_p
;
8569 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8570 c_parser_consume_token (parser
);
8573 c_parser_error (parser
, "expected identifier");
8574 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8576 result
.set_error ();
8582 error_at (atloc
, "expected identifier");
8583 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8585 result
.set_error ();
8589 result
.original_code
= INTEGER_CST
;
8590 result
.original_type
= boolean_type_node
;
8592 if (has_attribute (atloc
, oper
, attr
, default_conversion
))
8593 result
.value
= boolean_true_node
;
8595 result
.value
= boolean_false_node
;
8600 /* Helper function to read arguments of builtins which are interfaces
8601 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8602 others. The name of the builtin is passed using BNAME parameter.
8603 Function returns true if there were no errors while parsing and
8604 stores the arguments in CEXPR_LIST. If it returns true,
8605 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8608 c_parser_get_builtin_args (c_parser
*parser
, const char *bname
,
8609 vec
<c_expr_t
, va_gc
> **ret_cexpr_list
,
8611 location_t
*out_close_paren_loc
)
8613 location_t loc
= c_parser_peek_token (parser
)->location
;
8614 vec
<c_expr_t
, va_gc
> *cexpr_list
;
8616 bool saved_force_folding_builtin_constant_p
;
8618 *ret_cexpr_list
= NULL
;
8619 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
8621 error_at (loc
, "cannot take address of %qs", bname
);
8625 c_parser_consume_token (parser
);
8627 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8629 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
8630 c_parser_consume_token (parser
);
8634 saved_force_folding_builtin_constant_p
8635 = force_folding_builtin_constant_p
;
8636 force_folding_builtin_constant_p
|= choose_expr_p
;
8637 expr
= c_parser_expr_no_commas (parser
, NULL
);
8638 force_folding_builtin_constant_p
8639 = saved_force_folding_builtin_constant_p
;
8640 vec_alloc (cexpr_list
, 1);
8641 vec_safe_push (cexpr_list
, expr
);
8642 while (c_parser_next_token_is (parser
, CPP_COMMA
))
8644 c_parser_consume_token (parser
);
8645 expr
= c_parser_expr_no_commas (parser
, NULL
);
8646 vec_safe_push (cexpr_list
, expr
);
8649 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
8650 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
8653 *ret_cexpr_list
= cexpr_list
;
8657 /* This represents a single generic-association. */
8659 struct c_generic_association
8661 /* The location of the starting token of the type. */
8662 location_t type_location
;
8663 /* The association's type, or NULL_TREE for 'default'. */
8665 /* The association's expression. */
8666 struct c_expr expression
;
8669 /* Parse a generic-selection. (C11 6.5.1.1).
8672 _Generic ( assignment-expression , generic-assoc-list )
8676 generic-assoc-list , generic-association
8678 generic-association:
8679 type-name : assignment-expression
8680 default : assignment-expression
8683 static struct c_expr
8684 c_parser_generic_selection (c_parser
*parser
)
8686 struct c_expr selector
, error_expr
;
8688 struct c_generic_association matched_assoc
;
8689 int match_found
= -1;
8690 location_t generic_loc
, selector_loc
;
8692 error_expr
.original_code
= ERROR_MARK
;
8693 error_expr
.original_type
= NULL
;
8694 error_expr
.set_error ();
8695 matched_assoc
.type_location
= UNKNOWN_LOCATION
;
8696 matched_assoc
.type
= NULL_TREE
;
8697 matched_assoc
.expression
= error_expr
;
8699 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_GENERIC
));
8700 generic_loc
= c_parser_peek_token (parser
)->location
;
8701 c_parser_consume_token (parser
);
8703 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
8704 "ISO C99 does not support %<_Generic%>");
8706 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
8707 "ISO C90 does not support %<_Generic%>");
8709 matching_parens parens
;
8710 if (!parens
.require_open (parser
))
8713 c_inhibit_evaluation_warnings
++;
8714 selector_loc
= c_parser_peek_token (parser
)->location
;
8715 selector
= c_parser_expr_no_commas (parser
, NULL
);
8716 selector
= default_function_array_conversion (selector_loc
, selector
);
8717 c_inhibit_evaluation_warnings
--;
8719 if (selector
.value
== error_mark_node
)
8721 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8724 mark_exp_read (selector
.value
);
8725 selector_type
= TREE_TYPE (selector
.value
);
8726 /* In ISO C terms, rvalues (including the controlling expression of
8727 _Generic) do not have qualified types. */
8728 if (TREE_CODE (selector_type
) != ARRAY_TYPE
)
8729 selector_type
= TYPE_MAIN_VARIANT (selector_type
);
8730 /* In ISO C terms, _Noreturn is not part of the type of expressions
8731 such as &abort, but in GCC it is represented internally as a type
8733 if (FUNCTION_POINTER_TYPE_P (selector_type
)
8734 && TYPE_QUALS (TREE_TYPE (selector_type
)) != TYPE_UNQUALIFIED
)
8736 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type
)));
8738 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8740 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8744 auto_vec
<c_generic_association
> associations
;
8747 struct c_generic_association assoc
, *iter
;
8749 c_token
*token
= c_parser_peek_token (parser
);
8751 assoc
.type_location
= token
->location
;
8752 if (token
->type
== CPP_KEYWORD
&& token
->keyword
== RID_DEFAULT
)
8754 c_parser_consume_token (parser
);
8755 assoc
.type
= NULL_TREE
;
8759 struct c_type_name
*type_name
;
8761 type_name
= c_parser_type_name (parser
);
8762 if (type_name
== NULL
)
8764 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8767 assoc
.type
= groktypename (type_name
, NULL
, NULL
);
8768 if (assoc
.type
== error_mark_node
)
8770 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8774 if (TREE_CODE (assoc
.type
) == FUNCTION_TYPE
)
8775 error_at (assoc
.type_location
,
8776 "%<_Generic%> association has function type");
8777 else if (!COMPLETE_TYPE_P (assoc
.type
))
8778 error_at (assoc
.type_location
,
8779 "%<_Generic%> association has incomplete type");
8781 if (variably_modified_type_p (assoc
.type
, NULL_TREE
))
8782 error_at (assoc
.type_location
,
8783 "%<_Generic%> association has "
8784 "variable length type");
8787 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
8789 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8793 assoc
.expression
= c_parser_expr_no_commas (parser
, NULL
);
8794 if (assoc
.expression
.value
== error_mark_node
)
8796 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8800 for (ix
= 0; associations
.iterate (ix
, &iter
); ++ix
)
8802 if (assoc
.type
== NULL_TREE
)
8804 if (iter
->type
== NULL_TREE
)
8806 error_at (assoc
.type_location
,
8807 "duplicate %<default%> case in %<_Generic%>");
8808 inform (iter
->type_location
, "original %<default%> is here");
8811 else if (iter
->type
!= NULL_TREE
)
8813 if (comptypes (assoc
.type
, iter
->type
))
8815 error_at (assoc
.type_location
,
8816 "%<_Generic%> specifies two compatible types");
8817 inform (iter
->type_location
, "compatible type is here");
8822 if (assoc
.type
== NULL_TREE
)
8824 if (match_found
< 0)
8826 matched_assoc
= assoc
;
8827 match_found
= associations
.length ();
8830 else if (comptypes (assoc
.type
, selector_type
))
8832 if (match_found
< 0 || matched_assoc
.type
== NULL_TREE
)
8834 matched_assoc
= assoc
;
8835 match_found
= associations
.length ();
8839 error_at (assoc
.type_location
,
8840 "%<_Generic%> selector matches multiple associations");
8841 inform (matched_assoc
.type_location
,
8842 "other match is here");
8846 associations
.safe_push (assoc
);
8848 if (c_parser_peek_token (parser
)->type
!= CPP_COMMA
)
8850 c_parser_consume_token (parser
);
8854 struct c_generic_association
*iter
;
8855 FOR_EACH_VEC_ELT (associations
, ix
, iter
)
8856 if (ix
!= (unsigned) match_found
)
8857 mark_exp_read (iter
->expression
.value
);
8859 if (!parens
.require_close (parser
))
8861 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8865 if (match_found
< 0)
8867 error_at (selector_loc
, "%<_Generic%> selector of type %qT is not "
8868 "compatible with any association",
8873 return matched_assoc
.expression
;
8876 /* Check the validity of a function pointer argument *EXPR (argument
8877 position POS) to __builtin_tgmath. Return the number of function
8878 arguments if possibly valid; return 0 having reported an error if
8882 check_tgmath_function (c_expr
*expr
, unsigned int pos
)
8884 tree type
= TREE_TYPE (expr
->value
);
8885 if (!FUNCTION_POINTER_TYPE_P (type
))
8887 error_at (expr
->get_location (),
8888 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8892 type
= TREE_TYPE (type
);
8893 if (!prototype_p (type
))
8895 error_at (expr
->get_location (),
8896 "argument %u of %<__builtin_tgmath%> is unprototyped", pos
);
8899 if (stdarg_p (type
))
8901 error_at (expr
->get_location (),
8902 "argument %u of %<__builtin_tgmath%> has variable arguments",
8906 unsigned int nargs
= 0;
8907 function_args_iterator iter
;
8909 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
8911 if (t
== void_type_node
)
8917 error_at (expr
->get_location (),
8918 "argument %u of %<__builtin_tgmath%> has no arguments", pos
);
8924 /* Ways in which a parameter or return value of a type-generic macro
8925 may vary between the different functions the macro may call. */
8926 enum tgmath_parm_kind
8928 tgmath_fixed
, tgmath_real
, tgmath_complex
8931 /* Helper function for c_parser_postfix_expression. Parse predefined
8934 static struct c_expr
8935 c_parser_predefined_identifier (c_parser
*parser
)
8937 location_t loc
= c_parser_peek_token (parser
)->location
;
8938 switch (c_parser_peek_token (parser
)->keyword
)
8940 case RID_FUNCTION_NAME
:
8941 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
8942 "identifier", "__FUNCTION__");
8944 case RID_PRETTY_FUNCTION_NAME
:
8945 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
8946 "identifier", "__PRETTY_FUNCTION__");
8948 case RID_C99_FUNCTION_NAME
:
8949 pedwarn_c90 (loc
, OPT_Wpedantic
, "ISO C90 does not support "
8950 "%<__func__%> predefined identifier");
8957 expr
.original_code
= ERROR_MARK
;
8958 expr
.original_type
= NULL
;
8959 expr
.value
= fname_decl (loc
, c_parser_peek_token (parser
)->keyword
,
8960 c_parser_peek_token (parser
)->value
);
8961 set_c_expr_source_range (&expr
, loc
, loc
);
8962 c_parser_consume_token (parser
);
8966 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8967 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8968 call c_parser_postfix_expression_after_paren_type on encountering them.
8972 postfix-expression [ expression ]
8973 postfix-expression ( argument-expression-list[opt] )
8974 postfix-expression . identifier
8975 postfix-expression -> identifier
8976 postfix-expression ++
8977 postfix-expression --
8978 ( type-name ) { initializer-list }
8979 ( type-name ) { initializer-list , }
8981 argument-expression-list:
8983 argument-expression-list , argument-expression
8996 (treated as a keyword in GNU C)
8999 ( compound-statement )
9000 __builtin_va_arg ( assignment-expression , type-name )
9001 __builtin_offsetof ( type-name , offsetof-member-designator )
9002 __builtin_choose_expr ( assignment-expression ,
9003 assignment-expression ,
9004 assignment-expression )
9005 __builtin_types_compatible_p ( type-name , type-name )
9006 __builtin_tgmath ( expr-list )
9007 __builtin_complex ( assignment-expression , assignment-expression )
9008 __builtin_shuffle ( assignment-expression , assignment-expression )
9009 __builtin_shuffle ( assignment-expression ,
9010 assignment-expression ,
9011 assignment-expression, )
9012 __builtin_convertvector ( assignment-expression , type-name )
9014 offsetof-member-designator:
9016 offsetof-member-designator . identifier
9017 offsetof-member-designator [ expression ]
9022 [ objc-receiver objc-message-args ]
9023 @selector ( objc-selector-arg )
9024 @protocol ( identifier )
9025 @encode ( type-name )
9027 Classname . identifier
9030 static struct c_expr
9031 c_parser_postfix_expression (c_parser
*parser
)
9033 struct c_expr expr
, e1
;
9034 struct c_type_name
*t1
, *t2
;
9035 location_t loc
= c_parser_peek_token (parser
)->location
;
9036 source_range tok_range
= c_parser_peek_token (parser
)->get_range ();
9037 expr
.original_code
= ERROR_MARK
;
9038 expr
.original_type
= NULL
;
9039 switch (c_parser_peek_token (parser
)->type
)
9042 expr
.value
= c_parser_peek_token (parser
)->value
;
9043 set_c_expr_source_range (&expr
, tok_range
);
9044 loc
= c_parser_peek_token (parser
)->location
;
9045 c_parser_consume_token (parser
);
9046 if (TREE_CODE (expr
.value
) == FIXED_CST
9047 && !targetm
.fixed_point_supported_p ())
9049 error_at (loc
, "fixed-point types not supported for this target");
9058 expr
.value
= c_parser_peek_token (parser
)->value
;
9059 /* For the purpose of warning when a pointer is compared with
9060 a zero character constant. */
9061 expr
.original_type
= char_type_node
;
9062 set_c_expr_source_range (&expr
, tok_range
);
9063 c_parser_consume_token (parser
);
9069 case CPP_UTF8STRING
:
9070 expr
= c_parser_string_literal (parser
, parser
->translate_strings_p
,
9073 case CPP_OBJC_STRING
:
9074 gcc_assert (c_dialect_objc ());
9076 = objc_build_string_object (c_parser_peek_token (parser
)->value
);
9077 set_c_expr_source_range (&expr
, tok_range
);
9078 c_parser_consume_token (parser
);
9081 switch (c_parser_peek_token (parser
)->id_kind
)
9085 tree id
= c_parser_peek_token (parser
)->value
;
9086 c_parser_consume_token (parser
);
9087 expr
.value
= build_external_ref (loc
, id
,
9088 (c_parser_peek_token (parser
)->type
9090 &expr
.original_type
);
9091 set_c_expr_source_range (&expr
, tok_range
);
9094 case C_ID_CLASSNAME
:
9096 /* Here we parse the Objective-C 2.0 Class.name dot
9098 tree class_name
= c_parser_peek_token (parser
)->value
;
9100 c_parser_consume_token (parser
);
9101 gcc_assert (c_dialect_objc ());
9102 if (!c_parser_require (parser
, CPP_DOT
, "expected %<.%>"))
9107 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9109 c_parser_error (parser
, "expected identifier");
9113 c_token
*component_tok
= c_parser_peek_token (parser
);
9114 component
= component_tok
->value
;
9115 location_t end_loc
= component_tok
->get_finish ();
9116 c_parser_consume_token (parser
);
9117 expr
.value
= objc_build_class_component_ref (class_name
,
9119 set_c_expr_source_range (&expr
, loc
, end_loc
);
9123 c_parser_error (parser
, "expected expression");
9128 case CPP_OPEN_PAREN
:
9129 /* A parenthesized expression, statement expression or compound
9131 if (c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_BRACE
)
9133 /* A statement expression. */
9135 location_t brace_loc
;
9136 c_parser_consume_token (parser
);
9137 brace_loc
= c_parser_peek_token (parser
)->location
;
9138 c_parser_consume_token (parser
);
9139 /* If we've not yet started the current function's statement list,
9140 or we're in the parameter scope of an old-style function
9141 declaration, statement expressions are not allowed. */
9142 if (!building_stmt_list_p () || old_style_parameter_scope ())
9144 error_at (loc
, "braced-group within expression allowed "
9145 "only inside a function");
9146 parser
->error
= true;
9147 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
9148 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9152 stmt
= c_begin_stmt_expr ();
9153 c_parser_compound_statement_nostart (parser
);
9154 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9155 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9157 pedwarn (loc
, OPT_Wpedantic
,
9158 "ISO C forbids braced-groups within expressions");
9159 expr
.value
= c_finish_stmt_expr (brace_loc
, stmt
);
9160 set_c_expr_source_range (&expr
, loc
, close_loc
);
9161 mark_exp_read (expr
.value
);
9165 /* A parenthesized expression. */
9166 location_t loc_open_paren
= c_parser_peek_token (parser
)->location
;
9167 c_parser_consume_token (parser
);
9168 expr
= c_parser_expression (parser
);
9169 if (TREE_CODE (expr
.value
) == MODIFY_EXPR
)
9170 TREE_NO_WARNING (expr
.value
) = 1;
9171 if (expr
.original_code
!= C_MAYBE_CONST_EXPR
9172 && expr
.original_code
!= SIZEOF_EXPR
)
9173 expr
.original_code
= ERROR_MARK
;
9174 /* Don't change EXPR.ORIGINAL_TYPE. */
9175 location_t loc_close_paren
= c_parser_peek_token (parser
)->location
;
9176 set_c_expr_source_range (&expr
, loc_open_paren
, loc_close_paren
);
9177 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9178 "expected %<)%>", loc_open_paren
);
9182 switch (c_parser_peek_token (parser
)->keyword
)
9184 case RID_FUNCTION_NAME
:
9185 case RID_PRETTY_FUNCTION_NAME
:
9186 case RID_C99_FUNCTION_NAME
:
9187 expr
= c_parser_predefined_identifier (parser
);
9191 location_t start_loc
= loc
;
9192 c_parser_consume_token (parser
);
9193 matching_parens parens
;
9194 if (!parens
.require_open (parser
))
9199 e1
= c_parser_expr_no_commas (parser
, NULL
);
9200 mark_exp_read (e1
.value
);
9201 e1
.value
= c_fully_fold (e1
.value
, false, NULL
);
9202 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9204 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9208 loc
= c_parser_peek_token (parser
)->location
;
9209 t1
= c_parser_type_name (parser
);
9210 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9211 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9219 tree type_expr
= NULL_TREE
;
9220 expr
.value
= c_build_va_arg (start_loc
, e1
.value
, loc
,
9221 groktypename (t1
, &type_expr
, NULL
));
9224 expr
.value
= build2 (C_MAYBE_CONST_EXPR
,
9225 TREE_TYPE (expr
.value
), type_expr
,
9227 C_MAYBE_CONST_EXPR_NON_CONST (expr
.value
) = true;
9229 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
9235 c_parser_consume_token (parser
);
9236 matching_parens parens
;
9237 if (!parens
.require_open (parser
))
9242 t1
= c_parser_type_name (parser
);
9244 parser
->error
= true;
9245 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9246 gcc_assert (parser
->error
);
9249 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9253 tree type
= groktypename (t1
, NULL
, NULL
);
9255 if (type
== error_mark_node
)
9256 offsetof_ref
= error_mark_node
;
9259 offsetof_ref
= build1 (INDIRECT_REF
, type
, null_pointer_node
);
9260 SET_EXPR_LOCATION (offsetof_ref
, loc
);
9262 /* Parse the second argument to __builtin_offsetof. We
9263 must have one identifier, and beyond that we want to
9264 accept sub structure and sub array references. */
9265 if (c_parser_next_token_is (parser
, CPP_NAME
))
9267 c_token
*comp_tok
= c_parser_peek_token (parser
);
9268 offsetof_ref
= build_component_ref
9269 (loc
, offsetof_ref
, comp_tok
->value
, comp_tok
->location
);
9270 c_parser_consume_token (parser
);
9271 while (c_parser_next_token_is (parser
, CPP_DOT
)
9272 || c_parser_next_token_is (parser
,
9274 || c_parser_next_token_is (parser
,
9277 if (c_parser_next_token_is (parser
, CPP_DEREF
))
9279 loc
= c_parser_peek_token (parser
)->location
;
9280 offsetof_ref
= build_array_ref (loc
,
9285 else if (c_parser_next_token_is (parser
, CPP_DOT
))
9288 c_parser_consume_token (parser
);
9289 if (c_parser_next_token_is_not (parser
,
9292 c_parser_error (parser
, "expected identifier");
9295 c_token
*comp_tok
= c_parser_peek_token (parser
);
9296 offsetof_ref
= build_component_ref
9297 (loc
, offsetof_ref
, comp_tok
->value
,
9298 comp_tok
->location
);
9299 c_parser_consume_token (parser
);
9305 loc
= c_parser_peek_token (parser
)->location
;
9306 c_parser_consume_token (parser
);
9307 ce
= c_parser_expression (parser
);
9308 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
9310 idx
= c_fully_fold (idx
, false, NULL
);
9311 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
9313 offsetof_ref
= build_array_ref (loc
, offsetof_ref
, idx
);
9318 c_parser_error (parser
, "expected identifier");
9319 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9320 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9322 expr
.value
= fold_offsetof (offsetof_ref
);
9323 set_c_expr_source_range (&expr
, loc
, end_loc
);
9326 case RID_CHOOSE_EXPR
:
9328 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9329 c_expr_t
*e1_p
, *e2_p
, *e3_p
;
9331 location_t close_paren_loc
;
9333 c_parser_consume_token (parser
);
9334 if (!c_parser_get_builtin_args (parser
,
9335 "__builtin_choose_expr",
9343 if (vec_safe_length (cexpr_list
) != 3)
9345 error_at (loc
, "wrong number of arguments to "
9346 "%<__builtin_choose_expr%>");
9351 e1_p
= &(*cexpr_list
)[0];
9352 e2_p
= &(*cexpr_list
)[1];
9353 e3_p
= &(*cexpr_list
)[2];
9356 mark_exp_read (e2_p
->value
);
9357 mark_exp_read (e3_p
->value
);
9358 if (TREE_CODE (c
) != INTEGER_CST
9359 || !INTEGRAL_TYPE_P (TREE_TYPE (c
)))
9361 "first argument to %<__builtin_choose_expr%> not"
9363 constant_expression_warning (c
);
9364 expr
= integer_zerop (c
) ? *e3_p
: *e2_p
;
9365 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9368 case RID_TYPES_COMPATIBLE_P
:
9370 c_parser_consume_token (parser
);
9371 matching_parens parens
;
9372 if (!parens
.require_open (parser
))
9377 t1
= c_parser_type_name (parser
);
9383 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9385 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9389 t2
= c_parser_type_name (parser
);
9395 location_t close_paren_loc
= c_parser_peek_token (parser
)->location
;
9396 parens
.skip_until_found_close (parser
);
9398 e1
= groktypename (t1
, NULL
, NULL
);
9399 e2
= groktypename (t2
, NULL
, NULL
);
9400 if (e1
== error_mark_node
|| e2
== error_mark_node
)
9406 e1
= TYPE_MAIN_VARIANT (e1
);
9407 e2
= TYPE_MAIN_VARIANT (e2
);
9410 = comptypes (e1
, e2
) ? integer_one_node
: integer_zero_node
;
9411 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9414 case RID_BUILTIN_TGMATH
:
9416 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9417 location_t close_paren_loc
;
9419 c_parser_consume_token (parser
);
9420 if (!c_parser_get_builtin_args (parser
,
9429 if (vec_safe_length (cexpr_list
) < 3)
9431 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9438 FOR_EACH_VEC_ELT (*cexpr_list
, i
, p
)
9439 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
9440 unsigned int nargs
= check_tgmath_function (&(*cexpr_list
)[0], 1);
9446 if (vec_safe_length (cexpr_list
) < nargs
)
9448 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9452 unsigned int num_functions
= vec_safe_length (cexpr_list
) - nargs
;
9453 if (num_functions
< 2)
9455 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9460 /* The first NUM_FUNCTIONS expressions are the function
9461 pointers. The remaining NARGS expressions are the
9462 arguments that are to be passed to one of those
9463 functions, chosen following <tgmath.h> rules. */
9464 for (unsigned int j
= 1; j
< num_functions
; j
++)
9466 unsigned int this_nargs
9467 = check_tgmath_function (&(*cexpr_list
)[j
], j
+ 1);
9468 if (this_nargs
== 0)
9473 if (this_nargs
!= nargs
)
9475 error_at ((*cexpr_list
)[j
].get_location (),
9476 "argument %u of %<__builtin_tgmath%> has "
9477 "wrong number of arguments", j
+ 1);
9483 /* The functions all have the same number of arguments.
9484 Determine whether arguments and return types vary in
9485 ways permitted for <tgmath.h> functions. */
9486 /* The first entry in each of these vectors is for the
9487 return type, subsequent entries for parameter
9489 auto_vec
<enum tgmath_parm_kind
> parm_kind (nargs
+ 1);
9490 auto_vec
<tree
> parm_first (nargs
+ 1);
9491 auto_vec
<bool> parm_complex (nargs
+ 1);
9492 auto_vec
<bool> parm_varies (nargs
+ 1);
9493 tree first_type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[0].value
));
9494 tree first_ret
= TYPE_MAIN_VARIANT (TREE_TYPE (first_type
));
9495 parm_first
.quick_push (first_ret
);
9496 parm_complex
.quick_push (TREE_CODE (first_ret
) == COMPLEX_TYPE
);
9497 parm_varies
.quick_push (false);
9498 function_args_iterator iter
;
9500 unsigned int argpos
;
9501 FOREACH_FUNCTION_ARGS (first_type
, t
, iter
)
9503 if (t
== void_type_node
)
9505 parm_first
.quick_push (TYPE_MAIN_VARIANT (t
));
9506 parm_complex
.quick_push (TREE_CODE (t
) == COMPLEX_TYPE
);
9507 parm_varies
.quick_push (false);
9509 for (unsigned int j
= 1; j
< num_functions
; j
++)
9511 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9512 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
9513 if (ret
!= parm_first
[0])
9515 parm_varies
[0] = true;
9516 if (!SCALAR_FLOAT_TYPE_P (parm_first
[0])
9517 && !COMPLEX_FLOAT_TYPE_P (parm_first
[0]))
9519 error_at ((*cexpr_list
)[0].get_location (),
9520 "invalid type-generic return type for "
9521 "argument %u of %<__builtin_tgmath%>",
9526 if (!SCALAR_FLOAT_TYPE_P (ret
)
9527 && !COMPLEX_FLOAT_TYPE_P (ret
))
9529 error_at ((*cexpr_list
)[j
].get_location (),
9530 "invalid type-generic return type for "
9531 "argument %u of %<__builtin_tgmath%>",
9537 if (TREE_CODE (ret
) == COMPLEX_TYPE
)
9538 parm_complex
[0] = true;
9540 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9542 if (t
== void_type_node
)
9544 t
= TYPE_MAIN_VARIANT (t
);
9545 if (t
!= parm_first
[argpos
])
9547 parm_varies
[argpos
] = true;
9548 if (!SCALAR_FLOAT_TYPE_P (parm_first
[argpos
])
9549 && !COMPLEX_FLOAT_TYPE_P (parm_first
[argpos
]))
9551 error_at ((*cexpr_list
)[0].get_location (),
9552 "invalid type-generic type for "
9553 "argument %u of argument %u of "
9554 "%<__builtin_tgmath%>", argpos
, 1);
9558 if (!SCALAR_FLOAT_TYPE_P (t
)
9559 && !COMPLEX_FLOAT_TYPE_P (t
))
9561 error_at ((*cexpr_list
)[j
].get_location (),
9562 "invalid type-generic type for "
9563 "argument %u of argument %u of "
9564 "%<__builtin_tgmath%>", argpos
, j
+ 1);
9569 if (TREE_CODE (t
) == COMPLEX_TYPE
)
9570 parm_complex
[argpos
] = true;
9574 enum tgmath_parm_kind max_variation
= tgmath_fixed
;
9575 for (unsigned int j
= 0; j
<= nargs
; j
++)
9577 enum tgmath_parm_kind this_kind
;
9580 if (parm_complex
[j
])
9581 max_variation
= this_kind
= tgmath_complex
;
9584 this_kind
= tgmath_real
;
9585 if (max_variation
!= tgmath_complex
)
9586 max_variation
= tgmath_real
;
9590 this_kind
= tgmath_fixed
;
9591 parm_kind
.quick_push (this_kind
);
9593 if (max_variation
== tgmath_fixed
)
9595 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
9596 "all have the same type");
9601 /* Identify a parameter (not the return type) that varies,
9602 including with complex types if any variation includes
9603 complex types; there must be at least one such
9605 unsigned int tgarg
= 0;
9606 for (unsigned int j
= 1; j
<= nargs
; j
++)
9607 if (parm_kind
[j
] == max_variation
)
9614 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
9615 "lack type-generic parameter");
9620 /* Determine the type of the relevant parameter for each
9622 auto_vec
<tree
> tg_type (num_functions
);
9623 for (unsigned int j
= 0; j
< num_functions
; j
++)
9625 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9627 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9629 if (argpos
== tgarg
)
9631 tg_type
.quick_push (TYPE_MAIN_VARIANT (t
));
9638 /* Verify that the corresponding types are different for
9639 all the listed functions. Also determine whether all
9640 the types are complex, whether all the types are
9641 standard or binary, and whether all the types are
9643 bool all_complex
= true;
9644 bool all_binary
= true;
9645 bool all_decimal
= true;
9646 hash_set
<tree
> tg_types
;
9647 FOR_EACH_VEC_ELT (tg_type
, i
, t
)
9649 if (TREE_CODE (t
) == COMPLEX_TYPE
)
9650 all_decimal
= false;
9653 all_complex
= false;
9654 if (DECIMAL_FLOAT_TYPE_P (t
))
9657 all_decimal
= false;
9659 if (tg_types
.add (t
))
9661 error_at ((*cexpr_list
)[i
].get_location (),
9662 "duplicate type-generic parameter type for "
9663 "function argument %u of %<__builtin_tgmath%>",
9670 /* Verify that other parameters and the return type whose
9671 types vary have their types varying in the correct
9673 for (unsigned int j
= 0; j
< num_functions
; j
++)
9675 tree exp_type
= tg_type
[j
];
9676 tree exp_real_type
= exp_type
;
9677 if (TREE_CODE (exp_type
) == COMPLEX_TYPE
)
9678 exp_real_type
= TREE_TYPE (exp_type
);
9679 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9680 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
9681 if ((parm_kind
[0] == tgmath_complex
&& ret
!= exp_type
)
9682 || (parm_kind
[0] == tgmath_real
&& ret
!= exp_real_type
))
9684 error_at ((*cexpr_list
)[j
].get_location (),
9685 "bad return type for function argument %u "
9686 "of %<__builtin_tgmath%>", j
+ 1);
9691 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9693 if (t
== void_type_node
)
9695 t
= TYPE_MAIN_VARIANT (t
);
9696 if ((parm_kind
[argpos
] == tgmath_complex
9698 || (parm_kind
[argpos
] == tgmath_real
9699 && t
!= exp_real_type
))
9701 error_at ((*cexpr_list
)[j
].get_location (),
9702 "bad type for argument %u of "
9703 "function argument %u of "
9704 "%<__builtin_tgmath%>", argpos
, j
+ 1);
9712 /* The functions listed are a valid set of functions for a
9713 <tgmath.h> macro to select between. Identify the
9714 matching function, if any. First, the argument types
9715 must be combined following <tgmath.h> rules. Integer
9716 types are treated as _Decimal64 if any type-generic
9717 argument is decimal, or if the only alternatives for
9718 type-generic arguments are of decimal types, and are
9719 otherwise treated as double (or _Complex double for
9720 complex integer types, or _Float64 or _Complex _Float64
9721 if all the return types are the same _FloatN or
9722 _FloatNx type). After that adjustment, types are
9723 combined following the usual arithmetic conversions.
9724 If the function only accepts complex arguments, a
9725 complex type is produced. */
9726 bool arg_complex
= all_complex
;
9727 bool arg_binary
= all_binary
;
9728 bool arg_int_decimal
= all_decimal
;
9729 for (unsigned int j
= 1; j
<= nargs
; j
++)
9731 if (parm_kind
[j
] == tgmath_fixed
)
9733 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9734 tree type
= TREE_TYPE (ce
->value
);
9735 if (!INTEGRAL_TYPE_P (type
)
9736 && !SCALAR_FLOAT_TYPE_P (type
)
9737 && TREE_CODE (type
) != COMPLEX_TYPE
)
9739 error_at (ce
->get_location (),
9740 "invalid type of argument %u of type-generic "
9745 if (DECIMAL_FLOAT_TYPE_P (type
))
9747 arg_int_decimal
= true;
9750 error_at (ce
->get_location (),
9751 "decimal floating-point argument %u to "
9752 "complex-only type-generic function", j
);
9756 else if (all_binary
)
9758 error_at (ce
->get_location (),
9759 "decimal floating-point argument %u to "
9760 "binary-only type-generic function", j
);
9764 else if (arg_complex
)
9766 error_at (ce
->get_location (),
9767 "both complex and decimal floating-point "
9768 "arguments to type-generic function");
9772 else if (arg_binary
)
9774 error_at (ce
->get_location (),
9775 "both binary and decimal floating-point "
9776 "arguments to type-generic function");
9781 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
9784 if (COMPLEX_FLOAT_TYPE_P (type
))
9788 error_at (ce
->get_location (),
9789 "complex argument %u to "
9790 "decimal-only type-generic function", j
);
9794 else if (arg_int_decimal
)
9796 error_at (ce
->get_location (),
9797 "both complex and decimal floating-point "
9798 "arguments to type-generic function");
9803 else if (SCALAR_FLOAT_TYPE_P (type
))
9808 error_at (ce
->get_location (),
9809 "binary argument %u to "
9810 "decimal-only type-generic function", j
);
9814 else if (arg_int_decimal
)
9816 error_at (ce
->get_location (),
9817 "both binary and decimal floating-point "
9818 "arguments to type-generic function");
9824 /* For a macro rounding its result to a narrower type, map
9825 integer types to _Float64 not double if the return type
9826 is a _FloatN or _FloatNx type. */
9827 bool arg_int_float64
= false;
9828 if (parm_kind
[0] == tgmath_fixed
9829 && SCALAR_FLOAT_TYPE_P (parm_first
[0])
9830 && float64_type_node
!= NULL_TREE
)
9831 for (unsigned int j
= 0; j
< NUM_FLOATN_NX_TYPES
; j
++)
9832 if (parm_first
[0] == FLOATN_TYPE_NODE (j
))
9834 arg_int_float64
= true;
9837 tree arg_real
= NULL_TREE
;
9838 for (unsigned int j
= 1; j
<= nargs
; j
++)
9840 if (parm_kind
[j
] == tgmath_fixed
)
9842 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9843 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (ce
->value
));
9844 if (TREE_CODE (type
) == COMPLEX_TYPE
)
9845 type
= TREE_TYPE (type
);
9846 if (INTEGRAL_TYPE_P (type
))
9847 type
= (arg_int_decimal
9848 ? dfloat64_type_node
9851 : double_type_node
);
9852 if (arg_real
== NULL_TREE
)
9855 arg_real
= common_type (arg_real
, type
);
9856 if (arg_real
== error_mark_node
)
9862 tree arg_type
= (arg_complex
9863 ? build_complex_type (arg_real
)
9866 /* Look for a function to call with type-generic parameter
9868 c_expr_t
*fn
= NULL
;
9869 for (unsigned int j
= 0; j
< num_functions
; j
++)
9871 if (tg_type
[j
] == arg_type
)
9873 fn
= &(*cexpr_list
)[j
];
9878 && parm_kind
[0] == tgmath_fixed
9879 && SCALAR_FLOAT_TYPE_P (parm_first
[0]))
9881 /* Presume this is a macro that rounds its result to a
9882 narrower type, and look for the first function with
9883 at least the range and precision of the argument
9885 for (unsigned int j
= 0; j
< num_functions
; j
++)
9888 != (TREE_CODE (tg_type
[j
]) == COMPLEX_TYPE
))
9890 tree real_tg_type
= (arg_complex
9891 ? TREE_TYPE (tg_type
[j
])
9893 if (DECIMAL_FLOAT_TYPE_P (arg_real
)
9894 != DECIMAL_FLOAT_TYPE_P (real_tg_type
))
9896 scalar_float_mode arg_mode
9897 = SCALAR_FLOAT_TYPE_MODE (arg_real
);
9898 scalar_float_mode tg_mode
9899 = SCALAR_FLOAT_TYPE_MODE (real_tg_type
);
9900 const real_format
*arg_fmt
= REAL_MODE_FORMAT (arg_mode
);
9901 const real_format
*tg_fmt
= REAL_MODE_FORMAT (tg_mode
);
9902 if (arg_fmt
->b
== tg_fmt
->b
9903 && arg_fmt
->p
<= tg_fmt
->p
9904 && arg_fmt
->emax
<= tg_fmt
->emax
9905 && (arg_fmt
->emin
- arg_fmt
->p
9906 >= tg_fmt
->emin
- tg_fmt
->p
))
9908 fn
= &(*cexpr_list
)[j
];
9915 error_at (loc
, "no matching function for type-generic call");
9920 /* Construct a call to FN. */
9921 vec
<tree
, va_gc
> *args
;
9922 vec_alloc (args
, nargs
);
9923 vec
<tree
, va_gc
> *origtypes
;
9924 vec_alloc (origtypes
, nargs
);
9925 auto_vec
<location_t
> arg_loc (nargs
);
9926 for (unsigned int j
= 0; j
< nargs
; j
++)
9928 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
];
9929 args
->quick_push (ce
->value
);
9930 arg_loc
.quick_push (ce
->get_location ());
9931 origtypes
->quick_push (ce
->original_type
);
9933 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fn
->value
,
9935 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9938 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN
:
9940 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9943 location_t close_paren_loc
;
9945 c_parser_consume_token (parser
);
9946 if (!c_parser_get_builtin_args (parser
,
9947 "__builtin_call_with_static_chain",
9954 if (vec_safe_length (cexpr_list
) != 2)
9956 error_at (loc
, "wrong number of arguments to "
9957 "%<__builtin_call_with_static_chain%>");
9962 expr
= (*cexpr_list
)[0];
9963 e2_p
= &(*cexpr_list
)[1];
9964 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
9965 chain_value
= e2_p
->value
;
9966 mark_exp_read (chain_value
);
9968 if (TREE_CODE (expr
.value
) != CALL_EXPR
)
9969 error_at (loc
, "first argument to "
9970 "%<__builtin_call_with_static_chain%> "
9971 "must be a call expression");
9972 else if (TREE_CODE (TREE_TYPE (chain_value
)) != POINTER_TYPE
)
9973 error_at (loc
, "second argument to "
9974 "%<__builtin_call_with_static_chain%> "
9975 "must be a pointer type");
9977 CALL_EXPR_STATIC_CHAIN (expr
.value
) = chain_value
;
9978 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9981 case RID_BUILTIN_COMPLEX
:
9983 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9984 c_expr_t
*e1_p
, *e2_p
;
9985 location_t close_paren_loc
;
9987 c_parser_consume_token (parser
);
9988 if (!c_parser_get_builtin_args (parser
,
9989 "__builtin_complex",
9997 if (vec_safe_length (cexpr_list
) != 2)
9999 error_at (loc
, "wrong number of arguments to "
10000 "%<__builtin_complex%>");
10005 e1_p
= &(*cexpr_list
)[0];
10006 e2_p
= &(*cexpr_list
)[1];
10008 *e1_p
= convert_lvalue_to_rvalue (loc
, *e1_p
, true, true);
10009 if (TREE_CODE (e1_p
->value
) == EXCESS_PRECISION_EXPR
)
10010 e1_p
->value
= convert (TREE_TYPE (e1_p
->value
),
10011 TREE_OPERAND (e1_p
->value
, 0));
10012 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
10013 if (TREE_CODE (e2_p
->value
) == EXCESS_PRECISION_EXPR
)
10014 e2_p
->value
= convert (TREE_TYPE (e2_p
->value
),
10015 TREE_OPERAND (e2_p
->value
, 0));
10016 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
10017 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
10018 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
))
10019 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
)))
10021 error_at (loc
, "%<__builtin_complex%> operand "
10022 "not of real binary floating-point type");
10026 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p
->value
))
10027 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p
->value
)))
10030 "%<__builtin_complex%> operands of different types");
10034 pedwarn_c90 (loc
, OPT_Wpedantic
,
10035 "ISO C90 does not support complex types");
10036 expr
.value
= build2_loc (loc
, COMPLEX_EXPR
,
10039 (TREE_TYPE (e1_p
->value
))),
10040 e1_p
->value
, e2_p
->value
);
10041 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10044 case RID_BUILTIN_SHUFFLE
:
10046 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10049 location_t close_paren_loc
;
10051 c_parser_consume_token (parser
);
10052 if (!c_parser_get_builtin_args (parser
,
10053 "__builtin_shuffle",
10054 &cexpr_list
, false,
10061 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
10062 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
10064 if (vec_safe_length (cexpr_list
) == 2)
10065 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10067 (*cexpr_list
)[1].value
);
10069 else if (vec_safe_length (cexpr_list
) == 3)
10070 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10071 (*cexpr_list
)[1].value
,
10072 (*cexpr_list
)[2].value
);
10075 error_at (loc
, "wrong number of arguments to "
10076 "%<__builtin_shuffle%>");
10079 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10082 case RID_BUILTIN_CONVERTVECTOR
:
10084 location_t start_loc
= loc
;
10085 c_parser_consume_token (parser
);
10086 matching_parens parens
;
10087 if (!parens
.require_open (parser
))
10092 e1
= c_parser_expr_no_commas (parser
, NULL
);
10093 mark_exp_read (e1
.value
);
10094 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10096 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10100 loc
= c_parser_peek_token (parser
)->location
;
10101 t1
= c_parser_type_name (parser
);
10102 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10103 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10109 tree type_expr
= NULL_TREE
;
10110 expr
.value
= c_build_vec_convert (start_loc
, e1
.value
, loc
,
10111 groktypename (t1
, &type_expr
,
10113 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10117 case RID_AT_SELECTOR
:
10119 gcc_assert (c_dialect_objc ());
10120 c_parser_consume_token (parser
);
10121 matching_parens parens
;
10122 if (!parens
.require_open (parser
))
10127 tree sel
= c_parser_objc_selector_arg (parser
);
10128 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10129 parens
.skip_until_found_close (parser
);
10130 expr
.value
= objc_build_selector_expr (loc
, sel
);
10131 set_c_expr_source_range (&expr
, loc
, close_loc
);
10134 case RID_AT_PROTOCOL
:
10136 gcc_assert (c_dialect_objc ());
10137 c_parser_consume_token (parser
);
10138 matching_parens parens
;
10139 if (!parens
.require_open (parser
))
10144 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10146 c_parser_error (parser
, "expected identifier");
10147 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10151 tree id
= c_parser_peek_token (parser
)->value
;
10152 c_parser_consume_token (parser
);
10153 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10154 parens
.skip_until_found_close (parser
);
10155 expr
.value
= objc_build_protocol_expr (id
);
10156 set_c_expr_source_range (&expr
, loc
, close_loc
);
10159 case RID_AT_ENCODE
:
10161 /* Extension to support C-structures in the archiver. */
10162 gcc_assert (c_dialect_objc ());
10163 c_parser_consume_token (parser
);
10164 matching_parens parens
;
10165 if (!parens
.require_open (parser
))
10170 t1
= c_parser_type_name (parser
);
10174 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10177 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10178 parens
.skip_until_found_close (parser
);
10179 tree type
= groktypename (t1
, NULL
, NULL
);
10180 expr
.value
= objc_build_encode_expr (type
);
10181 set_c_expr_source_range (&expr
, loc
, close_loc
);
10185 expr
= c_parser_generic_selection (parser
);
10188 c_parser_error (parser
, "expected expression");
10193 case CPP_OPEN_SQUARE
:
10194 if (c_dialect_objc ())
10196 tree receiver
, args
;
10197 c_parser_consume_token (parser
);
10198 receiver
= c_parser_objc_receiver (parser
);
10199 args
= c_parser_objc_message_args (parser
);
10200 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10201 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10203 expr
.value
= objc_build_message_expr (receiver
, args
);
10204 set_c_expr_source_range (&expr
, loc
, close_loc
);
10207 /* Else fall through to report error. */
10210 c_parser_error (parser
, "expected expression");
10215 return c_parser_postfix_expression_after_primary
10216 (parser
, EXPR_LOC_OR_LOC (expr
.value
, loc
), expr
);
10219 /* Parse a postfix expression after a parenthesized type name: the
10220 brace-enclosed initializer of a compound literal, possibly followed
10221 by some postfix operators. This is separate because it is not
10222 possible to tell until after the type name whether a cast
10223 expression has a cast or a compound literal, or whether the operand
10224 of sizeof is a parenthesized type name or starts with a compound
10225 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10226 location of the first token after the parentheses around the type
10229 static struct c_expr
10230 c_parser_postfix_expression_after_paren_type (c_parser
*parser
,
10231 struct c_type_name
*type_name
,
10232 location_t type_loc
)
10235 struct c_expr init
;
10237 struct c_expr expr
;
10238 location_t start_loc
;
10239 tree type_expr
= NULL_TREE
;
10240 bool type_expr_const
= true;
10241 check_compound_literal_type (type_loc
, type_name
);
10242 rich_location
richloc (line_table
, type_loc
);
10243 start_init (NULL_TREE
, NULL
, 0, &richloc
);
10244 type
= groktypename (type_name
, &type_expr
, &type_expr_const
);
10245 start_loc
= c_parser_peek_token (parser
)->location
;
10246 if (type
!= error_mark_node
&& C_TYPE_VARIABLE_SIZE (type
))
10248 error_at (type_loc
, "compound literal has variable size");
10249 type
= error_mark_node
;
10251 init
= c_parser_braced_init (parser
, type
, false, NULL
);
10253 maybe_warn_string_init (type_loc
, type
, init
);
10255 if (type
!= error_mark_node
10256 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type
))
10257 && current_function_decl
)
10259 error ("compound literal qualified by address-space qualifier");
10260 type
= error_mark_node
;
10263 pedwarn_c90 (start_loc
, OPT_Wpedantic
, "ISO C90 forbids compound literals");
10264 non_const
= ((init
.value
&& TREE_CODE (init
.value
) == CONSTRUCTOR
)
10265 ? CONSTRUCTOR_NON_CONST (init
.value
)
10266 : init
.original_code
== C_MAYBE_CONST_EXPR
);
10267 non_const
|= !type_expr_const
;
10268 unsigned int alignas_align
= 0;
10269 if (type
!= error_mark_node
10270 && type_name
->specs
->align_log
!= -1)
10272 alignas_align
= 1U << type_name
->specs
->align_log
;
10273 if (alignas_align
< min_align_of_type (type
))
10275 error_at (type_name
->specs
->locations
[cdw_alignas
],
10276 "%<_Alignas%> specifiers cannot reduce "
10277 "alignment of compound literal");
10281 expr
.value
= build_compound_literal (start_loc
, type
, init
.value
, non_const
,
10283 set_c_expr_source_range (&expr
, init
.src_range
);
10284 expr
.original_code
= ERROR_MARK
;
10285 expr
.original_type
= NULL
;
10286 if (type
!= error_mark_node
10287 && expr
.value
!= error_mark_node
10290 if (TREE_CODE (expr
.value
) == C_MAYBE_CONST_EXPR
)
10292 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr
.value
) == NULL_TREE
);
10293 C_MAYBE_CONST_EXPR_PRE (expr
.value
) = type_expr
;
10297 gcc_assert (!non_const
);
10298 expr
.value
= build2 (C_MAYBE_CONST_EXPR
, type
,
10299 type_expr
, expr
.value
);
10302 return c_parser_postfix_expression_after_primary (parser
, start_loc
, expr
);
10305 /* Callback function for sizeof_pointer_memaccess_warning to compare
10309 sizeof_ptr_memacc_comptypes (tree type1
, tree type2
)
10311 return comptypes (type1
, type2
) == 1;
10314 /* Warn for patterns where abs-like function appears to be used incorrectly,
10315 gracefully ignore any non-abs-like function. The warning location should
10316 be LOC. FNDECL is the declaration of called function, it must be a
10317 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10321 warn_for_abs (location_t loc
, tree fndecl
, tree arg
)
10323 /* Avoid warning in unreachable subexpressions. */
10324 if (c_inhibit_evaluation_warnings
)
10327 tree atype
= TREE_TYPE (arg
);
10329 /* Casts from pointers (and thus arrays and fndecls) will generate
10330 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10331 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10332 types and possibly other exotic types. */
10333 if (!INTEGRAL_TYPE_P (atype
)
10334 && !SCALAR_FLOAT_TYPE_P (atype
)
10335 && TREE_CODE (atype
) != COMPLEX_TYPE
)
10338 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
10343 case BUILT_IN_LABS
:
10344 case BUILT_IN_LLABS
:
10345 case BUILT_IN_IMAXABS
:
10346 if (!INTEGRAL_TYPE_P (atype
))
10348 if (SCALAR_FLOAT_TYPE_P (atype
))
10349 warning_at (loc
, OPT_Wabsolute_value
,
10350 "using integer absolute value function %qD when "
10351 "argument is of floating-point type %qT",
10353 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10354 warning_at (loc
, OPT_Wabsolute_value
,
10355 "using integer absolute value function %qD when "
10356 "argument is of complex type %qT", fndecl
, atype
);
10358 gcc_unreachable ();
10361 if (TYPE_UNSIGNED (atype
))
10362 warning_at (loc
, OPT_Wabsolute_value
,
10363 "taking the absolute value of unsigned type %qT "
10364 "has no effect", atype
);
10367 CASE_FLT_FN (BUILT_IN_FABS
):
10368 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS
):
10369 if (!SCALAR_FLOAT_TYPE_P (atype
)
10370 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype
)))
10372 if (INTEGRAL_TYPE_P (atype
))
10373 warning_at (loc
, OPT_Wabsolute_value
,
10374 "using floating-point absolute value function %qD "
10375 "when argument is of integer type %qT", fndecl
, atype
);
10376 else if (DECIMAL_FLOAT_TYPE_P (atype
))
10377 warning_at (loc
, OPT_Wabsolute_value
,
10378 "using floating-point absolute value function %qD "
10379 "when argument is of decimal floating-point type %qT",
10381 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10382 warning_at (loc
, OPT_Wabsolute_value
,
10383 "using floating-point absolute value function %qD when "
10384 "argument is of complex type %qT", fndecl
, atype
);
10386 gcc_unreachable ();
10391 CASE_FLT_FN (BUILT_IN_CABS
):
10392 if (TREE_CODE (atype
) != COMPLEX_TYPE
)
10394 if (INTEGRAL_TYPE_P (atype
))
10395 warning_at (loc
, OPT_Wabsolute_value
,
10396 "using complex absolute value function %qD when "
10397 "argument is of integer type %qT", fndecl
, atype
);
10398 else if (SCALAR_FLOAT_TYPE_P (atype
))
10399 warning_at (loc
, OPT_Wabsolute_value
,
10400 "using complex absolute value function %qD when "
10401 "argument is of floating-point type %qT",
10404 gcc_unreachable ();
10410 case BUILT_IN_FABSD32
:
10411 case BUILT_IN_FABSD64
:
10412 case BUILT_IN_FABSD128
:
10413 if (!DECIMAL_FLOAT_TYPE_P (atype
))
10415 if (INTEGRAL_TYPE_P (atype
))
10416 warning_at (loc
, OPT_Wabsolute_value
,
10417 "using decimal floating-point absolute value "
10418 "function %qD when argument is of integer type %qT",
10420 else if (SCALAR_FLOAT_TYPE_P (atype
))
10421 warning_at (loc
, OPT_Wabsolute_value
,
10422 "using decimal floating-point absolute value "
10423 "function %qD when argument is of floating-point "
10424 "type %qT", fndecl
, atype
);
10425 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10426 warning_at (loc
, OPT_Wabsolute_value
,
10427 "using decimal floating-point absolute value "
10428 "function %qD when argument is of complex type %qT",
10431 gcc_unreachable ();
10440 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl
)))
10443 tree ftype
= TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
10444 if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10446 gcc_assert (TREE_CODE (ftype
) == COMPLEX_TYPE
);
10447 atype
= TREE_TYPE (atype
);
10448 ftype
= TREE_TYPE (ftype
);
10451 if (TYPE_PRECISION (ftype
) < TYPE_PRECISION (atype
))
10452 warning_at (loc
, OPT_Wabsolute_value
,
10453 "absolute value function %qD given an argument of type %qT "
10454 "but has parameter of type %qT which may cause truncation "
10455 "of value", fndecl
, atype
, ftype
);
10459 /* Parse a postfix expression after the initial primary or compound
10460 literal; that is, parse a series of postfix operators.
10462 EXPR_LOC is the location of the primary expression. */
10464 static struct c_expr
10465 c_parser_postfix_expression_after_primary (c_parser
*parser
,
10466 location_t expr_loc
,
10467 struct c_expr expr
)
10469 struct c_expr orig_expr
;
10471 location_t sizeof_arg_loc
[3], comp_loc
;
10472 tree sizeof_arg
[3];
10473 unsigned int literal_zero_mask
;
10475 vec
<tree
, va_gc
> *exprlist
;
10476 vec
<tree
, va_gc
> *origtypes
= NULL
;
10477 vec
<location_t
> arg_loc
= vNULL
;
10483 location_t op_loc
= c_parser_peek_token (parser
)->location
;
10484 switch (c_parser_peek_token (parser
)->type
)
10486 case CPP_OPEN_SQUARE
:
10487 /* Array reference. */
10488 c_parser_consume_token (parser
);
10489 idx
= c_parser_expression (parser
).value
;
10490 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10492 start
= expr
.get_start ();
10493 finish
= parser
->tokens_buf
[0].location
;
10494 expr
.value
= build_array_ref (op_loc
, expr
.value
, idx
);
10495 set_c_expr_source_range (&expr
, start
, finish
);
10496 expr
.original_code
= ERROR_MARK
;
10497 expr
.original_type
= NULL
;
10499 case CPP_OPEN_PAREN
:
10500 /* Function call. */
10502 matching_parens parens
;
10503 parens
.consume_open (parser
);
10504 for (i
= 0; i
< 3; i
++)
10506 sizeof_arg
[i
] = NULL_TREE
;
10507 sizeof_arg_loc
[i
] = UNKNOWN_LOCATION
;
10509 literal_zero_mask
= 0;
10510 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10513 exprlist
= c_parser_expr_list (parser
, true, false, &origtypes
,
10514 sizeof_arg_loc
, sizeof_arg
,
10515 &arg_loc
, &literal_zero_mask
);
10516 parens
.skip_until_found_close (parser
);
10519 mark_exp_read (expr
.value
);
10520 if (warn_sizeof_pointer_memaccess
)
10521 sizeof_pointer_memaccess_warning (sizeof_arg_loc
,
10522 expr
.value
, exprlist
,
10524 sizeof_ptr_memacc_comptypes
);
10525 if (TREE_CODE (expr
.value
) == FUNCTION_DECL
)
10527 if (fndecl_built_in_p (expr
.value
, BUILT_IN_MEMSET
)
10528 && vec_safe_length (exprlist
) == 3)
10530 tree arg0
= (*exprlist
)[0];
10531 tree arg2
= (*exprlist
)[2];
10532 warn_for_memset (expr_loc
, arg0
, arg2
, literal_zero_mask
);
10534 if (warn_absolute_value
10535 && fndecl_built_in_p (expr
.value
, BUILT_IN_NORMAL
)
10536 && vec_safe_length (exprlist
) == 1)
10537 warn_for_abs (expr_loc
, expr
.value
, (*exprlist
)[0]);
10540 start
= expr
.get_start ();
10541 finish
= parser
->tokens_buf
[0].get_finish ();
10543 = c_build_function_call_vec (expr_loc
, arg_loc
, expr
.value
,
10544 exprlist
, origtypes
);
10545 set_c_expr_source_range (&expr
, start
, finish
);
10547 expr
.original_code
= ERROR_MARK
;
10548 if (TREE_CODE (expr
.value
) == INTEGER_CST
10549 && TREE_CODE (orig_expr
.value
) == FUNCTION_DECL
10550 && fndecl_built_in_p (orig_expr
.value
, BUILT_IN_CONSTANT_P
))
10551 expr
.original_code
= C_MAYBE_CONST_EXPR
;
10552 expr
.original_type
= NULL
;
10555 release_tree_vector (exprlist
);
10556 release_tree_vector (origtypes
);
10558 arg_loc
.release ();
10561 /* Structure element reference. */
10562 c_parser_consume_token (parser
);
10563 expr
= default_function_array_conversion (expr_loc
, expr
);
10564 if (c_parser_next_token_is (parser
, CPP_NAME
))
10566 c_token
*comp_tok
= c_parser_peek_token (parser
);
10567 ident
= comp_tok
->value
;
10568 comp_loc
= comp_tok
->location
;
10572 c_parser_error (parser
, "expected identifier");
10574 expr
.original_code
= ERROR_MARK
;
10575 expr
.original_type
= NULL
;
10578 start
= expr
.get_start ();
10579 finish
= c_parser_peek_token (parser
)->get_finish ();
10580 c_parser_consume_token (parser
);
10581 expr
.value
= build_component_ref (op_loc
, expr
.value
, ident
,
10583 set_c_expr_source_range (&expr
, start
, finish
);
10584 expr
.original_code
= ERROR_MARK
;
10585 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
10586 expr
.original_type
= NULL
;
10589 /* Remember the original type of a bitfield. */
10590 tree field
= TREE_OPERAND (expr
.value
, 1);
10591 if (TREE_CODE (field
) != FIELD_DECL
)
10592 expr
.original_type
= NULL
;
10594 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
10598 /* Structure element reference. */
10599 c_parser_consume_token (parser
);
10600 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, false);
10601 if (c_parser_next_token_is (parser
, CPP_NAME
))
10603 c_token
*comp_tok
= c_parser_peek_token (parser
);
10604 ident
= comp_tok
->value
;
10605 comp_loc
= comp_tok
->location
;
10609 c_parser_error (parser
, "expected identifier");
10611 expr
.original_code
= ERROR_MARK
;
10612 expr
.original_type
= NULL
;
10615 start
= expr
.get_start ();
10616 finish
= c_parser_peek_token (parser
)->get_finish ();
10617 c_parser_consume_token (parser
);
10618 expr
.value
= build_component_ref (op_loc
,
10619 build_indirect_ref (op_loc
,
10623 set_c_expr_source_range (&expr
, start
, finish
);
10624 expr
.original_code
= ERROR_MARK
;
10625 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
10626 expr
.original_type
= NULL
;
10629 /* Remember the original type of a bitfield. */
10630 tree field
= TREE_OPERAND (expr
.value
, 1);
10631 if (TREE_CODE (field
) != FIELD_DECL
)
10632 expr
.original_type
= NULL
;
10634 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
10637 case CPP_PLUS_PLUS
:
10638 /* Postincrement. */
10639 start
= expr
.get_start ();
10640 finish
= c_parser_peek_token (parser
)->get_finish ();
10641 c_parser_consume_token (parser
);
10642 expr
= default_function_array_read_conversion (expr_loc
, expr
);
10643 expr
.value
= build_unary_op (op_loc
, POSTINCREMENT_EXPR
,
10644 expr
.value
, false);
10645 set_c_expr_source_range (&expr
, start
, finish
);
10646 expr
.original_code
= ERROR_MARK
;
10647 expr
.original_type
= NULL
;
10649 case CPP_MINUS_MINUS
:
10650 /* Postdecrement. */
10651 start
= expr
.get_start ();
10652 finish
= c_parser_peek_token (parser
)->get_finish ();
10653 c_parser_consume_token (parser
);
10654 expr
= default_function_array_read_conversion (expr_loc
, expr
);
10655 expr
.value
= build_unary_op (op_loc
, POSTDECREMENT_EXPR
,
10656 expr
.value
, false);
10657 set_c_expr_source_range (&expr
, start
, finish
);
10658 expr
.original_code
= ERROR_MARK
;
10659 expr
.original_type
= NULL
;
10667 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10670 assignment-expression
10671 expression , assignment-expression
10674 static struct c_expr
10675 c_parser_expression (c_parser
*parser
)
10677 location_t tloc
= c_parser_peek_token (parser
)->location
;
10678 struct c_expr expr
;
10679 expr
= c_parser_expr_no_commas (parser
, NULL
);
10680 if (c_parser_next_token_is (parser
, CPP_COMMA
))
10681 expr
= convert_lvalue_to_rvalue (tloc
, expr
, true, false);
10682 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10684 struct c_expr next
;
10686 location_t loc
= c_parser_peek_token (parser
)->location
;
10687 location_t expr_loc
;
10688 c_parser_consume_token (parser
);
10689 expr_loc
= c_parser_peek_token (parser
)->location
;
10690 lhsval
= expr
.value
;
10691 while (TREE_CODE (lhsval
) == COMPOUND_EXPR
)
10692 lhsval
= TREE_OPERAND (lhsval
, 1);
10693 if (DECL_P (lhsval
) || handled_component_p (lhsval
))
10694 mark_exp_read (lhsval
);
10695 next
= c_parser_expr_no_commas (parser
, NULL
);
10696 next
= convert_lvalue_to_rvalue (expr_loc
, next
, true, false);
10697 expr
.value
= build_compound_expr (loc
, expr
.value
, next
.value
);
10698 expr
.original_code
= COMPOUND_EXPR
;
10699 expr
.original_type
= next
.original_type
;
10704 /* Parse an expression and convert functions or arrays to pointers and
10705 lvalues to rvalues. */
10707 static struct c_expr
10708 c_parser_expression_conv (c_parser
*parser
)
10710 struct c_expr expr
;
10711 location_t loc
= c_parser_peek_token (parser
)->location
;
10712 expr
= c_parser_expression (parser
);
10713 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, false);
10717 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10718 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10721 c_parser_check_literal_zero (c_parser
*parser
, unsigned *literal_zero_mask
,
10724 if (idx
>= HOST_BITS_PER_INT
)
10727 c_token
*tok
= c_parser_peek_token (parser
);
10736 /* If a parameter is literal zero alone, remember it
10737 for -Wmemset-transposed-args warning. */
10738 if (integer_zerop (tok
->value
)
10739 && !TREE_OVERFLOW (tok
->value
)
10740 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
10741 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
10742 *literal_zero_mask
|= 1U << idx
;
10748 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10749 functions and arrays to pointers and lvalues to rvalues. If
10750 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10751 locations of function arguments into this vector.
10753 nonempty-expr-list:
10754 assignment-expression
10755 nonempty-expr-list , assignment-expression
10758 static vec
<tree
, va_gc
> *
10759 c_parser_expr_list (c_parser
*parser
, bool convert_p
, bool fold_p
,
10760 vec
<tree
, va_gc
> **p_orig_types
,
10761 location_t
*sizeof_arg_loc
, tree
*sizeof_arg
,
10762 vec
<location_t
> *locations
,
10763 unsigned int *literal_zero_mask
)
10765 vec
<tree
, va_gc
> *ret
;
10766 vec
<tree
, va_gc
> *orig_types
;
10767 struct c_expr expr
;
10768 unsigned int idx
= 0;
10770 ret
= make_tree_vector ();
10771 if (p_orig_types
== NULL
)
10774 orig_types
= make_tree_vector ();
10776 if (literal_zero_mask
)
10777 c_parser_check_literal_zero (parser
, literal_zero_mask
, 0);
10778 expr
= c_parser_expr_no_commas (parser
, NULL
);
10780 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true, true);
10782 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
10783 ret
->quick_push (expr
.value
);
10785 orig_types
->quick_push (expr
.original_type
);
10787 locations
->safe_push (expr
.get_location ());
10788 if (sizeof_arg
!= NULL
10789 && expr
.original_code
== SIZEOF_EXPR
)
10791 sizeof_arg
[0] = c_last_sizeof_arg
;
10792 sizeof_arg_loc
[0] = c_last_sizeof_loc
;
10794 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10796 c_parser_consume_token (parser
);
10797 if (literal_zero_mask
)
10798 c_parser_check_literal_zero (parser
, literal_zero_mask
, idx
+ 1);
10799 expr
= c_parser_expr_no_commas (parser
, NULL
);
10801 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true,
10804 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
10805 vec_safe_push (ret
, expr
.value
);
10807 vec_safe_push (orig_types
, expr
.original_type
);
10809 locations
->safe_push (expr
.get_location ());
10811 && sizeof_arg
!= NULL
10812 && expr
.original_code
== SIZEOF_EXPR
)
10814 sizeof_arg
[idx
] = c_last_sizeof_arg
;
10815 sizeof_arg_loc
[idx
] = c_last_sizeof_loc
;
10819 *p_orig_types
= orig_types
;
10823 /* Parse Objective-C-specific constructs. */
10825 /* Parse an objc-class-definition.
10827 objc-class-definition:
10828 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10829 objc-class-instance-variables[opt] objc-methodprotolist @end
10830 @implementation identifier objc-superclass[opt]
10831 objc-class-instance-variables[opt]
10832 @interface identifier ( identifier ) objc-protocol-refs[opt]
10833 objc-methodprotolist @end
10834 @interface identifier ( ) objc-protocol-refs[opt]
10835 objc-methodprotolist @end
10836 @implementation identifier ( identifier )
10841 "@interface identifier (" must start "@interface identifier (
10842 identifier ) ...": objc-methodprotolist in the first production may
10843 not start with a parenthesized identifier as a declarator of a data
10844 definition with no declaration specifiers if the objc-superclass,
10845 objc-protocol-refs and objc-class-instance-variables are omitted. */
10848 c_parser_objc_class_definition (c_parser
*parser
, tree attributes
)
10853 if (c_parser_next_token_is_keyword (parser
, RID_AT_INTERFACE
))
10855 else if (c_parser_next_token_is_keyword (parser
, RID_AT_IMPLEMENTATION
))
10858 gcc_unreachable ();
10860 c_parser_consume_token (parser
);
10861 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10863 c_parser_error (parser
, "expected identifier");
10866 id1
= c_parser_peek_token (parser
)->value
;
10867 c_parser_consume_token (parser
);
10868 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
10870 /* We have a category or class extension. */
10872 tree proto
= NULL_TREE
;
10873 matching_parens parens
;
10874 parens
.consume_open (parser
);
10875 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10877 if (iface_p
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10879 /* We have a class extension. */
10884 c_parser_error (parser
, "expected identifier or %<)%>");
10885 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10891 id2
= c_parser_peek_token (parser
)->value
;
10892 c_parser_consume_token (parser
);
10894 parens
.skip_until_found_close (parser
);
10897 objc_start_category_implementation (id1
, id2
);
10900 if (c_parser_next_token_is (parser
, CPP_LESS
))
10901 proto
= c_parser_objc_protocol_refs (parser
);
10902 objc_start_category_interface (id1
, id2
, proto
, attributes
);
10903 c_parser_objc_methodprotolist (parser
);
10904 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10905 objc_finish_interface ();
10908 if (c_parser_next_token_is (parser
, CPP_COLON
))
10910 c_parser_consume_token (parser
);
10911 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10913 c_parser_error (parser
, "expected identifier");
10916 superclass
= c_parser_peek_token (parser
)->value
;
10917 c_parser_consume_token (parser
);
10920 superclass
= NULL_TREE
;
10923 tree proto
= NULL_TREE
;
10924 if (c_parser_next_token_is (parser
, CPP_LESS
))
10925 proto
= c_parser_objc_protocol_refs (parser
);
10926 objc_start_class_interface (id1
, superclass
, proto
, attributes
);
10929 objc_start_class_implementation (id1
, superclass
);
10930 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
10931 c_parser_objc_class_instance_variables (parser
);
10934 objc_continue_interface ();
10935 c_parser_objc_methodprotolist (parser
);
10936 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10937 objc_finish_interface ();
10941 objc_continue_implementation ();
10946 /* Parse objc-class-instance-variables.
10948 objc-class-instance-variables:
10949 { objc-instance-variable-decl-list[opt] }
10951 objc-instance-variable-decl-list:
10952 objc-visibility-spec
10953 objc-instance-variable-decl ;
10955 objc-instance-variable-decl-list objc-visibility-spec
10956 objc-instance-variable-decl-list objc-instance-variable-decl ;
10957 objc-instance-variable-decl-list ;
10959 objc-visibility-spec:
10964 objc-instance-variable-decl:
10969 c_parser_objc_class_instance_variables (c_parser
*parser
)
10971 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
10972 c_parser_consume_token (parser
);
10973 while (c_parser_next_token_is_not (parser
, CPP_EOF
))
10976 /* Parse any stray semicolon. */
10977 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
10979 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
10980 "extra semicolon");
10981 c_parser_consume_token (parser
);
10984 /* Stop if at the end of the instance variables. */
10985 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
10987 c_parser_consume_token (parser
);
10990 /* Parse any objc-visibility-spec. */
10991 if (c_parser_next_token_is_keyword (parser
, RID_AT_PRIVATE
))
10993 c_parser_consume_token (parser
);
10994 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE
);
10997 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROTECTED
))
10999 c_parser_consume_token (parser
);
11000 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED
);
11003 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PUBLIC
))
11005 c_parser_consume_token (parser
);
11006 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC
);
11009 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PACKAGE
))
11011 c_parser_consume_token (parser
);
11012 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE
);
11015 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
11017 c_parser_pragma (parser
, pragma_external
, NULL
);
11021 /* Parse some comma-separated declarations. */
11022 decls
= c_parser_struct_declaration (parser
);
11025 /* There is a syntax error. We want to skip the offending
11026 tokens up to the next ';' (included) or '}'
11029 /* First, skip manually a ')' or ']'. This is because they
11030 reduce the nesting level, so c_parser_skip_until_found()
11031 wouldn't be able to skip past them. */
11032 c_token
*token
= c_parser_peek_token (parser
);
11033 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_CLOSE_SQUARE
)
11034 c_parser_consume_token (parser
);
11036 /* Then, do the standard skipping. */
11037 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11039 /* We hopefully recovered. Start normal parsing again. */
11040 parser
->error
= false;
11045 /* Comma-separated instance variables are chained together
11046 in reverse order; add them one by one. */
11047 tree ivar
= nreverse (decls
);
11048 for (; ivar
; ivar
= DECL_CHAIN (ivar
))
11049 objc_add_instance_variable (copy_node (ivar
));
11051 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11055 /* Parse an objc-class-declaration.
11057 objc-class-declaration:
11058 @class identifier-list ;
11062 c_parser_objc_class_declaration (c_parser
*parser
)
11064 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_CLASS
));
11065 c_parser_consume_token (parser
);
11066 /* Any identifiers, including those declared as type names, are OK
11071 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11073 c_parser_error (parser
, "expected identifier");
11074 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11075 parser
->error
= false;
11078 id
= c_parser_peek_token (parser
)->value
;
11079 objc_declare_class (id
);
11080 c_parser_consume_token (parser
);
11081 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11082 c_parser_consume_token (parser
);
11086 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11089 /* Parse an objc-alias-declaration.
11091 objc-alias-declaration:
11092 @compatibility_alias identifier identifier ;
11096 c_parser_objc_alias_declaration (c_parser
*parser
)
11099 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_ALIAS
));
11100 c_parser_consume_token (parser
);
11101 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11103 c_parser_error (parser
, "expected identifier");
11104 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11107 id1
= c_parser_peek_token (parser
)->value
;
11108 c_parser_consume_token (parser
);
11109 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11111 c_parser_error (parser
, "expected identifier");
11112 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11115 id2
= c_parser_peek_token (parser
)->value
;
11116 c_parser_consume_token (parser
);
11117 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11118 objc_declare_alias (id1
, id2
);
11121 /* Parse an objc-protocol-definition.
11123 objc-protocol-definition:
11124 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11125 @protocol identifier-list ;
11127 "@protocol identifier ;" should be resolved as "@protocol
11128 identifier-list ;": objc-methodprotolist may not start with a
11129 semicolon in the first alternative if objc-protocol-refs are
11133 c_parser_objc_protocol_definition (c_parser
*parser
, tree attributes
)
11135 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROTOCOL
));
11137 c_parser_consume_token (parser
);
11138 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11140 c_parser_error (parser
, "expected identifier");
11143 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
11144 || c_parser_peek_2nd_token (parser
)->type
== CPP_SEMICOLON
)
11146 /* Any identifiers, including those declared as type names, are
11151 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11153 c_parser_error (parser
, "expected identifier");
11156 id
= c_parser_peek_token (parser
)->value
;
11157 objc_declare_protocol (id
, attributes
);
11158 c_parser_consume_token (parser
);
11159 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11160 c_parser_consume_token (parser
);
11164 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11168 tree id
= c_parser_peek_token (parser
)->value
;
11169 tree proto
= NULL_TREE
;
11170 c_parser_consume_token (parser
);
11171 if (c_parser_next_token_is (parser
, CPP_LESS
))
11172 proto
= c_parser_objc_protocol_refs (parser
);
11173 parser
->objc_pq_context
= true;
11174 objc_start_protocol (id
, proto
, attributes
);
11175 c_parser_objc_methodprotolist (parser
);
11176 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
11177 parser
->objc_pq_context
= false;
11178 objc_finish_interface ();
11182 /* Parse an objc-method-type.
11188 Return true if it is a class method (+) and false if it is
11189 an instance method (-).
11192 c_parser_objc_method_type (c_parser
*parser
)
11194 switch (c_parser_peek_token (parser
)->type
)
11197 c_parser_consume_token (parser
);
11200 c_parser_consume_token (parser
);
11203 gcc_unreachable ();
11207 /* Parse an objc-method-definition.
11209 objc-method-definition:
11210 objc-method-type objc-method-decl ;[opt] compound-statement
11214 c_parser_objc_method_definition (c_parser
*parser
)
11216 bool is_class_method
= c_parser_objc_method_type (parser
);
11217 tree decl
, attributes
= NULL_TREE
, expr
= NULL_TREE
;
11218 parser
->objc_pq_context
= true;
11219 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11221 if (decl
== error_mark_node
)
11222 return; /* Bail here. */
11224 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11226 c_parser_consume_token (parser
);
11227 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11228 "extra semicolon in method definition specified");
11231 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11233 c_parser_error (parser
, "expected %<{%>");
11237 parser
->objc_pq_context
= false;
11238 if (objc_start_method_definition (is_class_method
, decl
, attributes
, expr
))
11240 add_stmt (c_parser_compound_statement (parser
));
11241 objc_finish_method_definition (current_function_decl
);
11245 /* This code is executed when we find a method definition
11246 outside of an @implementation context (or invalid for other
11247 reasons). Parse the method (to keep going) but do not emit
11250 c_parser_compound_statement (parser
);
11254 /* Parse an objc-methodprotolist.
11256 objc-methodprotolist:
11258 objc-methodprotolist objc-methodproto
11259 objc-methodprotolist declaration
11260 objc-methodprotolist ;
11264 The declaration is a data definition, which may be missing
11265 declaration specifiers under the same rules and diagnostics as
11266 other data definitions outside functions, and the stray semicolon
11267 is diagnosed the same way as a stray semicolon outside a
11271 c_parser_objc_methodprotolist (c_parser
*parser
)
11275 /* The list is terminated by @end. */
11276 switch (c_parser_peek_token (parser
)->type
)
11278 case CPP_SEMICOLON
:
11279 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11280 "ISO C does not allow extra %<;%> outside of a function");
11281 c_parser_consume_token (parser
);
11285 c_parser_objc_methodproto (parser
);
11288 c_parser_pragma (parser
, pragma_external
, NULL
);
11293 if (c_parser_next_token_is_keyword (parser
, RID_AT_END
))
11295 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
))
11296 c_parser_objc_at_property_declaration (parser
);
11297 else if (c_parser_next_token_is_keyword (parser
, RID_AT_OPTIONAL
))
11299 objc_set_method_opt (true);
11300 c_parser_consume_token (parser
);
11302 else if (c_parser_next_token_is_keyword (parser
, RID_AT_REQUIRED
))
11304 objc_set_method_opt (false);
11305 c_parser_consume_token (parser
);
11308 c_parser_declaration_or_fndef (parser
, false, false, true,
11309 false, true, NULL
, vNULL
);
11315 /* Parse an objc-methodproto.
11318 objc-method-type objc-method-decl ;
11322 c_parser_objc_methodproto (c_parser
*parser
)
11324 bool is_class_method
= c_parser_objc_method_type (parser
);
11325 tree decl
, attributes
= NULL_TREE
;
11327 /* Remember protocol qualifiers in prototypes. */
11328 parser
->objc_pq_context
= true;
11329 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11331 /* Forget protocol qualifiers now. */
11332 parser
->objc_pq_context
= false;
11334 /* Do not allow the presence of attributes to hide an erroneous
11335 method implementation in the interface section. */
11336 if (!c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11338 c_parser_error (parser
, "expected %<;%>");
11342 if (decl
!= error_mark_node
)
11343 objc_add_method_declaration (is_class_method
, decl
, attributes
);
11345 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11348 /* If we are at a position that method attributes may be present, check that
11349 there are not any parsed already (a syntax error) and then collect any
11350 specified at the current location. Finally, if new attributes were present,
11351 check that the next token is legal ( ';' for decls and '{' for defs). */
11354 c_parser_objc_maybe_method_attributes (c_parser
* parser
, tree
* attributes
)
11359 c_parser_error (parser
,
11360 "method attributes must be specified at the end only");
11361 *attributes
= NULL_TREE
;
11365 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
11366 *attributes
= c_parser_gnu_attributes (parser
);
11368 /* If there were no attributes here, just report any earlier error. */
11369 if (*attributes
== NULL_TREE
|| bad
)
11372 /* If the attributes are followed by a ; or {, then just report any earlier
11374 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
11375 || c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11378 /* We've got attributes, but not at the end. */
11379 c_parser_error (parser
,
11380 "expected %<;%> or %<{%> after method attribute definition");
11384 /* Parse an objc-method-decl.
11387 ( objc-type-name ) objc-selector
11389 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11390 objc-keyword-selector objc-optparmlist
11393 objc-keyword-selector:
11395 objc-keyword-selector objc-keyword-decl
11398 objc-selector : ( objc-type-name ) identifier
11399 objc-selector : identifier
11400 : ( objc-type-name ) identifier
11404 objc-optparms objc-optellipsis
11408 objc-opt-parms , parameter-declaration
11416 c_parser_objc_method_decl (c_parser
*parser
, bool is_class_method
,
11417 tree
*attributes
, tree
*expr
)
11419 tree type
= NULL_TREE
;
11421 tree parms
= NULL_TREE
;
11422 bool ellipsis
= false;
11423 bool attr_err
= false;
11425 *attributes
= NULL_TREE
;
11426 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11428 matching_parens parens
;
11429 parens
.consume_open (parser
);
11430 type
= c_parser_objc_type_name (parser
);
11431 parens
.skip_until_found_close (parser
);
11433 sel
= c_parser_objc_selector (parser
);
11434 /* If there is no selector, or a colon follows, we have an
11435 objc-keyword-selector. If there is a selector, and a colon does
11436 not follow, that selector ends the objc-method-decl. */
11437 if (!sel
|| c_parser_next_token_is (parser
, CPP_COLON
))
11440 tree list
= NULL_TREE
;
11443 tree atype
= NULL_TREE
, id
, keyworddecl
;
11444 tree param_attr
= NULL_TREE
;
11445 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11447 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11449 c_parser_consume_token (parser
);
11450 atype
= c_parser_objc_type_name (parser
);
11451 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
11454 /* New ObjC allows attributes on method parameters. */
11455 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
11456 param_attr
= c_parser_gnu_attributes (parser
);
11457 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11459 c_parser_error (parser
, "expected identifier");
11460 return error_mark_node
;
11462 id
= c_parser_peek_token (parser
)->value
;
11463 c_parser_consume_token (parser
);
11464 keyworddecl
= objc_build_keyword_decl (tsel
, atype
, id
, param_attr
);
11465 list
= chainon (list
, keyworddecl
);
11466 tsel
= c_parser_objc_selector (parser
);
11467 if (!tsel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11471 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
11473 /* Parse the optional parameter list. Optional Objective-C
11474 method parameters follow the C syntax, and may include '...'
11475 to denote a variable number of arguments. */
11476 parms
= make_node (TREE_LIST
);
11477 while (c_parser_next_token_is (parser
, CPP_COMMA
))
11479 struct c_parm
*parm
;
11480 c_parser_consume_token (parser
);
11481 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
11484 c_parser_consume_token (parser
);
11485 attr_err
|= c_parser_objc_maybe_method_attributes
11486 (parser
, attributes
) ;
11489 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
11492 parms
= chainon (parms
,
11493 build_tree_list (NULL_TREE
, grokparm (parm
, expr
)));
11498 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
11502 c_parser_error (parser
, "objective-c method declaration is expected");
11503 return error_mark_node
;
11507 return error_mark_node
;
11509 return objc_build_method_signature (is_class_method
, type
, sel
, parms
, ellipsis
);
11512 /* Parse an objc-type-name.
11515 objc-type-qualifiers[opt] type-name
11516 objc-type-qualifiers[opt]
11518 objc-type-qualifiers:
11519 objc-type-qualifier
11520 objc-type-qualifiers objc-type-qualifier
11522 objc-type-qualifier: one of
11523 in out inout bycopy byref oneway
11527 c_parser_objc_type_name (c_parser
*parser
)
11529 tree quals
= NULL_TREE
;
11530 struct c_type_name
*type_name
= NULL
;
11531 tree type
= NULL_TREE
;
11534 c_token
*token
= c_parser_peek_token (parser
);
11535 if (token
->type
== CPP_KEYWORD
11536 && (token
->keyword
== RID_IN
11537 || token
->keyword
== RID_OUT
11538 || token
->keyword
== RID_INOUT
11539 || token
->keyword
== RID_BYCOPY
11540 || token
->keyword
== RID_BYREF
11541 || token
->keyword
== RID_ONEWAY
))
11543 quals
= chainon (build_tree_list (NULL_TREE
, token
->value
), quals
);
11544 c_parser_consume_token (parser
);
11549 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
11550 type_name
= c_parser_type_name (parser
);
11552 type
= groktypename (type_name
, NULL
, NULL
);
11554 /* If the type is unknown, and error has already been produced and
11555 we need to recover from the error. In that case, use NULL_TREE
11556 for the type, as if no type had been specified; this will use the
11557 default type ('id') which is good for error recovery. */
11558 if (type
== error_mark_node
)
11561 return build_tree_list (quals
, type
);
11564 /* Parse objc-protocol-refs.
11566 objc-protocol-refs:
11567 < identifier-list >
11571 c_parser_objc_protocol_refs (c_parser
*parser
)
11573 tree list
= NULL_TREE
;
11574 gcc_assert (c_parser_next_token_is (parser
, CPP_LESS
));
11575 c_parser_consume_token (parser
);
11576 /* Any identifiers, including those declared as type names, are OK
11581 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11583 c_parser_error (parser
, "expected identifier");
11586 id
= c_parser_peek_token (parser
)->value
;
11587 list
= chainon (list
, build_tree_list (NULL_TREE
, id
));
11588 c_parser_consume_token (parser
);
11589 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11590 c_parser_consume_token (parser
);
11594 c_parser_require (parser
, CPP_GREATER
, "expected %<>%>");
11598 /* Parse an objc-try-catch-finally-statement.
11600 objc-try-catch-finally-statement:
11601 @try compound-statement objc-catch-list[opt]
11602 @try compound-statement objc-catch-list[opt] @finally compound-statement
11605 @catch ( objc-catch-parameter-declaration ) compound-statement
11606 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11608 objc-catch-parameter-declaration:
11609 parameter-declaration
11612 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11614 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11615 for C++. Keep them in sync. */
11618 c_parser_objc_try_catch_finally_statement (c_parser
*parser
)
11620 location_t location
;
11623 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_TRY
));
11624 c_parser_consume_token (parser
);
11625 location
= c_parser_peek_token (parser
)->location
;
11626 objc_maybe_warn_exceptions (location
);
11627 stmt
= c_parser_compound_statement (parser
);
11628 objc_begin_try_stmt (location
, stmt
);
11630 while (c_parser_next_token_is_keyword (parser
, RID_AT_CATCH
))
11632 struct c_parm
*parm
;
11633 tree parameter_declaration
= error_mark_node
;
11634 bool seen_open_paren
= false;
11636 c_parser_consume_token (parser
);
11637 matching_parens parens
;
11638 if (!parens
.require_open (parser
))
11639 seen_open_paren
= true;
11640 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
11642 /* We have "@catch (...)" (where the '...' are literally
11643 what is in the code). Skip the '...'.
11644 parameter_declaration is set to NULL_TREE, and
11645 objc_being_catch_clauses() knows that that means
11647 c_parser_consume_token (parser
);
11648 parameter_declaration
= NULL_TREE
;
11652 /* We have "@catch (NSException *exception)" or something
11653 like that. Parse the parameter declaration. */
11654 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
11656 parameter_declaration
= error_mark_node
;
11658 parameter_declaration
= grokparm (parm
, NULL
);
11660 if (seen_open_paren
)
11661 parens
.require_close (parser
);
11664 /* If there was no open parenthesis, we are recovering from
11665 an error, and we are trying to figure out what mistake
11666 the user has made. */
11668 /* If there is an immediate closing parenthesis, the user
11669 probably forgot the opening one (ie, they typed "@catch
11670 NSException *e)". Parse the closing parenthesis and keep
11672 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
11673 c_parser_consume_token (parser
);
11675 /* If these is no immediate closing parenthesis, the user
11676 probably doesn't know that parenthesis are required at
11677 all (ie, they typed "@catch NSException *e"). So, just
11678 forget about the closing parenthesis and keep going. */
11680 objc_begin_catch_clause (parameter_declaration
);
11681 if (c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
11682 c_parser_compound_statement_nostart (parser
);
11683 objc_finish_catch_clause ();
11685 if (c_parser_next_token_is_keyword (parser
, RID_AT_FINALLY
))
11687 c_parser_consume_token (parser
);
11688 location
= c_parser_peek_token (parser
)->location
;
11689 stmt
= c_parser_compound_statement (parser
);
11690 objc_build_finally_clause (location
, stmt
);
11692 objc_finish_try_stmt ();
11695 /* Parse an objc-synchronized-statement.
11697 objc-synchronized-statement:
11698 @synchronized ( expression ) compound-statement
11702 c_parser_objc_synchronized_statement (c_parser
*parser
)
11706 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNCHRONIZED
));
11707 c_parser_consume_token (parser
);
11708 loc
= c_parser_peek_token (parser
)->location
;
11709 objc_maybe_warn_exceptions (loc
);
11710 matching_parens parens
;
11711 if (parens
.require_open (parser
))
11713 struct c_expr ce
= c_parser_expression (parser
);
11714 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
11716 expr
= c_fully_fold (expr
, false, NULL
);
11717 parens
.skip_until_found_close (parser
);
11720 expr
= error_mark_node
;
11721 stmt
= c_parser_compound_statement (parser
);
11722 objc_build_synchronized (loc
, expr
, stmt
);
11725 /* Parse an objc-selector; return NULL_TREE without an error if the
11726 next token is not an objc-selector.
11731 enum struct union if else while do for switch case default
11732 break continue return goto asm sizeof typeof __alignof
11733 unsigned long const short volatile signed restrict _Complex
11734 in out inout bycopy byref oneway int char float double void _Bool
11737 ??? Why this selection of keywords but not, for example, storage
11738 class specifiers? */
11741 c_parser_objc_selector (c_parser
*parser
)
11743 c_token
*token
= c_parser_peek_token (parser
);
11744 tree value
= token
->value
;
11745 if (token
->type
== CPP_NAME
)
11747 c_parser_consume_token (parser
);
11750 if (token
->type
!= CPP_KEYWORD
)
11752 switch (token
->keyword
)
11791 CASE_RID_FLOATN_NX
:
11795 case RID_AUTO_TYPE
:
11800 c_parser_consume_token (parser
);
11807 /* Parse an objc-selector-arg.
11811 objc-keywordname-list
11813 objc-keywordname-list:
11815 objc-keywordname-list objc-keywordname
11823 c_parser_objc_selector_arg (c_parser
*parser
)
11825 tree sel
= c_parser_objc_selector (parser
);
11826 tree list
= NULL_TREE
;
11828 && c_parser_next_token_is_not (parser
, CPP_COLON
)
11829 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
11833 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
11835 c_parser_consume_token (parser
);
11836 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
11837 list
= chainon (list
, build_tree_list (NULL_TREE
, NULL_TREE
));
11841 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11843 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
11845 sel
= c_parser_objc_selector (parser
);
11847 && c_parser_next_token_is_not (parser
, CPP_COLON
)
11848 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
11854 /* Parse an objc-receiver.
11863 c_parser_objc_receiver (c_parser
*parser
)
11865 location_t loc
= c_parser_peek_token (parser
)->location
;
11867 if (c_parser_peek_token (parser
)->type
== CPP_NAME
11868 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
11869 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
11871 tree id
= c_parser_peek_token (parser
)->value
;
11872 c_parser_consume_token (parser
);
11873 return objc_get_class_reference (id
);
11875 struct c_expr ce
= c_parser_expression (parser
);
11876 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
11877 return c_fully_fold (ce
.value
, false, NULL
);
11880 /* Parse objc-message-args.
11884 objc-keywordarg-list
11886 objc-keywordarg-list:
11888 objc-keywordarg-list objc-keywordarg
11891 objc-selector : objc-keywordexpr
11896 c_parser_objc_message_args (c_parser
*parser
)
11898 tree sel
= c_parser_objc_selector (parser
);
11899 tree list
= NULL_TREE
;
11900 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11905 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11906 return error_mark_node
;
11907 keywordexpr
= c_parser_objc_keywordexpr (parser
);
11908 list
= chainon (list
, build_tree_list (sel
, keywordexpr
));
11909 sel
= c_parser_objc_selector (parser
);
11910 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11916 /* Parse an objc-keywordexpr.
11923 c_parser_objc_keywordexpr (c_parser
*parser
)
11926 vec
<tree
, va_gc
> *expr_list
= c_parser_expr_list (parser
, true, true,
11927 NULL
, NULL
, NULL
, NULL
);
11928 if (vec_safe_length (expr_list
) == 1)
11930 /* Just return the expression, remove a level of
11932 ret
= (*expr_list
)[0];
11936 /* We have a comma expression, we will collapse later. */
11937 ret
= build_tree_list_vec (expr_list
);
11939 release_tree_vector (expr_list
);
11943 /* A check, needed in several places, that ObjC interface, implementation or
11944 method definitions are not prefixed by incorrect items. */
11946 c_parser_objc_diagnose_bad_element_prefix (c_parser
*parser
,
11947 struct c_declspecs
*specs
)
11949 if (!specs
->declspecs_seen_p
|| specs
->non_sc_seen_p
11950 || specs
->typespec_kind
!= ctsk_none
)
11952 c_parser_error (parser
,
11953 "no type or storage class may be specified here,");
11954 c_parser_skip_to_end_of_block_or_statement (parser
);
11960 /* Parse an Objective-C @property declaration. The syntax is:
11962 objc-property-declaration:
11963 '@property' objc-property-attributes[opt] struct-declaration ;
11965 objc-property-attributes:
11966 '(' objc-property-attribute-list ')'
11968 objc-property-attribute-list:
11969 objc-property-attribute
11970 objc-property-attribute-list, objc-property-attribute
11972 objc-property-attribute
11973 'getter' = identifier
11974 'setter' = identifier
11983 @property NSString *name;
11984 @property (readonly) id object;
11985 @property (retain, nonatomic, getter=getTheName) id name;
11986 @property int a, b, c;
11988 PS: This function is identical to cp_parser_objc_at_propery_declaration
11989 for C++. Keep them in sync. */
11991 c_parser_objc_at_property_declaration (c_parser
*parser
)
11993 /* The following variables hold the attributes of the properties as
11994 parsed. They are 'false' or 'NULL_TREE' if the attribute was not
11995 seen. When we see an attribute, we set them to 'true' (if they
11996 are boolean properties) or to the identifier (if they have an
11997 argument, ie, for getter and setter). Note that here we only
11998 parse the list of attributes, check the syntax and accumulate the
11999 attributes that we find. objc_add_property_declaration() will
12000 then process the information. */
12001 bool property_assign
= false;
12002 bool property_copy
= false;
12003 tree property_getter_ident
= NULL_TREE
;
12004 bool property_nonatomic
= false;
12005 bool property_readonly
= false;
12006 bool property_readwrite
= false;
12007 bool property_retain
= false;
12008 tree property_setter_ident
= NULL_TREE
;
12010 /* 'properties' is the list of properties that we read. Usually a
12011 single one, but maybe more (eg, in "@property int a, b, c;" there
12016 loc
= c_parser_peek_token (parser
)->location
;
12017 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
));
12019 c_parser_consume_token (parser
); /* Eat '@property'. */
12021 /* Parse the optional attribute list... */
12022 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
12024 matching_parens parens
;
12027 parens
.consume_open (parser
);
12029 /* Property attribute keywords are valid now. */
12030 parser
->objc_property_attr_context
= true;
12034 bool syntax_error
= false;
12035 c_token
*token
= c_parser_peek_token (parser
);
12038 if (token
->type
!= CPP_KEYWORD
)
12040 if (token
->type
== CPP_CLOSE_PAREN
)
12041 c_parser_error (parser
, "expected identifier");
12044 c_parser_consume_token (parser
);
12045 c_parser_error (parser
, "unknown property attribute");
12049 keyword
= token
->keyword
;
12050 c_parser_consume_token (parser
);
12053 case RID_ASSIGN
: property_assign
= true; break;
12054 case RID_COPY
: property_copy
= true; break;
12055 case RID_NONATOMIC
: property_nonatomic
= true; break;
12056 case RID_READONLY
: property_readonly
= true; break;
12057 case RID_READWRITE
: property_readwrite
= true; break;
12058 case RID_RETAIN
: property_retain
= true; break;
12062 if (c_parser_next_token_is_not (parser
, CPP_EQ
))
12064 if (keyword
== RID_GETTER
)
12065 c_parser_error (parser
,
12066 "missing %<=%> (after %<getter%> attribute)");
12068 c_parser_error (parser
,
12069 "missing %<=%> (after %<setter%> attribute)");
12070 syntax_error
= true;
12073 c_parser_consume_token (parser
); /* eat the = */
12074 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12076 c_parser_error (parser
, "expected identifier");
12077 syntax_error
= true;
12080 if (keyword
== RID_SETTER
)
12082 if (property_setter_ident
!= NULL_TREE
)
12083 c_parser_error (parser
, "the %<setter%> attribute may only be specified once");
12085 property_setter_ident
= c_parser_peek_token (parser
)->value
;
12086 c_parser_consume_token (parser
);
12087 if (c_parser_next_token_is_not (parser
, CPP_COLON
))
12088 c_parser_error (parser
, "setter name must terminate with %<:%>");
12090 c_parser_consume_token (parser
);
12094 if (property_getter_ident
!= NULL_TREE
)
12095 c_parser_error (parser
, "the %<getter%> attribute may only be specified once");
12097 property_getter_ident
= c_parser_peek_token (parser
)->value
;
12098 c_parser_consume_token (parser
);
12102 c_parser_error (parser
, "unknown property attribute");
12103 syntax_error
= true;
12110 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12111 c_parser_consume_token (parser
);
12115 parser
->objc_property_attr_context
= false;
12116 parens
.skip_until_found_close (parser
);
12118 /* ... and the property declaration(s). */
12119 properties
= c_parser_struct_declaration (parser
);
12121 if (properties
== error_mark_node
)
12123 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12124 parser
->error
= false;
12128 if (properties
== NULL_TREE
)
12129 c_parser_error (parser
, "expected identifier");
12132 /* Comma-separated properties are chained together in
12133 reverse order; add them one by one. */
12134 properties
= nreverse (properties
);
12136 for (; properties
; properties
= TREE_CHAIN (properties
))
12137 objc_add_property_declaration (loc
, copy_node (properties
),
12138 property_readonly
, property_readwrite
,
12139 property_assign
, property_retain
,
12140 property_copy
, property_nonatomic
,
12141 property_getter_ident
, property_setter_ident
);
12144 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12145 parser
->error
= false;
12148 /* Parse an Objective-C @synthesize declaration. The syntax is:
12150 objc-synthesize-declaration:
12151 @synthesize objc-synthesize-identifier-list ;
12153 objc-synthesize-identifier-list:
12154 objc-synthesize-identifier
12155 objc-synthesize-identifier-list, objc-synthesize-identifier
12157 objc-synthesize-identifier
12159 identifier = identifier
12162 @synthesize MyProperty;
12163 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12165 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12166 for C++. Keep them in sync.
12169 c_parser_objc_at_synthesize_declaration (c_parser
*parser
)
12171 tree list
= NULL_TREE
;
12173 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNTHESIZE
));
12174 loc
= c_parser_peek_token (parser
)->location
;
12176 c_parser_consume_token (parser
);
12179 tree property
, ivar
;
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 /* Once we find the semicolon, we can resume normal parsing.
12185 We have to reset parser->error manually because
12186 c_parser_skip_until_found() won't reset it for us if the
12187 next token is precisely a semicolon. */
12188 parser
->error
= false;
12191 property
= c_parser_peek_token (parser
)->value
;
12192 c_parser_consume_token (parser
);
12193 if (c_parser_next_token_is (parser
, CPP_EQ
))
12195 c_parser_consume_token (parser
);
12196 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12198 c_parser_error (parser
, "expected identifier");
12199 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12200 parser
->error
= false;
12203 ivar
= c_parser_peek_token (parser
)->value
;
12204 c_parser_consume_token (parser
);
12208 list
= chainon (list
, build_tree_list (ivar
, property
));
12209 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12210 c_parser_consume_token (parser
);
12214 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12215 objc_add_synthesize_declaration (loc
, list
);
12218 /* Parse an Objective-C @dynamic declaration. The syntax is:
12220 objc-dynamic-declaration:
12221 @dynamic identifier-list ;
12224 @dynamic MyProperty;
12225 @dynamic MyProperty, AnotherProperty;
12227 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12228 for C++. Keep them in sync.
12231 c_parser_objc_at_dynamic_declaration (c_parser
*parser
)
12233 tree list
= NULL_TREE
;
12235 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_DYNAMIC
));
12236 loc
= c_parser_peek_token (parser
)->location
;
12238 c_parser_consume_token (parser
);
12242 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12244 c_parser_error (parser
, "expected identifier");
12245 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12246 parser
->error
= false;
12249 property
= c_parser_peek_token (parser
)->value
;
12250 list
= chainon (list
, build_tree_list (NULL_TREE
, property
));
12251 c_parser_consume_token (parser
);
12252 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12253 c_parser_consume_token (parser
);
12257 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12258 objc_add_dynamic_declaration (loc
, list
);
12262 /* Parse a pragma GCC ivdep. */
12265 c_parse_pragma_ivdep (c_parser
*parser
)
12267 c_parser_consume_pragma (parser
);
12268 c_parser_skip_to_pragma_eol (parser
);
12272 /* Parse a pragma GCC unroll. */
12274 static unsigned short
12275 c_parser_pragma_unroll (c_parser
*parser
)
12277 unsigned short unroll
;
12278 c_parser_consume_pragma (parser
);
12279 location_t location
= c_parser_peek_token (parser
)->location
;
12280 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
12281 mark_exp_read (expr
);
12282 expr
= c_fully_fold (expr
, false, NULL
);
12283 HOST_WIDE_INT lunroll
= 0;
12284 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
12285 || TREE_CODE (expr
) != INTEGER_CST
12286 || (lunroll
= tree_to_shwi (expr
)) < 0
12287 || lunroll
>= USHRT_MAX
)
12289 error_at (location
, "%<#pragma GCC unroll%> requires an"
12290 " assignment-expression that evaluates to a non-negative"
12291 " integral constant less than %u", USHRT_MAX
);
12296 unroll
= (unsigned short)lunroll
;
12301 c_parser_skip_to_pragma_eol (parser
);
12305 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12306 should be considered, statements. ALLOW_STMT is true if we're within
12307 the context of a function and such pragmas are to be allowed. Returns
12308 true if we actually parsed such a pragma. */
12311 c_parser_pragma (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
12314 const char *construct
= NULL
;
12316 id
= c_parser_peek_token (parser
)->pragma_kind
;
12317 gcc_assert (id
!= PRAGMA_NONE
);
12321 case PRAGMA_OACC_DECLARE
:
12322 c_parser_oacc_declare (parser
);
12325 case PRAGMA_OACC_ENTER_DATA
:
12326 if (context
!= pragma_compound
)
12328 construct
= "acc enter data";
12330 if (context
== pragma_stmt
)
12332 error_at (c_parser_peek_token (parser
)->location
,
12333 "%<#pragma %s%> may only be used in compound "
12334 "statements", construct
);
12335 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12340 c_parser_oacc_enter_exit_data (parser
, true);
12343 case PRAGMA_OACC_EXIT_DATA
:
12344 if (context
!= pragma_compound
)
12346 construct
= "acc exit data";
12349 c_parser_oacc_enter_exit_data (parser
, false);
12352 case PRAGMA_OACC_ROUTINE
:
12353 if (context
!= pragma_external
)
12355 error_at (c_parser_peek_token (parser
)->location
,
12356 "%<#pragma acc routine%> must be at file scope");
12357 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12360 c_parser_oacc_routine (parser
, context
);
12363 case PRAGMA_OACC_UPDATE
:
12364 if (context
!= pragma_compound
)
12366 construct
= "acc update";
12369 c_parser_oacc_update (parser
);
12372 case PRAGMA_OMP_BARRIER
:
12373 if (context
!= pragma_compound
)
12375 construct
= "omp barrier";
12378 c_parser_omp_barrier (parser
);
12381 case PRAGMA_OMP_DEPOBJ
:
12382 if (context
!= pragma_compound
)
12384 construct
= "omp depobj";
12387 c_parser_omp_depobj (parser
);
12390 case PRAGMA_OMP_FLUSH
:
12391 if (context
!= pragma_compound
)
12393 construct
= "omp flush";
12396 c_parser_omp_flush (parser
);
12399 case PRAGMA_OMP_TASKWAIT
:
12400 if (context
!= pragma_compound
)
12402 construct
= "omp taskwait";
12405 c_parser_omp_taskwait (parser
);
12408 case PRAGMA_OMP_TASKYIELD
:
12409 if (context
!= pragma_compound
)
12411 construct
= "omp taskyield";
12414 c_parser_omp_taskyield (parser
);
12417 case PRAGMA_OMP_CANCEL
:
12418 if (context
!= pragma_compound
)
12420 construct
= "omp cancel";
12423 c_parser_omp_cancel (parser
);
12426 case PRAGMA_OMP_CANCELLATION_POINT
:
12427 c_parser_omp_cancellation_point (parser
, context
);
12430 case PRAGMA_OMP_THREADPRIVATE
:
12431 c_parser_omp_threadprivate (parser
);
12434 case PRAGMA_OMP_TARGET
:
12435 return c_parser_omp_target (parser
, context
, if_p
);
12437 case PRAGMA_OMP_END_DECLARE_TARGET
:
12438 c_parser_omp_end_declare_target (parser
);
12441 case PRAGMA_OMP_SCAN
:
12442 error_at (c_parser_peek_token (parser
)->location
,
12443 "%<#pragma omp scan%> may only be used in "
12444 "a loop construct with %<inscan%> %<reduction%> clause");
12445 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12448 case PRAGMA_OMP_SECTION
:
12449 error_at (c_parser_peek_token (parser
)->location
,
12450 "%<#pragma omp section%> may only be used in "
12451 "%<#pragma omp sections%> construct");
12452 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12455 case PRAGMA_OMP_DECLARE
:
12456 c_parser_omp_declare (parser
, context
);
12459 case PRAGMA_OMP_REQUIRES
:
12460 if (context
!= pragma_external
)
12462 error_at (c_parser_peek_token (parser
)->location
,
12463 "%<#pragma omp requires%> may only be used at file scope");
12464 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12467 c_parser_omp_requires (parser
);
12470 case PRAGMA_OMP_ORDERED
:
12471 return c_parser_omp_ordered (parser
, context
, if_p
);
12475 const bool ivdep
= c_parse_pragma_ivdep (parser
);
12476 unsigned short unroll
;
12477 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_UNROLL
)
12478 unroll
= c_parser_pragma_unroll (parser
);
12481 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12482 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12483 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12485 c_parser_error (parser
, "for, while or do statement expected");
12488 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12489 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12490 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12491 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12493 c_parser_do_statement (parser
, ivdep
, unroll
);
12497 case PRAGMA_UNROLL
:
12499 unsigned short unroll
= c_parser_pragma_unroll (parser
);
12501 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_IVDEP
)
12502 ivdep
= c_parse_pragma_ivdep (parser
);
12505 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12506 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12507 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12509 c_parser_error (parser
, "for, while or do statement expected");
12512 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12513 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12514 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12515 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12517 c_parser_do_statement (parser
, ivdep
, unroll
);
12521 case PRAGMA_GCC_PCH_PREPROCESS
:
12522 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
12523 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12526 case PRAGMA_OACC_WAIT
:
12527 if (context
!= pragma_compound
)
12529 construct
= "acc wait";
12532 /* FALL THROUGH. */
12535 if (id
< PRAGMA_FIRST_EXTERNAL
)
12537 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
12540 c_parser_error (parser
, "expected declaration specifiers");
12541 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12544 c_parser_omp_construct (parser
, if_p
);
12550 c_parser_consume_pragma (parser
);
12551 c_invoke_pragma_handler (id
);
12553 /* Skip to EOL, but suppress any error message. Those will have been
12554 generated by the handler routine through calling error, as opposed
12555 to calling c_parser_error. */
12556 parser
->error
= true;
12557 c_parser_skip_to_pragma_eol (parser
);
12562 /* The interface the pragma parsers have to the lexer. */
12565 pragma_lex (tree
*value
, location_t
*loc
)
12567 c_token
*tok
= c_parser_peek_token (the_parser
);
12568 enum cpp_ttype ret
= tok
->type
;
12570 *value
= tok
->value
;
12572 *loc
= tok
->location
;
12574 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
12576 else if (ret
== CPP_STRING
)
12577 *value
= c_parser_string_literal (the_parser
, false, false).value
;
12580 if (ret
== CPP_KEYWORD
)
12582 c_parser_consume_token (the_parser
);
12589 c_parser_pragma_pch_preprocess (c_parser
*parser
)
12593 parser
->lex_joined_string
= true;
12594 c_parser_consume_pragma (parser
);
12595 if (c_parser_next_token_is (parser
, CPP_STRING
))
12597 name
= c_parser_peek_token (parser
)->value
;
12598 c_parser_consume_token (parser
);
12601 c_parser_error (parser
, "expected string literal");
12602 c_parser_skip_to_pragma_eol (parser
);
12603 parser
->lex_joined_string
= false;
12606 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
12609 /* OpenACC and OpenMP parsing routines. */
12611 /* Returns name of the next clause.
12612 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12613 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12614 returned and the token is consumed. */
12616 static pragma_omp_clause
12617 c_parser_omp_clause_name (c_parser
*parser
)
12619 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
12621 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
12622 result
= PRAGMA_OACC_CLAUSE_AUTO
;
12623 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
12624 result
= PRAGMA_OMP_CLAUSE_IF
;
12625 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
12626 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
12627 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12628 result
= PRAGMA_OMP_CLAUSE_FOR
;
12629 else if (c_parser_next_token_is (parser
, CPP_NAME
))
12631 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
12636 if (!strcmp ("aligned", p
))
12637 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
12638 else if (!strcmp ("async", p
))
12639 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
12640 else if (!strcmp ("attach", p
))
12641 result
= PRAGMA_OACC_CLAUSE_ATTACH
;
12644 if (!strcmp ("bind", p
))
12645 result
= PRAGMA_OMP_CLAUSE_BIND
;
12648 if (!strcmp ("collapse", p
))
12649 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
12650 else if (!strcmp ("copy", p
))
12651 result
= PRAGMA_OACC_CLAUSE_COPY
;
12652 else if (!strcmp ("copyin", p
))
12653 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
12654 else if (!strcmp ("copyout", p
))
12655 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12656 else if (!strcmp ("copyprivate", p
))
12657 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
12658 else if (!strcmp ("create", p
))
12659 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12662 if (!strcmp ("defaultmap", p
))
12663 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
12664 else if (!strcmp ("delete", p
))
12665 result
= PRAGMA_OACC_CLAUSE_DELETE
;
12666 else if (!strcmp ("depend", p
))
12667 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
12668 else if (!strcmp ("detach", p
))
12669 result
= PRAGMA_OACC_CLAUSE_DETACH
;
12670 else if (!strcmp ("device", p
))
12671 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
12672 else if (!strcmp ("deviceptr", p
))
12673 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
12674 else if (!strcmp ("device_resident", p
))
12675 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
12676 else if (!strcmp ("device_type", p
))
12677 result
= PRAGMA_OMP_CLAUSE_DEVICE_TYPE
;
12678 else if (!strcmp ("dist_schedule", p
))
12679 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
12682 if (!strcmp ("final", p
))
12683 result
= PRAGMA_OMP_CLAUSE_FINAL
;
12684 else if (!strcmp ("finalize", p
))
12685 result
= PRAGMA_OACC_CLAUSE_FINALIZE
;
12686 else if (!strcmp ("firstprivate", p
))
12687 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
12688 else if (!strcmp ("from", p
))
12689 result
= PRAGMA_OMP_CLAUSE_FROM
;
12692 if (!strcmp ("gang", p
))
12693 result
= PRAGMA_OACC_CLAUSE_GANG
;
12694 else if (!strcmp ("grainsize", p
))
12695 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
12698 if (!strcmp ("hint", p
))
12699 result
= PRAGMA_OMP_CLAUSE_HINT
;
12700 else if (!strcmp ("host", p
))
12701 result
= PRAGMA_OACC_CLAUSE_HOST
;
12704 if (!strcmp ("if_present", p
))
12705 result
= PRAGMA_OACC_CLAUSE_IF_PRESENT
;
12706 else if (!strcmp ("in_reduction", p
))
12707 result
= PRAGMA_OMP_CLAUSE_IN_REDUCTION
;
12708 else if (!strcmp ("inbranch", p
))
12709 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
12710 else if (!strcmp ("independent", p
))
12711 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
12712 else if (!strcmp ("is_device_ptr", p
))
12713 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
12716 if (!strcmp ("lastprivate", p
))
12717 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
12718 else if (!strcmp ("linear", p
))
12719 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
12720 else if (!strcmp ("link", p
))
12721 result
= PRAGMA_OMP_CLAUSE_LINK
;
12724 if (!strcmp ("map", p
))
12725 result
= PRAGMA_OMP_CLAUSE_MAP
;
12726 else if (!strcmp ("mergeable", p
))
12727 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
12730 if (!strcmp ("no_create", p
))
12731 result
= PRAGMA_OACC_CLAUSE_NO_CREATE
;
12732 else if (!strcmp ("nogroup", p
))
12733 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
12734 else if (!strcmp ("nontemporal", p
))
12735 result
= PRAGMA_OMP_CLAUSE_NONTEMPORAL
;
12736 else if (!strcmp ("notinbranch", p
))
12737 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
12738 else if (!strcmp ("nowait", p
))
12739 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
12740 else if (!strcmp ("num_gangs", p
))
12741 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
12742 else if (!strcmp ("num_tasks", p
))
12743 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
12744 else if (!strcmp ("num_teams", p
))
12745 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
12746 else if (!strcmp ("num_threads", p
))
12747 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
12748 else if (!strcmp ("num_workers", p
))
12749 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
12752 if (!strcmp ("ordered", p
))
12753 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
12754 else if (!strcmp ("order", p
))
12755 result
= PRAGMA_OMP_CLAUSE_ORDER
;
12758 if (!strcmp ("parallel", p
))
12759 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
12760 else if (!strcmp ("present", p
))
12761 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
12762 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12764 else if (!strcmp ("present_or_copy", p
)
12765 || !strcmp ("pcopy", p
))
12766 result
= PRAGMA_OACC_CLAUSE_COPY
;
12767 else if (!strcmp ("present_or_copyin", p
)
12768 || !strcmp ("pcopyin", p
))
12769 result
= PRAGMA_OACC_CLAUSE_COPYIN
;
12770 else if (!strcmp ("present_or_copyout", p
)
12771 || !strcmp ("pcopyout", p
))
12772 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12773 else if (!strcmp ("present_or_create", p
)
12774 || !strcmp ("pcreate", p
))
12775 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12776 else if (!strcmp ("priority", p
))
12777 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
12778 else if (!strcmp ("private", p
))
12779 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
12780 else if (!strcmp ("proc_bind", p
))
12781 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
12784 if (!strcmp ("reduction", p
))
12785 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
12788 if (!strcmp ("safelen", p
))
12789 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
12790 else if (!strcmp ("schedule", p
))
12791 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
12792 else if (!strcmp ("sections", p
))
12793 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
12794 else if (!strcmp ("self", p
)) /* "self" is a synonym for "host". */
12795 result
= PRAGMA_OACC_CLAUSE_HOST
;
12796 else if (!strcmp ("seq", p
))
12797 result
= PRAGMA_OACC_CLAUSE_SEQ
;
12798 else if (!strcmp ("shared", p
))
12799 result
= PRAGMA_OMP_CLAUSE_SHARED
;
12800 else if (!strcmp ("simd", p
))
12801 result
= PRAGMA_OMP_CLAUSE_SIMD
;
12802 else if (!strcmp ("simdlen", p
))
12803 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
12806 if (!strcmp ("task_reduction", p
))
12807 result
= PRAGMA_OMP_CLAUSE_TASK_REDUCTION
;
12808 else if (!strcmp ("taskgroup", p
))
12809 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
12810 else if (!strcmp ("thread_limit", p
))
12811 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
12812 else if (!strcmp ("threads", p
))
12813 result
= PRAGMA_OMP_CLAUSE_THREADS
;
12814 else if (!strcmp ("tile", p
))
12815 result
= PRAGMA_OACC_CLAUSE_TILE
;
12816 else if (!strcmp ("to", p
))
12817 result
= PRAGMA_OMP_CLAUSE_TO
;
12820 if (!strcmp ("uniform", p
))
12821 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
12822 else if (!strcmp ("untied", p
))
12823 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
12824 else if (!strcmp ("use_device", p
))
12825 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
12826 else if (!strcmp ("use_device_addr", p
))
12827 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
;
12828 else if (!strcmp ("use_device_ptr", p
))
12829 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
12832 if (!strcmp ("vector", p
))
12833 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
12834 else if (!strcmp ("vector_length", p
))
12835 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
12838 if (!strcmp ("wait", p
))
12839 result
= PRAGMA_OACC_CLAUSE_WAIT
;
12840 else if (!strcmp ("worker", p
))
12841 result
= PRAGMA_OACC_CLAUSE_WORKER
;
12846 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
12847 c_parser_consume_token (parser
);
12852 /* Validate that a clause of the given type does not already exist. */
12855 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
12858 if (tree c
= omp_find_clause (clauses
, code
))
12859 error_at (OMP_CLAUSE_LOCATION (c
), "too many %qs clauses", name
);
12863 Parse wait clause or wait directive parameters. */
12866 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
12868 vec
<tree
, va_gc
> *args
;
12871 matching_parens parens
;
12872 if (!parens
.require_open (parser
))
12875 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
12876 args_tree
= build_tree_list_vec (args
);
12878 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
12880 tree targ
= TREE_VALUE (t
);
12882 if (targ
!= error_mark_node
)
12884 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
12886 c_parser_error (parser
, "expression must be integral");
12887 targ
= error_mark_node
;
12891 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
12893 OMP_CLAUSE_DECL (c
) = targ
;
12894 OMP_CLAUSE_CHAIN (c
) = list
;
12900 release_tree_vector (args
);
12901 parens
.require_close (parser
);
12905 /* OpenACC 2.0, OpenMP 2.5:
12908 variable-list , identifier
12910 If KIND is nonzero, create the appropriate node and install the
12911 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
12912 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
12914 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
12915 return the list created.
12917 The optional ALLOW_DEREF argument is true if list items can use the deref
12921 c_parser_omp_variable_list (c_parser
*parser
,
12922 location_t clause_loc
,
12923 enum omp_clause_code kind
, tree list
,
12924 bool allow_deref
= false)
12926 auto_vec
<c_token
> tokens
;
12927 unsigned int tokens_avail
= 0;
12932 bool array_section_p
= false;
12933 if (kind
== OMP_CLAUSE_DEPEND
)
12935 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
12936 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
12938 struct c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
12939 if (expr
.value
!= error_mark_node
)
12941 tree u
= build_omp_clause (clause_loc
, kind
);
12942 OMP_CLAUSE_DECL (u
) = expr
.value
;
12943 OMP_CLAUSE_CHAIN (u
) = list
;
12947 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
12950 c_parser_consume_token (parser
);
12955 tokens
.truncate (0);
12956 unsigned int nesting_depth
= 0;
12959 c_token
*token
= c_parser_peek_token (parser
);
12960 switch (token
->type
)
12963 case CPP_PRAGMA_EOL
:
12965 case CPP_OPEN_BRACE
:
12966 case CPP_OPEN_PAREN
:
12967 case CPP_OPEN_SQUARE
:
12970 case CPP_CLOSE_BRACE
:
12971 case CPP_CLOSE_PAREN
:
12972 case CPP_CLOSE_SQUARE
:
12973 if (nesting_depth
-- == 0)
12977 if (nesting_depth
== 0)
12982 tokens
.safe_push (*token
);
12983 c_parser_consume_token (parser
);
12989 /* Make sure nothing tries to read past the end of the tokens. */
12991 memset (&eof_token
, 0, sizeof (eof_token
));
12992 eof_token
.type
= CPP_EOF
;
12993 tokens
.safe_push (eof_token
);
12994 tokens
.safe_push (eof_token
);
12996 tokens_avail
= parser
->tokens_avail
;
12997 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
12998 parser
->tokens
= tokens
.address ();
12999 parser
->tokens_avail
= tokens
.length ();
13002 tree t
= NULL_TREE
;
13004 if (c_parser_next_token_is (parser
, CPP_NAME
)
13005 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
13007 t
= lookup_name (c_parser_peek_token (parser
)->value
);
13009 if (t
== NULL_TREE
)
13011 undeclared_variable (c_parser_peek_token (parser
)->location
,
13012 c_parser_peek_token (parser
)->value
);
13013 t
= error_mark_node
;
13016 c_parser_consume_token (parser
);
13018 else if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
13019 && (c_parser_peek_token (parser
)->keyword
== RID_FUNCTION_NAME
13020 || (c_parser_peek_token (parser
)->keyword
13021 == RID_PRETTY_FUNCTION_NAME
)
13022 || (c_parser_peek_token (parser
)->keyword
13023 == RID_C99_FUNCTION_NAME
)))
13024 t
= c_parser_predefined_identifier (parser
).value
;
13028 c_parser_error (parser
, "expected identifier");
13032 if (t
== error_mark_node
)
13034 else if (kind
!= 0)
13038 case OMP_CLAUSE__CACHE_
:
13039 /* The OpenACC cache directive explicitly only allows "array
13040 elements or subarrays". */
13041 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
13043 c_parser_error (parser
, "expected %<[%>");
13044 t
= error_mark_node
;
13048 case OMP_CLAUSE_MAP
:
13049 case OMP_CLAUSE_FROM
:
13050 case OMP_CLAUSE_TO
:
13051 while (c_parser_next_token_is (parser
, CPP_DOT
)
13053 && c_parser_next_token_is (parser
, CPP_DEREF
)))
13055 location_t op_loc
= c_parser_peek_token (parser
)->location
;
13056 if (c_parser_next_token_is (parser
, CPP_DEREF
))
13057 t
= build_simple_mem_ref (t
);
13058 c_parser_consume_token (parser
);
13059 if (!c_parser_next_token_is (parser
, CPP_NAME
))
13061 c_parser_error (parser
, "expected identifier");
13062 t
= error_mark_node
;
13066 c_token
*comp_tok
= c_parser_peek_token (parser
);
13067 tree ident
= comp_tok
->value
;
13068 location_t comp_loc
= comp_tok
->location
;
13069 c_parser_consume_token (parser
);
13070 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
);
13073 case OMP_CLAUSE_DEPEND
:
13074 case OMP_CLAUSE_REDUCTION
:
13075 case OMP_CLAUSE_IN_REDUCTION
:
13076 case OMP_CLAUSE_TASK_REDUCTION
:
13077 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
13079 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
13081 c_parser_consume_token (parser
);
13082 if (!c_parser_next_token_is (parser
, CPP_COLON
))
13084 location_t expr_loc
13085 = c_parser_peek_token (parser
)->location
;
13086 c_expr expr
= c_parser_expression (parser
);
13087 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13089 low_bound
= expr
.value
;
13091 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13092 length
= integer_one_node
;
13095 /* Look for `:'. */
13096 if (!c_parser_require (parser
, CPP_COLON
,
13099 t
= error_mark_node
;
13102 array_section_p
= true;
13103 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13105 location_t expr_loc
13106 = c_parser_peek_token (parser
)->location
;
13107 c_expr expr
= c_parser_expression (parser
);
13108 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13110 length
= expr
.value
;
13113 /* Look for the closing `]'. */
13114 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
13117 t
= error_mark_node
;
13121 t
= tree_cons (low_bound
, length
, t
);
13123 if (kind
== OMP_CLAUSE_DEPEND
13124 && t
!= error_mark_node
13125 && parser
->tokens_avail
!= 2)
13127 if (array_section_p
)
13129 error_at (c_parser_peek_token (parser
)->location
,
13130 "expected %<)%> or %<,%>");
13131 t
= error_mark_node
;
13135 parser
->tokens
= tokens
.address ();
13136 parser
->tokens_avail
= tokens
.length ();
13138 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
13139 if (t
!= error_mark_node
&& parser
->tokens_avail
!= 2)
13141 error_at (c_parser_peek_token (parser
)->location
,
13142 "expected %<)%> or %<,%>");
13143 t
= error_mark_node
;
13152 if (t
!= error_mark_node
)
13154 tree u
= build_omp_clause (clause_loc
, kind
);
13155 OMP_CLAUSE_DECL (u
) = t
;
13156 OMP_CLAUSE_CHAIN (u
) = list
;
13161 list
= tree_cons (t
, NULL_TREE
, list
);
13163 if (kind
== OMP_CLAUSE_DEPEND
)
13165 parser
->tokens
= &parser
->tokens_buf
[0];
13166 parser
->tokens_avail
= tokens_avail
;
13168 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
13171 c_parser_consume_token (parser
);
13178 /* Similarly, but expect leading and trailing parenthesis. This is a very
13179 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13180 argument is true if list items can use the deref (->) operator. */
13183 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
13184 tree list
, bool allow_deref
= false)
13186 /* The clauses location. */
13187 location_t loc
= c_parser_peek_token (parser
)->location
;
13189 matching_parens parens
;
13190 if (parens
.require_open (parser
))
13192 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
, allow_deref
);
13193 parens
.skip_until_found_close (parser
);
13199 copy ( variable-list )
13200 copyin ( variable-list )
13201 copyout ( variable-list )
13202 create ( variable-list )
13203 delete ( variable-list )
13204 present ( variable-list )
13207 no_create ( variable-list )
13208 attach ( variable-list )
13209 detach ( variable-list ) */
13212 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
13215 enum gomp_map_kind kind
;
13218 case PRAGMA_OACC_CLAUSE_ATTACH
:
13219 kind
= GOMP_MAP_ATTACH
;
13221 case PRAGMA_OACC_CLAUSE_COPY
:
13222 kind
= GOMP_MAP_TOFROM
;
13224 case PRAGMA_OACC_CLAUSE_COPYIN
:
13225 kind
= GOMP_MAP_TO
;
13227 case PRAGMA_OACC_CLAUSE_COPYOUT
:
13228 kind
= GOMP_MAP_FROM
;
13230 case PRAGMA_OACC_CLAUSE_CREATE
:
13231 kind
= GOMP_MAP_ALLOC
;
13233 case PRAGMA_OACC_CLAUSE_DELETE
:
13234 kind
= GOMP_MAP_RELEASE
;
13236 case PRAGMA_OACC_CLAUSE_DETACH
:
13237 kind
= GOMP_MAP_DETACH
;
13239 case PRAGMA_OACC_CLAUSE_DEVICE
:
13240 kind
= GOMP_MAP_FORCE_TO
;
13242 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
13243 kind
= GOMP_MAP_DEVICE_RESIDENT
;
13245 case PRAGMA_OACC_CLAUSE_HOST
:
13246 kind
= GOMP_MAP_FORCE_FROM
;
13248 case PRAGMA_OACC_CLAUSE_LINK
:
13249 kind
= GOMP_MAP_LINK
;
13251 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
13252 kind
= GOMP_MAP_IF_PRESENT
;
13254 case PRAGMA_OACC_CLAUSE_PRESENT
:
13255 kind
= GOMP_MAP_FORCE_PRESENT
;
13258 gcc_unreachable ();
13261 nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_MAP
, list
, true);
13263 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13264 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
13270 deviceptr ( variable-list ) */
13273 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
13275 location_t loc
= c_parser_peek_token (parser
)->location
;
13278 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13279 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13280 variable-list must only allow for pointer variables. */
13281 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
13282 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
13284 tree v
= TREE_PURPOSE (t
);
13286 /* FIXME diagnostics: Ideally we should keep individual
13287 locations for all the variables in the var list to make the
13288 following errors more precise. Perhaps
13289 c_parser_omp_var_list_parens() should construct a list of
13290 locations to go along with the var list. */
13292 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
13293 error_at (loc
, "%qD is not a variable", v
);
13294 else if (TREE_TYPE (v
) == error_mark_node
)
13296 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
13297 error_at (loc
, "%qD is not a pointer variable", v
);
13299 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
13300 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
13301 OMP_CLAUSE_DECL (u
) = v
;
13302 OMP_CLAUSE_CHAIN (u
) = list
;
13309 /* OpenACC 2.0, OpenMP 3.0:
13310 collapse ( constant-expression ) */
13313 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
13315 tree c
, num
= error_mark_node
;
13319 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
13320 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
13322 loc
= c_parser_peek_token (parser
)->location
;
13323 matching_parens parens
;
13324 if (parens
.require_open (parser
))
13326 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
13327 parens
.skip_until_found_close (parser
);
13329 if (num
== error_mark_node
)
13331 mark_exp_read (num
);
13332 num
= c_fully_fold (num
, false, NULL
);
13333 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
13334 || !tree_fits_shwi_p (num
)
13335 || (n
= tree_to_shwi (num
)) <= 0
13339 "collapse argument needs positive constant integer expression");
13342 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
13343 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
13344 OMP_CLAUSE_CHAIN (c
) = list
;
13349 copyin ( variable-list ) */
13352 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
13354 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
13358 copyprivate ( variable-list ) */
13361 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
13363 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
13367 default ( none | shared )
13370 default ( none | present ) */
13373 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
13375 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
13376 location_t loc
= c_parser_peek_token (parser
)->location
;
13379 matching_parens parens
;
13380 if (!parens
.require_open (parser
))
13382 if (c_parser_next_token_is (parser
, CPP_NAME
))
13384 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13389 if (strcmp ("none", p
) != 0)
13391 kind
= OMP_CLAUSE_DEFAULT_NONE
;
13395 if (strcmp ("present", p
) != 0 || !is_oacc
)
13397 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
13401 if (strcmp ("shared", p
) != 0 || is_oacc
)
13403 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
13410 c_parser_consume_token (parser
);
13416 c_parser_error (parser
, "expected %<none%> or %<present%>");
13418 c_parser_error (parser
, "expected %<none%> or %<shared%>");
13420 parens
.skip_until_found_close (parser
);
13422 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
13425 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
13426 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
13427 OMP_CLAUSE_CHAIN (c
) = list
;
13428 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
13434 firstprivate ( variable-list ) */
13437 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
13439 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
13443 final ( expression ) */
13446 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
13448 location_t loc
= c_parser_peek_token (parser
)->location
;
13449 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13451 matching_parens parens
;
13453 if (!parens
.require_open (parser
))
13454 t
= error_mark_node
;
13457 location_t eloc
= c_parser_peek_token (parser
)->location
;
13458 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13459 t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
13460 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
13461 t
= c_fully_fold (t
, false, NULL
);
13462 parens
.skip_until_found_close (parser
);
13465 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
13467 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
13468 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
13469 OMP_CLAUSE_CHAIN (c
) = list
;
13473 c_parser_error (parser
, "expected %<(%>");
13478 /* OpenACC, OpenMP 2.5:
13482 if ( directive-name-modifier : expression )
13484 directive-name-modifier:
13485 parallel | task | taskloop | target data | target | target update
13486 | target enter data | target exit data
13489 directive-name-modifier:
13490 ... | simd | cancel */
13493 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
13495 location_t location
= c_parser_peek_token (parser
)->location
;
13496 enum tree_code if_modifier
= ERROR_MARK
;
13498 matching_parens parens
;
13499 if (!parens
.require_open (parser
))
13502 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
13504 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13506 if (strcmp (p
, "cancel") == 0)
13507 if_modifier
= VOID_CST
;
13508 else if (strcmp (p
, "parallel") == 0)
13509 if_modifier
= OMP_PARALLEL
;
13510 else if (strcmp (p
, "simd") == 0)
13511 if_modifier
= OMP_SIMD
;
13512 else if (strcmp (p
, "task") == 0)
13513 if_modifier
= OMP_TASK
;
13514 else if (strcmp (p
, "taskloop") == 0)
13515 if_modifier
= OMP_TASKLOOP
;
13516 else if (strcmp (p
, "target") == 0)
13518 if_modifier
= OMP_TARGET
;
13519 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
13521 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
13522 if (strcmp ("data", p
) == 0)
13523 if_modifier
= OMP_TARGET_DATA
;
13524 else if (strcmp ("update", p
) == 0)
13525 if_modifier
= OMP_TARGET_UPDATE
;
13526 else if (strcmp ("enter", p
) == 0)
13527 if_modifier
= OMP_TARGET_ENTER_DATA
;
13528 else if (strcmp ("exit", p
) == 0)
13529 if_modifier
= OMP_TARGET_EXIT_DATA
;
13530 if (if_modifier
!= OMP_TARGET
)
13533 c_parser_consume_token (parser
);
13537 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
13538 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
13540 if_modifier
= ERROR_MARK
;
13542 if (if_modifier
== OMP_TARGET_ENTER_DATA
13543 || if_modifier
== OMP_TARGET_EXIT_DATA
)
13545 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
13547 p
= IDENTIFIER_POINTER
13548 (c_parser_peek_2nd_token (parser
)->value
);
13549 if (strcmp ("data", p
) == 0)
13553 c_parser_consume_token (parser
);
13557 = c_parser_peek_2nd_token (parser
)->location
;
13558 error_at (loc
, "expected %<data%>");
13559 if_modifier
= ERROR_MARK
;
13564 if (if_modifier
!= ERROR_MARK
)
13566 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13568 c_parser_consume_token (parser
);
13569 c_parser_consume_token (parser
);
13575 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
13576 error_at (loc
, "expected %<:%>");
13578 if_modifier
= ERROR_MARK
;
13583 location_t loc
= c_parser_peek_token (parser
)->location
;
13584 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13585 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
13586 tree t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
), c
;
13587 t
= c_fully_fold (t
, false, NULL
);
13588 parens
.skip_until_found_close (parser
);
13590 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
13591 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
13593 if (if_modifier
!= ERROR_MARK
13594 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
13596 const char *p
= NULL
;
13597 switch (if_modifier
)
13599 case VOID_CST
: p
= "cancel"; break;
13600 case OMP_PARALLEL
: p
= "parallel"; break;
13601 case OMP_SIMD
: p
= "simd"; break;
13602 case OMP_TASK
: p
= "task"; break;
13603 case OMP_TASKLOOP
: p
= "taskloop"; break;
13604 case OMP_TARGET_DATA
: p
= "target data"; break;
13605 case OMP_TARGET
: p
= "target"; break;
13606 case OMP_TARGET_UPDATE
: p
= "target update"; break;
13607 case OMP_TARGET_ENTER_DATA
: p
= "target enter data"; break;
13608 case OMP_TARGET_EXIT_DATA
: p
= "target exit data"; break;
13609 default: gcc_unreachable ();
13611 error_at (location
, "too many %<if%> clauses with %qs modifier",
13615 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
13618 error_at (location
, "too many %<if%> clauses");
13620 error_at (location
, "too many %<if%> clauses without modifier");
13623 else if (if_modifier
== ERROR_MARK
13624 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
13626 error_at (location
, "if any %<if%> clause has modifier, then all "
13627 "%<if%> clauses have to use modifier");
13632 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
13633 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
13634 OMP_CLAUSE_IF_EXPR (c
) = t
;
13635 OMP_CLAUSE_CHAIN (c
) = list
;
13640 lastprivate ( variable-list )
13643 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13646 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
13648 /* The clauses location. */
13649 location_t loc
= c_parser_peek_token (parser
)->location
;
13651 if (c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
13653 bool conditional
= false;
13654 if (c_parser_next_token_is (parser
, CPP_NAME
)
13655 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13658 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13659 if (strcmp (p
, "conditional") == 0)
13661 conditional
= true;
13662 c_parser_consume_token (parser
);
13663 c_parser_consume_token (parser
);
13666 tree nlist
= c_parser_omp_variable_list (parser
, loc
,
13667 OMP_CLAUSE_LASTPRIVATE
, list
);
13668 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
13670 for (tree c
= nlist
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13671 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 1;
13681 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13685 /* FIXME: Should we allow duplicates? */
13686 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
13688 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
13689 OMP_CLAUSE_MERGEABLE
);
13690 OMP_CLAUSE_CHAIN (c
) = list
;
13699 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13702 location_t loc
= c_parser_peek_token (parser
)->location
;
13704 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
13706 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
13707 OMP_CLAUSE_CHAIN (c
) = list
;
13712 num_threads ( expression ) */
13715 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
13717 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
13718 matching_parens parens
;
13719 if (parens
.require_open (parser
))
13721 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13722 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13723 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13724 tree c
, t
= expr
.value
;
13725 t
= c_fully_fold (t
, false, NULL
);
13727 parens
.skip_until_found_close (parser
);
13729 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13731 c_parser_error (parser
, "expected integer expression");
13735 /* Attempt to statically determine when the number isn't positive. */
13736 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13737 build_int_cst (TREE_TYPE (t
), 0));
13738 protected_set_expr_location (c
, expr_loc
);
13739 if (c
== boolean_true_node
)
13741 warning_at (expr_loc
, 0,
13742 "%<num_threads%> value must be positive");
13743 t
= integer_one_node
;
13746 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
13748 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
13749 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
13750 OMP_CLAUSE_CHAIN (c
) = list
;
13758 num_tasks ( expression ) */
13761 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
13763 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
13764 matching_parens parens
;
13765 if (parens
.require_open (parser
))
13767 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13768 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13769 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13770 tree c
, t
= expr
.value
;
13771 t
= c_fully_fold (t
, false, NULL
);
13773 parens
.skip_until_found_close (parser
);
13775 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13777 c_parser_error (parser
, "expected integer expression");
13781 /* Attempt to statically determine when the number isn't positive. */
13782 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13783 build_int_cst (TREE_TYPE (t
), 0));
13784 if (CAN_HAVE_LOCATION_P (c
))
13785 SET_EXPR_LOCATION (c
, expr_loc
);
13786 if (c
== boolean_true_node
)
13788 warning_at (expr_loc
, 0, "%<num_tasks%> value must be positive");
13789 t
= integer_one_node
;
13792 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
13794 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
13795 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
13796 OMP_CLAUSE_CHAIN (c
) = list
;
13804 grainsize ( expression ) */
13807 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
13809 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
13810 matching_parens parens
;
13811 if (parens
.require_open (parser
))
13813 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13814 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13815 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13816 tree c
, t
= expr
.value
;
13817 t
= c_fully_fold (t
, false, NULL
);
13819 parens
.skip_until_found_close (parser
);
13821 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13823 c_parser_error (parser
, "expected integer expression");
13827 /* Attempt to statically determine when the number isn't positive. */
13828 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13829 build_int_cst (TREE_TYPE (t
), 0));
13830 if (CAN_HAVE_LOCATION_P (c
))
13831 SET_EXPR_LOCATION (c
, expr_loc
);
13832 if (c
== boolean_true_node
)
13834 warning_at (expr_loc
, 0, "%<grainsize%> value must be positive");
13835 t
= integer_one_node
;
13838 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
13840 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
13841 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
13842 OMP_CLAUSE_CHAIN (c
) = list
;
13850 priority ( expression ) */
13853 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
13855 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
13856 matching_parens parens
;
13857 if (parens
.require_open (parser
))
13859 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13860 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13861 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13862 tree c
, t
= expr
.value
;
13863 t
= c_fully_fold (t
, false, NULL
);
13865 parens
.skip_until_found_close (parser
);
13867 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13869 c_parser_error (parser
, "expected integer expression");
13873 /* Attempt to statically determine when the number isn't
13875 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
13876 build_int_cst (TREE_TYPE (t
), 0));
13877 if (CAN_HAVE_LOCATION_P (c
))
13878 SET_EXPR_LOCATION (c
, expr_loc
);
13879 if (c
== boolean_true_node
)
13881 warning_at (expr_loc
, 0, "%<priority%> value must be non-negative");
13882 t
= integer_one_node
;
13885 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
13887 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
13888 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
13889 OMP_CLAUSE_CHAIN (c
) = list
;
13897 hint ( expression ) */
13900 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
13902 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
13903 matching_parens parens
;
13904 if (parens
.require_open (parser
))
13906 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13907 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13908 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13909 tree c
, t
= expr
.value
;
13910 t
= c_fully_fold (t
, false, NULL
);
13911 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
13912 || TREE_CODE (t
) != INTEGER_CST
13913 || tree_int_cst_sgn (t
) == -1)
13915 c_parser_error (parser
, "expected constant integer expression "
13916 "with valid sync-hint value");
13919 parens
.skip_until_found_close (parser
);
13920 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
13922 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
13923 OMP_CLAUSE_HINT_EXPR (c
) = t
;
13924 OMP_CLAUSE_CHAIN (c
) = list
;
13932 defaultmap ( tofrom : scalar )
13935 defaultmap ( implicit-behavior [ : variable-category ] ) */
13938 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
13940 location_t loc
= c_parser_peek_token (parser
)->location
;
13943 enum omp_clause_defaultmap_kind behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
13944 enum omp_clause_defaultmap_kind category
13945 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
13947 matching_parens parens
;
13948 if (!parens
.require_open (parser
))
13950 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
13952 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
13955 c_parser_error (parser
, "expected %<alloc%>, %<to%>, %<from%>, "
13956 "%<tofrom%>, %<firstprivate%>, %<none%> "
13961 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13966 if (strcmp ("alloc", p
) == 0)
13967 behavior
= OMP_CLAUSE_DEFAULTMAP_ALLOC
;
13969 goto invalid_behavior
;
13973 if (strcmp ("default", p
) == 0)
13974 behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
13976 goto invalid_behavior
;
13980 if (strcmp ("firstprivate", p
) == 0)
13981 behavior
= OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
13982 else if (strcmp ("from", p
) == 0)
13983 behavior
= OMP_CLAUSE_DEFAULTMAP_FROM
;
13985 goto invalid_behavior
;
13989 if (strcmp ("none", p
) == 0)
13990 behavior
= OMP_CLAUSE_DEFAULTMAP_NONE
;
13992 goto invalid_behavior
;
13996 if (strcmp ("tofrom", p
) == 0)
13997 behavior
= OMP_CLAUSE_DEFAULTMAP_TOFROM
;
13998 else if (strcmp ("to", p
) == 0)
13999 behavior
= OMP_CLAUSE_DEFAULTMAP_TO
;
14001 goto invalid_behavior
;
14005 goto invalid_behavior
;
14007 c_parser_consume_token (parser
);
14009 if (!c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
14011 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14013 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14016 c_parser_error (parser
, "expected %<scalar%>, %<aggregate%> or "
14020 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14024 if (strcmp ("aggregate", p
) == 0)
14025 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
;
14027 goto invalid_category
;
14031 if (strcmp ("pointer", p
) == 0)
14032 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
;
14034 goto invalid_category
;
14038 if (strcmp ("scalar", p
) == 0)
14039 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
;
14041 goto invalid_category
;
14045 goto invalid_category
;
14048 c_parser_consume_token (parser
);
14050 parens
.skip_until_found_close (parser
);
14052 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
14053 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEFAULTMAP
14054 && (category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14055 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
) == category
14056 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
14057 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)))
14059 enum omp_clause_defaultmap_kind cat
= category
;
14060 location_t loc
= OMP_CLAUSE_LOCATION (c
);
14061 if (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
14062 cat
= OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
);
14066 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
14069 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
14072 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
14075 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
14079 gcc_unreachable ();
14082 error_at (loc
, "too many %<defaultmap%> clauses with %qs category",
14085 error_at (loc
, "too many %<defaultmap%> clauses with unspecified "
14090 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
14091 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c
, behavior
, category
);
14092 OMP_CLAUSE_CHAIN (c
) = list
;
14096 parens
.skip_until_found_close (parser
);
14101 use_device ( variable-list )
14104 use_device_ptr ( variable-list ) */
14107 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
14109 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
14114 use_device_addr ( variable-list ) */
14117 c_parser_omp_clause_use_device_addr (c_parser
*parser
, tree list
)
14119 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_ADDR
,
14124 is_device_ptr ( variable-list ) */
14127 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
14129 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
14133 num_gangs ( expression )
14134 num_workers ( expression )
14135 vector_length ( expression ) */
14138 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
14141 location_t loc
= c_parser_peek_token (parser
)->location
;
14143 matching_parens parens
;
14144 if (!parens
.require_open (parser
))
14147 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14148 c_expr expr
= c_parser_expression (parser
);
14149 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14150 tree c
, t
= expr
.value
;
14151 t
= c_fully_fold (t
, false, NULL
);
14153 parens
.skip_until_found_close (parser
);
14155 if (t
== error_mark_node
)
14157 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14159 error_at (expr_loc
, "%qs expression must be integral",
14160 omp_clause_code_name
[code
]);
14164 /* Attempt to statically determine when the number isn't positive. */
14165 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14166 build_int_cst (TREE_TYPE (t
), 0));
14167 protected_set_expr_location (c
, expr_loc
);
14168 if (c
== boolean_true_node
)
14170 warning_at (expr_loc
, 0,
14171 "%qs value must be positive",
14172 omp_clause_code_name
[code
]);
14173 t
= integer_one_node
;
14176 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14178 c
= build_omp_clause (loc
, code
);
14179 OMP_CLAUSE_OPERAND (c
, 0) = t
;
14180 OMP_CLAUSE_CHAIN (c
) = list
;
14186 gang [( gang-arg-list )]
14187 worker [( [num:] int-expr )]
14188 vector [( [length:] int-expr )]
14190 where gang-arg is one of:
14195 and size-expr may be:
14202 c_parser_oacc_shape_clause (c_parser
*parser
, location_t loc
,
14203 omp_clause_code kind
,
14204 const char *str
, tree list
)
14206 const char *id
= "num";
14207 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
14209 if (kind
== OMP_CLAUSE_VECTOR
)
14212 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14214 c_parser_consume_token (parser
);
14218 c_token
*next
= c_parser_peek_token (parser
);
14221 /* Gang static argument. */
14222 if (kind
== OMP_CLAUSE_GANG
14223 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
14225 c_parser_consume_token (parser
);
14227 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14228 goto cleanup_error
;
14231 if (ops
[idx
] != NULL_TREE
)
14233 c_parser_error (parser
, "too many %<static%> arguments");
14234 goto cleanup_error
;
14237 /* Check for the '*' argument. */
14238 if (c_parser_next_token_is (parser
, CPP_MULT
)
14239 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14240 || c_parser_peek_2nd_token (parser
)->type
14241 == CPP_CLOSE_PAREN
))
14243 c_parser_consume_token (parser
);
14244 ops
[idx
] = integer_minus_one_node
;
14246 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14248 c_parser_consume_token (parser
);
14255 /* Worker num: argument and vector length: arguments. */
14256 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14257 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
14258 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14260 c_parser_consume_token (parser
); /* id */
14261 c_parser_consume_token (parser
); /* ':' */
14264 /* Now collect the actual argument. */
14265 if (ops
[idx
] != NULL_TREE
)
14267 c_parser_error (parser
, "unexpected argument");
14268 goto cleanup_error
;
14271 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14272 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14273 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14274 tree expr
= cexpr
.value
;
14275 if (expr
== error_mark_node
)
14276 goto cleanup_error
;
14278 expr
= c_fully_fold (expr
, false, NULL
);
14280 /* Attempt to statically determine when the number isn't a
14281 positive integer. */
14283 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
14285 c_parser_error (parser
, "expected integer expression");
14289 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
14290 build_int_cst (TREE_TYPE (expr
), 0));
14291 if (c
== boolean_true_node
)
14293 warning_at (loc
, 0,
14294 "%qs value must be positive", str
);
14295 expr
= integer_one_node
;
14300 if (kind
== OMP_CLAUSE_GANG
14301 && c_parser_next_token_is (parser
, CPP_COMMA
))
14303 c_parser_consume_token (parser
);
14310 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14311 goto cleanup_error
;
14314 check_no_duplicate_clause (list
, kind
, str
);
14316 c
= build_omp_clause (loc
, kind
);
14319 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
14321 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
14322 OMP_CLAUSE_CHAIN (c
) = list
;
14327 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14339 c_parser_oacc_simple_clause (location_t loc
, enum omp_clause_code code
,
14342 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14344 tree c
= build_omp_clause (loc
, code
);
14345 OMP_CLAUSE_CHAIN (c
) = list
;
14351 async [( int-expr )] */
14354 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
14357 location_t loc
= c_parser_peek_token (parser
)->location
;
14359 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14361 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14363 c_parser_consume_token (parser
);
14365 t
= c_parser_expression (parser
).value
;
14366 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14367 c_parser_error (parser
, "expected integer expression");
14368 else if (t
== error_mark_node
14369 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14373 t
= c_fully_fold (t
, false, NULL
);
14375 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
14377 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
14378 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
14379 OMP_CLAUSE_CHAIN (c
) = list
;
14386 tile ( size-expr-list ) */
14389 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
14391 tree c
, expr
= error_mark_node
;
14393 tree tile
= NULL_TREE
;
14395 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
14396 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
14398 loc
= c_parser_peek_token (parser
)->location
;
14399 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
14404 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
14407 if (c_parser_next_token_is (parser
, CPP_MULT
)
14408 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14409 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
14411 c_parser_consume_token (parser
);
14412 expr
= integer_zero_node
;
14416 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14417 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14418 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14419 expr
= cexpr
.value
;
14421 if (expr
== error_mark_node
)
14423 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
14428 expr
= c_fully_fold (expr
, false, NULL
);
14430 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
14431 || !tree_fits_shwi_p (expr
)
14432 || tree_to_shwi (expr
) <= 0)
14434 error_at (expr_loc
, "%<tile%> argument needs positive"
14435 " integral constant");
14436 expr
= integer_zero_node
;
14440 tile
= tree_cons (NULL_TREE
, expr
, tile
);
14442 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
14444 /* Consume the trailing ')'. */
14445 c_parser_consume_token (parser
);
14447 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
14448 tile
= nreverse (tile
);
14449 OMP_CLAUSE_TILE_LIST (c
) = tile
;
14450 OMP_CLAUSE_CHAIN (c
) = list
;
14455 wait [( int-expr-list )] */
14458 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
14460 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14462 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14463 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
14466 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
14468 OMP_CLAUSE_DECL (c
) = build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14469 OMP_CLAUSE_CHAIN (c
) = list
;
14478 order ( concurrent ) */
14481 c_parser_omp_clause_order (c_parser
*parser
, tree list
)
14483 location_t loc
= c_parser_peek_token (parser
)->location
;
14487 matching_parens parens
;
14488 if (!parens
.require_open (parser
))
14490 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14492 c_parser_error (parser
, "expected %<concurrent%>");
14495 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14496 if (strcmp (p
, "concurrent") != 0)
14498 c_parser_error (parser
, "expected %<concurrent%>");
14501 c_parser_consume_token (parser
);
14502 parens
.skip_until_found_close (parser
);
14503 /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */
14504 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDER
);
14505 OMP_CLAUSE_CHAIN (c
) = list
;
14509 parens
.skip_until_found_close (parser
);
14515 bind ( teams | parallel | thread ) */
14518 c_parser_omp_clause_bind (c_parser
*parser
, tree list
)
14520 location_t loc
= c_parser_peek_token (parser
)->location
;
14523 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
14525 matching_parens parens
;
14526 if (!parens
.require_open (parser
))
14528 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14531 c_parser_error (parser
,
14532 "expected %<teams%>, %<parallel%> or %<thread%>");
14533 parens
.skip_until_found_close (parser
);
14536 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14537 if (strcmp (p
, "teams") == 0)
14538 kind
= OMP_CLAUSE_BIND_TEAMS
;
14539 else if (strcmp (p
, "parallel") == 0)
14540 kind
= OMP_CLAUSE_BIND_PARALLEL
;
14541 else if (strcmp (p
, "thread") != 0)
14543 c_parser_consume_token (parser
);
14544 parens
.skip_until_found_close (parser
);
14545 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14546 c
= build_omp_clause (loc
, OMP_CLAUSE_BIND
);
14547 OMP_CLAUSE_BIND_KIND (c
) = kind
;
14548 OMP_CLAUSE_CHAIN (c
) = list
;
14557 ordered ( constant-expression ) */
14560 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
14562 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
14564 tree c
, num
= NULL_TREE
;
14566 location_t loc
= c_parser_peek_token (parser
)->location
;
14567 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14569 matching_parens parens
;
14570 parens
.consume_open (parser
);
14571 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
14572 parens
.skip_until_found_close (parser
);
14574 if (num
== error_mark_node
)
14578 mark_exp_read (num
);
14579 num
= c_fully_fold (num
, false, NULL
);
14580 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
14581 || !tree_fits_shwi_p (num
)
14582 || (n
= tree_to_shwi (num
)) <= 0
14585 error_at (loc
, "ordered argument needs positive "
14586 "constant integer expression");
14590 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
14591 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
14592 OMP_CLAUSE_CHAIN (c
) = list
;
14597 private ( variable-list ) */
14600 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
14602 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
14606 reduction ( reduction-operator : variable-list )
14608 reduction-operator:
14609 One of: + * - & ^ | && ||
14613 reduction-operator:
14614 One of: + * - & ^ | && || max min
14618 reduction-operator:
14619 One of: + * - & ^ | && ||
14623 reduction ( reduction-modifier, reduction-operator : variable-list )
14624 in_reduction ( reduction-operator : variable-list )
14625 task_reduction ( reduction-operator : variable-list ) */
14628 c_parser_omp_clause_reduction (c_parser
*parser
, enum omp_clause_code kind
,
14629 bool is_omp
, tree list
)
14631 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14632 matching_parens parens
;
14633 if (parens
.require_open (parser
))
14636 bool inscan
= false;
14637 enum tree_code code
= ERROR_MARK
;
14638 tree reduc_id
= NULL_TREE
;
14640 if (kind
== OMP_CLAUSE_REDUCTION
&& is_omp
)
14642 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
14643 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
14645 c_parser_consume_token (parser
);
14646 c_parser_consume_token (parser
);
14648 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14649 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
14652 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14653 if (strcmp (p
, "task") == 0)
14655 else if (strcmp (p
, "inscan") == 0)
14657 if (task
|| inscan
)
14659 c_parser_consume_token (parser
);
14660 c_parser_consume_token (parser
);
14665 switch (c_parser_peek_token (parser
)->type
)
14677 code
= BIT_AND_EXPR
;
14680 code
= BIT_XOR_EXPR
;
14683 code
= BIT_IOR_EXPR
;
14686 code
= TRUTH_ANDIF_EXPR
;
14689 code
= TRUTH_ORIF_EXPR
;
14694 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14695 if (strcmp (p
, "min") == 0)
14700 if (strcmp (p
, "max") == 0)
14705 reduc_id
= c_parser_peek_token (parser
)->value
;
14709 c_parser_error (parser
,
14710 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
14711 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
14712 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14715 c_parser_consume_token (parser
);
14716 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
14717 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14721 nl
= c_parser_omp_variable_list (parser
, clause_loc
, kind
, list
);
14722 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
14724 tree d
= OMP_CLAUSE_DECL (c
), type
;
14725 if (TREE_CODE (d
) != TREE_LIST
)
14726 type
= TREE_TYPE (d
);
14731 for (t
= d
; TREE_CODE (t
) == TREE_LIST
; t
= TREE_CHAIN (t
))
14733 type
= TREE_TYPE (t
);
14736 if (TREE_CODE (type
) != POINTER_TYPE
14737 && TREE_CODE (type
) != ARRAY_TYPE
)
14739 type
= TREE_TYPE (type
);
14743 while (TREE_CODE (type
) == ARRAY_TYPE
)
14744 type
= TREE_TYPE (type
);
14745 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
14747 OMP_CLAUSE_REDUCTION_TASK (c
) = 1;
14749 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 1;
14750 if (code
== ERROR_MARK
14751 || !(INTEGRAL_TYPE_P (type
)
14752 || TREE_CODE (type
) == REAL_TYPE
14753 || TREE_CODE (type
) == COMPLEX_TYPE
))
14754 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
14755 = c_omp_reduction_lookup (reduc_id
,
14756 TYPE_MAIN_VARIANT (type
));
14761 parens
.skip_until_found_close (parser
);
14767 schedule ( schedule-kind )
14768 schedule ( schedule-kind , expression )
14771 static | dynamic | guided | runtime | auto
14774 schedule ( schedule-modifier : schedule-kind )
14775 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
14783 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
14786 location_t loc
= c_parser_peek_token (parser
)->location
;
14787 int modifiers
= 0, nmodifiers
= 0;
14789 matching_parens parens
;
14790 if (!parens
.require_open (parser
))
14793 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
14795 location_t comma
= UNKNOWN_LOCATION
;
14796 while (c_parser_next_token_is (parser
, CPP_NAME
))
14798 tree kind
= c_parser_peek_token (parser
)->value
;
14799 const char *p
= IDENTIFIER_POINTER (kind
);
14800 if (strcmp ("simd", p
) == 0)
14801 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
14802 else if (strcmp ("monotonic", p
) == 0)
14803 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
14804 else if (strcmp ("nonmonotonic", p
) == 0)
14805 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
14808 comma
= UNKNOWN_LOCATION
;
14809 c_parser_consume_token (parser
);
14810 if (nmodifiers
++ == 0
14811 && c_parser_next_token_is (parser
, CPP_COMMA
))
14813 comma
= c_parser_peek_token (parser
)->location
;
14814 c_parser_consume_token (parser
);
14818 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
14822 if (comma
!= UNKNOWN_LOCATION
)
14823 error_at (comma
, "expected %<:%>");
14825 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
14826 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
14827 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
14828 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
14830 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
14835 if (c_parser_next_token_is (parser
, CPP_NAME
))
14837 tree kind
= c_parser_peek_token (parser
)->value
;
14838 const char *p
= IDENTIFIER_POINTER (kind
);
14843 if (strcmp ("dynamic", p
) != 0)
14845 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
14849 if (strcmp ("guided", p
) != 0)
14851 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
14855 if (strcmp ("runtime", p
) != 0)
14857 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
14864 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
14865 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
14866 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
14867 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
14871 c_parser_consume_token (parser
);
14872 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14875 c_parser_consume_token (parser
);
14877 here
= c_parser_peek_token (parser
)->location
;
14878 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14879 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
14881 t
= c_fully_fold (t
, false, NULL
);
14883 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
14884 error_at (here
, "schedule %<runtime%> does not take "
14885 "a %<chunk_size%> parameter");
14886 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
14888 "schedule %<auto%> does not take "
14889 "a %<chunk_size%> parameter");
14890 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
)
14892 /* Attempt to statically determine when the number isn't
14894 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
14895 build_int_cst (TREE_TYPE (t
), 0));
14896 protected_set_expr_location (s
, loc
);
14897 if (s
== boolean_true_node
)
14899 warning_at (loc
, 0,
14900 "chunk size value must be positive");
14901 t
= integer_one_node
;
14903 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
14906 c_parser_error (parser
, "expected integer expression");
14908 parens
.skip_until_found_close (parser
);
14911 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
14912 "expected %<,%> or %<)%>");
14914 OMP_CLAUSE_SCHEDULE_KIND (c
)
14915 = (enum omp_clause_schedule_kind
)
14916 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
14918 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
14919 OMP_CLAUSE_CHAIN (c
) = list
;
14923 c_parser_error (parser
, "invalid schedule kind");
14924 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14929 shared ( variable-list ) */
14932 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
14934 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
14941 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
14945 /* FIXME: Should we allow duplicates? */
14946 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
14948 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
14949 OMP_CLAUSE_UNTIED
);
14950 OMP_CLAUSE_CHAIN (c
) = list
;
14960 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
14961 enum omp_clause_code code
, tree list
)
14963 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14965 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
14966 OMP_CLAUSE_CHAIN (c
) = list
;
14978 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
14979 enum omp_clause_code code
, tree list
)
14981 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
14982 OMP_CLAUSE_CHAIN (c
) = list
;
14991 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
14993 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
14994 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
14995 OMP_CLAUSE_NOGROUP
);
14996 OMP_CLAUSE_CHAIN (c
) = list
;
15005 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
15006 enum omp_clause_code code
, tree list
)
15008 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15009 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15010 OMP_CLAUSE_CHAIN (c
) = list
;
15015 num_teams ( expression ) */
15018 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
15020 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
15021 matching_parens parens
;
15022 if (parens
.require_open (parser
))
15024 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15025 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15026 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15027 tree c
, t
= expr
.value
;
15028 t
= c_fully_fold (t
, false, NULL
);
15030 parens
.skip_until_found_close (parser
);
15032 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15034 c_parser_error (parser
, "expected integer expression");
15038 /* Attempt to statically determine when the number isn't positive. */
15039 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
15040 build_int_cst (TREE_TYPE (t
), 0));
15041 protected_set_expr_location (c
, expr_loc
);
15042 if (c
== boolean_true_node
)
15044 warning_at (expr_loc
, 0, "%<num_teams%> value must be positive");
15045 t
= integer_one_node
;
15048 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
15050 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
15051 OMP_CLAUSE_NUM_TEAMS_EXPR (c
) = t
;
15052 OMP_CLAUSE_CHAIN (c
) = list
;
15060 thread_limit ( expression ) */
15063 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
15065 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
15066 matching_parens parens
;
15067 if (parens
.require_open (parser
))
15069 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15070 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15071 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15072 tree c
, t
= expr
.value
;
15073 t
= c_fully_fold (t
, false, NULL
);
15075 parens
.skip_until_found_close (parser
);
15077 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15079 c_parser_error (parser
, "expected integer expression");
15083 /* Attempt to statically determine when the number isn't positive. */
15084 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
15085 build_int_cst (TREE_TYPE (t
), 0));
15086 protected_set_expr_location (c
, expr_loc
);
15087 if (c
== boolean_true_node
)
15089 warning_at (expr_loc
, 0, "%<thread_limit%> value must be positive");
15090 t
= integer_one_node
;
15093 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
15096 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
15097 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
15098 OMP_CLAUSE_CHAIN (c
) = list
;
15106 aligned ( variable-list )
15107 aligned ( variable-list : constant-expression ) */
15110 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
15112 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15115 matching_parens parens
;
15116 if (!parens
.require_open (parser
))
15119 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15120 OMP_CLAUSE_ALIGNED
, list
);
15122 if (c_parser_next_token_is (parser
, CPP_COLON
))
15124 c_parser_consume_token (parser
);
15125 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15126 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15127 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15128 tree alignment
= expr
.value
;
15129 alignment
= c_fully_fold (alignment
, false, NULL
);
15130 if (TREE_CODE (alignment
) != INTEGER_CST
15131 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
15132 || tree_int_cst_sgn (alignment
) != 1)
15134 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
15135 "be positive constant integer expression");
15136 alignment
= NULL_TREE
;
15139 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15140 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
15143 parens
.skip_until_found_close (parser
);
15148 linear ( variable-list )
15149 linear ( variable-list : expression )
15152 linear ( modifier ( variable-list ) )
15153 linear ( modifier ( variable-list ) : expression ) */
15156 c_parser_omp_clause_linear (c_parser
*parser
, tree list
)
15158 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15160 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15162 matching_parens parens
;
15163 if (!parens
.require_open (parser
))
15166 if (c_parser_next_token_is (parser
, CPP_NAME
))
15168 c_token
*tok
= c_parser_peek_token (parser
);
15169 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15170 if (strcmp ("val", p
) == 0)
15171 kind
= OMP_CLAUSE_LINEAR_VAL
;
15172 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
15173 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15174 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15176 c_parser_consume_token (parser
);
15177 c_parser_consume_token (parser
);
15181 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15182 OMP_CLAUSE_LINEAR
, list
);
15184 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15185 parens
.skip_until_found_close (parser
);
15187 if (c_parser_next_token_is (parser
, CPP_COLON
))
15189 c_parser_consume_token (parser
);
15190 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15191 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15192 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15194 step
= c_fully_fold (step
, false, NULL
);
15195 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
15197 error_at (clause_loc
, "%<linear%> clause step expression must "
15199 step
= integer_one_node
;
15204 step
= integer_one_node
;
15206 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15208 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
15209 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
15212 parens
.skip_until_found_close (parser
);
15217 nontemporal ( variable-list ) */
15220 c_parser_omp_clause_nontemporal (c_parser
*parser
, tree list
)
15222 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_NONTEMPORAL
, list
);
15226 safelen ( constant-expression ) */
15229 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
15231 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15234 matching_parens parens
;
15235 if (!parens
.require_open (parser
))
15238 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15239 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15240 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15242 t
= c_fully_fold (t
, false, NULL
);
15243 if (TREE_CODE (t
) != INTEGER_CST
15244 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
15245 || tree_int_cst_sgn (t
) != 1)
15247 error_at (clause_loc
, "%<safelen%> clause expression must "
15248 "be positive constant integer expression");
15252 parens
.skip_until_found_close (parser
);
15253 if (t
== NULL_TREE
|| t
== error_mark_node
)
15256 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
15258 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
15259 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
15260 OMP_CLAUSE_CHAIN (c
) = list
;
15265 simdlen ( constant-expression ) */
15268 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
15270 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15273 matching_parens parens
;
15274 if (!parens
.require_open (parser
))
15277 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15278 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15279 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15281 t
= c_fully_fold (t
, false, NULL
);
15282 if (TREE_CODE (t
) != INTEGER_CST
15283 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
15284 || tree_int_cst_sgn (t
) != 1)
15286 error_at (clause_loc
, "%<simdlen%> clause expression must "
15287 "be positive constant integer expression");
15291 parens
.skip_until_found_close (parser
);
15292 if (t
== NULL_TREE
|| t
== error_mark_node
)
15295 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
15297 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
15298 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
15299 OMP_CLAUSE_CHAIN (c
) = list
;
15305 identifier [+/- integer]
15306 vec , identifier [+/- integer]
15310 c_parser_omp_clause_depend_sink (c_parser
*parser
, location_t clause_loc
,
15314 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
15315 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
15317 c_parser_error (parser
, "expected identifier");
15321 while (c_parser_next_token_is (parser
, CPP_NAME
)
15322 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
15324 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
15325 tree addend
= NULL
;
15327 if (t
== NULL_TREE
)
15329 undeclared_variable (c_parser_peek_token (parser
)->location
,
15330 c_parser_peek_token (parser
)->value
);
15331 t
= error_mark_node
;
15334 c_parser_consume_token (parser
);
15337 if (c_parser_next_token_is (parser
, CPP_MINUS
))
15339 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
15341 addend
= integer_zero_node
;
15343 goto add_to_vector
;
15345 c_parser_consume_token (parser
);
15347 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
15349 c_parser_error (parser
, "expected integer");
15353 addend
= c_parser_peek_token (parser
)->value
;
15354 if (TREE_CODE (addend
) != INTEGER_CST
)
15356 c_parser_error (parser
, "expected integer");
15359 c_parser_consume_token (parser
);
15362 if (t
!= error_mark_node
)
15364 vec
= tree_cons (addend
, t
, vec
);
15366 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec
) = 1;
15369 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
15372 c_parser_consume_token (parser
);
15375 if (vec
== NULL_TREE
)
15378 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
15379 OMP_CLAUSE_DEPEND_KIND (u
) = OMP_CLAUSE_DEPEND_SINK
;
15380 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
15381 OMP_CLAUSE_CHAIN (u
) = list
;
15386 iterators ( iterators-definition )
15388 iterators-definition:
15390 iterator-specifier , iterators-definition
15392 iterator-specifier:
15393 identifier = range-specification
15394 iterator-type identifier = range-specification
15396 range-specification:
15398 begin : end : step */
15401 c_parser_omp_iterators (c_parser
*parser
)
15403 tree ret
= NULL_TREE
, *last
= &ret
;
15404 c_parser_consume_token (parser
);
15408 matching_parens parens
;
15409 if (!parens
.require_open (parser
))
15410 return error_mark_node
;
15414 tree iter_type
= NULL_TREE
, type_expr
= NULL_TREE
;
15415 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
15417 struct c_type_name
*type
= c_parser_type_name (parser
);
15419 iter_type
= groktypename (type
, &type_expr
, NULL
);
15421 if (iter_type
== NULL_TREE
)
15422 iter_type
= integer_type_node
;
15424 location_t loc
= c_parser_peek_token (parser
)->location
;
15425 if (!c_parser_next_token_is (parser
, CPP_NAME
))
15427 c_parser_error (parser
, "expected identifier");
15431 tree id
= c_parser_peek_token (parser
)->value
;
15432 c_parser_consume_token (parser
);
15434 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
15437 location_t eloc
= c_parser_peek_token (parser
)->location
;
15438 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15439 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15440 tree begin
= expr
.value
;
15442 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15445 eloc
= c_parser_peek_token (parser
)->location
;
15446 expr
= c_parser_expr_no_commas (parser
, NULL
);
15447 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15448 tree end
= expr
.value
;
15450 tree step
= integer_one_node
;
15451 if (c_parser_next_token_is (parser
, CPP_COLON
))
15453 c_parser_consume_token (parser
);
15454 eloc
= c_parser_peek_token (parser
)->location
;
15455 expr
= c_parser_expr_no_commas (parser
, NULL
);
15456 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15460 tree iter_var
= build_decl (loc
, VAR_DECL
, id
, iter_type
);
15461 DECL_ARTIFICIAL (iter_var
) = 1;
15462 DECL_CONTEXT (iter_var
) = current_function_decl
;
15463 pushdecl (iter_var
);
15465 *last
= make_tree_vec (6);
15466 TREE_VEC_ELT (*last
, 0) = iter_var
;
15467 TREE_VEC_ELT (*last
, 1) = begin
;
15468 TREE_VEC_ELT (*last
, 2) = end
;
15469 TREE_VEC_ELT (*last
, 3) = step
;
15470 last
= &TREE_CHAIN (*last
);
15472 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15474 c_parser_consume_token (parser
);
15481 parens
.skip_until_found_close (parser
);
15482 return ret
? ret
: error_mark_node
;
15486 depend ( depend-kind: variable-list )
15494 depend ( sink : vec )
15497 depend ( depend-modifier , depend-kind: variable-list )
15500 in | out | inout | mutexinoutset | depobj
15503 iterator ( iterators-definition ) */
15506 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
15508 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15509 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_LAST
;
15510 tree nl
, c
, iterators
= NULL_TREE
;
15512 matching_parens parens
;
15513 if (!parens
.require_open (parser
))
15518 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
15521 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15522 if (strcmp ("iterator", p
) == 0 && iterators
== NULL_TREE
)
15524 iterators
= c_parser_omp_iterators (parser
);
15525 c_parser_require (parser
, CPP_COMMA
, "expected %<,%>");
15528 if (strcmp ("in", p
) == 0)
15529 kind
= OMP_CLAUSE_DEPEND_IN
;
15530 else if (strcmp ("inout", p
) == 0)
15531 kind
= OMP_CLAUSE_DEPEND_INOUT
;
15532 else if (strcmp ("mutexinoutset", p
) == 0)
15533 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
15534 else if (strcmp ("out", p
) == 0)
15535 kind
= OMP_CLAUSE_DEPEND_OUT
;
15536 else if (strcmp ("depobj", p
) == 0)
15537 kind
= OMP_CLAUSE_DEPEND_DEPOBJ
;
15538 else if (strcmp ("sink", p
) == 0)
15539 kind
= OMP_CLAUSE_DEPEND_SINK
;
15540 else if (strcmp ("source", p
) == 0)
15541 kind
= OMP_CLAUSE_DEPEND_SOURCE
;
15548 c_parser_consume_token (parser
);
15551 && (kind
== OMP_CLAUSE_DEPEND_SOURCE
|| kind
== OMP_CLAUSE_DEPEND_SINK
))
15554 error_at (clause_loc
, "%<iterator%> modifier incompatible with %qs",
15555 kind
== OMP_CLAUSE_DEPEND_SOURCE
? "source" : "sink");
15556 iterators
= NULL_TREE
;
15559 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
15561 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
15562 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
15563 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
15564 OMP_CLAUSE_CHAIN (c
) = list
;
15565 parens
.skip_until_found_close (parser
);
15569 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15572 if (kind
== OMP_CLAUSE_DEPEND_SINK
)
15573 nl
= c_parser_omp_clause_depend_sink (parser
, clause_loc
, list
);
15576 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15577 OMP_CLAUSE_DEPEND
, list
);
15581 tree block
= pop_scope ();
15582 if (iterators
== error_mark_node
)
15583 iterators
= NULL_TREE
;
15585 TREE_VEC_ELT (iterators
, 5) = block
;
15588 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15590 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
15592 OMP_CLAUSE_DECL (c
)
15593 = build_tree_list (iterators
, OMP_CLAUSE_DECL (c
));
15597 parens
.skip_until_found_close (parser
);
15601 c_parser_error (parser
, "invalid depend kind");
15603 parens
.skip_until_found_close (parser
);
15610 map ( map-kind: variable-list )
15611 map ( variable-list )
15614 alloc | to | from | tofrom
15618 alloc | to | from | tofrom | release | delete
15620 map ( always [,] map-kind: variable-list ) */
15623 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
15625 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15626 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
15628 enum c_id_kind always_id_kind
= C_ID_NONE
;
15629 location_t always_loc
= UNKNOWN_LOCATION
;
15630 tree always_id
= NULL_TREE
;
15633 matching_parens parens
;
15634 if (!parens
.require_open (parser
))
15637 if (c_parser_next_token_is (parser
, CPP_NAME
))
15639 c_token
*tok
= c_parser_peek_token (parser
);
15640 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15641 always_id_kind
= tok
->id_kind
;
15642 always_loc
= tok
->location
;
15643 always_id
= tok
->value
;
15644 if (strcmp ("always", p
) == 0)
15646 c_token
*sectok
= c_parser_peek_2nd_token (parser
);
15647 if (sectok
->type
== CPP_COMMA
)
15649 c_parser_consume_token (parser
);
15650 c_parser_consume_token (parser
);
15653 else if (sectok
->type
== CPP_NAME
)
15655 p
= IDENTIFIER_POINTER (sectok
->value
);
15656 if (strcmp ("alloc", p
) == 0
15657 || strcmp ("to", p
) == 0
15658 || strcmp ("from", p
) == 0
15659 || strcmp ("tofrom", p
) == 0
15660 || strcmp ("release", p
) == 0
15661 || strcmp ("delete", p
) == 0)
15663 c_parser_consume_token (parser
);
15670 if (c_parser_next_token_is (parser
, CPP_NAME
)
15671 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
15673 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15674 if (strcmp ("alloc", p
) == 0)
15675 kind
= GOMP_MAP_ALLOC
;
15676 else if (strcmp ("to", p
) == 0)
15677 kind
= always
? GOMP_MAP_ALWAYS_TO
: GOMP_MAP_TO
;
15678 else if (strcmp ("from", p
) == 0)
15679 kind
= always
? GOMP_MAP_ALWAYS_FROM
: GOMP_MAP_FROM
;
15680 else if (strcmp ("tofrom", p
) == 0)
15681 kind
= always
? GOMP_MAP_ALWAYS_TOFROM
: GOMP_MAP_TOFROM
;
15682 else if (strcmp ("release", p
) == 0)
15683 kind
= GOMP_MAP_RELEASE
;
15684 else if (strcmp ("delete", p
) == 0)
15685 kind
= GOMP_MAP_DELETE
;
15688 c_parser_error (parser
, "invalid map kind");
15689 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15693 c_parser_consume_token (parser
);
15694 c_parser_consume_token (parser
);
15698 if (always_id_kind
!= C_ID_ID
)
15700 c_parser_error (parser
, "expected identifier");
15701 parens
.skip_until_found_close (parser
);
15705 tree t
= lookup_name (always_id
);
15706 if (t
== NULL_TREE
)
15708 undeclared_variable (always_loc
, always_id
);
15709 t
= error_mark_node
;
15711 if (t
!= error_mark_node
)
15713 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_MAP
);
15714 OMP_CLAUSE_DECL (u
) = t
;
15715 OMP_CLAUSE_CHAIN (u
) = list
;
15716 OMP_CLAUSE_SET_MAP_KIND (u
, kind
);
15721 parens
.skip_until_found_close (parser
);
15726 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
);
15728 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15729 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
15731 parens
.skip_until_found_close (parser
);
15736 device ( expression ) */
15739 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
15741 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15742 matching_parens parens
;
15743 if (parens
.require_open (parser
))
15745 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15746 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15747 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15748 tree c
, t
= expr
.value
;
15749 t
= c_fully_fold (t
, false, NULL
);
15751 parens
.skip_until_found_close (parser
);
15753 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15755 c_parser_error (parser
, "expected integer expression");
15759 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
15761 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
15762 OMP_CLAUSE_DEVICE_ID (c
) = t
;
15763 OMP_CLAUSE_CHAIN (c
) = list
;
15771 dist_schedule ( static )
15772 dist_schedule ( static , expression ) */
15775 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
15777 tree c
, t
= NULL_TREE
;
15778 location_t loc
= c_parser_peek_token (parser
)->location
;
15780 matching_parens parens
;
15781 if (!parens
.require_open (parser
))
15784 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
15786 c_parser_error (parser
, "invalid dist_schedule kind");
15787 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15792 c_parser_consume_token (parser
);
15793 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15795 c_parser_consume_token (parser
);
15797 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15798 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15799 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15801 t
= c_fully_fold (t
, false, NULL
);
15802 parens
.skip_until_found_close (parser
);
15805 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15806 "expected %<,%> or %<)%>");
15808 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
15809 "dist_schedule"); */
15810 if (omp_find_clause (list
, OMP_CLAUSE_DIST_SCHEDULE
))
15811 warning_at (loc
, 0, "too many %qs clauses", "dist_schedule");
15812 if (t
== error_mark_node
)
15815 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
15816 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
15817 OMP_CLAUSE_CHAIN (c
) = list
;
15822 proc_bind ( proc-bind-kind )
15825 master | close | spread */
15828 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
15830 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15831 enum omp_clause_proc_bind_kind kind
;
15834 matching_parens parens
;
15835 if (!parens
.require_open (parser
))
15838 if (c_parser_next_token_is (parser
, CPP_NAME
))
15840 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15841 if (strcmp ("master", p
) == 0)
15842 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
15843 else if (strcmp ("close", p
) == 0)
15844 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
15845 else if (strcmp ("spread", p
) == 0)
15846 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
15853 check_no_duplicate_clause (list
, OMP_CLAUSE_PROC_BIND
, "proc_bind");
15854 c_parser_consume_token (parser
);
15855 parens
.skip_until_found_close (parser
);
15856 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
15857 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
15858 OMP_CLAUSE_CHAIN (c
) = list
;
15862 c_parser_error (parser
, "invalid proc_bind kind");
15863 parens
.skip_until_found_close (parser
);
15868 device_type ( host | nohost | any ) */
15871 c_parser_omp_clause_device_type (c_parser
*parser
, tree list
)
15873 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15874 enum omp_clause_device_type_kind kind
;
15877 matching_parens parens
;
15878 if (!parens
.require_open (parser
))
15881 if (c_parser_next_token_is (parser
, CPP_NAME
))
15883 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15884 if (strcmp ("host", p
) == 0)
15885 kind
= OMP_CLAUSE_DEVICE_TYPE_HOST
;
15886 else if (strcmp ("nohost", p
) == 0)
15887 kind
= OMP_CLAUSE_DEVICE_TYPE_NOHOST
;
15888 else if (strcmp ("any", p
) == 0)
15889 kind
= OMP_CLAUSE_DEVICE_TYPE_ANY
;
15896 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
15898 c_parser_consume_token (parser
);
15899 parens
.skip_until_found_close (parser
);
15900 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE_TYPE
);
15901 OMP_CLAUSE_DEVICE_TYPE_KIND (c
) = kind
;
15902 OMP_CLAUSE_CHAIN (c
) = list
;
15906 c_parser_error (parser
, "expected %<host%>, %<nohost%> or %<any%>");
15907 parens
.skip_until_found_close (parser
);
15912 to ( variable-list ) */
15915 c_parser_omp_clause_to (c_parser
*parser
, tree list
)
15917 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO
, list
);
15921 from ( variable-list ) */
15924 c_parser_omp_clause_from (c_parser
*parser
, tree list
)
15926 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FROM
, list
);
15930 uniform ( variable-list ) */
15933 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
15935 /* The clauses location. */
15936 location_t loc
= c_parser_peek_token (parser
)->location
;
15938 matching_parens parens
;
15939 if (parens
.require_open (parser
))
15941 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
15943 parens
.skip_until_found_close (parser
);
15948 /* Parse all OpenACC clauses. The set clauses allowed by the directive
15949 is a bitmask in MASK. Return the list of clauses found. */
15952 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
15953 const char *where
, bool finish_p
= true)
15955 tree clauses
= NULL
;
15958 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
15961 pragma_omp_clause c_kind
;
15962 const char *c_name
;
15963 tree prev
= clauses
;
15965 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
15966 c_parser_consume_token (parser
);
15968 here
= c_parser_peek_token (parser
)->location
;
15969 c_kind
= c_parser_omp_clause_name (parser
);
15973 case PRAGMA_OACC_CLAUSE_ASYNC
:
15974 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
15977 case PRAGMA_OACC_CLAUSE_AUTO
:
15978 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_AUTO
,
15982 case PRAGMA_OACC_CLAUSE_ATTACH
:
15983 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15986 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
15987 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
15988 c_name
= "collapse";
15990 case PRAGMA_OACC_CLAUSE_COPY
:
15991 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15994 case PRAGMA_OACC_CLAUSE_COPYIN
:
15995 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
15998 case PRAGMA_OACC_CLAUSE_COPYOUT
:
15999 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16000 c_name
= "copyout";
16002 case PRAGMA_OACC_CLAUSE_CREATE
:
16003 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16006 case PRAGMA_OACC_CLAUSE_DELETE
:
16007 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16010 case PRAGMA_OMP_CLAUSE_DEFAULT
:
16011 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
16012 c_name
= "default";
16014 case PRAGMA_OACC_CLAUSE_DETACH
:
16015 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16018 case PRAGMA_OACC_CLAUSE_DEVICE
:
16019 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16022 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
16023 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
16024 c_name
= "deviceptr";
16026 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
16027 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16028 c_name
= "device_resident";
16030 case PRAGMA_OACC_CLAUSE_FINALIZE
:
16031 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_FINALIZE
,
16033 c_name
= "finalize";
16035 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
16036 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
16037 c_name
= "firstprivate";
16039 case PRAGMA_OACC_CLAUSE_GANG
:
16041 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_GANG
,
16044 case PRAGMA_OACC_CLAUSE_HOST
:
16045 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16048 case PRAGMA_OACC_CLAUSE_IF
:
16049 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
16052 case PRAGMA_OACC_CLAUSE_IF_PRESENT
:
16053 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_IF_PRESENT
,
16055 c_name
= "if_present";
16057 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
16058 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_INDEPENDENT
,
16060 c_name
= "independent";
16062 case PRAGMA_OACC_CLAUSE_LINK
:
16063 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16066 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
16067 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16068 c_name
= "no_create";
16070 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
16071 clauses
= c_parser_oacc_single_int_clause (parser
,
16072 OMP_CLAUSE_NUM_GANGS
,
16074 c_name
= "num_gangs";
16076 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
16077 clauses
= c_parser_oacc_single_int_clause (parser
,
16078 OMP_CLAUSE_NUM_WORKERS
,
16080 c_name
= "num_workers";
16082 case PRAGMA_OACC_CLAUSE_PRESENT
:
16083 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16084 c_name
= "present";
16086 case PRAGMA_OACC_CLAUSE_PRIVATE
:
16087 clauses
= c_parser_omp_clause_private (parser
, clauses
);
16088 c_name
= "private";
16090 case PRAGMA_OACC_CLAUSE_REDUCTION
:
16092 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
16094 c_name
= "reduction";
16096 case PRAGMA_OACC_CLAUSE_SEQ
:
16097 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_SEQ
,
16101 case PRAGMA_OACC_CLAUSE_TILE
:
16102 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
16105 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
16106 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
16107 c_name
= "use_device";
16109 case PRAGMA_OACC_CLAUSE_VECTOR
:
16111 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_VECTOR
,
16114 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
16115 clauses
= c_parser_oacc_single_int_clause (parser
,
16116 OMP_CLAUSE_VECTOR_LENGTH
,
16118 c_name
= "vector_length";
16120 case PRAGMA_OACC_CLAUSE_WAIT
:
16121 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
16124 case PRAGMA_OACC_CLAUSE_WORKER
:
16126 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_WORKER
,
16130 c_parser_error (parser
, "expected %<#pragma acc%> clause");
16136 if (((mask
>> c_kind
) & 1) == 0)
16138 /* Remove the invalid clause(s) from the list to avoid
16139 confusing the rest of the compiler. */
16141 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
16146 c_parser_skip_to_pragma_eol (parser
);
16149 return c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16154 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16155 is a bitmask in MASK. Return the list of clauses found.
16156 FINISH_P set if c_finish_omp_clauses should be called.
16157 NESTED non-zero if clauses should be terminated by closing paren instead
16158 of end of pragma. If it is 2, additionally commas are required in between
16162 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
16163 const char *where
, bool finish_p
= true,
16166 tree clauses
= NULL
;
16169 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
16172 pragma_omp_clause c_kind
;
16173 const char *c_name
;
16174 tree prev
= clauses
;
16176 if (nested
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
16181 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16182 c_parser_consume_token (parser
);
16183 else if (nested
== 2)
16184 error_at (c_parser_peek_token (parser
)->location
,
16185 "clauses in %<simd%> trait should be separated "
16189 here
= c_parser_peek_token (parser
)->location
;
16190 c_kind
= c_parser_omp_clause_name (parser
);
16194 case PRAGMA_OMP_CLAUSE_BIND
:
16195 clauses
= c_parser_omp_clause_bind (parser
, clauses
);
16198 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
16199 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
16200 c_name
= "collapse";
16202 case PRAGMA_OMP_CLAUSE_COPYIN
:
16203 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
16206 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
16207 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
16208 c_name
= "copyprivate";
16210 case PRAGMA_OMP_CLAUSE_DEFAULT
:
16211 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
16212 c_name
= "default";
16214 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
16215 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
16216 c_name
= "firstprivate";
16218 case PRAGMA_OMP_CLAUSE_FINAL
:
16219 clauses
= c_parser_omp_clause_final (parser
, clauses
);
16222 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
16223 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
16224 c_name
= "grainsize";
16226 case PRAGMA_OMP_CLAUSE_HINT
:
16227 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
16230 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
16231 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
16232 c_name
= "defaultmap";
16234 case PRAGMA_OMP_CLAUSE_IF
:
16235 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
16238 case PRAGMA_OMP_CLAUSE_IN_REDUCTION
:
16240 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_IN_REDUCTION
,
16242 c_name
= "in_reduction";
16244 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
16245 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
16246 c_name
= "lastprivate";
16248 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
16249 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
16250 c_name
= "mergeable";
16252 case PRAGMA_OMP_CLAUSE_NOWAIT
:
16253 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
16256 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
16257 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
16258 c_name
= "num_tasks";
16260 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
16261 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
16262 c_name
= "num_threads";
16264 case PRAGMA_OMP_CLAUSE_ORDER
:
16265 clauses
= c_parser_omp_clause_order (parser
, clauses
);
16268 case PRAGMA_OMP_CLAUSE_ORDERED
:
16269 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
16270 c_name
= "ordered";
16272 case PRAGMA_OMP_CLAUSE_PRIORITY
:
16273 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
16274 c_name
= "priority";
16276 case PRAGMA_OMP_CLAUSE_PRIVATE
:
16277 clauses
= c_parser_omp_clause_private (parser
, clauses
);
16278 c_name
= "private";
16280 case PRAGMA_OMP_CLAUSE_REDUCTION
:
16282 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
16284 c_name
= "reduction";
16286 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
16287 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
16288 c_name
= "schedule";
16290 case PRAGMA_OMP_CLAUSE_SHARED
:
16291 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
16294 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION
:
16296 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_TASK_REDUCTION
,
16298 c_name
= "task_reduction";
16300 case PRAGMA_OMP_CLAUSE_UNTIED
:
16301 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
16304 case PRAGMA_OMP_CLAUSE_INBRANCH
:
16305 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
16307 c_name
= "inbranch";
16309 case PRAGMA_OMP_CLAUSE_NONTEMPORAL
:
16310 clauses
= c_parser_omp_clause_nontemporal (parser
, clauses
);
16311 c_name
= "nontemporal";
16313 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
16314 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
16316 c_name
= "notinbranch";
16318 case PRAGMA_OMP_CLAUSE_PARALLEL
:
16320 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
16322 c_name
= "parallel";
16326 error_at (here
, "%qs must be the first clause of %qs",
16331 case PRAGMA_OMP_CLAUSE_FOR
:
16333 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
16337 goto clause_not_first
;
16339 case PRAGMA_OMP_CLAUSE_SECTIONS
:
16341 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
16343 c_name
= "sections";
16345 goto clause_not_first
;
16347 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
16349 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
16351 c_name
= "taskgroup";
16353 goto clause_not_first
;
16355 case PRAGMA_OMP_CLAUSE_LINK
:
16357 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
16360 case PRAGMA_OMP_CLAUSE_TO
:
16361 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
16363 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO_DECLARE
,
16366 clauses
= c_parser_omp_clause_to (parser
, clauses
);
16369 case PRAGMA_OMP_CLAUSE_FROM
:
16370 clauses
= c_parser_omp_clause_from (parser
, clauses
);
16373 case PRAGMA_OMP_CLAUSE_UNIFORM
:
16374 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
16375 c_name
= "uniform";
16377 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
16378 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
16379 c_name
= "num_teams";
16381 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
16382 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
16383 c_name
= "thread_limit";
16385 case PRAGMA_OMP_CLAUSE_ALIGNED
:
16386 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
16387 c_name
= "aligned";
16389 case PRAGMA_OMP_CLAUSE_LINEAR
:
16390 clauses
= c_parser_omp_clause_linear (parser
, clauses
);
16393 case PRAGMA_OMP_CLAUSE_DEPEND
:
16394 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
16397 case PRAGMA_OMP_CLAUSE_MAP
:
16398 clauses
= c_parser_omp_clause_map (parser
, clauses
);
16401 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
16402 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
16403 c_name
= "use_device_ptr";
16405 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
:
16406 clauses
= c_parser_omp_clause_use_device_addr (parser
, clauses
);
16407 c_name
= "use_device_addr";
16409 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
16410 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
16411 c_name
= "is_device_ptr";
16413 case PRAGMA_OMP_CLAUSE_DEVICE
:
16414 clauses
= c_parser_omp_clause_device (parser
, clauses
);
16417 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
16418 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
16419 c_name
= "dist_schedule";
16421 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
16422 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
16423 c_name
= "proc_bind";
16425 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE
:
16426 clauses
= c_parser_omp_clause_device_type (parser
, clauses
);
16427 c_name
= "device_type";
16429 case PRAGMA_OMP_CLAUSE_SAFELEN
:
16430 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
16431 c_name
= "safelen";
16433 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
16434 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
16435 c_name
= "simdlen";
16437 case PRAGMA_OMP_CLAUSE_NOGROUP
:
16438 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
16439 c_name
= "nogroup";
16441 case PRAGMA_OMP_CLAUSE_THREADS
:
16443 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
16445 c_name
= "threads";
16447 case PRAGMA_OMP_CLAUSE_SIMD
:
16449 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
16454 c_parser_error (parser
, "expected %<#pragma omp%> clause");
16460 if (((mask
>> c_kind
) & 1) == 0)
16462 /* Remove the invalid clause(s) from the list to avoid
16463 confusing the rest of the compiler. */
16465 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
16471 c_parser_skip_to_pragma_eol (parser
);
16475 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
16476 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
16477 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
16483 /* OpenACC 2.0, OpenMP 2.5:
16487 In practice, we're also interested in adding the statement to an
16488 outer node. So it is convenient if we work around the fact that
16489 c_parser_statement calls add_stmt. */
16492 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
16494 tree stmt
= push_stmt_list ();
16495 c_parser_statement (parser
, if_p
);
16496 return pop_stmt_list (stmt
);
16500 # pragma acc cache (variable-list) new-line
16502 LOC is the location of the #pragma token.
16506 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
16508 tree stmt
, clauses
;
16510 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE__CACHE_
, NULL
);
16511 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16513 c_parser_skip_to_pragma_eol (parser
);
16515 stmt
= make_node (OACC_CACHE
);
16516 TREE_TYPE (stmt
) = void_type_node
;
16517 OACC_CACHE_CLAUSES (stmt
) = clauses
;
16518 SET_EXPR_LOCATION (stmt
, loc
);
16525 # pragma acc data oacc-data-clause[optseq] new-line
16528 LOC is the location of the #pragma token.
16531 #define OACC_DATA_CLAUSE_MASK \
16532 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16533 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16534 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16535 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16536 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16537 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16538 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16539 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16540 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16543 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
16545 tree stmt
, clauses
, block
;
16547 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
16548 "#pragma acc data");
16550 block
= c_begin_omp_parallel ();
16551 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
16553 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
16559 # pragma acc declare oacc-data-clause[optseq] new-line
16562 #define OACC_DECLARE_CLAUSE_MASK \
16563 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16564 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16565 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16566 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16567 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16568 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
16569 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
16570 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16573 c_parser_oacc_declare (c_parser
*parser
)
16575 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
16576 tree clauses
, stmt
, t
, decl
;
16578 bool error
= false;
16580 c_parser_consume_pragma (parser
);
16582 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
16583 "#pragma acc declare");
16586 error_at (pragma_loc
,
16587 "no valid clauses specified in %<#pragma acc declare%>");
16591 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
16593 location_t loc
= OMP_CLAUSE_LOCATION (t
);
16594 decl
= OMP_CLAUSE_DECL (t
);
16595 if (!DECL_P (decl
))
16597 error_at (loc
, "array section in %<#pragma acc declare%>");
16602 switch (OMP_CLAUSE_MAP_KIND (t
))
16604 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
16605 case GOMP_MAP_ALLOC
:
16607 case GOMP_MAP_FORCE_DEVICEPTR
:
16608 case GOMP_MAP_DEVICE_RESIDENT
:
16611 case GOMP_MAP_LINK
:
16612 if (!global_bindings_p ()
16613 && (TREE_STATIC (decl
)
16614 || !DECL_EXTERNAL (decl
)))
16617 "%qD must be a global variable in "
16618 "%<#pragma acc declare link%>",
16626 if (global_bindings_p ())
16628 error_at (loc
, "invalid OpenACC clause at file scope");
16632 if (DECL_EXTERNAL (decl
))
16635 "invalid use of %<extern%> variable %qD "
16636 "in %<#pragma acc declare%>", decl
);
16640 else if (TREE_PUBLIC (decl
))
16643 "invalid use of %<global%> variable %qD "
16644 "in %<#pragma acc declare%>", decl
);
16651 if (!c_check_in_current_scope (decl
))
16654 "%qD must be a variable declared in the same scope as "
16655 "%<#pragma acc declare%>", decl
);
16660 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
16661 || lookup_attribute ("omp declare target link",
16662 DECL_ATTRIBUTES (decl
)))
16664 error_at (loc
, "variable %qD used more than once with "
16665 "%<#pragma acc declare%>", decl
);
16674 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
16675 id
= get_identifier ("omp declare target link");
16677 id
= get_identifier ("omp declare target");
16679 DECL_ATTRIBUTES (decl
)
16680 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
16682 if (global_bindings_p ())
16684 symtab_node
*node
= symtab_node::get (decl
);
16687 node
->offloadable
= 1;
16688 if (ENABLE_OFFLOADING
)
16690 g
->have_offload
= true;
16691 if (is_a
<varpool_node
*> (node
))
16692 vec_safe_push (offload_vars
, decl
);
16699 if (error
|| global_bindings_p ())
16702 stmt
= make_node (OACC_DECLARE
);
16703 TREE_TYPE (stmt
) = void_type_node
;
16704 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
16705 SET_EXPR_LOCATION (stmt
, pragma_loc
);
16713 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
16717 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
16720 LOC is the location of the #pragma token.
16723 #define OACC_ENTER_DATA_CLAUSE_MASK \
16724 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16726 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16727 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16728 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16729 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16731 #define OACC_EXIT_DATA_CLAUSE_MASK \
16732 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16733 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
16736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
16737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
16738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16741 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
16743 location_t loc
= c_parser_peek_token (parser
)->location
;
16744 tree clauses
, stmt
;
16745 const char *p
= "";
16747 c_parser_consume_pragma (parser
);
16749 if (c_parser_next_token_is (parser
, CPP_NAME
))
16751 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16752 c_parser_consume_token (parser
);
16755 if (strcmp (p
, "data") != 0)
16757 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
16758 enter
? "enter" : "exit");
16759 parser
->error
= true;
16760 c_parser_skip_to_pragma_eol (parser
);
16765 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
16766 "#pragma acc enter data");
16768 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
16769 "#pragma acc exit data");
16771 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
16773 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
16774 enter
? "enter" : "exit");
16778 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
16779 TREE_TYPE (stmt
) = void_type_node
;
16780 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
16781 SET_EXPR_LOCATION (stmt
, loc
);
16787 # pragma acc host_data oacc-data-clause[optseq] new-line
16791 #define OACC_HOST_DATA_CLAUSE_MASK \
16792 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
16793 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16794 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
16797 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
16799 tree stmt
, clauses
, block
;
16801 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
16802 "#pragma acc host_data");
16804 block
= c_begin_omp_parallel ();
16805 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
16806 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
16813 # pragma acc loop oacc-loop-clause[optseq] new-line
16816 LOC is the location of the #pragma token.
16819 #define OACC_LOOP_CLAUSE_MASK \
16820 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
16821 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16822 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16823 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16824 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16825 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16826 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
16827 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
16828 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
16829 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
16831 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
16832 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
16834 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
16836 strcat (p_name
, " loop");
16837 mask
|= OACC_LOOP_CLAUSE_MASK
;
16839 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
16843 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
16845 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC
);
16847 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16850 tree block
= c_begin_compound_stmt (true);
16851 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
16853 block
= c_end_compound_stmt (loc
, block
, true);
16860 # pragma acc kernels oacc-kernels-clause[optseq] new-line
16865 # pragma acc parallel oacc-parallel-clause[optseq] new-line
16870 # pragma acc serial oacc-serial-clause[optseq] new-line
16873 LOC is the location of the #pragma token.
16876 #define OACC_KERNELS_CLAUSE_MASK \
16877 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16878 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16879 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16880 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16881 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16882 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16883 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16884 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16885 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16886 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16888 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16889 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16890 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16893 #define OACC_PARALLEL_CLAUSE_MASK \
16894 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16895 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16896 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16897 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16898 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16899 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16900 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16901 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16902 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16904 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16905 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
16906 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16907 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16908 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16909 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16910 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16913 #define OACC_SERIAL_CLAUSE_MASK \
16914 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16915 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
16916 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16917 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16918 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16919 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16920 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16921 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16922 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16923 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
16924 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16925 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
16926 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16927 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16928 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16931 c_parser_oacc_compute (location_t loc
, c_parser
*parser
,
16932 enum pragma_kind p_kind
, char *p_name
, bool *if_p
)
16934 omp_clause_mask mask
;
16935 enum tree_code code
;
16938 case PRAGMA_OACC_KERNELS
:
16939 strcat (p_name
, " kernels");
16940 mask
= OACC_KERNELS_CLAUSE_MASK
;
16941 code
= OACC_KERNELS
;
16943 case PRAGMA_OACC_PARALLEL
:
16944 strcat (p_name
, " parallel");
16945 mask
= OACC_PARALLEL_CLAUSE_MASK
;
16946 code
= OACC_PARALLEL
;
16948 case PRAGMA_OACC_SERIAL
:
16949 strcat (p_name
, " serial");
16950 mask
= OACC_SERIAL_CLAUSE_MASK
;
16951 code
= OACC_SERIAL
;
16954 gcc_unreachable ();
16957 if (c_parser_next_token_is (parser
, CPP_NAME
))
16959 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16960 if (strcmp (p
, "loop") == 0)
16962 c_parser_consume_token (parser
);
16963 tree block
= c_begin_omp_parallel ();
16965 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
16966 return c_finish_omp_construct (loc
, code
, block
, clauses
);
16970 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
);
16972 tree block
= c_begin_omp_parallel ();
16973 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
16975 return c_finish_omp_construct (loc
, code
, block
, clauses
);
16979 # pragma acc routine oacc-routine-clause[optseq] new-line
16980 function-definition
16982 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
16985 #define OACC_ROUTINE_CLAUSE_MASK \
16986 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16987 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16988 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16989 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) )
16991 /* Parse an OpenACC routine directive. For named directives, we apply
16992 immediately to the named function. For unnamed ones we then parse
16993 a declaration or definition, which must be for a function. */
16996 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
16998 gcc_checking_assert (context
== pragma_external
);
17000 oacc_routine_data data
;
17001 data
.error_seen
= false;
17002 data
.fndecl_seen
= false;
17003 data
.loc
= c_parser_peek_token (parser
)->location
;
17005 c_parser_consume_pragma (parser
);
17007 /* Look for optional '( name )'. */
17008 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17010 c_parser_consume_token (parser
); /* '(' */
17012 tree decl
= NULL_TREE
;
17013 c_token
*name_token
= c_parser_peek_token (parser
);
17014 location_t name_loc
= name_token
->location
;
17015 if (name_token
->type
== CPP_NAME
17016 && (name_token
->id_kind
== C_ID_ID
17017 || name_token
->id_kind
== C_ID_TYPENAME
))
17019 decl
= lookup_name (name_token
->value
);
17021 error_at (name_loc
,
17022 "%qE has not been declared", name_token
->value
);
17023 c_parser_consume_token (parser
);
17026 c_parser_error (parser
, "expected function name");
17029 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
17031 c_parser_skip_to_pragma_eol (parser
, false);
17036 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
17037 "#pragma acc routine");
17038 /* The clauses are in reverse order; fix that to make later diagnostic
17039 emission easier. */
17040 data
.clauses
= nreverse (data
.clauses
);
17042 if (TREE_CODE (decl
) != FUNCTION_DECL
)
17044 error_at (name_loc
, "%qD does not refer to a function", decl
);
17048 c_finish_oacc_routine (&data
, decl
, false);
17050 else /* No optional '( name )'. */
17053 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
17054 "#pragma acc routine");
17055 /* The clauses are in reverse order; fix that to make later diagnostic
17056 emission easier. */
17057 data
.clauses
= nreverse (data
.clauses
);
17059 /* Emit a helpful diagnostic if there's another pragma following this
17060 one. Also don't allow a static assertion declaration, as in the
17061 following we'll just parse a *single* "declaration or function
17062 definition", and the static assertion counts an one. */
17063 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
17064 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
17066 error_at (data
.loc
,
17067 "%<#pragma acc routine%> not immediately followed by"
17068 " function declaration or definition");
17069 /* ..., and then just keep going. */
17073 /* We only have to consider the pragma_external case here. */
17074 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
17075 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
17077 int ext
= disable_extension_diagnostics ();
17079 c_parser_consume_token (parser
);
17080 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
17081 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
17082 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
17083 NULL
, vNULL
, false, NULL
, &data
);
17084 restore_extension_diagnostics (ext
);
17087 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
17088 NULL
, vNULL
, false, NULL
, &data
);
17092 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17093 IS_DEFN is true if we're applying it to the definition. */
17096 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
17099 /* Keep going if we're in error reporting mode. */
17100 if (data
->error_seen
17101 || fndecl
== error_mark_node
)
17104 if (data
->fndecl_seen
)
17106 error_at (data
->loc
,
17107 "%<#pragma acc routine%> not immediately followed by"
17108 " a single function declaration or definition");
17109 data
->error_seen
= true;
17112 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
17114 error_at (data
->loc
,
17115 "%<#pragma acc routine%> not immediately followed by"
17116 " function declaration or definition");
17117 data
->error_seen
= true;
17122 = oacc_verify_routine_clauses (fndecl
, &data
->clauses
, data
->loc
,
17123 "#pragma acc routine");
17124 if (compatible
< 0)
17126 data
->error_seen
= true;
17129 if (compatible
> 0)
17134 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
17136 error_at (data
->loc
,
17138 ? G_("%<#pragma acc routine%> must be applied before use")
17139 : G_("%<#pragma acc routine%> must be applied before"
17141 data
->error_seen
= true;
17145 /* Set the routine's level of parallelism. */
17146 tree dims
= oacc_build_routine_dims (data
->clauses
);
17147 oacc_replace_fn_attrib (fndecl
, dims
);
17149 /* Add an "omp declare target" attribute. */
17150 DECL_ATTRIBUTES (fndecl
)
17151 = tree_cons (get_identifier ("omp declare target"),
17152 data
->clauses
, DECL_ATTRIBUTES (fndecl
));
17155 /* Remember that we've used this "#pragma acc routine". */
17156 data
->fndecl_seen
= true;
17160 # pragma acc update oacc-update-clause[optseq] new-line
17163 #define OACC_UPDATE_CLAUSE_MASK \
17164 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17165 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17166 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17167 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17168 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
17169 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17172 c_parser_oacc_update (c_parser
*parser
)
17174 location_t loc
= c_parser_peek_token (parser
)->location
;
17176 c_parser_consume_pragma (parser
);
17178 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
17179 "#pragma acc update");
17180 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
17183 "%<#pragma acc update%> must contain at least one "
17184 "%<device%> or %<host%> or %<self%> clause");
17191 tree stmt
= make_node (OACC_UPDATE
);
17192 TREE_TYPE (stmt
) = void_type_node
;
17193 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
17194 SET_EXPR_LOCATION (stmt
, loc
);
17199 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
17201 LOC is the location of the #pragma token.
17204 #define OACC_WAIT_CLAUSE_MASK \
17205 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
17208 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
17210 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
17212 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
17213 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
17215 strcpy (p_name
, " wait");
17216 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
17217 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
17224 # pragma omp atomic new-line
17228 x binop= expr | x++ | ++x | x-- | --x
17230 +, *, -, /, &, ^, |, <<, >>
17232 where x is an lvalue expression with scalar type.
17235 # pragma omp atomic new-line
17238 # pragma omp atomic read new-line
17241 # pragma omp atomic write new-line
17244 # pragma omp atomic update new-line
17247 # pragma omp atomic capture new-line
17250 # pragma omp atomic capture new-line
17258 expression-stmt | x = x binop expr
17260 v = expression-stmt
17262 { v = x; update-stmt; } | { update-stmt; v = x; }
17266 expression-stmt | x = x binop expr | x = expr binop x
17270 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
17272 where x and v are lvalue expressions with scalar type.
17274 LOC is the location of the #pragma token. */
17277 c_parser_omp_atomic (location_t loc
, c_parser
*parser
)
17279 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
;
17280 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
17281 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
17282 enum tree_code code
= ERROR_MARK
, opcode
= NOP_EXPR
;
17283 enum omp_memory_order memory_order
= OMP_MEMORY_ORDER_UNSPECIFIED
;
17284 struct c_expr expr
;
17286 bool structured_block
= false;
17287 bool swapped
= false;
17290 tree clauses
= NULL_TREE
;
17292 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17294 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
17295 c_parser_consume_token (parser
);
17299 if (c_parser_next_token_is (parser
, CPP_NAME
))
17302 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17303 location_t cloc
= c_parser_peek_token (parser
)->location
;
17304 enum tree_code new_code
= ERROR_MARK
;
17305 enum omp_memory_order new_memory_order
17306 = OMP_MEMORY_ORDER_UNSPECIFIED
;
17308 if (!strcmp (p
, "read"))
17309 new_code
= OMP_ATOMIC_READ
;
17310 else if (!strcmp (p
, "write"))
17311 new_code
= NOP_EXPR
;
17312 else if (!strcmp (p
, "update"))
17313 new_code
= OMP_ATOMIC
;
17314 else if (!strcmp (p
, "capture"))
17315 new_code
= OMP_ATOMIC_CAPTURE_NEW
;
17316 else if (!strcmp (p
, "seq_cst"))
17317 new_memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17318 else if (!strcmp (p
, "acq_rel"))
17319 new_memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
17320 else if (!strcmp (p
, "release"))
17321 new_memory_order
= OMP_MEMORY_ORDER_RELEASE
;
17322 else if (!strcmp (p
, "acquire"))
17323 new_memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
17324 else if (!strcmp (p
, "relaxed"))
17325 new_memory_order
= OMP_MEMORY_ORDER_RELAXED
;
17326 else if (!strcmp (p
, "hint"))
17328 c_parser_consume_token (parser
);
17329 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
17335 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
17336 "%<capture%>, %<seq_cst%>, %<acq_rel%>, "
17337 "%<release%>, %<relaxed%> or %<hint%> clause");
17341 if (new_code
!= ERROR_MARK
)
17343 if (code
!= ERROR_MARK
)
17344 error_at (cloc
, "too many atomic clauses");
17348 else if (new_memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
17350 if (memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
17351 error_at (cloc
, "too many memory order clauses");
17353 memory_order
= new_memory_order
;
17355 c_parser_consume_token (parser
);
17361 c_parser_skip_to_pragma_eol (parser
);
17363 if (code
== ERROR_MARK
)
17365 if (memory_order
== OMP_MEMORY_ORDER_UNSPECIFIED
)
17368 = (enum omp_requires
) (omp_requires_mask
17369 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
);
17370 switch ((enum omp_memory_order
)
17371 (omp_requires_mask
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
))
17373 case OMP_MEMORY_ORDER_UNSPECIFIED
:
17374 case OMP_MEMORY_ORDER_RELAXED
:
17375 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
17377 case OMP_MEMORY_ORDER_SEQ_CST
:
17378 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17380 case OMP_MEMORY_ORDER_ACQ_REL
:
17383 case OMP_ATOMIC_READ
:
17384 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
17386 case NOP_EXPR
: /* atomic write */
17388 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
17391 memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
17396 gcc_unreachable ();
17402 case OMP_ATOMIC_READ
:
17403 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
17404 || memory_order
== OMP_MEMORY_ORDER_RELEASE
)
17406 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
17407 "%<acq_rel%> or %<release%> clauses");
17408 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17411 case NOP_EXPR
: /* atomic write */
17412 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
17413 || memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
17415 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
17416 "%<acq_rel%> or %<acquire%> clauses");
17417 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17421 if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
17422 || memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
17424 error_at (loc
, "%<#pragma omp atomic update%> incompatible with "
17425 "%<acq_rel%> or %<acquire%> clauses");
17426 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
17435 case OMP_ATOMIC_READ
:
17436 case NOP_EXPR
: /* atomic write */
17437 v
= c_parser_cast_expression (parser
, NULL
).value
;
17438 non_lvalue_p
= !lvalue_p (v
);
17439 v
= c_fully_fold (v
, false, NULL
, true);
17440 if (v
== error_mark_node
)
17443 v
= non_lvalue (v
);
17444 loc
= c_parser_peek_token (parser
)->location
;
17445 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
17447 if (code
== NOP_EXPR
)
17449 lhs
= c_parser_expression (parser
).value
;
17450 lhs
= c_fully_fold (lhs
, false, NULL
);
17451 if (lhs
== error_mark_node
)
17456 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
17457 non_lvalue_p
= !lvalue_p (lhs
);
17458 lhs
= c_fully_fold (lhs
, false, NULL
, true);
17459 if (lhs
== error_mark_node
)
17462 lhs
= non_lvalue (lhs
);
17464 if (code
== NOP_EXPR
)
17466 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
17474 case OMP_ATOMIC_CAPTURE_NEW
:
17475 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
17477 c_parser_consume_token (parser
);
17478 structured_block
= true;
17482 v
= c_parser_cast_expression (parser
, NULL
).value
;
17483 non_lvalue_p
= !lvalue_p (v
);
17484 v
= c_fully_fold (v
, false, NULL
, true);
17485 if (v
== error_mark_node
)
17488 v
= non_lvalue (v
);
17489 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
17497 /* For structured_block case we don't know yet whether
17498 old or new x should be captured. */
17500 eloc
= c_parser_peek_token (parser
)->location
;
17501 expr
= c_parser_cast_expression (parser
, NULL
);
17503 expr
= default_function_array_conversion (eloc
, expr
);
17504 unfolded_lhs
= expr
.value
;
17505 lhs
= c_fully_fold (lhs
, false, NULL
, true);
17507 switch (TREE_CODE (lhs
))
17511 c_parser_skip_to_end_of_block_or_statement (parser
);
17512 if (structured_block
)
17514 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
17515 c_parser_consume_token (parser
);
17516 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
17518 c_parser_skip_to_end_of_block_or_statement (parser
);
17519 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
17520 c_parser_consume_token (parser
);
17525 case POSTINCREMENT_EXPR
:
17526 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
17527 code
= OMP_ATOMIC_CAPTURE_OLD
;
17529 case PREINCREMENT_EXPR
:
17530 lhs
= TREE_OPERAND (lhs
, 0);
17531 unfolded_lhs
= NULL_TREE
;
17532 opcode
= PLUS_EXPR
;
17533 rhs
= integer_one_node
;
17536 case POSTDECREMENT_EXPR
:
17537 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
17538 code
= OMP_ATOMIC_CAPTURE_OLD
;
17540 case PREDECREMENT_EXPR
:
17541 lhs
= TREE_OPERAND (lhs
, 0);
17542 unfolded_lhs
= NULL_TREE
;
17543 opcode
= MINUS_EXPR
;
17544 rhs
= integer_one_node
;
17547 case COMPOUND_EXPR
:
17548 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
17549 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
17550 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
17551 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
17552 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
17553 (TREE_OPERAND (lhs
, 1), 0), 0)))
17555 /* Undo effects of boolean_increment for post {in,de}crement. */
17556 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
17559 if (TREE_CODE (lhs
) == MODIFY_EXPR
17560 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs
, 0))) == BOOLEAN_TYPE
)
17562 /* Undo effects of boolean_increment. */
17563 if (integer_onep (TREE_OPERAND (lhs
, 1)))
17565 /* This is pre or post increment. */
17566 rhs
= TREE_OPERAND (lhs
, 1);
17567 lhs
= TREE_OPERAND (lhs
, 0);
17568 unfolded_lhs
= NULL_TREE
;
17570 if (code
== OMP_ATOMIC_CAPTURE_NEW
17571 && !structured_block
17572 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
17573 code
= OMP_ATOMIC_CAPTURE_OLD
;
17576 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
17577 && TREE_OPERAND (lhs
, 0)
17578 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
17580 /* This is pre or post decrement. */
17581 rhs
= TREE_OPERAND (lhs
, 1);
17582 lhs
= TREE_OPERAND (lhs
, 0);
17583 unfolded_lhs
= NULL_TREE
;
17585 if (code
== OMP_ATOMIC_CAPTURE_NEW
17586 && !structured_block
17587 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
17588 code
= OMP_ATOMIC_CAPTURE_OLD
;
17594 if (!lvalue_p (unfolded_lhs
))
17595 lhs
= non_lvalue (lhs
);
17596 switch (c_parser_peek_token (parser
)->type
)
17599 opcode
= MULT_EXPR
;
17602 opcode
= TRUNC_DIV_EXPR
;
17605 opcode
= PLUS_EXPR
;
17608 opcode
= MINUS_EXPR
;
17610 case CPP_LSHIFT_EQ
:
17611 opcode
= LSHIFT_EXPR
;
17613 case CPP_RSHIFT_EQ
:
17614 opcode
= RSHIFT_EXPR
;
17617 opcode
= BIT_AND_EXPR
;
17620 opcode
= BIT_IOR_EXPR
;
17623 opcode
= BIT_XOR_EXPR
;
17626 c_parser_consume_token (parser
);
17627 eloc
= c_parser_peek_token (parser
)->location
;
17628 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
17630 switch (TREE_CODE (rhs1
))
17633 case TRUNC_DIV_EXPR
:
17642 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
17644 opcode
= TREE_CODE (rhs1
);
17645 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
17647 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
17651 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
17653 opcode
= TREE_CODE (rhs1
);
17654 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
17656 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
17658 swapped
= !commutative_tree_code (opcode
);
17667 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
17669 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
17671 code
= OMP_ATOMIC_CAPTURE_OLD
;
17674 expr
= default_function_array_read_conversion (eloc
, expr
);
17675 unfolded_lhs1
= expr
.value
;
17676 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
17678 c_parser_consume_token (parser
);
17681 if (structured_block
)
17684 expr
= default_function_array_read_conversion (eloc
, expr
);
17685 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
17690 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
17693 c_parser_error (parser
,
17694 "invalid operator for %<#pragma omp atomic%>");
17698 /* Arrange to pass the location of the assignment operator to
17699 c_finish_omp_atomic. */
17700 loc
= c_parser_peek_token (parser
)->location
;
17701 c_parser_consume_token (parser
);
17702 eloc
= c_parser_peek_token (parser
)->location
;
17703 expr
= c_parser_expression (parser
);
17704 expr
= default_function_array_read_conversion (eloc
, expr
);
17706 rhs
= c_fully_fold (rhs
, false, NULL
, true);
17710 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
17712 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
17714 v
= c_parser_cast_expression (parser
, NULL
).value
;
17715 non_lvalue_p
= !lvalue_p (v
);
17716 v
= c_fully_fold (v
, false, NULL
, true);
17717 if (v
== error_mark_node
)
17720 v
= non_lvalue (v
);
17721 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
17723 eloc
= c_parser_peek_token (parser
)->location
;
17724 expr
= c_parser_cast_expression (parser
, NULL
);
17726 expr
= default_function_array_read_conversion (eloc
, expr
);
17727 unfolded_lhs1
= expr
.value
;
17728 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
17729 if (lhs1
== error_mark_node
)
17731 if (!lvalue_p (unfolded_lhs1
))
17732 lhs1
= non_lvalue (lhs1
);
17734 if (structured_block
)
17736 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
17737 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
17740 if (unfolded_lhs
&& unfolded_lhs1
17741 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
17743 error ("%<#pragma omp atomic capture%> uses two different "
17744 "expressions for memory");
17745 stmt
= error_mark_node
;
17748 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
,
17749 swapped
, memory_order
);
17750 if (stmt
!= error_mark_node
)
17753 if (!structured_block
)
17754 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
17759 # pragma omp barrier new-line
17763 c_parser_omp_barrier (c_parser
*parser
)
17765 location_t loc
= c_parser_peek_token (parser
)->location
;
17766 c_parser_consume_pragma (parser
);
17767 c_parser_skip_to_pragma_eol (parser
);
17769 c_finish_omp_barrier (loc
);
17773 # pragma omp critical [(name)] new-line
17777 # pragma omp critical [(name) [hint(expression)]] new-line
17779 LOC is the location of the #pragma itself. */
17781 #define OMP_CRITICAL_CLAUSE_MASK \
17782 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
17785 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
17787 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
17789 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17791 c_parser_consume_token (parser
);
17792 if (c_parser_next_token_is (parser
, CPP_NAME
))
17794 name
= c_parser_peek_token (parser
)->value
;
17795 c_parser_consume_token (parser
);
17796 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
17799 c_parser_error (parser
, "expected identifier");
17801 if (c_parser_next_token_is (parser
, CPP_COMMA
)
17802 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
17803 c_parser_consume_token (parser
);
17805 clauses
= c_parser_omp_all_clauses (parser
, OMP_CRITICAL_CLAUSE_MASK
,
17806 "#pragma omp critical");
17807 stmt
= c_parser_omp_structured_block (parser
, if_p
);
17808 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
17812 # pragma omp depobj ( depobj ) depobj-clause new-line
17815 depend (dependence-type : locator)
17817 update (dependence-type)
17826 c_parser_omp_depobj (c_parser
*parser
)
17828 location_t loc
= c_parser_peek_token (parser
)->location
;
17829 c_parser_consume_pragma (parser
);
17830 matching_parens parens
;
17831 if (!parens
.require_open (parser
))
17833 c_parser_skip_to_pragma_eol (parser
);
17837 tree depobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
17838 if (depobj
!= error_mark_node
)
17840 if (!lvalue_p (depobj
))
17842 error_at (EXPR_LOC_OR_LOC (depobj
, loc
),
17843 "%<depobj%> expression is not lvalue expression");
17844 depobj
= error_mark_node
;
17848 tree addr
= build_unary_op (EXPR_LOC_OR_LOC (depobj
, loc
), ADDR_EXPR
,
17850 if (addr
== error_mark_node
)
17851 depobj
= error_mark_node
;
17853 depobj
= build_indirect_ref (EXPR_LOC_OR_LOC (depobj
, loc
),
17854 addr
, RO_UNARY_STAR
);
17858 parens
.skip_until_found_close (parser
);
17859 tree clause
= NULL_TREE
;
17860 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_SOURCE
;
17861 location_t c_loc
= c_parser_peek_token (parser
)->location
;
17862 if (c_parser_next_token_is (parser
, CPP_NAME
))
17864 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17866 c_parser_consume_token (parser
);
17867 if (!strcmp ("depend", p
))
17869 clause
= c_parser_omp_clause_depend (parser
, NULL_TREE
);
17870 clause
= c_finish_omp_clauses (clause
, C_ORT_OMP
);
17872 clause
= error_mark_node
;
17874 else if (!strcmp ("destroy", p
))
17875 kind
= OMP_CLAUSE_DEPEND_LAST
;
17876 else if (!strcmp ("update", p
))
17878 matching_parens c_parens
;
17879 if (c_parens
.require_open (parser
))
17881 location_t c2_loc
= c_parser_peek_token (parser
)->location
;
17882 if (c_parser_next_token_is (parser
, CPP_NAME
))
17885 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17887 c_parser_consume_token (parser
);
17888 if (!strcmp ("in", p2
))
17889 kind
= OMP_CLAUSE_DEPEND_IN
;
17890 else if (!strcmp ("out", p2
))
17891 kind
= OMP_CLAUSE_DEPEND_OUT
;
17892 else if (!strcmp ("inout", p2
))
17893 kind
= OMP_CLAUSE_DEPEND_INOUT
;
17894 else if (!strcmp ("mutexinoutset", p2
))
17895 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
17897 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
17899 clause
= error_mark_node
;
17900 error_at (c2_loc
, "expected %<in%>, %<out%>, %<inout%> or "
17901 "%<mutexinoutset%>");
17903 c_parens
.skip_until_found_close (parser
);
17906 clause
= error_mark_node
;
17909 if (!clause
&& kind
== OMP_CLAUSE_DEPEND_SOURCE
)
17911 clause
= error_mark_node
;
17912 error_at (c_loc
, "expected %<depend%>, %<destroy%> or %<update%> clause");
17914 c_parser_skip_to_pragma_eol (parser
);
17916 c_finish_omp_depobj (loc
, depobj
, kind
, clause
);
17921 # pragma omp flush flush-vars[opt] new-line
17927 # pragma omp flush memory-order-clause new-line */
17930 c_parser_omp_flush (c_parser
*parser
)
17932 location_t loc
= c_parser_peek_token (parser
)->location
;
17933 c_parser_consume_pragma (parser
);
17934 enum memmodel mo
= MEMMODEL_LAST
;
17935 if (c_parser_next_token_is (parser
, CPP_NAME
))
17938 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17940 if (!strcmp (p
, "acq_rel"))
17941 mo
= MEMMODEL_ACQ_REL
;
17942 else if (!strcmp (p
, "release"))
17943 mo
= MEMMODEL_RELEASE
;
17944 else if (!strcmp (p
, "acquire"))
17945 mo
= MEMMODEL_ACQUIRE
;
17947 error_at (c_parser_peek_token (parser
)->location
,
17948 "expected %<acq_rel%>, %<release%> or %<acquire%>");
17949 c_parser_consume_token (parser
);
17951 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17953 if (mo
!= MEMMODEL_LAST
)
17954 error_at (c_parser_peek_token (parser
)->location
,
17955 "%<flush%> list specified together with memory order "
17957 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
17959 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17960 c_parser_error (parser
, "expected %<(%> or end of line");
17961 c_parser_skip_to_pragma_eol (parser
);
17963 c_finish_omp_flush (loc
, mo
);
17969 { structured-block scan-directive structured-block } */
17972 c_parser_omp_scan_loop_body (c_parser
*parser
, bool open_brace_parsed
)
17976 tree clauses
= NULL_TREE
;
17978 loc
= c_parser_peek_token (parser
)->location
;
17979 if (!open_brace_parsed
17980 && !c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
17982 /* Avoid skipping until the end of the block. */
17983 parser
->error
= false;
17987 substmt
= c_parser_omp_structured_block (parser
, NULL
);
17988 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, NULL_TREE
);
17989 SET_EXPR_LOCATION (substmt
, loc
);
17990 add_stmt (substmt
);
17992 loc
= c_parser_peek_token (parser
)->location
;
17993 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SCAN
)
17995 enum omp_clause_code clause
= OMP_CLAUSE_ERROR
;
17997 c_parser_consume_pragma (parser
);
17999 if (c_parser_next_token_is (parser
, CPP_NAME
))
18002 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18003 if (strcmp (p
, "inclusive") == 0)
18004 clause
= OMP_CLAUSE_INCLUSIVE
;
18005 else if (strcmp (p
, "exclusive") == 0)
18006 clause
= OMP_CLAUSE_EXCLUSIVE
;
18008 if (clause
!= OMP_CLAUSE_ERROR
)
18010 c_parser_consume_token (parser
);
18011 clauses
= c_parser_omp_var_list_parens (parser
, clause
, NULL_TREE
);
18014 c_parser_error (parser
, "expected %<inclusive%> or "
18015 "%<exclusive%> clause");
18016 c_parser_skip_to_pragma_eol (parser
);
18019 error ("expected %<#pragma omp scan%>");
18021 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
18022 substmt
= c_parser_omp_structured_block (parser
, NULL
);
18023 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, clauses
);
18024 SET_EXPR_LOCATION (substmt
, loc
);
18025 add_stmt (substmt
);
18027 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
18031 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
18032 The real trick here is to determine the loop control variable early
18033 so that we can push a new decl if necessary to make it private.
18034 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
18038 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
18039 tree clauses
, tree
*cclauses
, bool *if_p
)
18041 tree decl
, cond
, incr
, save_break
, save_cont
, body
, init
, stmt
, cl
;
18042 tree declv
, condv
, incrv
, initv
, ret
= NULL_TREE
;
18043 tree pre_body
= NULL_TREE
, this_pre_body
;
18044 tree ordered_cl
= NULL_TREE
;
18045 bool fail
= false, open_brace_parsed
= false;
18046 int i
, collapse
= 1, ordered
= 0, count
, nbraces
= 0;
18047 location_t for_loc
;
18048 bool tiling
= false;
18049 bool inscan
= false;
18050 vec
<tree
, va_gc
> *for_block
= make_tree_vector ();
18052 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
18053 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
18054 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
18055 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
18058 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
18060 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
18061 && OMP_CLAUSE_ORDERED_EXPR (cl
))
18064 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
18066 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_REDUCTION
18067 && OMP_CLAUSE_REDUCTION_INSCAN (cl
)
18068 && (code
== OMP_SIMD
|| code
== OMP_FOR
))
18071 if (ordered
&& ordered
< collapse
)
18073 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
18074 "%<ordered%> clause parameter is less than %<collapse%>");
18075 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
18076 = build_int_cst (NULL_TREE
, collapse
);
18077 ordered
= collapse
;
18081 for (tree
*pc
= &clauses
; *pc
; )
18082 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LINEAR
)
18084 error_at (OMP_CLAUSE_LOCATION (*pc
),
18085 "%<linear%> clause may not be specified together "
18086 "with %<ordered%> clause with a parameter");
18087 *pc
= OMP_CLAUSE_CHAIN (*pc
);
18090 pc
= &OMP_CLAUSE_CHAIN (*pc
);
18093 gcc_assert (tiling
|| (collapse
>= 1 && ordered
>= 0));
18094 count
= ordered
? ordered
: collapse
;
18096 declv
= make_tree_vec (count
);
18097 initv
= make_tree_vec (count
);
18098 condv
= make_tree_vec (count
);
18099 incrv
= make_tree_vec (count
);
18101 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
))
18103 c_parser_error (parser
, "for statement expected");
18106 for_loc
= c_parser_peek_token (parser
)->location
;
18107 c_parser_consume_token (parser
);
18109 for (i
= 0; i
< count
; i
++)
18111 int bracecount
= 0;
18113 matching_parens parens
;
18114 if (!parens
.require_open (parser
))
18117 /* Parse the initialization declaration or expression. */
18118 if (c_parser_next_tokens_start_declaration (parser
))
18121 vec_safe_push (for_block
, c_begin_compound_stmt (true));
18122 this_pre_body
= push_stmt_list ();
18123 c_in_omp_for
= true;
18124 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
18126 c_in_omp_for
= false;
18129 this_pre_body
= pop_stmt_list (this_pre_body
);
18133 pre_body
= push_stmt_list ();
18135 add_stmt (this_pre_body
);
18136 pre_body
= pop_stmt_list (pre_body
);
18139 pre_body
= this_pre_body
;
18141 decl
= check_for_loop_decls (for_loc
, flag_isoc99
);
18144 if (DECL_INITIAL (decl
) == error_mark_node
)
18145 decl
= error_mark_node
;
18148 else if (c_parser_next_token_is (parser
, CPP_NAME
)
18149 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
18151 struct c_expr decl_exp
;
18152 struct c_expr init_exp
;
18153 location_t init_loc
;
18155 decl_exp
= c_parser_postfix_expression (parser
);
18156 decl
= decl_exp
.value
;
18158 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
18160 init_loc
= c_parser_peek_token (parser
)->location
;
18161 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
18162 init_exp
= default_function_array_read_conversion (init_loc
,
18164 c_in_omp_for
= true;
18165 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
18166 NOP_EXPR
, init_loc
, init_exp
.value
,
18167 init_exp
.original_type
);
18168 c_in_omp_for
= false;
18169 init
= c_process_expr_stmt (init_loc
, init
);
18171 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
18176 c_parser_error (parser
,
18177 "expected iteration declaration or initialization");
18178 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
18184 /* Parse the loop condition. */
18186 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
18188 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
18189 c_in_omp_for
= true;
18190 struct c_expr cond_expr
18191 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
18192 c_in_omp_for
= false;
18194 cond
= cond_expr
.value
;
18195 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
18196 switch (cond_expr
.original_code
)
18204 if (code
!= OACC_LOOP
)
18208 /* Can't be cond = error_mark_node, because we want to preserve
18209 the location until c_finish_omp_for. */
18210 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
18213 protected_set_expr_location (cond
, cond_loc
);
18215 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
18217 /* Parse the increment expression. */
18219 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
18221 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
18223 incr
= c_process_expr_stmt (incr_loc
,
18224 c_parser_expression (parser
).value
);
18226 parens
.skip_until_found_close (parser
);
18228 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
18232 TREE_VEC_ELT (declv
, i
) = decl
;
18233 TREE_VEC_ELT (initv
, i
) = init
;
18234 TREE_VEC_ELT (condv
, i
) = cond
;
18235 TREE_VEC_ELT (incrv
, i
) = incr
;
18239 if (i
== count
- 1)
18242 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
18243 in between the collapsed for loops to be still considered perfectly
18244 nested. Hopefully the final version clarifies this.
18245 For now handle (multiple) {'s and empty statements. */
18248 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
18250 c_parser_consume_token (parser
);
18253 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
18255 c_parser_consume_token (parser
);
18258 else if (bracecount
18259 && c_parser_next_token_is (parser
, CPP_SEMICOLON
))
18260 c_parser_consume_token (parser
);
18263 c_parser_error (parser
, "not enough perfectly nested loops");
18266 open_brace_parsed
= true;
18276 nbraces
+= bracecount
;
18282 save_break
= c_break_label
;
18283 c_break_label
= size_one_node
;
18284 save_cont
= c_cont_label
;
18285 c_cont_label
= NULL_TREE
;
18286 body
= push_stmt_list ();
18289 c_parser_omp_scan_loop_body (parser
, open_brace_parsed
);
18290 else if (open_brace_parsed
)
18292 location_t here
= c_parser_peek_token (parser
)->location
;
18293 stmt
= c_begin_compound_stmt (true);
18294 c_parser_compound_statement_nostart (parser
);
18295 add_stmt (c_end_compound_stmt (here
, stmt
, true));
18298 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
18301 tree t
= build1 (LABEL_EXPR
, void_type_node
, c_cont_label
);
18302 SET_EXPR_LOCATION (t
, loc
);
18306 body
= pop_stmt_list (body
);
18307 c_break_label
= save_break
;
18308 c_cont_label
= save_cont
;
18312 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18314 c_parser_consume_token (parser
);
18317 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
18318 c_parser_consume_token (parser
);
18321 c_parser_error (parser
, "collapsed loops not perfectly nested");
18324 location_t here
= c_parser_peek_token (parser
)->location
;
18325 stmt
= c_begin_compound_stmt (true);
18327 c_parser_compound_statement_nostart (parser
);
18328 body
= c_end_compound_stmt (here
, stmt
, true);
18335 /* Only bother calling c_finish_omp_for if we haven't already generated
18336 an error from the initialization parsing. */
18339 c_in_omp_for
= true;
18340 stmt
= c_finish_omp_for (loc
, code
, declv
, NULL
, initv
, condv
,
18341 incrv
, body
, pre_body
, true);
18342 c_in_omp_for
= false;
18344 /* Check for iterators appearing in lb, b or incr expressions. */
18345 if (stmt
&& !c_omp_check_loop_iv (stmt
, declv
, NULL
))
18352 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (stmt
)); i
++)
18354 tree init
= TREE_VEC_ELT (OMP_FOR_INIT (stmt
), i
);
18355 gcc_assert (TREE_CODE (init
) == MODIFY_EXPR
);
18356 tree decl
= TREE_OPERAND (init
, 0);
18357 tree cond
= TREE_VEC_ELT (OMP_FOR_COND (stmt
), i
);
18358 gcc_assert (COMPARISON_CLASS_P (cond
));
18359 gcc_assert (TREE_OPERAND (cond
, 0) == decl
);
18361 tree op0
= TREE_OPERAND (init
, 1);
18362 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
18363 || TREE_CODE (op0
) != TREE_VEC
)
18364 TREE_OPERAND (init
, 1) = c_fully_fold (op0
, false, NULL
);
18367 TREE_VEC_ELT (op0
, 1)
18368 = c_fully_fold (TREE_VEC_ELT (op0
, 1), false, NULL
);
18369 TREE_VEC_ELT (op0
, 2)
18370 = c_fully_fold (TREE_VEC_ELT (op0
, 2), false, NULL
);
18373 tree op1
= TREE_OPERAND (cond
, 1);
18374 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
18375 || TREE_CODE (op1
) != TREE_VEC
)
18376 TREE_OPERAND (cond
, 1) = c_fully_fold (op1
, false, NULL
);
18379 TREE_VEC_ELT (op1
, 1)
18380 = c_fully_fold (TREE_VEC_ELT (op1
, 1), false, NULL
);
18381 TREE_VEC_ELT (op1
, 2)
18382 = c_fully_fold (TREE_VEC_ELT (op1
, 2), false, NULL
);
18386 if (cclauses
!= NULL
18387 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
18390 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
18391 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
18392 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
18393 c
= &OMP_CLAUSE_CHAIN (*c
);
18396 for (i
= 0; i
< count
; i
++)
18397 if (TREE_VEC_ELT (declv
, i
) == OMP_CLAUSE_DECL (*c
))
18400 c
= &OMP_CLAUSE_CHAIN (*c
);
18401 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
18404 "iteration variable %qD should not be firstprivate",
18405 OMP_CLAUSE_DECL (*c
));
18406 *c
= OMP_CLAUSE_CHAIN (*c
);
18410 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
18412 *c
= OMP_CLAUSE_CHAIN (*c
);
18413 if (code
== OMP_SIMD
)
18415 OMP_CLAUSE_CHAIN (l
)
18416 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
18417 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
18421 OMP_CLAUSE_CHAIN (l
) = clauses
;
18427 OMP_FOR_CLAUSES (stmt
) = clauses
;
18432 while (!for_block
->is_empty ())
18434 /* FIXME diagnostics: LOC below should be the actual location of
18435 this particular for block. We need to build a list of
18436 locations to go along with FOR_BLOCK. */
18437 stmt
= c_end_compound_stmt (loc
, for_block
->pop (), true);
18440 release_tree_vector (for_block
);
18444 /* Helper function for OpenMP parsing, split clauses and call
18445 finish_omp_clauses on each of the set of clauses afterwards. */
18448 omp_split_clauses (location_t loc
, enum tree_code code
,
18449 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
18452 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
18453 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
18455 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
], C_ORT_OMP
);
18459 #pragma omp loop loop-clause[optseq] new-line
18462 LOC is the location of the #pragma token.
18465 #define OMP_LOOP_CLAUSE_MASK \
18466 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18467 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18468 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18469 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18470 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
18471 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18474 c_parser_omp_loop (location_t loc
, c_parser
*parser
,
18475 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18478 tree block
, clauses
, ret
;
18480 strcat (p_name
, " loop");
18481 mask
|= OMP_LOOP_CLAUSE_MASK
;
18483 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18486 omp_split_clauses (loc
, OMP_LOOP
, mask
, clauses
, cclauses
);
18487 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_LOOP
];
18490 block
= c_begin_compound_stmt (true);
18491 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_LOOP
, clauses
, cclauses
, if_p
);
18492 block
= c_end_compound_stmt (loc
, block
, true);
18499 #pragma omp simd simd-clause[optseq] new-line
18502 LOC is the location of the #pragma token.
18505 #define OMP_SIMD_CLAUSE_MASK \
18506 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
18507 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
18508 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18509 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
18510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18513 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18514 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18515 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
18516 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18519 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
18520 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18523 tree block
, clauses
, ret
;
18525 strcat (p_name
, " simd");
18526 mask
|= OMP_SIMD_CLAUSE_MASK
;
18528 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18531 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
18532 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
18533 tree c
= omp_find_clause (cclauses
[C_OMP_CLAUSE_SPLIT_FOR
],
18534 OMP_CLAUSE_ORDERED
);
18535 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
18537 error_at (OMP_CLAUSE_LOCATION (c
),
18538 "%<ordered%> clause with parameter may not be specified "
18539 "on %qs construct", p_name
);
18540 OMP_CLAUSE_ORDERED_EXPR (c
) = NULL_TREE
;
18544 block
= c_begin_compound_stmt (true);
18545 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
18546 block
= c_end_compound_stmt (loc
, block
, true);
18553 #pragma omp for for-clause[optseq] new-line
18557 #pragma omp for simd for-simd-clause[optseq] new-line
18560 LOC is the location of the #pragma token.
18563 #define OMP_FOR_CLAUSE_MASK \
18564 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18565 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18566 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18567 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
18568 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18569 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
18570 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
18571 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
18572 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
18573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18576 c_parser_omp_for (location_t loc
, c_parser
*parser
,
18577 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18580 tree block
, clauses
, ret
;
18582 strcat (p_name
, " for");
18583 mask
|= OMP_FOR_CLAUSE_MASK
;
18584 /* parallel for{, simd} disallows nowait clause, but for
18585 target {teams distribute ,}parallel for{, simd} it should be accepted. */
18586 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
18587 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
18588 /* Composite distribute parallel for{, simd} disallows ordered clause. */
18589 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
18590 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
18592 if (c_parser_next_token_is (parser
, CPP_NAME
))
18594 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18596 if (strcmp (p
, "simd") == 0)
18598 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18599 if (cclauses
== NULL
)
18600 cclauses
= cclauses_buf
;
18602 c_parser_consume_token (parser
);
18603 if (!flag_openmp
) /* flag_openmp_simd */
18604 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
18606 block
= c_begin_compound_stmt (true);
18607 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
18608 block
= c_end_compound_stmt (loc
, block
, true);
18609 if (ret
== NULL_TREE
)
18611 ret
= make_node (OMP_FOR
);
18612 TREE_TYPE (ret
) = void_type_node
;
18613 OMP_FOR_BODY (ret
) = block
;
18614 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
18615 SET_EXPR_LOCATION (ret
, loc
);
18620 if (!flag_openmp
) /* flag_openmp_simd */
18622 c_parser_skip_to_pragma_eol (parser
, false);
18626 /* Composite distribute parallel for disallows linear clause. */
18627 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
18628 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
18630 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18633 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
18634 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
18637 block
= c_begin_compound_stmt (true);
18638 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
18639 block
= c_end_compound_stmt (loc
, block
, true);
18645 static tree
c_parser_omp_taskloop (location_t
, c_parser
*, char *,
18646 omp_clause_mask
, tree
*, bool *);
18649 # pragma omp master new-line
18652 LOC is the location of the #pragma token.
18656 c_parser_omp_master (location_t loc
, c_parser
*parser
,
18657 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18660 tree block
, clauses
, ret
;
18662 strcat (p_name
, " master");
18664 if (c_parser_next_token_is (parser
, CPP_NAME
))
18666 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18668 if (strcmp (p
, "taskloop") == 0)
18670 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18671 if (cclauses
== NULL
)
18672 cclauses
= cclauses_buf
;
18674 c_parser_consume_token (parser
);
18675 if (!flag_openmp
) /* flag_openmp_simd */
18676 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
18678 block
= c_begin_compound_stmt (true);
18679 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
18681 block
= c_end_compound_stmt (loc
, block
, true);
18682 if (ret
== NULL_TREE
)
18684 ret
= c_finish_omp_master (loc
, block
);
18688 if (!flag_openmp
) /* flag_openmp_simd */
18690 c_parser_skip_to_pragma_eol (parser
, false);
18696 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, false);
18697 omp_split_clauses (loc
, OMP_MASTER
, mask
, clauses
, cclauses
);
18700 c_parser_skip_to_pragma_eol (parser
);
18702 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
18707 # pragma omp ordered new-line
18711 # pragma omp ordered ordered-clauses new-line
18714 # pragma omp ordered depend-clauses new-line */
18716 #define OMP_ORDERED_CLAUSE_MASK \
18717 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
18718 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
18720 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
18721 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
18724 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
18727 location_t loc
= c_parser_peek_token (parser
)->location
;
18728 c_parser_consume_pragma (parser
);
18730 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
18732 c_parser_error (parser
, "expected declaration specifiers");
18733 c_parser_skip_to_pragma_eol (parser
, false);
18737 if (c_parser_next_token_is (parser
, CPP_NAME
))
18739 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18741 if (!strcmp ("depend", p
))
18743 if (!flag_openmp
) /* flag_openmp_simd */
18745 c_parser_skip_to_pragma_eol (parser
, false);
18748 if (context
== pragma_stmt
)
18751 "%<#pragma omp ordered%> with %<depend%> clause may "
18752 "only be used in compound statements");
18753 c_parser_skip_to_pragma_eol (parser
, false);
18758 = c_parser_omp_all_clauses (parser
,
18759 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
18760 "#pragma omp ordered");
18761 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
18766 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
18767 "#pragma omp ordered");
18769 if (!flag_openmp
/* flag_openmp_simd */
18770 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
18773 c_finish_omp_ordered (loc
, clauses
,
18774 c_parser_omp_structured_block (parser
, if_p
));
18781 { section-sequence }
18784 section-directive[opt] structured-block
18785 section-sequence section-directive structured-block
18787 SECTIONS_LOC is the location of the #pragma omp sections. */
18790 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
18792 tree stmt
, substmt
;
18793 bool error_suppress
= false;
18796 loc
= c_parser_peek_token (parser
)->location
;
18797 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
18799 /* Avoid skipping until the end of the block. */
18800 parser
->error
= false;
18804 stmt
= push_stmt_list ();
18806 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
)
18808 substmt
= c_parser_omp_structured_block (parser
, NULL
);
18809 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
18810 SET_EXPR_LOCATION (substmt
, loc
);
18811 add_stmt (substmt
);
18816 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18818 if (c_parser_next_token_is (parser
, CPP_EOF
))
18821 loc
= c_parser_peek_token (parser
)->location
;
18822 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
18824 c_parser_consume_pragma (parser
);
18825 c_parser_skip_to_pragma_eol (parser
);
18826 error_suppress
= false;
18828 else if (!error_suppress
)
18830 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
18831 error_suppress
= true;
18834 substmt
= c_parser_omp_structured_block (parser
, NULL
);
18835 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
18836 SET_EXPR_LOCATION (substmt
, loc
);
18837 add_stmt (substmt
);
18839 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
18840 "expected %<#pragma omp section%> or %<}%>");
18842 substmt
= pop_stmt_list (stmt
);
18844 stmt
= make_node (OMP_SECTIONS
);
18845 SET_EXPR_LOCATION (stmt
, sections_loc
);
18846 TREE_TYPE (stmt
) = void_type_node
;
18847 OMP_SECTIONS_BODY (stmt
) = substmt
;
18849 return add_stmt (stmt
);
18853 # pragma omp sections sections-clause[optseq] newline
18856 LOC is the location of the #pragma token.
18859 #define OMP_SECTIONS_CLAUSE_MASK \
18860 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18861 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18862 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18863 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18864 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18867 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
18868 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
18870 tree block
, clauses
, ret
;
18872 strcat (p_name
, " sections");
18873 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
18875 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
18877 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
18880 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
18881 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
18884 block
= c_begin_compound_stmt (true);
18885 ret
= c_parser_omp_sections_scope (loc
, parser
);
18887 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
18888 block
= c_end_compound_stmt (loc
, block
, true);
18895 # pragma omp parallel parallel-clause[optseq] new-line
18897 # pragma omp parallel for parallel-for-clause[optseq] new-line
18899 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
18903 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
18906 LOC is the location of the #pragma token.
18909 #define OMP_PARALLEL_CLAUSE_MASK \
18910 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18912 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18913 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18914 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18915 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
18916 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18917 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
18918 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
18921 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
18922 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
18925 tree stmt
, clauses
, block
;
18927 strcat (p_name
, " parallel");
18928 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
18929 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
18930 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
18931 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
18932 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
18934 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
18936 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18937 if (cclauses
== NULL
)
18938 cclauses
= cclauses_buf
;
18940 c_parser_consume_token (parser
);
18941 if (!flag_openmp
) /* flag_openmp_simd */
18942 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
18943 block
= c_begin_omp_parallel ();
18944 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
18946 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
18948 if (ret
== NULL_TREE
)
18950 OMP_PARALLEL_COMBINED (stmt
) = 1;
18953 /* When combined with distribute, parallel has to be followed by for.
18954 #pragma omp target parallel is allowed though. */
18956 && (mask
& (OMP_CLAUSE_MASK_1
18957 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
18959 error_at (loc
, "expected %<for%> after %qs", p_name
);
18960 c_parser_skip_to_pragma_eol (parser
);
18963 else if (c_parser_next_token_is (parser
, CPP_NAME
))
18965 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18966 if (cclauses
== NULL
&& strcmp (p
, "master") == 0)
18968 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18969 cclauses
= cclauses_buf
;
18971 c_parser_consume_token (parser
);
18972 if (!flag_openmp
) /* flag_openmp_simd */
18973 return c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
18975 block
= c_begin_omp_parallel ();
18976 tree ret
= c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
18978 stmt
= c_finish_omp_parallel (loc
,
18979 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
18983 OMP_PARALLEL_COMBINED (stmt
) = 1;
18986 else if (strcmp (p
, "loop") == 0)
18988 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
18989 if (cclauses
== NULL
)
18990 cclauses
= cclauses_buf
;
18992 c_parser_consume_token (parser
);
18993 if (!flag_openmp
) /* flag_openmp_simd */
18994 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
18996 block
= c_begin_omp_parallel ();
18997 tree ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
19000 = c_finish_omp_parallel (loc
,
19001 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
19003 if (ret
== NULL_TREE
)
19005 OMP_PARALLEL_COMBINED (stmt
) = 1;
19008 else if (!flag_openmp
) /* flag_openmp_simd */
19010 c_parser_skip_to_pragma_eol (parser
, false);
19013 else if (cclauses
== NULL
&& strcmp (p
, "sections") == 0)
19015 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19016 cclauses
= cclauses_buf
;
19018 c_parser_consume_token (parser
);
19019 block
= c_begin_omp_parallel ();
19020 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
19021 stmt
= c_finish_omp_parallel (loc
,
19022 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
19024 OMP_PARALLEL_COMBINED (stmt
) = 1;
19028 else if (!flag_openmp
) /* flag_openmp_simd */
19030 c_parser_skip_to_pragma_eol (parser
, false);
19034 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19037 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
19038 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
19041 block
= c_begin_omp_parallel ();
19042 c_parser_statement (parser
, if_p
);
19043 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
19049 # pragma omp single single-clause[optseq] new-line
19052 LOC is the location of the #pragma.
19055 #define OMP_SINGLE_CLAUSE_MASK \
19056 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19057 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19058 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
19059 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19062 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
19064 tree stmt
= make_node (OMP_SINGLE
);
19065 SET_EXPR_LOCATION (stmt
, loc
);
19066 TREE_TYPE (stmt
) = void_type_node
;
19068 OMP_SINGLE_CLAUSES (stmt
)
19069 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
19070 "#pragma omp single");
19071 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
19073 return add_stmt (stmt
);
19077 # pragma omp task task-clause[optseq] new-line
19079 LOC is the location of the #pragma.
19082 #define OMP_TASK_CLAUSE_MASK \
19083 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19084 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
19085 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
19086 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19087 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19088 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
19089 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
19090 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
19091 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19092 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
19093 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
19096 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
19098 tree clauses
, block
;
19100 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
19101 "#pragma omp task");
19103 block
= c_begin_omp_task ();
19104 c_parser_statement (parser
, if_p
);
19105 return c_finish_omp_task (loc
, clauses
, block
);
19109 # pragma omp taskwait new-line
19112 # pragma omp taskwait taskwait-clause[optseq] new-line
19115 #define OMP_TASKWAIT_CLAUSE_MASK \
19116 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19119 c_parser_omp_taskwait (c_parser
*parser
)
19121 location_t loc
= c_parser_peek_token (parser
)->location
;
19122 c_parser_consume_pragma (parser
);
19125 = c_parser_omp_all_clauses (parser
, OMP_TASKWAIT_CLAUSE_MASK
,
19126 "#pragma omp taskwait");
19130 tree stmt
= make_node (OMP_TASK
);
19131 TREE_TYPE (stmt
) = void_node
;
19132 OMP_TASK_CLAUSES (stmt
) = clauses
;
19133 OMP_TASK_BODY (stmt
) = NULL_TREE
;
19134 SET_EXPR_LOCATION (stmt
, loc
);
19138 c_finish_omp_taskwait (loc
);
19142 # pragma omp taskyield new-line
19146 c_parser_omp_taskyield (c_parser
*parser
)
19148 location_t loc
= c_parser_peek_token (parser
)->location
;
19149 c_parser_consume_pragma (parser
);
19150 c_parser_skip_to_pragma_eol (parser
);
19152 c_finish_omp_taskyield (loc
);
19156 # pragma omp taskgroup new-line
19159 # pragma omp taskgroup taskgroup-clause[optseq] new-line
19162 #define OMP_TASKGROUP_CLAUSE_MASK \
19163 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
19166 c_parser_omp_taskgroup (location_t loc
, c_parser
*parser
, bool *if_p
)
19168 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_TASKGROUP_CLAUSE_MASK
,
19169 "#pragma omp taskgroup");
19171 tree body
= c_parser_omp_structured_block (parser
, if_p
);
19172 return c_finish_omp_taskgroup (loc
, body
, clauses
);
19176 # pragma omp cancel cancel-clause[optseq] new-line
19178 LOC is the location of the #pragma.
19181 #define OMP_CANCEL_CLAUSE_MASK \
19182 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19183 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19184 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19185 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
19186 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
19189 c_parser_omp_cancel (c_parser
*parser
)
19191 location_t loc
= c_parser_peek_token (parser
)->location
;
19193 c_parser_consume_pragma (parser
);
19194 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
19195 "#pragma omp cancel");
19197 c_finish_omp_cancel (loc
, clauses
);
19201 # pragma omp cancellation point cancelpt-clause[optseq] new-line
19203 LOC is the location of the #pragma.
19206 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
19207 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
19208 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
19209 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
19210 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
19213 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
19215 location_t loc
= c_parser_peek_token (parser
)->location
;
19217 bool point_seen
= false;
19219 c_parser_consume_pragma (parser
);
19220 if (c_parser_next_token_is (parser
, CPP_NAME
))
19222 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19223 if (strcmp (p
, "point") == 0)
19225 c_parser_consume_token (parser
);
19231 c_parser_error (parser
, "expected %<point%>");
19232 c_parser_skip_to_pragma_eol (parser
);
19236 if (context
!= pragma_compound
)
19238 if (context
== pragma_stmt
)
19240 "%<#pragma %s%> may only be used in compound statements",
19241 "omp cancellation point");
19243 c_parser_error (parser
, "expected declaration specifiers");
19244 c_parser_skip_to_pragma_eol (parser
, false);
19249 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
19250 "#pragma omp cancellation point");
19252 c_finish_omp_cancellation_point (loc
, clauses
);
19256 #pragma omp distribute distribute-clause[optseq] new-line
19259 #define OMP_DISTRIBUTE_CLAUSE_MASK \
19260 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19261 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19262 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19263 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
19264 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
19267 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
19268 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19271 tree clauses
, block
, ret
;
19273 strcat (p_name
, " distribute");
19274 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
19276 if (c_parser_next_token_is (parser
, CPP_NAME
))
19278 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19280 bool parallel
= false;
19282 if (strcmp (p
, "simd") == 0)
19285 parallel
= strcmp (p
, "parallel") == 0;
19286 if (parallel
|| simd
)
19288 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19289 if (cclauses
== NULL
)
19290 cclauses
= cclauses_buf
;
19291 c_parser_consume_token (parser
);
19292 if (!flag_openmp
) /* flag_openmp_simd */
19295 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
19298 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
19301 block
= c_begin_compound_stmt (true);
19303 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
19306 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
19308 block
= c_end_compound_stmt (loc
, block
, true);
19311 ret
= make_node (OMP_DISTRIBUTE
);
19312 TREE_TYPE (ret
) = void_type_node
;
19313 OMP_FOR_BODY (ret
) = block
;
19314 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
19315 SET_EXPR_LOCATION (ret
, loc
);
19320 if (!flag_openmp
) /* flag_openmp_simd */
19322 c_parser_skip_to_pragma_eol (parser
, false);
19326 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19329 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
19330 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
19333 block
= c_begin_compound_stmt (true);
19334 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
19336 block
= c_end_compound_stmt (loc
, block
, true);
19343 # pragma omp teams teams-clause[optseq] new-line
19344 structured-block */
19346 #define OMP_TEAMS_CLAUSE_MASK \
19347 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19348 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19349 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
19350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19351 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
19352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
19353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
19356 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
19357 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19360 tree clauses
, block
, ret
;
19362 strcat (p_name
, " teams");
19363 mask
|= OMP_TEAMS_CLAUSE_MASK
;
19365 if (c_parser_next_token_is (parser
, CPP_NAME
))
19367 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19368 if (strcmp (p
, "distribute") == 0)
19370 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19371 if (cclauses
== NULL
)
19372 cclauses
= cclauses_buf
;
19374 c_parser_consume_token (parser
);
19375 if (!flag_openmp
) /* flag_openmp_simd */
19376 return c_parser_omp_distribute (loc
, parser
, p_name
, mask
,
19378 block
= c_begin_omp_parallel ();
19379 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
19381 block
= c_end_compound_stmt (loc
, block
, true);
19384 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19385 ret
= make_node (OMP_TEAMS
);
19386 TREE_TYPE (ret
) = void_type_node
;
19387 OMP_TEAMS_CLAUSES (ret
) = clauses
;
19388 OMP_TEAMS_BODY (ret
) = block
;
19389 OMP_TEAMS_COMBINED (ret
) = 1;
19390 SET_EXPR_LOCATION (ret
, loc
);
19391 return add_stmt (ret
);
19393 else if (strcmp (p
, "loop") == 0)
19395 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19396 if (cclauses
== NULL
)
19397 cclauses
= cclauses_buf
;
19399 c_parser_consume_token (parser
);
19400 if (!flag_openmp
) /* flag_openmp_simd */
19401 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
19403 block
= c_begin_omp_parallel ();
19404 ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
19405 block
= c_end_compound_stmt (loc
, block
, true);
19408 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19409 ret
= make_node (OMP_TEAMS
);
19410 TREE_TYPE (ret
) = void_type_node
;
19411 OMP_TEAMS_CLAUSES (ret
) = clauses
;
19412 OMP_TEAMS_BODY (ret
) = block
;
19413 OMP_TEAMS_COMBINED (ret
) = 1;
19414 SET_EXPR_LOCATION (ret
, loc
);
19415 return add_stmt (ret
);
19418 if (!flag_openmp
) /* flag_openmp_simd */
19420 c_parser_skip_to_pragma_eol (parser
, false);
19424 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19427 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
19428 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19431 tree stmt
= make_node (OMP_TEAMS
);
19432 TREE_TYPE (stmt
) = void_type_node
;
19433 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
19434 block
= c_begin_omp_parallel ();
19435 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19436 OMP_TEAMS_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
19437 SET_EXPR_LOCATION (stmt
, loc
);
19439 return add_stmt (stmt
);
19443 # pragma omp target data target-data-clause[optseq] new-line
19444 structured-block */
19446 #define OMP_TARGET_DATA_CLAUSE_MASK \
19447 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19448 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19449 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19450 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
19451 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
19454 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
19457 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
19458 "#pragma omp target data");
19460 for (tree
*pc
= &clauses
; *pc
;)
19462 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
19463 switch (OMP_CLAUSE_MAP_KIND (*pc
))
19466 case GOMP_MAP_ALWAYS_TO
:
19467 case GOMP_MAP_FROM
:
19468 case GOMP_MAP_ALWAYS_FROM
:
19469 case GOMP_MAP_TOFROM
:
19470 case GOMP_MAP_ALWAYS_TOFROM
:
19471 case GOMP_MAP_ALLOC
:
19474 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19475 case GOMP_MAP_ALWAYS_POINTER
:
19479 error_at (OMP_CLAUSE_LOCATION (*pc
),
19480 "%<#pragma omp target data%> with map-type other "
19481 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19482 "on %<map%> clause");
19483 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19486 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
19487 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
19489 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19496 "%<#pragma omp target data%> must contain at least "
19497 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
19502 tree stmt
= make_node (OMP_TARGET_DATA
);
19503 TREE_TYPE (stmt
) = void_type_node
;
19504 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
19505 keep_next_level ();
19506 tree block
= c_begin_compound_stmt (true);
19507 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19508 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
19510 SET_EXPR_LOCATION (stmt
, loc
);
19511 return add_stmt (stmt
);
19515 # pragma omp target update target-update-clause[optseq] new-line */
19517 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
19518 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
19519 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
19520 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19521 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19522 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19523 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19526 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
19527 enum pragma_context context
)
19529 if (context
== pragma_stmt
)
19531 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
19532 "omp target update");
19533 c_parser_skip_to_pragma_eol (parser
, false);
19538 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
19539 "#pragma omp target update");
19540 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
19541 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
19544 "%<#pragma omp target update%> must contain at least one "
19545 "%<from%> or %<to%> clauses");
19549 tree stmt
= make_node (OMP_TARGET_UPDATE
);
19550 TREE_TYPE (stmt
) = void_type_node
;
19551 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
19552 SET_EXPR_LOCATION (stmt
, loc
);
19558 # pragma omp target enter data target-data-clause[optseq] new-line */
19560 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
19561 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19562 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19563 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19564 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19565 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19568 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
19569 enum pragma_context context
)
19571 bool data_seen
= false;
19572 if (c_parser_next_token_is (parser
, CPP_NAME
))
19574 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19575 if (strcmp (p
, "data") == 0)
19577 c_parser_consume_token (parser
);
19583 c_parser_error (parser
, "expected %<data%>");
19584 c_parser_skip_to_pragma_eol (parser
);
19588 if (context
== pragma_stmt
)
19590 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
19591 "omp target enter data");
19592 c_parser_skip_to_pragma_eol (parser
, false);
19597 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
19598 "#pragma omp target enter data");
19600 for (tree
*pc
= &clauses
; *pc
;)
19602 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
19603 switch (OMP_CLAUSE_MAP_KIND (*pc
))
19606 case GOMP_MAP_ALWAYS_TO
:
19607 case GOMP_MAP_ALLOC
:
19610 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19611 case GOMP_MAP_ALWAYS_POINTER
:
19615 error_at (OMP_CLAUSE_LOCATION (*pc
),
19616 "%<#pragma omp target enter data%> with map-type other "
19617 "than %<to%> or %<alloc%> on %<map%> clause");
19618 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19621 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19628 "%<#pragma omp target enter data%> must contain at least "
19629 "one %<map%> clause");
19633 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
19634 TREE_TYPE (stmt
) = void_type_node
;
19635 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
19636 SET_EXPR_LOCATION (stmt
, loc
);
19642 # pragma omp target exit data target-data-clause[optseq] new-line */
19644 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
19645 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19646 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19647 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19648 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19649 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19652 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
19653 enum pragma_context context
)
19655 bool data_seen
= false;
19656 if (c_parser_next_token_is (parser
, CPP_NAME
))
19658 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19659 if (strcmp (p
, "data") == 0)
19661 c_parser_consume_token (parser
);
19667 c_parser_error (parser
, "expected %<data%>");
19668 c_parser_skip_to_pragma_eol (parser
);
19672 if (context
== pragma_stmt
)
19674 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
19675 "omp target exit data");
19676 c_parser_skip_to_pragma_eol (parser
, false);
19681 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
19682 "#pragma omp target exit data");
19685 for (tree
*pc
= &clauses
; *pc
;)
19687 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
19688 switch (OMP_CLAUSE_MAP_KIND (*pc
))
19690 case GOMP_MAP_FROM
:
19691 case GOMP_MAP_ALWAYS_FROM
:
19692 case GOMP_MAP_RELEASE
:
19693 case GOMP_MAP_DELETE
:
19696 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19697 case GOMP_MAP_ALWAYS_POINTER
:
19701 error_at (OMP_CLAUSE_LOCATION (*pc
),
19702 "%<#pragma omp target exit data%> with map-type other "
19703 "than %<from%>, %<release%> or %<delete%> on %<map%>"
19705 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19708 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19715 "%<#pragma omp target exit data%> must contain at least one "
19720 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
19721 TREE_TYPE (stmt
) = void_type_node
;
19722 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
19723 SET_EXPR_LOCATION (stmt
, loc
);
19729 # pragma omp target target-clause[optseq] new-line
19730 structured-block */
19732 #define OMP_TARGET_CLAUSE_MASK \
19733 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
19734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
19735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
19737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
19741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
19744 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
19746 location_t loc
= c_parser_peek_token (parser
)->location
;
19747 c_parser_consume_pragma (parser
);
19748 tree
*pc
= NULL
, stmt
, block
;
19750 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
19752 c_parser_error (parser
, "expected declaration specifiers");
19753 c_parser_skip_to_pragma_eol (parser
);
19759 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
19761 if (c_parser_next_token_is (parser
, CPP_NAME
))
19763 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19764 enum tree_code ccode
= ERROR_MARK
;
19766 if (strcmp (p
, "teams") == 0)
19768 else if (strcmp (p
, "parallel") == 0)
19769 ccode
= OMP_PARALLEL
;
19770 else if (strcmp (p
, "simd") == 0)
19772 if (ccode
!= ERROR_MARK
)
19774 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
19775 char p_name
[sizeof ("#pragma omp target teams distribute "
19776 "parallel for simd")];
19778 c_parser_consume_token (parser
);
19779 strcpy (p_name
, "#pragma omp target");
19780 if (!flag_openmp
) /* flag_openmp_simd */
19786 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
19787 OMP_TARGET_CLAUSE_MASK
,
19791 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
19792 OMP_TARGET_CLAUSE_MASK
,
19796 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
19797 OMP_TARGET_CLAUSE_MASK
,
19801 gcc_unreachable ();
19803 return stmt
!= NULL_TREE
;
19805 keep_next_level ();
19806 tree block
= c_begin_compound_stmt (true), ret
;
19810 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
19811 OMP_TARGET_CLAUSE_MASK
, cclauses
,
19815 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
19816 OMP_TARGET_CLAUSE_MASK
, cclauses
,
19820 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
19821 OMP_TARGET_CLAUSE_MASK
, cclauses
,
19825 gcc_unreachable ();
19827 block
= c_end_compound_stmt (loc
, block
, true);
19828 if (ret
== NULL_TREE
)
19830 if (ccode
== OMP_TEAMS
)
19832 /* For combined target teams, ensure the num_teams and
19833 thread_limit clause expressions are evaluated on the host,
19834 before entering the target construct. */
19836 for (c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
19837 c
; c
= OMP_CLAUSE_CHAIN (c
))
19838 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
19839 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
19840 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, 0)) != INTEGER_CST
)
19842 tree expr
= OMP_CLAUSE_OPERAND (c
, 0);
19843 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
19844 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
19845 expr
, NULL_TREE
, NULL_TREE
);
19847 OMP_CLAUSE_OPERAND (c
, 0) = expr
;
19848 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
19849 OMP_CLAUSE_FIRSTPRIVATE
);
19850 OMP_CLAUSE_DECL (tc
) = tmp
;
19851 OMP_CLAUSE_CHAIN (tc
)
19852 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
19853 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
19856 tree stmt
= make_node (OMP_TARGET
);
19857 TREE_TYPE (stmt
) = void_type_node
;
19858 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
19859 OMP_TARGET_BODY (stmt
) = block
;
19860 OMP_TARGET_COMBINED (stmt
) = 1;
19861 SET_EXPR_LOCATION (stmt
, loc
);
19863 pc
= &OMP_TARGET_CLAUSES (stmt
);
19864 goto check_clauses
;
19866 else if (!flag_openmp
) /* flag_openmp_simd */
19868 c_parser_skip_to_pragma_eol (parser
, false);
19871 else if (strcmp (p
, "data") == 0)
19873 c_parser_consume_token (parser
);
19874 c_parser_omp_target_data (loc
, parser
, if_p
);
19877 else if (strcmp (p
, "enter") == 0)
19879 c_parser_consume_token (parser
);
19880 c_parser_omp_target_enter_data (loc
, parser
, context
);
19883 else if (strcmp (p
, "exit") == 0)
19885 c_parser_consume_token (parser
);
19886 c_parser_omp_target_exit_data (loc
, parser
, context
);
19889 else if (strcmp (p
, "update") == 0)
19891 c_parser_consume_token (parser
);
19892 return c_parser_omp_target_update (loc
, parser
, context
);
19895 if (!flag_openmp
) /* flag_openmp_simd */
19897 c_parser_skip_to_pragma_eol (parser
, false);
19901 stmt
= make_node (OMP_TARGET
);
19902 TREE_TYPE (stmt
) = void_type_node
;
19904 OMP_TARGET_CLAUSES (stmt
)
19905 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
19906 "#pragma omp target");
19907 pc
= &OMP_TARGET_CLAUSES (stmt
);
19908 keep_next_level ();
19909 block
= c_begin_compound_stmt (true);
19910 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19911 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
19913 SET_EXPR_LOCATION (stmt
, loc
);
19919 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
19920 switch (OMP_CLAUSE_MAP_KIND (*pc
))
19923 case GOMP_MAP_ALWAYS_TO
:
19924 case GOMP_MAP_FROM
:
19925 case GOMP_MAP_ALWAYS_FROM
:
19926 case GOMP_MAP_TOFROM
:
19927 case GOMP_MAP_ALWAYS_TOFROM
:
19928 case GOMP_MAP_ALLOC
:
19929 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19930 case GOMP_MAP_ALWAYS_POINTER
:
19933 error_at (OMP_CLAUSE_LOCATION (*pc
),
19934 "%<#pragma omp target%> with map-type other "
19935 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19936 "on %<map%> clause");
19937 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19940 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19942 cfun
->has_omp_target
= true;
19947 # pragma omp declare simd declare-simd-clauses[optseq] new-line
19950 # pragma omp declare variant (identifier) match(context-selector) new-line
19953 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
19954 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19955 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19956 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19957 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
19958 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
19959 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
19962 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
19964 c_token
*token
= c_parser_peek_token (parser
);
19965 gcc_assert (token
->type
== CPP_NAME
);
19966 tree kind
= token
->value
;
19967 gcc_assert (strcmp (IDENTIFIER_POINTER (kind
), "simd") == 0
19968 || strcmp (IDENTIFIER_POINTER (kind
), "variant") == 0);
19970 auto_vec
<c_token
> clauses
;
19971 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19973 c_token
*token
= c_parser_peek_token (parser
);
19974 if (token
->type
== CPP_EOF
)
19976 c_parser_skip_to_pragma_eol (parser
);
19979 clauses
.safe_push (*token
);
19980 c_parser_consume_token (parser
);
19982 clauses
.safe_push (*c_parser_peek_token (parser
));
19983 c_parser_skip_to_pragma_eol (parser
);
19985 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
19987 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_DECLARE
19988 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
19989 || c_parser_peek_2nd_token (parser
)->value
!= kind
)
19991 error ("%<#pragma omp declare %s%> must be followed by "
19992 "function declaration or definition or another "
19993 "%<#pragma omp declare %s%>",
19994 IDENTIFIER_POINTER (kind
), IDENTIFIER_POINTER (kind
));
19997 c_parser_consume_pragma (parser
);
19998 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
20000 c_token
*token
= c_parser_peek_token (parser
);
20001 if (token
->type
== CPP_EOF
)
20003 c_parser_skip_to_pragma_eol (parser
);
20006 clauses
.safe_push (*token
);
20007 c_parser_consume_token (parser
);
20009 clauses
.safe_push (*c_parser_peek_token (parser
));
20010 c_parser_skip_to_pragma_eol (parser
);
20013 /* Make sure nothing tries to read past the end of the tokens. */
20015 memset (&eof_token
, 0, sizeof (eof_token
));
20016 eof_token
.type
= CPP_EOF
;
20017 clauses
.safe_push (eof_token
);
20018 clauses
.safe_push (eof_token
);
20022 case pragma_external
:
20023 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20024 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
20026 int ext
= disable_extension_diagnostics ();
20028 c_parser_consume_token (parser
);
20029 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20030 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
20031 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
20033 restore_extension_diagnostics (ext
);
20036 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
20039 case pragma_struct
:
20042 error ("%<#pragma omp declare %s%> must be followed by "
20043 "function declaration or definition",
20044 IDENTIFIER_POINTER (kind
));
20046 case pragma_compound
:
20047 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20048 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
20050 int ext
= disable_extension_diagnostics ();
20052 c_parser_consume_token (parser
);
20053 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20054 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
20055 if (c_parser_next_tokens_start_declaration (parser
))
20057 c_parser_declaration_or_fndef (parser
, true, true, true, true,
20058 true, NULL
, clauses
);
20059 restore_extension_diagnostics (ext
);
20062 restore_extension_diagnostics (ext
);
20064 else if (c_parser_next_tokens_start_declaration (parser
))
20066 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
20070 error ("%<#pragma omp declare %s%> must be followed by "
20071 "function declaration or definition",
20072 IDENTIFIER_POINTER (kind
));
20075 gcc_unreachable ();
20079 static const char *const omp_construct_selectors
[] = {
20080 "simd", "target", "teams", "parallel", "for", NULL
};
20081 static const char *const omp_device_selectors
[] = {
20082 "kind", "isa", "arch", NULL
};
20083 static const char *const omp_implementation_selectors
[] = {
20084 "vendor", "extension", "atomic_default_mem_order", "unified_address",
20085 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL
};
20086 static const char *const omp_user_selectors
[] = {
20087 "condition", NULL
};
20092 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
20095 score(score-expression) */
20098 c_parser_omp_context_selector (c_parser
*parser
, tree set
, tree parms
)
20100 tree ret
= NULL_TREE
;
20104 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20105 || c_parser_next_token_is (parser
, CPP_NAME
))
20106 selector
= c_parser_peek_token (parser
)->value
;
20109 c_parser_error (parser
, "expected trait selector name");
20110 return error_mark_node
;
20113 tree properties
= NULL_TREE
;
20114 const char *const *selectors
= NULL
;
20115 bool allow_score
= true;
20116 bool allow_user
= false;
20117 int property_limit
= 0;
20118 enum { CTX_PROPERTY_NONE
, CTX_PROPERTY_USER
, CTX_PROPERTY_NAME_LIST
,
20119 CTX_PROPERTY_ID
, CTX_PROPERTY_EXPR
,
20120 CTX_PROPERTY_SIMD
} property_kind
= CTX_PROPERTY_NONE
;
20121 switch (IDENTIFIER_POINTER (set
)[0])
20123 case 'c': /* construct */
20124 selectors
= omp_construct_selectors
;
20125 allow_score
= false;
20126 property_limit
= 1;
20127 property_kind
= CTX_PROPERTY_SIMD
;
20129 case 'd': /* device */
20130 selectors
= omp_device_selectors
;
20131 allow_score
= false;
20133 property_limit
= 3;
20134 property_kind
= CTX_PROPERTY_NAME_LIST
;
20136 case 'i': /* implementation */
20137 selectors
= omp_implementation_selectors
;
20139 property_limit
= 3;
20140 property_kind
= CTX_PROPERTY_NAME_LIST
;
20142 case 'u': /* user */
20143 selectors
= omp_user_selectors
;
20144 property_limit
= 1;
20145 property_kind
= CTX_PROPERTY_EXPR
;
20148 gcc_unreachable ();
20150 for (int i
= 0; ; i
++)
20152 if (selectors
[i
] == NULL
)
20156 property_kind
= CTX_PROPERTY_USER
;
20161 error_at (c_parser_peek_token (parser
)->location
,
20162 "selector %qs not allowed for context selector "
20163 "set %qs", IDENTIFIER_POINTER (selector
),
20164 IDENTIFIER_POINTER (set
));
20165 c_parser_consume_token (parser
);
20166 return error_mark_node
;
20169 if (i
== property_limit
)
20170 property_kind
= CTX_PROPERTY_NONE
;
20171 if (strcmp (selectors
[i
], IDENTIFIER_POINTER (selector
)) == 0)
20174 if (property_kind
== CTX_PROPERTY_NAME_LIST
20175 && IDENTIFIER_POINTER (set
)[0] == 'i'
20176 && strcmp (IDENTIFIER_POINTER (selector
),
20177 "atomic_default_mem_order") == 0)
20178 property_kind
= CTX_PROPERTY_ID
;
20180 c_parser_consume_token (parser
);
20182 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
20184 if (property_kind
== CTX_PROPERTY_NONE
)
20186 error_at (c_parser_peek_token (parser
)->location
,
20187 "selector %qs does not accept any properties",
20188 IDENTIFIER_POINTER (selector
));
20189 return error_mark_node
;
20192 matching_parens parens
;
20193 parens
.require_open (parser
);
20195 c_token
*token
= c_parser_peek_token (parser
);
20197 && c_parser_next_token_is (parser
, CPP_NAME
)
20198 && strcmp (IDENTIFIER_POINTER (token
->value
), "score") == 0
20199 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
20201 c_parser_consume_token (parser
);
20203 matching_parens parens2
;
20204 parens2
.require_open (parser
);
20205 tree score
= c_parser_expr_no_commas (parser
, NULL
).value
;
20206 parens2
.skip_until_found_close (parser
);
20207 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
20208 if (score
!= error_mark_node
)
20210 mark_exp_read (score
);
20211 score
= c_fully_fold (score
, false, NULL
);
20212 if (!INTEGRAL_TYPE_P (TREE_TYPE (score
))
20213 || TREE_CODE (score
) != INTEGER_CST
)
20214 error_at (token
->location
, "score argument must be "
20215 "constant integer expression");
20216 else if (tree_int_cst_sgn (score
) < 0)
20217 error_at (token
->location
, "score argument must be "
20220 properties
= tree_cons (get_identifier (" score"),
20221 score
, properties
);
20223 token
= c_parser_peek_token (parser
);
20226 switch (property_kind
)
20229 case CTX_PROPERTY_USER
:
20232 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
20233 if (TREE_CODE (t
) == STRING_CST
)
20234 properties
= tree_cons (NULL_TREE
, t
, properties
);
20235 else if (t
!= error_mark_node
)
20238 t
= c_fully_fold (t
, false, NULL
);
20239 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
20240 || !tree_fits_shwi_p (t
))
20241 error_at (token
->location
, "property must be "
20242 "constant integer expression or string "
20245 properties
= tree_cons (NULL_TREE
, t
, properties
);
20248 return error_mark_node
;
20250 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20251 c_parser_consume_token (parser
);
20257 case CTX_PROPERTY_ID
:
20258 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20259 || c_parser_next_token_is (parser
, CPP_NAME
))
20261 tree prop
= c_parser_peek_token (parser
)->value
;
20262 c_parser_consume_token (parser
);
20263 properties
= tree_cons (prop
, NULL_TREE
, properties
);
20267 c_parser_error (parser
, "expected identifier");
20268 return error_mark_node
;
20271 case CTX_PROPERTY_NAME_LIST
:
20274 tree prop
= NULL_TREE
, value
= NULL_TREE
;
20275 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20276 || c_parser_next_token_is (parser
, CPP_NAME
))
20278 prop
= c_parser_peek_token (parser
)->value
;
20279 c_parser_consume_token (parser
);
20281 else if (c_parser_next_token_is (parser
, CPP_STRING
))
20282 value
= c_parser_string_literal (parser
, false,
20286 c_parser_error (parser
, "expected identifier or "
20288 return error_mark_node
;
20291 properties
= tree_cons (prop
, value
, properties
);
20293 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20294 c_parser_consume_token (parser
);
20300 case CTX_PROPERTY_EXPR
:
20301 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
20302 if (t
!= error_mark_node
)
20305 t
= c_fully_fold (t
, false, NULL
);
20306 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
20307 || !tree_fits_shwi_p (t
))
20308 error_at (token
->location
, "property must be "
20309 "constant integer expression");
20311 properties
= tree_cons (NULL_TREE
, t
, properties
);
20314 return error_mark_node
;
20316 case CTX_PROPERTY_SIMD
:
20317 if (parms
== NULL_TREE
)
20319 error_at (token
->location
, "properties for %<simd%> "
20320 "selector may not be specified in "
20321 "%<metadirective%>");
20322 return error_mark_node
;
20325 c
= c_parser_omp_all_clauses (parser
,
20326 OMP_DECLARE_SIMD_CLAUSE_MASK
,
20328 c
= c_omp_declare_simd_clauses_to_numbers (parms
20330 ? NULL_TREE
: parms
,
20335 gcc_unreachable ();
20338 parens
.skip_until_found_close (parser
);
20339 properties
= nreverse (properties
);
20341 else if (property_kind
== CTX_PROPERTY_NAME_LIST
20342 || property_kind
== CTX_PROPERTY_ID
20343 || property_kind
== CTX_PROPERTY_EXPR
)
20345 c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>");
20346 return error_mark_node
;
20349 ret
= tree_cons (selector
, properties
, ret
);
20351 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20352 c_parser_consume_token (parser
);
20358 return nreverse (ret
);
20363 trait-set-selector[,trait-set-selector[,...]]
20365 trait-set-selector:
20366 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
20368 trait-set-selector-name:
20375 c_parser_omp_context_selector_specification (c_parser
*parser
, tree parms
)
20377 tree ret
= NULL_TREE
;
20380 const char *setp
= "";
20381 if (c_parser_next_token_is (parser
, CPP_NAME
))
20382 setp
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20386 if (strcmp (setp
, "construct") == 0)
20390 if (strcmp (setp
, "device") == 0)
20394 if (strcmp (setp
, "implementation") == 0)
20398 if (strcmp (setp
, "user") == 0)
20406 c_parser_error (parser
, "expected %<construct%>, %<device%>, "
20407 "%<implementation%> or %<user%>");
20408 return error_mark_node
;
20411 tree set
= c_parser_peek_token (parser
)->value
;
20412 c_parser_consume_token (parser
);
20414 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
20415 return error_mark_node
;
20417 matching_braces braces
;
20418 if (!braces
.require_open (parser
))
20419 return error_mark_node
;
20421 tree selectors
= c_parser_omp_context_selector (parser
, set
, parms
);
20422 if (selectors
== error_mark_node
)
20423 ret
= error_mark_node
;
20424 else if (ret
!= error_mark_node
)
20425 ret
= tree_cons (set
, selectors
, ret
);
20427 braces
.skip_until_found_close (parser
);
20429 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20430 c_parser_consume_token (parser
);
20436 if (ret
== error_mark_node
)
20438 return nreverse (ret
);
20441 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
20442 that into "omp declare variant base" attribute. */
20445 c_finish_omp_declare_variant (c_parser
*parser
, tree fndecl
, tree parms
)
20447 matching_parens parens
;
20448 if (!parens
.require_open (parser
))
20451 c_parser_skip_to_pragma_eol (parser
, false);
20455 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
20456 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
20458 c_parser_error (parser
, "expected identifier");
20462 c_token
*token
= c_parser_peek_token (parser
);
20463 tree variant
= lookup_name (token
->value
);
20465 if (variant
== NULL_TREE
)
20467 undeclared_variable (token
->location
, token
->value
);
20468 variant
= error_mark_node
;
20471 c_parser_consume_token (parser
);
20473 parens
.require_close (parser
);
20475 const char *clause
= "";
20476 location_t match_loc
= c_parser_peek_token (parser
)->location
;
20477 if (c_parser_next_token_is (parser
, CPP_NAME
))
20478 clause
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20479 if (strcmp (clause
, "match"))
20481 c_parser_error (parser
, "expected %<match%>");
20485 c_parser_consume_token (parser
);
20487 if (!parens
.require_open (parser
))
20490 if (parms
== NULL_TREE
)
20491 parms
= error_mark_node
;
20493 tree ctx
= c_parser_omp_context_selector_specification (parser
, parms
);
20494 if (ctx
== error_mark_node
)
20496 ctx
= c_omp_check_context_selector (match_loc
, ctx
);
20497 if (ctx
!= error_mark_node
&& variant
!= error_mark_node
)
20499 if (TREE_CODE (variant
) != FUNCTION_DECL
)
20501 error_at (token
->location
, "variant %qD is not a function", variant
);
20502 variant
= error_mark_node
;
20504 else if (omp_get_context_selector (ctx
, "construct", "simd") == NULL_TREE
20505 && !comptypes (TREE_TYPE (fndecl
), TREE_TYPE (variant
)))
20507 error_at (token
->location
, "variant %qD and base %qD have "
20508 "incompatible types", variant
, fndecl
);
20509 variant
= error_mark_node
;
20511 else if (fndecl_built_in_p (variant
)
20512 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
20513 "__builtin_", strlen ("__builtin_")) == 0
20514 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
20515 "__sync_", strlen ("__sync_")) == 0
20516 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
20517 "__atomic_", strlen ("__atomic_")) == 0))
20519 error_at (token
->location
, "variant %qD is a built-in", variant
);
20520 variant
= error_mark_node
;
20522 if (variant
!= error_mark_node
)
20524 C_DECL_USED (variant
) = 1;
20525 tree construct
= omp_get_context_selector (ctx
, "construct", NULL
);
20526 c_omp_mark_declare_variant (match_loc
, variant
, construct
);
20527 if (omp_context_selector_matches (ctx
))
20530 = tree_cons (get_identifier ("omp declare variant base"),
20531 build_tree_list (variant
, ctx
),
20532 DECL_ATTRIBUTES (fndecl
));
20533 DECL_ATTRIBUTES (fndecl
) = attr
;
20538 parens
.require_close (parser
);
20539 c_parser_skip_to_pragma_eol (parser
);
20542 /* Finalize #pragma omp declare simd or #pragma omp declare variant
20543 clauses after FNDECL has been parsed, and put that into "omp declare simd"
20544 or "omp declare variant base" attribute. */
20547 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
20548 vec
<c_token
> clauses
)
20550 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
20551 indicates error has been reported and CPP_PRAGMA that
20552 c_finish_omp_declare_simd has already processed the tokens. */
20553 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
20555 const char *kind
= "simd";
20556 if (clauses
.exists ()
20557 && (clauses
[0].type
== CPP_NAME
|| clauses
[0].type
== CPP_PRAGMA
))
20558 kind
= IDENTIFIER_POINTER (clauses
[0].value
);
20559 gcc_assert (strcmp (kind
, "simd") == 0 || strcmp (kind
, "variant") == 0);
20560 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
20562 error ("%<#pragma omp declare %s%> not immediately followed by "
20563 "a function declaration or definition", kind
);
20564 clauses
[0].type
= CPP_EOF
;
20567 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
20569 error_at (DECL_SOURCE_LOCATION (fndecl
),
20570 "%<#pragma omp declare %s%> not immediately followed by "
20571 "a single function declaration or definition", kind
);
20572 clauses
[0].type
= CPP_EOF
;
20576 if (parms
== NULL_TREE
)
20577 parms
= DECL_ARGUMENTS (fndecl
);
20579 unsigned int tokens_avail
= parser
->tokens_avail
;
20580 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
20582 parser
->tokens
= clauses
.address ();
20583 parser
->tokens_avail
= clauses
.length ();
20585 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
20586 while (parser
->tokens_avail
> 3)
20588 c_token
*token
= c_parser_peek_token (parser
);
20589 gcc_assert (token
->type
== CPP_NAME
20590 && strcmp (IDENTIFIER_POINTER (token
->value
), kind
) == 0);
20591 c_parser_consume_token (parser
);
20592 parser
->in_pragma
= true;
20594 if (strcmp (kind
, "simd") == 0)
20597 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
20598 "#pragma omp declare simd");
20599 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
20600 if (c
!= NULL_TREE
)
20601 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
20602 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
20603 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
20604 DECL_ATTRIBUTES (fndecl
) = c
;
20608 gcc_assert (strcmp (kind
, "variant") == 0);
20609 c_finish_omp_declare_variant (parser
, fndecl
, parms
);
20613 parser
->tokens
= &parser
->tokens_buf
[0];
20614 parser
->tokens_avail
= tokens_avail
;
20615 if (clauses
.exists ())
20616 clauses
[0].type
= CPP_PRAGMA
;
20621 # pragma omp declare target new-line
20622 declarations and definitions
20623 # pragma omp end declare target new-line
20626 # pragma omp declare target ( extended-list ) new-line
20628 # pragma omp declare target declare-target-clauses[seq] new-line */
20630 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
20631 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
20632 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
20633 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
20636 c_parser_omp_declare_target (c_parser
*parser
)
20638 tree clauses
= NULL_TREE
;
20639 int device_type
= 0;
20640 bool only_device_type
= true;
20641 if (c_parser_next_token_is (parser
, CPP_NAME
))
20642 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
20643 "#pragma omp declare target");
20644 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
20646 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO_DECLARE
,
20648 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
20649 c_parser_skip_to_pragma_eol (parser
);
20653 c_parser_skip_to_pragma_eol (parser
);
20654 current_omp_declare_target_attribute
++;
20657 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
20658 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
20659 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
20660 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
20662 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
20664 tree t
= OMP_CLAUSE_DECL (c
), id
;
20665 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
20666 tree at2
= lookup_attribute ("omp declare target link",
20667 DECL_ATTRIBUTES (t
));
20668 only_device_type
= false;
20669 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
20671 id
= get_identifier ("omp declare target link");
20672 std::swap (at1
, at2
);
20675 id
= get_identifier ("omp declare target");
20678 error_at (OMP_CLAUSE_LOCATION (c
),
20679 "%qD specified both in declare target %<link%> and %<to%>"
20685 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
20686 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
20689 symtab_node
*node
= symtab_node::get (t
);
20692 node
->offloadable
= 1;
20693 if (ENABLE_OFFLOADING
)
20695 g
->have_offload
= true;
20696 if (is_a
<varpool_node
*> (node
))
20697 vec_safe_push (offload_vars
, t
);
20701 if (TREE_CODE (t
) != FUNCTION_DECL
)
20703 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_HOST
) != 0)
20705 tree at3
= lookup_attribute ("omp declare target host",
20706 DECL_ATTRIBUTES (t
));
20707 if (at3
== NULL_TREE
)
20709 id
= get_identifier ("omp declare target host");
20710 DECL_ATTRIBUTES (t
)
20711 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
20714 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_NOHOST
) != 0)
20716 tree at3
= lookup_attribute ("omp declare target nohost",
20717 DECL_ATTRIBUTES (t
));
20718 if (at3
== NULL_TREE
)
20720 id
= get_identifier ("omp declare target nohost");
20721 DECL_ATTRIBUTES (t
)
20722 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
20726 if (device_type
&& only_device_type
)
20727 warning_at (OMP_CLAUSE_LOCATION (clauses
), 0,
20728 "directive with only %<device_type%> clauses ignored");
20732 c_parser_omp_end_declare_target (c_parser
*parser
)
20734 location_t loc
= c_parser_peek_token (parser
)->location
;
20735 c_parser_consume_pragma (parser
);
20736 if (c_parser_next_token_is (parser
, CPP_NAME
)
20737 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
20740 c_parser_consume_token (parser
);
20741 if (c_parser_next_token_is (parser
, CPP_NAME
)
20742 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
20744 c_parser_consume_token (parser
);
20747 c_parser_error (parser
, "expected %<target%>");
20748 c_parser_skip_to_pragma_eol (parser
);
20754 c_parser_error (parser
, "expected %<declare%>");
20755 c_parser_skip_to_pragma_eol (parser
);
20758 c_parser_skip_to_pragma_eol (parser
);
20759 if (!current_omp_declare_target_attribute
)
20760 error_at (loc
, "%<#pragma omp end declare target%> without corresponding "
20761 "%<#pragma omp declare target%>");
20763 current_omp_declare_target_attribute
--;
20768 #pragma omp declare reduction (reduction-id : typename-list : expression) \
20769 initializer-clause[opt] new-line
20771 initializer-clause:
20772 initializer (omp_priv = initializer)
20773 initializer (function-name (argument-list)) */
20776 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
20778 unsigned int tokens_avail
= 0, i
;
20779 vec
<tree
> types
= vNULL
;
20780 vec
<c_token
> clauses
= vNULL
;
20781 enum tree_code reduc_code
= ERROR_MARK
;
20782 tree reduc_id
= NULL_TREE
;
20784 location_t rloc
= c_parser_peek_token (parser
)->location
;
20786 if (context
== pragma_struct
|| context
== pragma_param
)
20788 error ("%<#pragma omp declare reduction%> not at file or block scope");
20792 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
20795 switch (c_parser_peek_token (parser
)->type
)
20798 reduc_code
= PLUS_EXPR
;
20801 reduc_code
= MULT_EXPR
;
20804 reduc_code
= MINUS_EXPR
;
20807 reduc_code
= BIT_AND_EXPR
;
20810 reduc_code
= BIT_XOR_EXPR
;
20813 reduc_code
= BIT_IOR_EXPR
;
20816 reduc_code
= TRUTH_ANDIF_EXPR
;
20819 reduc_code
= TRUTH_ORIF_EXPR
;
20823 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20824 if (strcmp (p
, "min") == 0)
20826 reduc_code
= MIN_EXPR
;
20829 if (strcmp (p
, "max") == 0)
20831 reduc_code
= MAX_EXPR
;
20834 reduc_id
= c_parser_peek_token (parser
)->value
;
20837 c_parser_error (parser
,
20838 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
20839 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
20843 tree orig_reduc_id
, reduc_decl
;
20844 orig_reduc_id
= reduc_id
;
20845 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
20846 reduc_decl
= c_omp_reduction_decl (reduc_id
);
20847 c_parser_consume_token (parser
);
20849 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
20854 location_t loc
= c_parser_peek_token (parser
)->location
;
20855 struct c_type_name
*ctype
= c_parser_type_name (parser
);
20858 type
= groktypename (ctype
, NULL
, NULL
);
20859 if (type
== error_mark_node
)
20861 else if ((INTEGRAL_TYPE_P (type
)
20862 || TREE_CODE (type
) == REAL_TYPE
20863 || TREE_CODE (type
) == COMPLEX_TYPE
)
20864 && orig_reduc_id
== NULL_TREE
)
20865 error_at (loc
, "predeclared arithmetic type in "
20866 "%<#pragma omp declare reduction%>");
20867 else if (TREE_CODE (type
) == FUNCTION_TYPE
20868 || TREE_CODE (type
) == ARRAY_TYPE
)
20869 error_at (loc
, "function or array type in "
20870 "%<#pragma omp declare reduction%>");
20871 else if (TYPE_ATOMIC (type
))
20872 error_at (loc
, "%<_Atomic%> qualified type in "
20873 "%<#pragma omp declare reduction%>");
20874 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
20875 error_at (loc
, "const, volatile or restrict qualified type in "
20876 "%<#pragma omp declare reduction%>");
20880 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
20881 if (comptypes (TREE_PURPOSE (t
), type
))
20883 error_at (loc
, "redeclaration of %qs "
20884 "%<#pragma omp declare reduction%> for "
20886 IDENTIFIER_POINTER (reduc_id
)
20887 + sizeof ("omp declare reduction ") - 1,
20890 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
20892 error_at (ploc
, "previous %<#pragma omp declare "
20896 if (t
== NULL_TREE
)
20897 types
.safe_push (type
);
20899 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20900 c_parser_consume_token (parser
);
20908 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
20909 || types
.is_empty ())
20912 clauses
.release ();
20916 c_token
*token
= c_parser_peek_token (parser
);
20917 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
20919 c_parser_consume_token (parser
);
20921 c_parser_skip_to_pragma_eol (parser
);
20925 if (types
.length () > 1)
20927 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
20929 c_token
*token
= c_parser_peek_token (parser
);
20930 if (token
->type
== CPP_EOF
)
20932 clauses
.safe_push (*token
);
20933 c_parser_consume_token (parser
);
20935 clauses
.safe_push (*c_parser_peek_token (parser
));
20936 c_parser_skip_to_pragma_eol (parser
);
20938 /* Make sure nothing tries to read past the end of the tokens. */
20940 memset (&eof_token
, 0, sizeof (eof_token
));
20941 eof_token
.type
= CPP_EOF
;
20942 clauses
.safe_push (eof_token
);
20943 clauses
.safe_push (eof_token
);
20946 int errs
= errorcount
;
20947 FOR_EACH_VEC_ELT (types
, i
, type
)
20949 tokens_avail
= parser
->tokens_avail
;
20950 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
20951 if (!clauses
.is_empty ())
20953 parser
->tokens
= clauses
.address ();
20954 parser
->tokens_avail
= clauses
.length ();
20955 parser
->in_pragma
= true;
20958 bool nested
= current_function_decl
!= NULL_TREE
;
20960 c_push_function_context ();
20961 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
20962 reduc_id
, default_function_type
);
20963 current_function_decl
= fndecl
;
20964 allocate_struct_function (fndecl
, true);
20966 tree stmt
= push_stmt_list ();
20967 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
20968 warn about these. */
20969 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20970 get_identifier ("omp_out"), type
);
20971 DECL_ARTIFICIAL (omp_out
) = 1;
20972 DECL_CONTEXT (omp_out
) = fndecl
;
20973 pushdecl (omp_out
);
20974 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20975 get_identifier ("omp_in"), type
);
20976 DECL_ARTIFICIAL (omp_in
) = 1;
20977 DECL_CONTEXT (omp_in
) = fndecl
;
20979 struct c_expr combiner
= c_parser_expression (parser
);
20980 struct c_expr initializer
;
20981 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
20983 initializer
.set_error ();
20984 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
20986 else if (c_parser_next_token_is (parser
, CPP_NAME
)
20987 && strcmp (IDENTIFIER_POINTER
20988 (c_parser_peek_token (parser
)->value
),
20989 "initializer") == 0)
20991 c_parser_consume_token (parser
);
20994 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
20995 get_identifier ("omp_priv"), type
);
20996 DECL_ARTIFICIAL (omp_priv
) = 1;
20997 DECL_INITIAL (omp_priv
) = error_mark_node
;
20998 DECL_CONTEXT (omp_priv
) = fndecl
;
20999 pushdecl (omp_priv
);
21000 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
21001 get_identifier ("omp_orig"), type
);
21002 DECL_ARTIFICIAL (omp_orig
) = 1;
21003 DECL_CONTEXT (omp_orig
) = fndecl
;
21004 pushdecl (omp_orig
);
21005 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
21007 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
21009 c_parser_error (parser
, "expected %<omp_priv%> or "
21013 else if (strcmp (IDENTIFIER_POINTER
21014 (c_parser_peek_token (parser
)->value
),
21017 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
21018 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
21020 c_parser_error (parser
, "expected function-name %<(%>");
21024 initializer
= c_parser_postfix_expression (parser
);
21025 if (initializer
.value
21026 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
21029 tree c
= initializer
.value
;
21030 for (j
= 0; j
< call_expr_nargs (c
); j
++)
21032 tree a
= CALL_EXPR_ARG (c
, j
);
21034 if (TREE_CODE (a
) == ADDR_EXPR
21035 && TREE_OPERAND (a
, 0) == omp_priv
)
21038 if (j
== call_expr_nargs (c
))
21039 error ("one of the initializer call arguments should be "
21045 c_parser_consume_token (parser
);
21046 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21050 tree st
= push_stmt_list ();
21051 location_t loc
= c_parser_peek_token (parser
)->location
;
21052 rich_location
richloc (line_table
, loc
);
21053 start_init (omp_priv
, NULL_TREE
, 0, &richloc
);
21054 struct c_expr init
= c_parser_initializer (parser
);
21056 finish_decl (omp_priv
, loc
, init
.value
,
21057 init
.original_type
, NULL_TREE
);
21058 pop_stmt_list (st
);
21062 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
21068 c_parser_skip_to_pragma_eol (parser
);
21070 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
21071 DECL_INITIAL (reduc_decl
));
21072 DECL_INITIAL (reduc_decl
) = t
;
21073 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
21074 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
21075 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
21076 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
21077 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
21078 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
21081 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
21082 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
21083 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
21084 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
21085 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
21086 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
21087 walk_tree (&DECL_INITIAL (omp_priv
),
21088 c_check_omp_declare_reduction_r
,
21089 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
21093 pop_stmt_list (stmt
);
21095 if (cfun
->language
!= NULL
)
21097 ggc_free (cfun
->language
);
21098 cfun
->language
= NULL
;
21101 current_function_decl
= NULL_TREE
;
21103 c_pop_function_context ();
21105 if (!clauses
.is_empty ())
21107 parser
->tokens
= &parser
->tokens_buf
[0];
21108 parser
->tokens_avail
= tokens_avail
;
21112 if (errs
!= errorcount
)
21116 clauses
.release ();
21122 #pragma omp declare simd declare-simd-clauses[optseq] new-line
21123 #pragma omp declare reduction (reduction-id : typename-list : expression) \
21124 initializer-clause[opt] new-line
21125 #pragma omp declare target new-line
21128 #pragma omp declare variant (identifier) match (context-selector) */
21131 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
21133 c_parser_consume_pragma (parser
);
21134 if (c_parser_next_token_is (parser
, CPP_NAME
))
21136 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21137 if (strcmp (p
, "simd") == 0)
21139 /* c_parser_consume_token (parser); done in
21140 c_parser_omp_declare_simd. */
21141 c_parser_omp_declare_simd (parser
, context
);
21144 if (strcmp (p
, "reduction") == 0)
21146 c_parser_consume_token (parser
);
21147 c_parser_omp_declare_reduction (parser
, context
);
21150 if (!flag_openmp
) /* flag_openmp_simd */
21152 c_parser_skip_to_pragma_eol (parser
, false);
21155 if (strcmp (p
, "target") == 0)
21157 c_parser_consume_token (parser
);
21158 c_parser_omp_declare_target (parser
);
21161 if (strcmp (p
, "variant") == 0)
21163 /* c_parser_consume_token (parser); done in
21164 c_parser_omp_declare_simd. */
21165 c_parser_omp_declare_simd (parser
, context
);
21170 c_parser_error (parser
, "expected %<simd%>, %<reduction%>, "
21171 "%<target%> or %<variant%>");
21172 c_parser_skip_to_pragma_eol (parser
);
21176 #pragma omp requires clauses[optseq] new-line */
21179 c_parser_omp_requires (c_parser
*parser
)
21182 enum omp_requires new_req
= (enum omp_requires
) 0;
21184 c_parser_consume_pragma (parser
);
21186 location_t loc
= c_parser_peek_token (parser
)->location
;
21187 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21189 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
21190 c_parser_consume_token (parser
);
21194 if (c_parser_next_token_is (parser
, CPP_NAME
))
21197 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21198 location_t cloc
= c_parser_peek_token (parser
)->location
;
21199 enum omp_requires this_req
= (enum omp_requires
) 0;
21201 if (!strcmp (p
, "unified_address"))
21202 this_req
= OMP_REQUIRES_UNIFIED_ADDRESS
;
21203 else if (!strcmp (p
, "unified_shared_memory"))
21204 this_req
= OMP_REQUIRES_UNIFIED_SHARED_MEMORY
;
21205 else if (!strcmp (p
, "dynamic_allocators"))
21206 this_req
= OMP_REQUIRES_DYNAMIC_ALLOCATORS
;
21207 else if (!strcmp (p
, "reverse_offload"))
21208 this_req
= OMP_REQUIRES_REVERSE_OFFLOAD
;
21209 else if (!strcmp (p
, "atomic_default_mem_order"))
21211 c_parser_consume_token (parser
);
21213 matching_parens parens
;
21214 if (parens
.require_open (parser
))
21216 if (c_parser_next_token_is (parser
, CPP_NAME
))
21218 tree v
= c_parser_peek_token (parser
)->value
;
21219 p
= IDENTIFIER_POINTER (v
);
21221 if (!strcmp (p
, "seq_cst"))
21223 = (enum omp_requires
) OMP_MEMORY_ORDER_SEQ_CST
;
21224 else if (!strcmp (p
, "relaxed"))
21226 = (enum omp_requires
) OMP_MEMORY_ORDER_RELAXED
;
21227 else if (!strcmp (p
, "acq_rel"))
21229 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQ_REL
;
21233 error_at (c_parser_peek_token (parser
)->location
,
21234 "expected %<seq_cst%>, %<relaxed%> or "
21236 if (c_parser_peek_2nd_token (parser
)->type
21237 == CPP_CLOSE_PAREN
)
21238 c_parser_consume_token (parser
);
21241 c_parser_consume_token (parser
);
21243 parens
.skip_until_found_close (parser
);
21246 c_parser_skip_to_pragma_eol (parser
, false);
21254 error_at (cloc
, "expected %<unified_address%>, "
21255 "%<unified_shared_memory%>, "
21256 "%<dynamic_allocators%>, "
21257 "%<reverse_offload%> "
21258 "or %<atomic_default_mem_order%> clause");
21259 c_parser_skip_to_pragma_eol (parser
, false);
21263 sorry_at (cloc
, "%qs clause on %<requires%> directive not "
21264 "supported yet", p
);
21266 c_parser_consume_token (parser
);
21269 if ((this_req
& ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
21271 if ((this_req
& new_req
) != 0)
21272 error_at (cloc
, "too many %qs clauses", p
);
21273 if (this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
21274 && (omp_requires_mask
& OMP_REQUIRES_TARGET_USED
) != 0)
21275 error_at (cloc
, "%qs clause used lexically after first "
21276 "target construct or offloading API", p
);
21278 else if ((new_req
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
21280 error_at (cloc
, "too many %qs clauses",
21281 "atomic_default_mem_order");
21282 this_req
= (enum omp_requires
) 0;
21284 else if ((omp_requires_mask
21285 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
21287 error_at (cloc
, "more than one %<atomic_default_mem_order%>"
21288 " clause in a single compilation unit");
21290 = (enum omp_requires
)
21292 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
);
21294 else if ((omp_requires_mask
21295 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
) != 0)
21296 error_at (cloc
, "%<atomic_default_mem_order%> clause used "
21297 "lexically after first %<atomic%> construct "
21298 "without memory order clause");
21299 new_req
= (enum omp_requires
) (new_req
| this_req
);
21301 = (enum omp_requires
) (omp_requires_mask
| this_req
);
21307 c_parser_skip_to_pragma_eol (parser
);
21310 error_at (loc
, "%<pragma omp requires%> requires at least one clause");
21313 /* Helper function for c_parser_omp_taskloop.
21314 Disallow zero sized or potentially zero sized task reductions. */
21317 c_finish_taskloop_clauses (tree clauses
)
21319 tree
*pc
= &clauses
;
21320 for (tree c
= clauses
; c
; c
= *pc
)
21322 bool remove
= false;
21323 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
21325 tree type
= strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
21326 if (integer_zerop (TYPE_SIZE_UNIT (type
)))
21328 error_at (OMP_CLAUSE_LOCATION (c
),
21329 "zero sized type %qT in %<reduction%> clause", type
);
21332 else if (TREE_CODE (TYPE_SIZE_UNIT (type
)) != INTEGER_CST
)
21334 error_at (OMP_CLAUSE_LOCATION (c
),
21335 "variable sized type %qT in %<reduction%> clause",
21341 *pc
= OMP_CLAUSE_CHAIN (c
);
21343 pc
= &OMP_CLAUSE_CHAIN (c
);
21349 #pragma omp taskloop taskloop-clause[optseq] new-line
21352 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
21355 #define OMP_TASKLOOP_CLAUSE_MASK \
21356 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21357 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21358 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21359 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
21360 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
21361 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
21362 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
21363 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
21364 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
21365 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21366 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
21367 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
21368 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
21369 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
21370 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21371 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
21374 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
21375 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
21378 tree clauses
, block
, ret
;
21380 strcat (p_name
, " taskloop");
21381 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
21382 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
21384 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
)) != 0)
21385 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_IN_REDUCTION
);
21387 if (c_parser_next_token_is (parser
, CPP_NAME
))
21389 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21391 if (strcmp (p
, "simd") == 0)
21393 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
21394 if (cclauses
== NULL
)
21395 cclauses
= cclauses_buf
;
21396 c_parser_consume_token (parser
);
21397 if (!flag_openmp
) /* flag_openmp_simd */
21398 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
21400 block
= c_begin_compound_stmt (true);
21401 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
21402 block
= c_end_compound_stmt (loc
, block
, true);
21405 ret
= make_node (OMP_TASKLOOP
);
21406 TREE_TYPE (ret
) = void_type_node
;
21407 OMP_FOR_BODY (ret
) = block
;
21408 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
21409 OMP_FOR_CLAUSES (ret
)
21410 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret
));
21411 SET_EXPR_LOCATION (ret
, loc
);
21416 if (!flag_openmp
) /* flag_openmp_simd */
21418 c_parser_skip_to_pragma_eol (parser
, false);
21422 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
21425 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
21426 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
21429 clauses
= c_finish_taskloop_clauses (clauses
);
21430 block
= c_begin_compound_stmt (true);
21431 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
21432 block
= c_end_compound_stmt (loc
, block
, true);
21438 /* Main entry point to parsing most OpenMP pragmas. */
21441 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
21443 enum pragma_kind p_kind
;
21446 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
21447 omp_clause_mask
mask (0);
21449 loc
= c_parser_peek_token (parser
)->location
;
21450 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
21451 c_parser_consume_pragma (parser
);
21455 case PRAGMA_OACC_ATOMIC
:
21456 c_parser_omp_atomic (loc
, parser
);
21458 case PRAGMA_OACC_CACHE
:
21459 strcpy (p_name
, "#pragma acc");
21460 stmt
= c_parser_oacc_cache (loc
, parser
);
21462 case PRAGMA_OACC_DATA
:
21463 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
21465 case PRAGMA_OACC_HOST_DATA
:
21466 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
21468 case PRAGMA_OACC_KERNELS
:
21469 case PRAGMA_OACC_PARALLEL
:
21470 case PRAGMA_OACC_SERIAL
:
21471 strcpy (p_name
, "#pragma acc");
21472 stmt
= c_parser_oacc_compute (loc
, parser
, p_kind
, p_name
, if_p
);
21474 case PRAGMA_OACC_LOOP
:
21475 strcpy (p_name
, "#pragma acc");
21476 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21478 case PRAGMA_OACC_WAIT
:
21479 strcpy (p_name
, "#pragma wait");
21480 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
21482 case PRAGMA_OMP_ATOMIC
:
21483 c_parser_omp_atomic (loc
, parser
);
21485 case PRAGMA_OMP_CRITICAL
:
21486 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
21488 case PRAGMA_OMP_DISTRIBUTE
:
21489 strcpy (p_name
, "#pragma omp");
21490 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21492 case PRAGMA_OMP_FOR
:
21493 strcpy (p_name
, "#pragma omp");
21494 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21496 case PRAGMA_OMP_LOOP
:
21497 strcpy (p_name
, "#pragma omp");
21498 stmt
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21500 case PRAGMA_OMP_MASTER
:
21501 strcpy (p_name
, "#pragma omp");
21502 stmt
= c_parser_omp_master (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21504 case PRAGMA_OMP_PARALLEL
:
21505 strcpy (p_name
, "#pragma omp");
21506 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21508 case PRAGMA_OMP_SECTIONS
:
21509 strcpy (p_name
, "#pragma omp");
21510 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
21512 case PRAGMA_OMP_SIMD
:
21513 strcpy (p_name
, "#pragma omp");
21514 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21516 case PRAGMA_OMP_SINGLE
:
21517 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
21519 case PRAGMA_OMP_TASK
:
21520 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
21522 case PRAGMA_OMP_TASKGROUP
:
21523 stmt
= c_parser_omp_taskgroup (loc
, parser
, if_p
);
21525 case PRAGMA_OMP_TASKLOOP
:
21526 strcpy (p_name
, "#pragma omp");
21527 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21529 case PRAGMA_OMP_TEAMS
:
21530 strcpy (p_name
, "#pragma omp");
21531 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
21534 gcc_unreachable ();
21537 if (stmt
&& stmt
!= error_mark_node
)
21538 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
21543 # pragma omp threadprivate (variable-list) */
21546 c_parser_omp_threadprivate (c_parser
*parser
)
21551 c_parser_consume_pragma (parser
);
21552 loc
= c_parser_peek_token (parser
)->location
;
21553 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
21555 /* Mark every variable in VARS to be assigned thread local storage. */
21556 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
21558 tree v
= TREE_PURPOSE (t
);
21560 /* FIXME diagnostics: Ideally we should keep individual
21561 locations for all the variables in the var list to make the
21562 following errors more precise. Perhaps
21563 c_parser_omp_var_list_parens() should construct a list of
21564 locations to go along with the var list. */
21566 /* If V had already been marked threadprivate, it doesn't matter
21567 whether it had been used prior to this point. */
21569 error_at (loc
, "%qD is not a variable", v
);
21570 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
21571 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
21572 else if (! is_global_var (v
))
21573 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
21574 else if (TREE_TYPE (v
) == error_mark_node
)
21576 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
21577 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
21580 if (! DECL_THREAD_LOCAL_P (v
))
21582 set_decl_tls_model (v
, decl_default_tls_model (v
));
21583 /* If rtl has been already set for this var, call
21584 make_decl_rtl once again, so that encode_section_info
21585 has a chance to look at the new decl flags. */
21586 if (DECL_RTL_SET_P (v
))
21589 C_DECL_THREADPRIVATE_P (v
) = 1;
21593 c_parser_skip_to_pragma_eol (parser
);
21596 /* Parse a transaction attribute (GCC Extension).
21598 transaction-attribute:
21600 attribute-specifier
21604 c_parser_transaction_attributes (c_parser
*parser
)
21606 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
21607 return c_parser_gnu_attributes (parser
);
21609 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
21611 return c_parser_std_attribute_specifier (parser
, true);
21614 /* Parse a __transaction_atomic or __transaction_relaxed statement
21617 transaction-statement:
21618 __transaction_atomic transaction-attribute[opt] compound-statement
21619 __transaction_relaxed compound-statement
21621 Note that the only valid attribute is: "outer".
21625 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
21627 unsigned int old_in
= parser
->in_transaction
;
21628 unsigned int this_in
= 1, new_in
;
21629 location_t loc
= c_parser_peek_token (parser
)->location
;
21632 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
21633 || keyword
== RID_TRANSACTION_RELAXED
)
21634 && c_parser_next_token_is_keyword (parser
, keyword
));
21635 c_parser_consume_token (parser
);
21637 if (keyword
== RID_TRANSACTION_RELAXED
)
21638 this_in
|= TM_STMT_ATTR_RELAXED
;
21641 attrs
= c_parser_transaction_attributes (parser
);
21643 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
21646 /* Keep track if we're in the lexical scope of an outer transaction. */
21647 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
21649 parser
->in_transaction
= new_in
;
21650 stmt
= c_parser_compound_statement (parser
);
21651 parser
->in_transaction
= old_in
;
21654 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
21656 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
21657 "%<__transaction_atomic%> without transactional memory support enabled"
21658 : "%<__transaction_relaxed %> "
21659 "without transactional memory support enabled"));
21664 /* Parse a __transaction_atomic or __transaction_relaxed expression
21667 transaction-expression:
21668 __transaction_atomic ( expression )
21669 __transaction_relaxed ( expression )
21672 static struct c_expr
21673 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
21676 unsigned int old_in
= parser
->in_transaction
;
21677 unsigned int this_in
= 1;
21678 location_t loc
= c_parser_peek_token (parser
)->location
;
21681 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
21682 || keyword
== RID_TRANSACTION_RELAXED
)
21683 && c_parser_next_token_is_keyword (parser
, keyword
));
21684 c_parser_consume_token (parser
);
21686 if (keyword
== RID_TRANSACTION_RELAXED
)
21687 this_in
|= TM_STMT_ATTR_RELAXED
;
21690 attrs
= c_parser_transaction_attributes (parser
);
21692 this_in
|= parse_tm_stmt_attr (attrs
, 0);
21695 parser
->in_transaction
= this_in
;
21696 matching_parens parens
;
21697 if (parens
.require_open (parser
))
21699 tree expr
= c_parser_expression (parser
).value
;
21700 ret
.original_type
= TREE_TYPE (expr
);
21701 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
21702 if (this_in
& TM_STMT_ATTR_RELAXED
)
21703 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
21704 SET_EXPR_LOCATION (ret
.value
, loc
);
21705 ret
.original_code
= TRANSACTION_EXPR
;
21706 if (!parens
.require_close (parser
))
21708 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
21716 ret
.original_code
= ERROR_MARK
;
21717 ret
.original_type
= NULL
;
21719 parser
->in_transaction
= old_in
;
21722 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
21723 "%<__transaction_atomic%> without transactional memory support enabled"
21724 : "%<__transaction_relaxed %> "
21725 "without transactional memory support enabled"));
21727 set_c_expr_source_range (&ret
, loc
, loc
);
21732 /* Parse a __transaction_cancel statement (GCC Extension).
21734 transaction-cancel-statement:
21735 __transaction_cancel transaction-attribute[opt] ;
21737 Note that the only valid attribute is "outer".
21741 c_parser_transaction_cancel (c_parser
*parser
)
21743 location_t loc
= c_parser_peek_token (parser
)->location
;
21745 bool is_outer
= false;
21747 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
21748 c_parser_consume_token (parser
);
21750 attrs
= c_parser_transaction_attributes (parser
);
21752 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
21756 error_at (loc
, "%<__transaction_cancel%> without "
21757 "transactional memory support enabled");
21760 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
21762 error_at (loc
, "%<__transaction_cancel%> within a "
21763 "%<__transaction_relaxed%>");
21768 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
21769 && !is_tm_may_cancel_outer (current_function_decl
))
21771 error_at (loc
, "outer %<__transaction_cancel%> not "
21772 "within outer %<__transaction_atomic%> or "
21773 "a %<transaction_may_cancel_outer%> function");
21777 else if (parser
->in_transaction
== 0)
21779 error_at (loc
, "%<__transaction_cancel%> not within "
21780 "%<__transaction_atomic%>");
21784 return add_stmt (build_tm_abort_call (loc
, is_outer
));
21787 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
21790 /* Parse a single source file. */
21793 c_parse_file (void)
21795 /* Use local storage to begin. If the first token is a pragma, parse it.
21796 If it is #pragma GCC pch_preprocess, then this will load a PCH file
21797 which will cause garbage collection. */
21800 memset (&tparser
, 0, sizeof tparser
);
21801 tparser
.translate_strings_p
= true;
21802 tparser
.tokens
= &tparser
.tokens_buf
[0];
21803 the_parser
= &tparser
;
21805 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
21806 c_parser_pragma_pch_preprocess (&tparser
);
21808 c_common_no_more_pch ();
21810 the_parser
= ggc_alloc
<c_parser
> ();
21811 *the_parser
= tparser
;
21812 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
21813 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
21815 /* Initialize EH, if we've been told to do so. */
21816 if (flag_exceptions
)
21817 using_eh_for_cleanups ();
21819 c_parser_translation_unit (the_parser
);
21823 /* Parse the body of a function declaration marked with "__RTL".
21825 The RTL parser works on the level of characters read from a
21826 FILE *, whereas c_parser works at the level of tokens.
21827 Square this circle by consuming all of the tokens up to and
21828 including the closing brace, recording the start/end of the RTL
21829 fragment, and reopening the file and re-reading the relevant
21830 lines within the RTL parser.
21832 This requires the opening and closing braces of the C function
21833 to be on separate lines from the RTL they wrap.
21835 Take ownership of START_WITH_PASS, if non-NULL. */
21838 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
21840 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
21842 free (start_with_pass
);
21843 return c_parser_peek_token (parser
)->location
;
21846 location_t start_loc
= c_parser_peek_token (parser
)->location
;
21848 /* Consume all tokens, up to the closing brace, handling
21849 matching pairs of braces in the rtl dump. */
21850 int num_open_braces
= 1;
21853 switch (c_parser_peek_token (parser
)->type
)
21855 case CPP_OPEN_BRACE
:
21858 case CPP_CLOSE_BRACE
:
21859 if (--num_open_braces
== 0)
21860 goto found_closing_brace
;
21863 error_at (start_loc
, "no closing brace");
21864 free (start_with_pass
);
21865 return c_parser_peek_token (parser
)->location
;
21869 c_parser_consume_token (parser
);
21872 found_closing_brace
:
21873 /* At the closing brace; record its location. */
21874 location_t end_loc
= c_parser_peek_token (parser
)->location
;
21876 /* Consume the closing brace. */
21877 c_parser_consume_token (parser
);
21879 /* Invoke the RTL parser. */
21880 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
21882 free (start_with_pass
);
21886 /* Run the backend on the cfun created above, transferring ownership of
21887 START_WITH_PASS. */
21888 run_rtl_passes (start_with_pass
);
21892 #include "gt-c-c-parser.h"