1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2024 Free Software Foundation, Inc.
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 Make sure all relevant comments, and all relevant code from all
26 actions, brought over from old parser. Verify exact correspondence
29 Add testcases covering every input symbol in every state in old and
32 Include full syntax for GNU C, including erroneous cases accepted
33 with error messages, in syntax productions in comments.
35 Make more diagnostics in the front end generally take an explicit
36 location rather than implicitly using input_location. */
39 #define INCLUDE_MEMORY
41 #include "coretypes.h"
46 #include "stringpool.h"
49 #include "stor-layout.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
54 #include "c-family/c-objc.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
63 #include "gcc-rich-location.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
71 #include "tree-pretty-print.h"
73 #include "c-family/known-headers.h"
75 #include "analyzer/analyzer-language.h"
78 /* We need to walk over decls with incomplete struct/union/enum types
79 after parsing the whole translation unit.
80 In finish_decl(), if the decl is static, has incomplete
81 struct/union/enum type, it is appended to incomplete_record_decls.
82 In c_parser_translation_unit(), we iterate over incomplete_record_decls
83 and report error if any of the decls are still incomplete. */
85 vec
<tree
> incomplete_record_decls
;
88 set_c_expr_source_range (c_expr
*expr
,
89 location_t start
, location_t finish
)
91 expr
->src_range
.m_start
= start
;
92 expr
->src_range
.m_finish
= finish
;
94 set_source_range (expr
->value
, start
, finish
);
98 set_c_expr_source_range (c_expr
*expr
,
99 source_range src_range
)
101 expr
->src_range
= src_range
;
103 set_source_range (expr
->value
, src_range
);
107 /* Initialization routine for this file. */
112 /* The only initialization required is of the reserved word
118 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
119 the c_token structure. */
120 gcc_assert (RID_MAX
<= 255);
129 mask
|= D_ASM
| D_EXT
;
135 if (!c_dialect_objc ())
136 mask
|= D_OBJC
| D_CXX_OBJC
;
138 ridpointers
= ggc_cleared_vec_alloc
<tree
> ((int) RID_MAX
);
139 for (i
= 0; i
< num_c_common_reswords
; i
++)
141 /* If a keyword is disabled, do not enter it into the table
142 and so create a canonical spelling that isn't a keyword. */
143 if (c_common_reswords
[i
].disable
& mask
)
146 && (c_common_reswords
[i
].disable
& D_CXXWARN
))
148 id
= get_identifier (c_common_reswords
[i
].word
);
149 C_SET_RID_CODE (id
, RID_CXX_COMPAT_WARN
);
150 C_IS_RESERVED_WORD (id
) = 1;
155 id
= get_identifier (c_common_reswords
[i
].word
);
156 C_SET_RID_CODE (id
, c_common_reswords
[i
].rid
);
157 C_IS_RESERVED_WORD (id
) = 1;
158 ridpointers
[(int) c_common_reswords
[i
].rid
] = id
;
161 for (i
= 0; i
< NUM_INT_N_ENTS
; i
++)
163 /* We always create the symbols but they aren't always supported. */
165 sprintf (name
, "__int%d", int_n_data
[i
].bitsize
);
166 id
= get_identifier (name
);
167 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
168 C_IS_RESERVED_WORD (id
) = 1;
170 sprintf (name
, "__int%d__", int_n_data
[i
].bitsize
);
171 id
= get_identifier (name
);
172 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
173 C_IS_RESERVED_WORD (id
) = 1;
178 id
= get_identifier ("omp_all_memory");
179 C_SET_RID_CODE (id
, RID_OMP_ALL_MEMORY
);
180 C_IS_RESERVED_WORD (id
) = 1;
181 ridpointers
[RID_OMP_ALL_MEMORY
] = id
;
185 /* A parser structure recording information about the state and
186 context of parsing. Includes lexer information with up to two
187 tokens of look-ahead; more are not needed for C. */
188 struct GTY(()) c_parser
{
189 /* The look-ahead tokens. */
190 c_token
* GTY((skip
)) tokens
;
191 /* Buffer for look-ahead tokens. */
192 c_token tokens_buf
[4];
193 /* How many look-ahead tokens are available (0 - 4, or
194 more if parsing from pre-lexed tokens). */
195 unsigned int tokens_avail
;
196 /* Raw look-ahead tokens, used only for checking in Objective-C
197 whether '[[' starts attributes. */
198 vec
<c_token
, va_gc
> *raw_tokens
;
199 /* The number of raw look-ahead tokens that have since been fully
201 unsigned int raw_tokens_used
;
202 /* True if a syntax error is being recovered from; false otherwise.
203 c_parser_error sets this flag. It should clear this flag when
204 enough tokens have been consumed to recover from the error. */
205 BOOL_BITFIELD error
: 1;
206 /* True if we're processing a pragma, and shouldn't automatically
207 consume CPP_PRAGMA_EOL. */
208 BOOL_BITFIELD in_pragma
: 1;
209 /* True if we're parsing the outermost block of an if statement. */
210 BOOL_BITFIELD in_if_block
: 1;
211 /* True if we want to lex a translated, joined string (for an
212 initial #pragma pch_preprocess). Otherwise the parser is
213 responsible for concatenating strings and translating to the
214 execution character set as needed. */
215 BOOL_BITFIELD lex_joined_string
: 1;
216 /* True if, when the parser is concatenating string literals, it
217 should translate them to the execution character set (false
218 inside attributes). */
219 BOOL_BITFIELD translate_strings_p
: 1;
221 /* Objective-C specific parser/lexer information. */
223 /* True if we are in a context where the Objective-C "PQ" keywords
224 are considered keywords. */
225 BOOL_BITFIELD objc_pq_context
: 1;
226 /* True if we are parsing a (potential) Objective-C foreach
227 statement. This is set to true after we parsed 'for (' and while
228 we wait for 'in' or ';' to decide if it's a standard C for loop or an
229 Objective-C foreach loop. */
230 BOOL_BITFIELD objc_could_be_foreach_context
: 1;
231 /* The following flag is needed to contextualize Objective-C lexical
232 analysis. In some cases (e.g., 'int NSObject;'), it is
233 undesirable to bind an identifier to an Objective-C class, even
234 if a class with that name exists. */
235 BOOL_BITFIELD objc_need_raw_identifier
: 1;
236 /* Nonzero if we're processing a __transaction statement. The value
237 is 1 | TM_STMT_ATTR_*. */
238 unsigned int in_transaction
: 4;
239 /* True if we are in a context where the Objective-C "Property attribute"
240 keywords are valid. */
241 BOOL_BITFIELD objc_property_attr_context
: 1;
243 /* Whether we have just seen/constructed a string-literal. Set when
244 returning a string-literal from c_parser_string_literal. Reset
245 in consume_token. Useful when we get a parse error and see an
246 unknown token, which could have been a string-literal constant
248 BOOL_BITFIELD seen_string_literal
: 1;
250 /* TRUE if omp::directive, omp::decl or omp::sequence attributes may not
252 BOOL_BITFIELD omp_attrs_forbidden_p
: 1;
254 /* Location of the last consumed token. */
255 location_t last_token_location
;
257 /* Holds state for parsing collapsed OMP_FOR loops. Managed by
258 c_parser_omp_for_loop. */
259 struct omp_for_parse_data
* GTY((skip
)) omp_for_parse_state
;
261 /* If we're in the context of OpenMP directives written as C23
262 attributes turned into pragma, vector of tokens created from that,
264 vec
<c_token
, va_gc
> *in_omp_attribute_pragma
;
266 /* Set for omp::decl attribute parsing to the decl to which it
268 tree in_omp_decl_attribute
;
271 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
274 c_parser_tokens_buf (c_parser
*parser
, unsigned n
)
276 return &parser
->tokens_buf
[n
];
279 /* Return the error state of PARSER. */
282 c_parser_error (c_parser
*parser
)
284 return parser
->error
;
287 /* Set the error state of PARSER to ERR. */
290 c_parser_set_error (c_parser
*parser
, bool err
)
296 /* The actual parser and external interface. ??? Does this need to be
297 garbage-collected? */
299 static GTY (()) c_parser
*the_parser
;
301 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
302 context-sensitive postprocessing of the token is not done. */
305 c_lex_one_token (c_parser
*parser
, c_token
*token
, bool raw
= false)
307 timevar_push (TV_LEX
);
309 if (raw
|| vec_safe_length (parser
->raw_tokens
) == 0)
311 token
->type
= c_lex_with_flags (&token
->value
, &token
->location
,
313 (parser
->lex_joined_string
314 ? 0 : C_LEX_STRING_NO_JOIN
));
315 token
->id_kind
= C_ID_NONE
;
316 token
->keyword
= RID_MAX
;
317 token
->pragma_kind
= PRAGMA_NONE
;
321 /* Use a token previously lexed as a raw look-ahead token, and
322 complete the processing on it. */
323 *token
= (*parser
->raw_tokens
)[parser
->raw_tokens_used
];
324 ++parser
->raw_tokens_used
;
325 if (parser
->raw_tokens_used
== vec_safe_length (parser
->raw_tokens
))
327 vec_free (parser
->raw_tokens
);
328 parser
->raw_tokens_used
= 0;
341 bool objc_force_identifier
= parser
->objc_need_raw_identifier
;
342 if (c_dialect_objc ())
343 parser
->objc_need_raw_identifier
= false;
345 if (C_IS_RESERVED_WORD (token
->value
))
347 enum rid rid_code
= C_RID_CODE (token
->value
);
349 if (rid_code
== RID_CXX_COMPAT_WARN
)
351 warning_at (token
->location
,
353 "identifier %qE conflicts with C++ keyword",
356 else if (rid_code
>= RID_FIRST_ADDR_SPACE
357 && rid_code
<= RID_LAST_ADDR_SPACE
)
360 as
= (addr_space_t
) (rid_code
- RID_FIRST_ADDR_SPACE
);
361 targetm
.addr_space
.diagnose_usage (as
, token
->location
);
362 token
->id_kind
= C_ID_ADDRSPACE
;
363 token
->keyword
= rid_code
;
366 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code
))
368 /* We found an Objective-C "pq" keyword (in, out,
369 inout, bycopy, byref, oneway). They need special
370 care because the interpretation depends on the
372 if (parser
->objc_pq_context
)
374 token
->type
= CPP_KEYWORD
;
375 token
->keyword
= rid_code
;
378 else if (parser
->objc_could_be_foreach_context
379 && rid_code
== RID_IN
)
381 /* We are in Objective-C, inside a (potential)
382 foreach context (which means after having
383 parsed 'for (', but before having parsed ';'),
384 and we found 'in'. We consider it the keyword
385 which terminates the declaration at the
386 beginning of a foreach-statement. Note that
387 this means you can't use 'in' for anything else
388 in that context; in particular, in Objective-C
389 you can't use 'in' as the name of the running
390 variable in a C for loop. We could potentially
391 try to add code here to disambiguate, but it
392 seems a reasonable limitation. */
393 token
->type
= CPP_KEYWORD
;
394 token
->keyword
= rid_code
;
397 /* Else, "pq" keywords outside of the "pq" context are
398 not keywords, and we fall through to the code for
401 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code
))
403 /* We found an Objective-C "property attribute"
404 keyword (getter, setter, readonly, etc). These are
405 only valid in the property context. */
406 if (parser
->objc_property_attr_context
)
408 token
->type
= CPP_KEYWORD
;
409 token
->keyword
= rid_code
;
412 /* Else they are not special keywords.
415 else if (c_dialect_objc ()
416 && (OBJC_IS_AT_KEYWORD (rid_code
)
417 || OBJC_IS_CXX_KEYWORD (rid_code
)))
419 /* We found one of the Objective-C "@" keywords (defs,
420 selector, synchronized, etc) or one of the
421 Objective-C "cxx" keywords (class, private,
422 protected, public, try, catch, throw) without a
423 preceding '@' sign. Do nothing and fall through to
424 the code for normal tokens (in C++ we would still
425 consider the CXX ones keywords, but not in C). */
430 token
->type
= CPP_KEYWORD
;
431 token
->keyword
= rid_code
;
436 decl
= lookup_name (token
->value
);
439 if (TREE_CODE (decl
) == TYPE_DECL
)
441 token
->id_kind
= C_ID_TYPENAME
;
445 else if (c_dialect_objc ())
447 tree objc_interface_decl
= objc_is_class_name (token
->value
);
448 /* Objective-C class names are in the same namespace as
449 variables and typedefs, and hence are shadowed by local
451 if (objc_interface_decl
452 && (!objc_force_identifier
|| global_bindings_p ()))
454 token
->value
= objc_interface_decl
;
455 token
->id_kind
= C_ID_CLASSNAME
;
459 token
->id_kind
= C_ID_ID
;
463 /* This only happens in Objective-C; it must be a keyword. */
464 token
->type
= CPP_KEYWORD
;
465 switch (C_RID_CODE (token
->value
))
467 /* Replace 'class' with '@class', 'private' with '@private',
468 etc. This prevents confusion with the C++ keyword
469 'class', and makes the tokens consistent with other
470 Objective-C 'AT' keywords. For example '@class' is
471 reported as RID_AT_CLASS which is consistent with
472 '@synchronized', which is reported as
475 case RID_CLASS
: token
->keyword
= RID_AT_CLASS
; break;
476 case RID_PRIVATE
: token
->keyword
= RID_AT_PRIVATE
; break;
477 case RID_PROTECTED
: token
->keyword
= RID_AT_PROTECTED
; break;
478 case RID_PUBLIC
: token
->keyword
= RID_AT_PUBLIC
; break;
479 case RID_THROW
: token
->keyword
= RID_AT_THROW
; break;
480 case RID_TRY
: token
->keyword
= RID_AT_TRY
; break;
481 case RID_CATCH
: token
->keyword
= RID_AT_CATCH
; break;
482 case RID_SYNCHRONIZED
: token
->keyword
= RID_AT_SYNCHRONIZED
; break;
483 default: token
->keyword
= C_RID_CODE (token
->value
);
488 case CPP_CLOSE_PAREN
:
490 /* These tokens may affect the interpretation of any identifiers
491 following, if doing Objective-C. */
492 if (c_dialect_objc ())
493 parser
->objc_need_raw_identifier
= false;
496 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
497 token
->pragma_kind
= (enum pragma_kind
) TREE_INT_CST_LOW (token
->value
);
504 timevar_pop (TV_LEX
);
507 /* Return a pointer to the next token from PARSER, reading it in if
511 c_parser_peek_token (c_parser
*parser
)
513 if (parser
->tokens_avail
== 0)
515 c_lex_one_token (parser
, &parser
->tokens
[0]);
516 parser
->tokens_avail
= 1;
518 return &parser
->tokens
[0];
521 /* Return a pointer to the next-but-one token from PARSER, reading it
522 in if necessary. The next token is already read in. */
525 c_parser_peek_2nd_token (c_parser
*parser
)
527 if (parser
->tokens_avail
>= 2)
528 return &parser
->tokens
[1];
529 gcc_assert (parser
->tokens_avail
== 1);
530 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
531 gcc_assert (parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
532 c_lex_one_token (parser
, &parser
->tokens
[1]);
533 parser
->tokens_avail
= 2;
534 return &parser
->tokens
[1];
537 /* Return a pointer to the Nth token from PARSER, reading it
538 in if necessary. The N-1th token is already read in. */
541 c_parser_peek_nth_token (c_parser
*parser
, unsigned int n
)
543 /* N is 1-based, not zero-based. */
546 if (parser
->tokens_avail
>= n
)
547 return &parser
->tokens
[n
- 1];
548 gcc_assert (parser
->tokens_avail
== n
- 1);
549 c_lex_one_token (parser
, &parser
->tokens
[n
- 1]);
550 parser
->tokens_avail
= n
;
551 return &parser
->tokens
[n
- 1];
554 /* Return a pointer to the Nth token from PARSER, reading it in as a
555 raw look-ahead token if necessary. The N-1th token is already read
556 in. Raw look-ahead tokens remain available for when the non-raw
557 functions above are called. */
560 c_parser_peek_nth_token_raw (c_parser
*parser
, unsigned int n
)
562 /* N is 1-based, not zero-based. */
565 if (parser
->tokens_avail
>= n
)
566 return &parser
->tokens
[n
- 1];
567 unsigned int raw_len
= vec_safe_length (parser
->raw_tokens
);
568 unsigned int raw_avail
569 = parser
->tokens_avail
+ raw_len
- parser
->raw_tokens_used
;
570 gcc_assert (raw_avail
>= n
- 1);
572 return &(*parser
->raw_tokens
)[parser
->raw_tokens_used
573 + n
- 1 - parser
->tokens_avail
];
574 vec_safe_reserve (parser
->raw_tokens
, 1);
575 parser
->raw_tokens
->quick_grow (raw_len
+ 1);
576 c_lex_one_token (parser
, &(*parser
->raw_tokens
)[raw_len
], true);
577 return &(*parser
->raw_tokens
)[raw_len
];
581 c_keyword_starts_typename (enum rid keyword
)
605 case RID_TYPEOF_UNQUAL
:
618 if (keyword
>= RID_FIRST_INT_N
619 && keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
620 && int_n_enabled_p
[keyword
- RID_FIRST_INT_N
])
626 /* Return true if TOKEN can start a type name,
629 c_token_starts_typename (c_token
*token
)
634 switch (token
->id_kind
)
643 gcc_assert (c_dialect_objc ());
649 return c_keyword_starts_typename (token
->keyword
);
651 if (c_dialect_objc ())
659 /* Return true if the next token from PARSER can start a type name,
660 false otherwise. LA specifies how to do lookahead in order to
661 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
664 c_parser_next_tokens_start_typename (c_parser
*parser
, enum c_lookahead_kind la
)
666 c_token
*token
= c_parser_peek_token (parser
);
667 if (c_token_starts_typename (token
))
670 /* Try a bit harder to detect an unknown typename. */
671 if (la
!= cla_prefer_id
672 && token
->type
== CPP_NAME
673 && token
->id_kind
== C_ID_ID
675 /* Do not try too hard when we could have "object in array". */
676 && !parser
->objc_could_be_foreach_context
678 && (la
== cla_prefer_type
679 || c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
680 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
682 /* Only unknown identifiers. */
683 && !lookup_name (token
->value
))
689 /* Return true if TOKEN, after an open parenthesis, can start a
690 compound literal (either a storage class specifier allowed in that
691 context, or a type name), false otherwise. */
693 c_token_starts_compound_literal (c_token
*token
)
698 switch (token
->keyword
)
710 return c_token_starts_typename (token
);
714 /* Return true if TOKEN is a type qualifier, false otherwise. */
716 c_token_is_qualifier (c_token
*token
)
721 switch (token
->id_kind
)
729 switch (token
->keyword
)
747 /* Return true if the next token from PARSER is a type qualifier,
750 c_parser_next_token_is_qualifier (c_parser
*parser
)
752 c_token
*token
= c_parser_peek_token (parser
);
753 return c_token_is_qualifier (token
);
756 /* Return true if TOKEN can start declaration specifiers (not
757 including standard attributes), false otherwise. */
759 c_token_starts_declspecs (c_token
*token
)
764 switch (token
->id_kind
)
773 gcc_assert (c_dialect_objc ());
779 switch (token
->keyword
)
809 case RID_TYPEOF_UNQUAL
:
823 if (token
->keyword
>= RID_FIRST_INT_N
824 && token
->keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
825 && int_n_enabled_p
[token
->keyword
- RID_FIRST_INT_N
])
830 if (c_dialect_objc ())
839 /* Return true if TOKEN can start declaration specifiers (not
840 including standard attributes) or a static assertion, false
843 c_token_starts_declaration (c_token
*token
)
845 if (c_token_starts_declspecs (token
)
846 || token
->keyword
== RID_STATIC_ASSERT
)
852 /* Return true if the next token from PARSER can start declaration
853 specifiers (not including standard attributes), false
856 c_parser_next_token_starts_declspecs (c_parser
*parser
)
858 c_token
*token
= c_parser_peek_token (parser
);
860 /* In Objective-C, a classname normally starts a declspecs unless it
861 is immediately followed by a dot. In that case, it is the
862 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
863 setter/getter on the class. c_token_starts_declspecs() can't
864 differentiate between the two cases because it only checks the
865 current token, so we have a special check here. */
866 if (c_dialect_objc ()
867 && token
->type
== CPP_NAME
868 && token
->id_kind
== C_ID_CLASSNAME
869 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
872 return c_token_starts_declspecs (token
);
875 /* Return true if the next tokens from PARSER can start declaration
876 specifiers (not including standard attributes) or a static
877 assertion, false otherwise. */
879 c_parser_next_tokens_start_declaration (c_parser
*parser
)
881 c_token
*token
= c_parser_peek_token (parser
);
884 if (c_dialect_objc ()
885 && token
->type
== CPP_NAME
886 && token
->id_kind
== C_ID_CLASSNAME
887 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
890 /* Labels do not start declarations. */
891 if (token
->type
== CPP_NAME
892 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
895 if (c_token_starts_declaration (token
))
898 if (c_parser_next_tokens_start_typename (parser
, cla_nonabstract_decl
))
904 /* Consume the next token from PARSER. */
907 c_parser_consume_token (c_parser
*parser
)
909 gcc_assert (parser
->tokens_avail
>= 1);
910 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
911 gcc_assert (!parser
->in_pragma
|| parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
912 gcc_assert (parser
->error
|| parser
->tokens
[0].type
!= CPP_PRAGMA
);
913 parser
->last_token_location
= parser
->tokens
[0].location
;
914 if (parser
->tokens
!= &parser
->tokens_buf
[0])
916 else if (parser
->tokens_avail
>= 2)
918 parser
->tokens
[0] = parser
->tokens
[1];
919 if (parser
->tokens_avail
>= 3)
921 parser
->tokens
[1] = parser
->tokens
[2];
922 if (parser
->tokens_avail
>= 4)
923 parser
->tokens
[2] = parser
->tokens
[3];
926 parser
->tokens_avail
--;
927 parser
->seen_string_literal
= false;
930 /* Expect the current token to be a #pragma. Consume it and remember
931 that we've begun parsing a pragma. */
934 c_parser_consume_pragma (c_parser
*parser
)
936 gcc_assert (!parser
->in_pragma
);
937 gcc_assert (parser
->tokens_avail
>= 1);
938 gcc_assert (parser
->tokens
[0].type
== CPP_PRAGMA
);
939 if (parser
->tokens
!= &parser
->tokens_buf
[0])
941 else if (parser
->tokens_avail
>= 2)
943 parser
->tokens
[0] = parser
->tokens
[1];
944 if (parser
->tokens_avail
>= 3)
945 parser
->tokens
[1] = parser
->tokens
[2];
947 parser
->tokens_avail
--;
948 parser
->in_pragma
= true;
951 /* Update the global input_location from TOKEN. */
953 c_parser_set_source_position_from_token (c_token
*token
)
955 if (token
->type
!= CPP_EOF
)
957 input_location
= token
->location
;
961 /* Helper function for c_parser_error.
962 Having peeked a token of kind TOK1_KIND that might signify
963 a conflict marker, peek successor tokens to determine
964 if we actually do have a conflict marker.
965 Specifically, we consider a run of 7 '<', '=' or '>' characters
966 at the start of a line as a conflict marker.
967 These come through the lexer as three pairs and a single,
968 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
969 If it returns true, *OUT_LOC is written to with the location/range
973 c_parser_peek_conflict_marker (c_parser
*parser
, enum cpp_ttype tok1_kind
,
976 c_token
*token2
= c_parser_peek_2nd_token (parser
);
977 if (token2
->type
!= tok1_kind
)
979 c_token
*token3
= c_parser_peek_nth_token (parser
, 3);
980 if (token3
->type
!= tok1_kind
)
982 c_token
*token4
= c_parser_peek_nth_token (parser
, 4);
983 if (token4
->type
!= conflict_marker_get_final_tok_kind (tok1_kind
))
986 /* It must be at the start of the line. */
987 location_t start_loc
= c_parser_peek_token (parser
)->location
;
988 if (LOCATION_COLUMN (start_loc
) != 1)
991 /* We have a conflict marker. Construct a location of the form:
994 with start == caret, finishing at the end of the marker. */
995 location_t finish_loc
= get_finish (token4
->location
);
996 *out_loc
= make_location (start_loc
, start_loc
, finish_loc
);
1001 /* Issue a diagnostic of the form
1002 FILE:LINE: MESSAGE before TOKEN
1003 where TOKEN is the next token in the input stream of PARSER.
1004 MESSAGE (specified by the caller) is usually of the form "expected
1007 Use RICHLOC as the location of the diagnostic.
1009 Do not issue a diagnostic if still recovering from an error.
1011 Return true iff an error was actually emitted.
1013 ??? This is taken from the C++ parser, but building up messages in
1014 this way is not i18n-friendly and some other approach should be
1018 c_parser_error_richloc (c_parser
*parser
, const char *gmsgid
,
1019 rich_location
*richloc
)
1021 c_token
*token
= c_parser_peek_token (parser
);
1024 parser
->error
= true;
1028 /* If this is actually a conflict marker, report it as such. */
1029 if (token
->type
== CPP_LSHIFT
1030 || token
->type
== CPP_RSHIFT
1031 || token
->type
== CPP_EQ_EQ
)
1034 if (c_parser_peek_conflict_marker (parser
, token
->type
, &loc
))
1036 error_at (loc
, "version control conflict marker in file");
1041 /* If we were parsing a string-literal and there is an unknown name
1042 token right after, then check to see if that could also have been
1043 a literal string by checking the name against a list of known
1044 standard string literal constants defined in header files. If
1045 there is one, then add that as an hint to the error message. */
1046 auto_diagnostic_group d
;
1048 if (parser
->seen_string_literal
&& token
->type
== CPP_NAME
)
1050 tree name
= token
->value
;
1051 const char *token_name
= IDENTIFIER_POINTER (name
);
1052 const char *header_hint
1053 = get_c_stdlib_header_for_string_macro_name (token_name
);
1054 if (header_hint
!= NULL
)
1055 h
= name_hint (NULL
, new suggest_missing_header (token
->location
,
1060 c_parse_error (gmsgid
,
1061 /* Because c_parse_error does not understand
1062 CPP_KEYWORD, keywords are treated like
1064 (token
->type
== CPP_KEYWORD
? CPP_NAME
: token
->type
),
1065 /* ??? The C parser does not save the cpp flags of a
1066 token, we need to pass 0 here and we will not get
1067 the source spelling of some tokens but rather the
1068 canonical spelling. */
1069 token
->value
, /*flags=*/0, richloc
);
1073 /* As c_parser_error_richloc, but issue the message at the
1074 location of PARSER's next token, or at input_location
1075 if the next token is EOF. */
1078 c_parser_error (c_parser
*parser
, const char *gmsgid
)
1080 c_token
*token
= c_parser_peek_token (parser
);
1081 c_parser_set_source_position_from_token (token
);
1082 rich_location
richloc (line_table
, input_location
);
1083 return c_parser_error_richloc (parser
, gmsgid
, &richloc
);
1086 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1087 This class is for tracking such a matching pair of symbols.
1088 In particular, it tracks the location of the first token,
1089 so that if the second token is missing, we can highlight the
1090 location of the first token when notifying the user about the
1093 template <typename traits_t
>
1097 /* token_pair's ctor. */
1098 token_pair () : m_open_loc (UNKNOWN_LOCATION
) {}
1100 /* If the next token is the opening symbol for this pair, consume it and
1102 Otherwise, issue an error and return false.
1103 In either case, record the location of the opening token. */
1105 bool require_open (c_parser
*parser
)
1107 c_token
*token
= c_parser_peek_token (parser
);
1109 m_open_loc
= token
->location
;
1111 return c_parser_require (parser
, traits_t::open_token_type
,
1112 traits_t::open_gmsgid
);
1115 /* Consume the next token from PARSER, recording its location as
1116 that of the opening token within the pair. */
1118 void consume_open (c_parser
*parser
)
1120 c_token
*token
= c_parser_peek_token (parser
);
1121 gcc_assert (token
->type
== traits_t::open_token_type
);
1122 m_open_loc
= token
->location
;
1123 c_parser_consume_token (parser
);
1126 /* If the next token is the closing symbol for this pair, consume it
1128 Otherwise, issue an error, highlighting the location of the
1129 corresponding opening token, and return false. */
1131 bool require_close (c_parser
*parser
) const
1133 return c_parser_require (parser
, traits_t::close_token_type
,
1134 traits_t::close_gmsgid
, m_open_loc
);
1137 /* Like token_pair::require_close, except that tokens will be skipped
1138 until the desired token is found. An error message is still produced
1139 if the next token is not as expected. */
1141 void skip_until_found_close (c_parser
*parser
) const
1143 c_parser_skip_until_found (parser
, traits_t::close_token_type
,
1144 traits_t::close_gmsgid
, m_open_loc
);
1148 location_t m_open_loc
;
1151 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1153 struct matching_paren_traits
1155 static const enum cpp_ttype open_token_type
= CPP_OPEN_PAREN
;
1156 static const char * const open_gmsgid
;
1157 static const enum cpp_ttype close_token_type
= CPP_CLOSE_PAREN
;
1158 static const char * const close_gmsgid
;
1161 const char * const matching_paren_traits::open_gmsgid
= "expected %<(%>";
1162 const char * const matching_paren_traits::close_gmsgid
= "expected %<)%>";
1164 /* "matching_parens" is a token_pair<T> class for tracking matching
1165 pairs of parentheses. */
1167 typedef token_pair
<matching_paren_traits
> matching_parens
;
1169 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1171 struct matching_brace_traits
1173 static const enum cpp_ttype open_token_type
= CPP_OPEN_BRACE
;
1174 static const char * const open_gmsgid
;
1175 static const enum cpp_ttype close_token_type
= CPP_CLOSE_BRACE
;
1176 static const char * const close_gmsgid
;
1179 const char * const matching_brace_traits::open_gmsgid
= "expected %<{%>";
1180 const char * const matching_brace_traits::close_gmsgid
= "expected %<}%>";
1182 /* "matching_braces" is a token_pair<T> class for tracking matching
1185 typedef token_pair
<matching_brace_traits
> matching_braces
;
1187 /* Get a description of the matching symbol to TYPE e.g. "(" for
1191 get_matching_symbol (enum cpp_ttype type
)
1197 case CPP_CLOSE_PAREN
:
1199 case CPP_CLOSE_BRACE
:
1204 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1205 issue the error MSGID. If MSGID is NULL then a message has already
1206 been produced and no message will be produced this time. Returns
1207 true if found, false otherwise.
1209 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1210 within any error as the location of an "opening" token matching
1211 the close token TYPE (e.g. the location of the '(' when TYPE is
1214 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1215 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1216 attempt to generate a fix-it hint for the problem.
1217 Otherwise msgid describes multiple token types (e.g.
1218 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1219 generate a fix-it hint. */
1222 c_parser_require (c_parser
*parser
,
1223 enum cpp_ttype type
,
1225 location_t matching_location
,
1226 bool type_is_unique
)
1228 if (c_parser_next_token_is (parser
, type
))
1230 c_parser_consume_token (parser
);
1235 location_t next_token_loc
= c_parser_peek_token (parser
)->location
;
1236 gcc_rich_location
richloc (next_token_loc
);
1238 /* Potentially supply a fix-it hint, suggesting to add the
1239 missing token immediately after the *previous* token.
1240 This may move the primary location within richloc. */
1241 if (!parser
->error
&& type_is_unique
)
1242 maybe_suggest_missing_token_insertion (&richloc
, type
,
1243 parser
->last_token_location
);
1245 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1246 Attempt to consolidate diagnostics by printing it as a
1247 secondary range within the main diagnostic. */
1248 bool added_matching_location
= false;
1249 if (matching_location
!= UNKNOWN_LOCATION
)
1250 added_matching_location
1251 = richloc
.add_location_if_nearby (*global_dc
, matching_location
);
1253 if (c_parser_error_richloc (parser
, msgid
, &richloc
))
1254 /* If we weren't able to consolidate matching_location, then
1255 print it as a secondary diagnostic. */
1256 if (matching_location
!= UNKNOWN_LOCATION
&& !added_matching_location
)
1257 inform (matching_location
, "to match this %qs",
1258 get_matching_symbol (type
));
1264 /* If the next token is the indicated keyword, consume it. Otherwise,
1265 issue the error MSGID. Returns true if found, false otherwise. */
1268 c_parser_require_keyword (c_parser
*parser
,
1272 if (c_parser_next_token_is_keyword (parser
, keyword
))
1274 c_parser_consume_token (parser
);
1279 c_parser_error (parser
, msgid
);
1284 /* Like c_parser_require, except that tokens will be skipped until the
1285 desired token is found. An error message is still produced if the
1286 next token is not as expected. If MSGID is NULL then a message has
1287 already been produced and no message will be produced this
1290 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1291 within any error as the location of an "opening" token matching
1292 the close token TYPE (e.g. the location of the '(' when TYPE is
1293 CPP_CLOSE_PAREN). */
1296 c_parser_skip_until_found (c_parser
*parser
,
1297 enum cpp_ttype type
,
1299 location_t matching_location
)
1301 unsigned nesting_depth
= 0;
1303 if (c_parser_require (parser
, type
, msgid
, matching_location
))
1305 if (UNLIKELY (type
== CPP_PRAGMA_EOL
) && parser
->in_omp_attribute_pragma
)
1307 c_token
*token
= c_parser_peek_token (parser
);
1308 if (token
->type
== CPP_EOF
)
1310 parser
->tokens
= &parser
->tokens_buf
[0];
1311 parser
->tokens_avail
= token
->flags
;
1312 parser
->in_omp_attribute_pragma
= NULL
;
1318 /* Skip tokens until the desired token is found. */
1321 /* Peek at the next token. */
1322 c_token
*token
= c_parser_peek_token (parser
);
1323 /* If we've reached the token we want, consume it and stop. */
1324 if (token
->type
== type
&& !nesting_depth
)
1326 c_parser_consume_token (parser
);
1327 if (UNLIKELY (type
== CPP_PRAGMA_EOL
)
1328 && parser
->in_omp_attribute_pragma
)
1330 c_token
*token
= c_parser_peek_token (parser
);
1331 if (token
->type
== CPP_EOF
)
1333 parser
->tokens
= &parser
->tokens_buf
[0];
1334 parser
->tokens_avail
= token
->flags
;
1335 parser
->in_omp_attribute_pragma
= NULL
;
1341 /* If we've run out of tokens, stop. */
1342 if (token
->type
== CPP_EOF
)
1344 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1346 if (token
->type
== CPP_OPEN_BRACE
1347 || token
->type
== CPP_OPEN_PAREN
1348 || token
->type
== CPP_OPEN_SQUARE
)
1350 else if (token
->type
== CPP_CLOSE_BRACE
1351 || token
->type
== CPP_CLOSE_PAREN
1352 || token
->type
== CPP_CLOSE_SQUARE
)
1354 if (nesting_depth
-- == 0)
1357 /* Consume this token. */
1358 c_parser_consume_token (parser
);
1360 parser
->error
= false;
1363 /* Skip tokens until the end of a parameter is found, but do not
1364 consume the comma, semicolon or closing delimiter. */
1367 c_parser_skip_to_end_of_parameter (c_parser
*parser
)
1369 unsigned nesting_depth
= 0;
1373 c_token
*token
= c_parser_peek_token (parser
);
1374 if ((token
->type
== CPP_COMMA
|| token
->type
== CPP_SEMICOLON
)
1377 /* If we've run out of tokens, stop. */
1378 if (token
->type
== CPP_EOF
)
1380 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1382 if (token
->type
== CPP_OPEN_BRACE
1383 || token
->type
== CPP_OPEN_PAREN
1384 || token
->type
== CPP_OPEN_SQUARE
)
1386 else if (token
->type
== CPP_CLOSE_BRACE
1387 || token
->type
== CPP_CLOSE_PAREN
1388 || token
->type
== CPP_CLOSE_SQUARE
)
1390 if (nesting_depth
-- == 0)
1393 /* Consume this token. */
1394 c_parser_consume_token (parser
);
1396 parser
->error
= false;
1399 /* Expect to be at the end of the pragma directive and consume an
1400 end of line marker. */
1403 c_parser_skip_to_pragma_eol (c_parser
*parser
, bool error_if_not_eol
= true)
1405 gcc_assert (parser
->in_pragma
);
1406 parser
->in_pragma
= false;
1408 if (error_if_not_eol
&& c_parser_peek_token (parser
)->type
!= CPP_PRAGMA_EOL
)
1409 c_parser_error (parser
, "expected end of line");
1411 cpp_ttype token_type
;
1414 c_token
*token
= c_parser_peek_token (parser
);
1415 token_type
= token
->type
;
1416 if (token_type
== CPP_EOF
)
1418 c_parser_consume_token (parser
);
1420 while (token_type
!= CPP_PRAGMA_EOL
);
1422 if (parser
->in_omp_attribute_pragma
)
1424 c_token
*token
= c_parser_peek_token (parser
);
1425 if (token
->type
== CPP_EOF
)
1427 parser
->tokens
= &parser
->tokens_buf
[0];
1428 parser
->tokens_avail
= token
->flags
;
1429 parser
->in_omp_attribute_pragma
= NULL
;
1433 parser
->error
= false;
1436 /* Skip tokens until we have consumed an entire block, or until we
1437 have consumed a non-nested ';'. */
1440 c_parser_skip_to_end_of_block_or_statement (c_parser
*parser
)
1442 unsigned nesting_depth
= 0;
1443 bool save_error
= parser
->error
;
1449 /* Peek at the next token. */
1450 token
= c_parser_peek_token (parser
);
1452 switch (token
->type
)
1457 case CPP_PRAGMA_EOL
:
1458 if (parser
->in_pragma
)
1463 /* If the next token is a ';', we have reached the
1464 end of the statement. */
1467 /* Consume the ';'. */
1468 c_parser_consume_token (parser
);
1473 case CPP_CLOSE_BRACE
:
1474 /* If the next token is a non-nested '}', then we have
1475 reached the end of the current block. */
1476 if (nesting_depth
== 0 || --nesting_depth
== 0)
1478 c_parser_consume_token (parser
);
1483 case CPP_OPEN_BRACE
:
1484 /* If it the next token is a '{', then we are entering a new
1485 block. Consume the entire block. */
1490 /* If we see a pragma, consume the whole thing at once. We
1491 have some safeguards against consuming pragmas willy-nilly.
1492 Normally, we'd expect to be here with parser->error set,
1493 which disables these safeguards. But it's possible to get
1494 here for secondary error recovery, after parser->error has
1496 c_parser_consume_pragma (parser
);
1497 c_parser_skip_to_pragma_eol (parser
);
1498 parser
->error
= save_error
;
1505 c_parser_consume_token (parser
);
1509 parser
->error
= false;
1512 /* CPP's options (initialized by c-opts.cc). */
1513 extern cpp_options
*cpp_opts
;
1515 /* Save the warning flags which are controlled by __extension__. */
1518 disable_extension_diagnostics (void)
1521 | (warn_pointer_arith
<< 1)
1522 | (warn_traditional
<< 2)
1524 | (warn_long_long
<< 4)
1525 | (warn_cxx_compat
<< 5)
1526 | (warn_overlength_strings
<< 6)
1527 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1528 play tricks to properly restore it. */
1529 | ((warn_c90_c99_compat
== 1) << 7)
1530 | ((warn_c90_c99_compat
== -1) << 8)
1531 /* Similarly for warn_c99_c11_compat. */
1532 | ((warn_c99_c11_compat
== 1) << 9)
1533 | ((warn_c99_c11_compat
== -1) << 10)
1534 /* Similarly for warn_c11_c23_compat. */
1535 | ((warn_c11_c23_compat
== 1) << 11)
1536 | ((warn_c11_c23_compat
== -1) << 12)
1537 /* Similarly for warn_c23_c2y_compat. */
1538 | ((warn_c23_c2y_compat
== 1) << 13)
1539 | ((warn_c23_c2y_compat
== -1) << 14)
1541 cpp_opts
->cpp_pedantic
= pedantic
= 0;
1542 warn_pointer_arith
= 0;
1543 cpp_opts
->cpp_warn_traditional
= warn_traditional
= 0;
1545 cpp_opts
->cpp_warn_long_long
= warn_long_long
= 0;
1546 warn_cxx_compat
= 0;
1547 warn_overlength_strings
= 0;
1548 warn_c90_c99_compat
= 0;
1549 warn_c99_c11_compat
= 0;
1550 warn_c11_c23_compat
= 0;
1551 warn_c23_c2y_compat
= 0;
1555 /* Restore the warning flags which are controlled by __extension__.
1556 FLAGS is the return value from disable_extension_diagnostics. */
1559 restore_extension_diagnostics (int flags
)
1561 cpp_opts
->cpp_pedantic
= pedantic
= flags
& 1;
1562 warn_pointer_arith
= (flags
>> 1) & 1;
1563 cpp_opts
->cpp_warn_traditional
= warn_traditional
= (flags
>> 2) & 1;
1564 flag_iso
= (flags
>> 3) & 1;
1565 cpp_opts
->cpp_warn_long_long
= warn_long_long
= (flags
>> 4) & 1;
1566 warn_cxx_compat
= (flags
>> 5) & 1;
1567 warn_overlength_strings
= (flags
>> 6) & 1;
1568 /* See above for why is this needed. */
1569 warn_c90_c99_compat
= (flags
>> 7) & 1 ? 1 : ((flags
>> 8) & 1 ? -1 : 0);
1570 warn_c99_c11_compat
= (flags
>> 9) & 1 ? 1 : ((flags
>> 10) & 1 ? -1 : 0);
1571 warn_c11_c23_compat
= (flags
>> 11) & 1 ? 1 : ((flags
>> 12) & 1 ? -1 : 0);
1572 warn_c23_c2y_compat
= (flags
>> 13) & 1 ? 1 : ((flags
>> 14) & 1 ? -1 : 0);
1575 /* Helper data structure for parsing #pragma acc routine. */
1576 struct oacc_routine_data
{
1577 bool error_seen
; /* Set if error has been reported. */
1578 bool fndecl_seen
; /* Set if one fn decl/definition has been seen already. */
1583 /* Used for parsing objc foreach statements. */
1584 static tree objc_foreach_break_label
, objc_foreach_continue_label
;
1586 /* Used for parsing OMP for loops.
1588 Some notes on flags used for context:
1589 parser->omp_for_parse_state is non-null anywhere inside the OMP FOR
1590 construct, except for the final-loop-body.
1591 The want_nested_loop flag is true if inside a {} sequence where
1592 a loop-nest (or another {} sequence containing a loop-nest) is expected,
1593 but has not yet been seen. It's false when parsing intervening code
1594 statements or their substatements that cannot contain a loop-nest.
1595 The in_intervening_code flag is true when parsing any intervening code,
1596 including substatements, and whether or not want_nested_loop is true.
1598 And, about error handling:
1599 The saw_intervening_code flag is set if the loop is not perfectly
1600 nested, even in the usual case where this is not an error.
1601 perfect_nesting_fail is set if an error has been diagnosed because an
1602 imperfectly-nested loop was found where a perfectly-nested one is
1603 required (we diagnose this only once).
1604 fail is set if any kind of structural error in the loop nest
1605 has been found and diagnosed.
1607 struct omp_for_parse_data
{
1608 enum tree_code code
;
1609 tree declv
, condv
, incrv
, initv
;
1612 int count
; /* Expected nesting depth. */
1613 int depth
; /* Current nesting depth. */
1617 bool want_nested_loop
: 1;
1618 bool in_intervening_code
: 1;
1619 bool saw_intervening_code
: 1;
1620 bool perfect_nesting_fail
: 1;
1626 /* True if we parsed a musttail attribute for return. */
1630 static bool c_parser_nth_token_starts_std_attributes (c_parser
*,
1632 static tree
c_parser_std_attribute_specifier_sequence (c_parser
*);
1633 static void c_parser_external_declaration (c_parser
*);
1634 static void c_parser_asm_definition (c_parser
*);
1635 static void c_parser_declaration_or_fndef (c_parser
*, bool, bool, bool,
1636 bool, bool, tree
* = NULL
,
1637 vec
<c_token
> * = NULL
,
1638 bool have_attrs
= false,
1640 struct oacc_routine_data
* = NULL
,
1642 static bool c_parser_handle_statement_omp_attributes (c_parser
*, tree
&,
1644 static void c_parser_static_assert_declaration_no_semi (c_parser
*);
1645 static void c_parser_static_assert_declaration (c_parser
*);
1646 static struct c_typespec
c_parser_enum_specifier (c_parser
*);
1647 static struct c_typespec
c_parser_struct_or_union_specifier (c_parser
*);
1648 static tree
c_parser_struct_declaration (c_parser
*, tree
*);
1649 static struct c_typespec
c_parser_typeof_specifier (c_parser
*);
1650 static tree
c_parser_alignas_specifier (c_parser
*);
1651 static struct c_declarator
*c_parser_direct_declarator (c_parser
*, bool,
1653 static struct c_declarator
*c_parser_direct_declarator_inner (c_parser
*,
1655 struct c_declarator
*);
1656 static struct c_arg_info
*c_parser_parms_declarator (c_parser
*, bool, tree
,
1658 static struct c_arg_info
*c_parser_parms_list_declarator (c_parser
*, tree
,
1660 static struct c_parm
*c_parser_parameter_declaration (c_parser
*, tree
, bool);
1661 static tree
c_parser_simple_asm_expr (c_parser
*);
1662 static tree
c_parser_gnu_attributes (c_parser
*);
1663 static struct c_expr
c_parser_initializer (c_parser
*, tree
);
1664 static struct c_expr
c_parser_braced_init (c_parser
*, tree
, bool,
1665 struct obstack
*, tree
);
1666 static void c_parser_initelt (c_parser
*, struct obstack
*);
1667 static void c_parser_initval (c_parser
*, struct c_expr
*,
1669 static tree
c_parser_compound_statement (c_parser
*, location_t
* = NULL
);
1670 static location_t
c_parser_compound_statement_nostart (c_parser
*);
1671 static void c_parser_label (c_parser
*, tree
);
1672 static void c_parser_statement (c_parser
*, bool *, location_t
* = NULL
);
1673 static void c_parser_statement_after_labels (c_parser
*, bool *,
1676 static tree
c_parser_c99_block_statement (c_parser
*, bool *,
1677 location_t
* = NULL
);
1678 static void c_parser_if_statement (c_parser
*, bool *, vec
<tree
> *);
1679 static void c_parser_switch_statement (c_parser
*, bool *);
1680 static void c_parser_while_statement (c_parser
*, bool, unsigned short, bool,
1682 static void c_parser_do_statement (c_parser
*, bool, unsigned short, bool);
1683 static void c_parser_for_statement (c_parser
*, bool, unsigned short, bool,
1685 static tree
c_parser_asm_statement (c_parser
*);
1686 static tree
c_parser_asm_operands (c_parser
*);
1687 static tree
c_parser_asm_goto_operands (c_parser
*);
1688 static tree
c_parser_asm_clobbers (c_parser
*);
1689 static struct c_expr
c_parser_expr_no_commas (c_parser
*, struct c_expr
*,
1691 static struct c_expr
c_parser_conditional_expression (c_parser
*,
1692 struct c_expr
*, tree
);
1693 static struct c_expr
c_parser_binary_expression (c_parser
*, struct c_expr
*,
1695 static struct c_expr
c_parser_cast_expression (c_parser
*, struct c_expr
*);
1696 static struct c_expr
c_parser_unary_expression (c_parser
*);
1697 static struct c_expr
c_parser_sizeof_expression (c_parser
*);
1698 static struct c_expr
c_parser_alignof_expression (c_parser
*);
1699 static struct c_expr
c_parser_postfix_expression (c_parser
*);
1700 static struct c_expr
c_parser_postfix_expression_after_paren_type (c_parser
*,
1701 struct c_declspecs
*,
1702 struct c_type_name
*,
1704 static struct c_expr
c_parser_postfix_expression_after_primary (c_parser
*,
1707 static tree
c_parser_transaction (c_parser
*, enum rid
);
1708 static struct c_expr
c_parser_transaction_expression (c_parser
*, enum rid
);
1709 static tree
c_parser_transaction_cancel (c_parser
*);
1710 static struct c_expr
c_parser_expression (c_parser
*);
1711 static struct c_expr
c_parser_expression_conv (c_parser
*);
1712 static vec
<tree
, va_gc
> *c_parser_expr_list (c_parser
*, bool, bool,
1713 vec
<tree
, va_gc
> **, location_t
*,
1714 tree
*, vec
<location_t
> *,
1715 unsigned int * = NULL
);
1716 static struct c_expr
c_parser_has_attribute_expression (c_parser
*);
1718 static void c_parser_oacc_declare (c_parser
*);
1719 static void c_parser_oacc_enter_exit_data (c_parser
*, bool);
1720 static void c_parser_oacc_update (c_parser
*);
1721 static void c_parser_omp_construct (c_parser
*, bool *);
1722 static void c_parser_omp_threadprivate (c_parser
*);
1723 static void c_parser_omp_barrier (c_parser
*);
1724 static void c_parser_omp_depobj (c_parser
*);
1725 static void c_parser_omp_flush (c_parser
*);
1726 static bool c_parser_omp_next_tokens_can_be_canon_loop (c_parser
*,
1727 enum tree_code
, bool);
1728 static tree
c_parser_omp_loop_nest (c_parser
*, bool *);
1729 static tree
c_parser_omp_for_loop (location_t
, c_parser
*, enum tree_code
,
1730 tree
, tree
*, bool *);
1731 static void c_parser_omp_taskwait (c_parser
*);
1732 static void c_parser_omp_taskyield (c_parser
*);
1733 static void c_parser_omp_cancel (c_parser
*);
1734 static void c_parser_omp_nothing (c_parser
*);
1736 enum pragma_context
{ pragma_external
, pragma_struct
, pragma_param
,
1737 pragma_stmt
, pragma_compound
};
1738 static bool c_parser_pragma (c_parser
*, enum pragma_context
, bool *);
1739 static bool c_parser_omp_cancellation_point (c_parser
*, enum pragma_context
);
1740 static bool c_parser_omp_target (c_parser
*, enum pragma_context
, bool *);
1741 static void c_parser_omp_begin (c_parser
*);
1742 static void c_parser_omp_end (c_parser
*);
1743 static bool c_parser_omp_declare (c_parser
*, enum pragma_context
);
1744 static void c_parser_omp_requires (c_parser
*);
1745 static bool c_parser_omp_error (c_parser
*, enum pragma_context
);
1746 static void c_parser_omp_assumption_clauses (c_parser
*, bool);
1747 static void c_parser_omp_allocate (c_parser
*);
1748 static void c_parser_omp_assumes (c_parser
*);
1749 static bool c_parser_omp_ordered (c_parser
*, enum pragma_context
, bool *);
1750 static void c_parser_oacc_routine (c_parser
*, enum pragma_context
);
1752 /* These Objective-C parser functions are only ever called when
1753 compiling Objective-C. */
1754 static void c_parser_objc_class_definition (c_parser
*, tree
);
1755 static void c_parser_objc_class_instance_variables (c_parser
*);
1756 static void c_parser_objc_class_declaration (c_parser
*);
1757 static void c_parser_objc_alias_declaration (c_parser
*);
1758 static void c_parser_objc_protocol_definition (c_parser
*, tree
);
1759 static bool c_parser_objc_method_type (c_parser
*);
1760 static void c_parser_objc_method_definition (c_parser
*);
1761 static void c_parser_objc_methodprotolist (c_parser
*);
1762 static void c_parser_objc_methodproto (c_parser
*);
1763 static tree
c_parser_objc_method_decl (c_parser
*, bool, tree
*, tree
*);
1764 static tree
c_parser_objc_type_name (c_parser
*);
1765 static tree
c_parser_objc_protocol_refs (c_parser
*);
1766 static void c_parser_objc_try_catch_finally_statement (c_parser
*);
1767 static void c_parser_objc_synchronized_statement (c_parser
*);
1768 static tree
c_parser_objc_selector (c_parser
*);
1769 static tree
c_parser_objc_selector_arg (c_parser
*);
1770 static tree
c_parser_objc_receiver (c_parser
*);
1771 static tree
c_parser_objc_message_args (c_parser
*);
1772 static tree
c_parser_objc_keywordexpr (c_parser
*);
1773 static void c_parser_objc_at_property_declaration (c_parser
*);
1774 static void c_parser_objc_at_synthesize_declaration (c_parser
*);
1775 static void c_parser_objc_at_dynamic_declaration (c_parser
*);
1776 static bool c_parser_objc_diagnose_bad_element_prefix
1777 (c_parser
*, struct c_declspecs
*);
1778 static location_t
c_parser_parse_rtl_body (c_parser
*, char *);
1784 /* Concrete implementation of ana::translation_unit for the C frontend. */
1786 class c_translation_unit
: public translation_unit
1789 /* Implementation of translation_unit::lookup_constant_by_id for use by the
1790 analyzer to look up named constants in the user's source code. */
1791 tree
lookup_constant_by_id (tree id
) const final override
1793 /* Consider decls. */
1794 if (tree decl
= lookup_name (id
))
1795 if (TREE_CODE (decl
) == CONST_DECL
)
1796 if (tree value
= DECL_INITIAL (decl
))
1797 if (TREE_CODE (value
) == INTEGER_CST
)
1800 /* Consider macros. */
1801 cpp_hashnode
*hashnode
= C_CPP_HASHNODE (id
);
1802 if (cpp_macro_p (hashnode
))
1803 if (tree value
= consider_macro (hashnode
->value
.macro
))
1810 lookup_type_by_id (tree id
) const final override
1812 if (tree type_decl
= lookup_name (id
))
1813 if (TREE_CODE (type_decl
) == TYPE_DECL
)
1815 tree record_type
= TREE_TYPE (type_decl
);
1816 if (TREE_CODE (record_type
) == RECORD_TYPE
)
1824 lookup_global_var_by_id (tree id
) const final override
1826 if (tree var_decl
= lookup_name (id
))
1827 if (TREE_CODE (var_decl
) == VAR_DECL
)
1834 /* Attempt to get an INTEGER_CST from MACRO.
1835 Only handle the simplest cases: where MACRO's definition is a single
1836 token containing a number, by lexing the number again.
1837 This will handle e.g.
1839 and other bases but not negative numbers, parentheses or e.g.
1841 as doing so would require a parser. */
1842 tree
consider_macro (cpp_macro
*macro
) const
1844 if (macro
->paramc
> 0)
1846 if (macro
->kind
!= cmk_macro
)
1848 if (macro
->count
!= 1)
1850 const cpp_token
&tok
= macro
->exp
.tokens
[0];
1851 if (tok
.type
!= CPP_NUMBER
)
1854 cpp_reader
*old_parse_in
= parse_in
;
1855 parse_in
= cpp_create_reader (CLK_GNUC89
, NULL
, line_table
);
1858 pp_string (&pp
, (const char *) tok
.val
.str
.text
);
1860 cpp_push_buffer (parse_in
,
1861 (const unsigned char *) pp_formatted_text (&pp
),
1862 strlen (pp_formatted_text (&pp
)),
1867 unsigned char cpp_flags
;
1868 c_lex_with_flags (&value
, &loc
, &cpp_flags
, 0);
1870 cpp_destroy (parse_in
);
1871 parse_in
= old_parse_in
;
1873 if (value
&& TREE_CODE (value
) == INTEGER_CST
)
1882 #endif /* #if ENABLE_ANALYZER */
1884 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1887 external-declarations
1889 external-declarations:
1890 external-declaration
1891 external-declarations external-declaration
1900 c_parser_translation_unit (c_parser
*parser
)
1902 if (c_parser_next_token_is (parser
, CPP_EOF
))
1904 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1905 "ISO C forbids an empty translation unit");
1909 void *obstack_position
= obstack_alloc (&parser_obstack
, 0);
1910 mark_valid_location_for_stdc_pragma (false);
1914 c_parser_external_declaration (parser
);
1915 obstack_free (&parser_obstack
, obstack_position
);
1917 while (c_parser_next_token_is_not (parser
, CPP_EOF
));
1922 FOR_EACH_VEC_ELT (incomplete_record_decls
, i
, decl
)
1923 if (DECL_SIZE (decl
) == NULL_TREE
&& TREE_TYPE (decl
) != error_mark_node
)
1924 error ("storage size of %q+D isn%'t known", decl
);
1926 if (vec_safe_length (current_omp_declare_target_attribute
))
1928 c_omp_declare_target_attr
1929 a
= current_omp_declare_target_attribute
->pop ();
1931 error ("%qs without corresponding %qs",
1932 a
.device_type
>= 0 ? "#pragma omp begin declare target"
1933 : "#pragma omp declare target",
1934 "#pragma omp end declare target");
1935 vec_safe_truncate (current_omp_declare_target_attribute
, 0);
1937 if (vec_safe_length (current_omp_begin_assumes
))
1940 error ("%qs without corresponding %qs",
1941 "#pragma omp begin assumes", "#pragma omp end assumes");
1942 vec_safe_truncate (current_omp_begin_assumes
, 0);
1948 ana::c_translation_unit tu
;
1949 ana::on_finish_translation_unit (tu
);
1954 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1956 external-declaration:
1962 external-declaration:
1965 __extension__ external-declaration
1969 external-declaration:
1970 objc-class-definition
1971 objc-class-declaration
1972 objc-alias-declaration
1973 objc-protocol-definition
1974 objc-method-definition
1979 c_parser_external_declaration (c_parser
*parser
)
1982 switch (c_parser_peek_token (parser
)->type
)
1985 switch (c_parser_peek_token (parser
)->keyword
)
1988 ext
= disable_extension_diagnostics ();
1989 c_parser_consume_token (parser
);
1990 c_parser_external_declaration (parser
);
1991 restore_extension_diagnostics (ext
);
1994 c_parser_asm_definition (parser
);
1996 case RID_AT_INTERFACE
:
1997 case RID_AT_IMPLEMENTATION
:
1998 gcc_assert (c_dialect_objc ());
1999 c_parser_objc_class_definition (parser
, NULL_TREE
);
2002 gcc_assert (c_dialect_objc ());
2003 c_parser_objc_class_declaration (parser
);
2006 gcc_assert (c_dialect_objc ());
2007 c_parser_objc_alias_declaration (parser
);
2009 case RID_AT_PROTOCOL
:
2010 gcc_assert (c_dialect_objc ());
2011 c_parser_objc_protocol_definition (parser
, NULL_TREE
);
2013 case RID_AT_PROPERTY
:
2014 gcc_assert (c_dialect_objc ());
2015 c_parser_objc_at_property_declaration (parser
);
2017 case RID_AT_SYNTHESIZE
:
2018 gcc_assert (c_dialect_objc ());
2019 c_parser_objc_at_synthesize_declaration (parser
);
2021 case RID_AT_DYNAMIC
:
2022 gcc_assert (c_dialect_objc ());
2023 c_parser_objc_at_dynamic_declaration (parser
);
2026 gcc_assert (c_dialect_objc ());
2027 c_parser_consume_token (parser
);
2028 objc_finish_implementation ();
2035 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
2036 "ISO C does not allow extra %<;%> outside of a function");
2037 c_parser_consume_token (parser
);
2040 mark_valid_location_for_stdc_pragma (true);
2041 c_parser_pragma (parser
, pragma_external
, NULL
);
2042 mark_valid_location_for_stdc_pragma (false);
2046 if (c_dialect_objc ())
2048 c_parser_objc_method_definition (parser
);
2051 /* Else fall through, and yield a syntax error trying to parse
2052 as a declaration or function definition. */
2056 /* A declaration or a function definition (or, in Objective-C,
2057 an @interface or @protocol with prefix attributes). We can
2058 only tell which after parsing the declaration specifiers, if
2059 any, and the first declarator. */
2060 c_parser_declaration_or_fndef (parser
, true, true, true, false, true);
2065 static void c_parser_handle_directive_omp_attributes (tree
&, vec
<c_token
> *&,
2067 static void c_finish_omp_declare_simd (c_parser
*, tree
, tree
, vec
<c_token
> *);
2068 static void c_finish_oacc_routine (struct oacc_routine_data
*, tree
, bool);
2070 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
2073 add_debug_begin_stmt (location_t loc
)
2075 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
2076 if (!MAY_HAVE_DEBUG_MARKER_STMTS
|| !building_stmt_list_p ())
2079 tree stmt
= build0 (DEBUG_BEGIN_STMT
, void_type_node
);
2080 SET_EXPR_LOCATION (stmt
, loc
);
2084 /* Helper function for c_parser_declaration_or_fndef and
2085 Handle assume attribute(s). */
2088 handle_assume_attribute (location_t here
, tree attrs
, bool nested
)
2091 for (tree attr
= lookup_attribute ("gnu", "assume", attrs
); attr
;
2092 attr
= lookup_attribute ("gnu", "assume", TREE_CHAIN (attr
)))
2094 tree args
= TREE_VALUE (attr
);
2095 int nargs
= list_length (args
);
2098 error_at (here
, "wrong number of arguments specified "
2099 "for %qE attribute",
2100 get_attribute_name (attr
));
2101 inform (here
, "expected %i, found %i", 1, nargs
);
2105 tree arg
= TREE_VALUE (args
);
2106 arg
= c_objc_common_truthvalue_conversion (here
, arg
);
2107 arg
= c_fully_fold (arg
, false, NULL
);
2108 if (arg
!= error_mark_node
)
2110 tree fn
= build_call_expr_internal_loc (here
, IFN_ASSUME
,
2118 pedwarn (here
, OPT_Wattributes
,
2119 "%<assume%> attribute at top level");
2121 return remove_attribute ("gnu", "assume", attrs
);
2124 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
2125 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
2126 is accepted; otherwise (old-style parameter declarations) only other
2127 declarations are accepted. If STATIC_ASSERT_OK is true, a static
2128 assertion is accepted; otherwise (old-style parameter declarations)
2129 it is not. If NESTED is true, we are inside a function or parsing
2130 old-style parameter declarations; any functions encountered are
2131 nested functions and declaration specifiers are required; otherwise
2132 we are at top level and functions are normal functions and
2133 declaration specifiers may be optional. If EMPTY_OK is true, empty
2134 declarations are OK (subject to all other constraints); otherwise
2135 (old-style parameter declarations) they are diagnosed. If
2136 START_ATTR_OK is true, the declaration specifiers may start with
2137 attributes (GNU or standard); otherwise they may not.
2138 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
2139 declaration when parsing an Objective-C foreach statement.
2140 FALLTHRU_ATTR_P is used to signal whether this function parsed
2141 "__attribute__((fallthrough));". ATTRS are any standard attributes
2142 parsed in the caller (in contexts where such attributes had to be
2143 parsed to determine whether what follows is a declaration or a
2144 statement); HAVE_ATTRS says whether there were any such attributes
2148 declaration-specifiers init-declarator-list[opt] ;
2149 static_assert-declaration
2151 function-definition:
2152 declaration-specifiers[opt] declarator declaration-list[opt]
2157 declaration-list declaration
2159 init-declarator-list:
2161 init-declarator-list , init-declarator
2164 declarator simple-asm-expr[opt] gnu-attributes[opt]
2165 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
2169 nested-function-definition:
2170 declaration-specifiers declarator declaration-list[opt]
2176 gnu-attributes objc-class-definition
2177 gnu-attributes objc-category-definition
2178 gnu-attributes objc-protocol-definition
2180 The simple-asm-expr and gnu-attributes are GNU extensions.
2182 This function does not handle __extension__; that is handled in its
2183 callers. ??? Following the old parser, __extension__ may start
2184 external declarations, declarations in functions and declarations
2185 at the start of "for" loops, but not old-style parameter
2188 C99 requires declaration specifiers in a function definition; the
2189 absence is diagnosed through the diagnosis of implicit int. In GNU
2190 C we also allow but diagnose declarations without declaration
2191 specifiers, but only at top level (elsewhere they conflict with
2194 In Objective-C, declarations of the looping variable in a foreach
2195 statement are exceptionally terminated by 'in' (for example, 'for
2196 (NSObject *object in array) { ... }').
2201 threadprivate-directive
2205 gimple-function-definition:
2206 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
2207 declaration-list[opt] compound-statement
2209 rtl-function-definition:
2210 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
2211 declaration-list[opt] compound-statement */
2214 c_parser_declaration_or_fndef (c_parser
*parser
, bool fndef_ok
,
2215 bool static_assert_ok
, bool empty_ok
,
2216 bool nested
, bool start_attr_ok
,
2217 tree
*objc_foreach_object_declaration
2219 vec
<c_token
> *omp_declare_simd_clauses
2221 bool have_attrs
/* = false */,
2222 tree attrs
/* = NULL_TREE */,
2223 struct oacc_routine_data
*oacc_routine_data
2225 bool *fallthru_attr_p
/* = NULL */)
2227 struct c_declspecs
*specs
;
2229 tree all_prefix_attrs
;
2230 bool diagnosed_no_specs
= false;
2231 location_t here
= c_parser_peek_token (parser
)->location
;
2233 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
2235 if (static_assert_ok
2236 && c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
2238 c_parser_static_assert_declaration (parser
);
2241 specs
= build_null_declspecs ();
2243 /* Handle any standard attributes parsed in the caller. */
2246 declspecs_add_attrs (here
, specs
, attrs
);
2247 specs
->non_std_attrs_seen_p
= false;
2250 /* Try to detect an unknown type name when we have "A B" or "A *B". */
2251 if (c_parser_peek_token (parser
)->type
== CPP_NAME
2252 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
2253 && (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
2254 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
2255 && (!nested
|| !lookup_name (c_parser_peek_token (parser
)->value
)))
2257 tree name
= c_parser_peek_token (parser
)->value
;
2259 /* Issue a warning about NAME being an unknown type name, perhaps
2260 with some kind of hint.
2261 If the user forgot a "struct" etc, suggest inserting
2262 it. Otherwise, attempt to look for misspellings. */
2263 gcc_rich_location
richloc (here
);
2264 if (tag_exists_p (RECORD_TYPE
, name
))
2266 /* This is not C++ with its implicit typedef. */
2267 richloc
.add_fixit_insert_before ("struct ");
2269 "unknown type name %qE;"
2270 " use %<struct%> keyword to refer to the type",
2273 else if (tag_exists_p (UNION_TYPE
, name
))
2275 richloc
.add_fixit_insert_before ("union ");
2277 "unknown type name %qE;"
2278 " use %<union%> keyword to refer to the type",
2281 else if (tag_exists_p (ENUMERAL_TYPE
, name
))
2283 richloc
.add_fixit_insert_before ("enum ");
2285 "unknown type name %qE;"
2286 " use %<enum%> keyword to refer to the type",
2291 auto_diagnostic_group d
;
2292 name_hint hint
= lookup_name_fuzzy (name
, FUZZY_LOOKUP_TYPENAME
,
2294 if (const char *suggestion
= hint
.suggestion ())
2296 richloc
.add_fixit_replace (suggestion
);
2298 "unknown type name %qE; did you mean %qs?",
2302 error_at (here
, "unknown type name %qE", name
);
2305 /* Parse declspecs normally to get a correct pointer type, but avoid
2306 a further "fails to be a type name" error. Refuse nested functions
2307 since it is not how the user likely wants us to recover. */
2308 c_parser_peek_token (parser
)->type
= CPP_KEYWORD
;
2309 c_parser_peek_token (parser
)->keyword
= RID_VOID
;
2310 c_parser_peek_token (parser
)->value
= error_mark_node
;
2314 /* When there are standard attributes at the start of the
2315 declaration (to apply to the entity being declared), an
2316 init-declarator-list or function definition must be present. */
2317 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
2320 c_parser_declspecs (parser
, specs
, true, true, start_attr_ok
,
2321 true, true, start_attr_ok
, true, cla_nonabstract_decl
);
2324 c_parser_skip_to_end_of_block_or_statement (parser
);
2327 if (nested
&& !specs
->declspecs_seen_p
)
2329 c_parser_error (parser
, "expected declaration specifiers");
2330 c_parser_skip_to_end_of_block_or_statement (parser
);
2334 finish_declspecs (specs
);
2335 bool gnu_auto_type_p
= specs
->typespec_word
== cts_auto_type
;
2336 bool std_auto_type_p
= specs
->c23_auto_p
;
2337 bool any_auto_type_p
= gnu_auto_type_p
|| std_auto_type_p
;
2338 gcc_assert (!(gnu_auto_type_p
&& std_auto_type_p
));
2339 const char *auto_type_keyword
= gnu_auto_type_p
? "__auto_type" : "auto";
2340 if (specs
->constexpr_p
)
2342 /* An underspecified declaration may not declare tags or members
2343 or structures or unions; it is undefined behavior to declare
2344 the members of an enumeration. Where the structure, union or
2345 enumeration type is declared within an initializer, this is
2346 diagnosed elsewhere. Diagnose here the case of declaring
2347 such a type in the type specifiers of a constexpr
2349 switch (specs
->typespec_kind
)
2351 case ctsk_tagfirstref
:
2352 case ctsk_tagfirstref_attrs
:
2353 error_at (here
, "%qT declared in underspecified object declaration",
2358 error_at (here
, "%qT defined in underspecified object declaration",
2366 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2368 bool handled_assume
= false;
2371 && specs
->typespec_kind
== ctsk_none
2372 && c_parser_handle_statement_omp_attributes (parser
, specs
->attrs
,
2376 c_warn_unused_attributes (specs
->attrs
);
2377 while (parser
->in_omp_attribute_pragma
)
2379 gcc_assert (c_parser_next_token_is (parser
, CPP_PRAGMA
));
2380 c_parser_pragma (parser
, pragma_external
, NULL
);
2382 c_parser_consume_token (parser
);
2385 if (specs
->typespec_kind
== ctsk_none
2386 && lookup_attribute ("gnu", "assume", specs
->attrs
))
2388 handled_assume
= true;
2390 = handle_assume_attribute (here
, specs
->attrs
, nested
);
2392 if (any_auto_type_p
)
2393 error_at (here
, "%qs in empty declaration", auto_type_keyword
);
2394 else if (specs
->typespec_kind
== ctsk_none
2395 && attribute_fallthrough_p (specs
->attrs
))
2397 if (fallthru_attr_p
!= NULL
)
2398 *fallthru_attr_p
= true;
2401 tree fn
= build_call_expr_internal_loc (here
, IFN_FALLTHROUGH
,
2406 pedwarn (here
, OPT_Wattributes
,
2407 "%<fallthrough%> attribute at top level");
2410 && !(have_attrs
&& specs
->non_std_attrs_seen_p
)
2415 shadow_tag_warned (specs
, 1);
2416 if (!handled_assume
)
2417 pedwarn (here
, 0, "empty declaration");
2419 /* We still have to evaluate size expressions. */
2421 add_stmt (fold_convert (void_type_node
, specs
->expr
));
2422 c_parser_consume_token (parser
);
2423 if (oacc_routine_data
)
2424 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2428 /* Provide better error recovery. Note that a type name here is usually
2429 better diagnosed as a redeclaration. */
2431 && specs
->typespec_kind
== ctsk_tagdef
2432 && c_parser_next_token_starts_declspecs (parser
)
2433 && !c_parser_next_token_is (parser
, CPP_NAME
))
2435 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
2436 parser
->error
= false;
2437 shadow_tag_warned (specs
, 1);
2440 else if (c_dialect_objc () && !any_auto_type_p
)
2442 /* Prefix attributes are an error on method decls. */
2443 switch (c_parser_peek_token (parser
)->type
)
2447 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2451 warning_at (c_parser_peek_token (parser
)->location
,
2453 "prefix attributes are ignored for methods");
2454 specs
->attrs
= NULL_TREE
;
2457 c_parser_objc_method_definition (parser
);
2459 c_parser_objc_methodproto (parser
);
2465 /* This is where we parse 'attributes @interface ...',
2466 'attributes @implementation ...', 'attributes @protocol ...'
2467 (where attributes could be, for example, __attribute__
2470 switch (c_parser_peek_token (parser
)->keyword
)
2472 case RID_AT_INTERFACE
:
2474 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2476 c_parser_objc_class_definition (parser
, specs
->attrs
);
2480 case RID_AT_IMPLEMENTATION
:
2482 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2486 warning_at (c_parser_peek_token (parser
)->location
,
2488 "prefix attributes are ignored for implementations");
2489 specs
->attrs
= NULL_TREE
;
2491 c_parser_objc_class_definition (parser
, NULL_TREE
);
2495 case RID_AT_PROTOCOL
:
2497 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2499 c_parser_objc_protocol_definition (parser
, specs
->attrs
);
2506 case RID_AT_PROPERTY
:
2509 c_parser_error (parser
, "unexpected attribute");
2510 specs
->attrs
= NULL
;
2517 else if (attribute_fallthrough_p (specs
->attrs
))
2518 warning_at (here
, OPT_Wattributes
,
2519 "%<fallthrough%> attribute not followed by %<;%>");
2520 else if (lookup_attribute ("gnu", "assume", specs
->attrs
))
2521 warning_at (here
, OPT_Wattributes
,
2522 "%<assume%> attribute not followed by %<;%>");
2524 auto_vec
<c_token
> omp_declare_simd_attr_clauses
;
2525 c_parser_handle_directive_omp_attributes (specs
->attrs
,
2526 omp_declare_simd_clauses
,
2527 &omp_declare_simd_attr_clauses
);
2528 pending_xref_error ();
2529 prefix_attrs
= specs
->attrs
;
2530 all_prefix_attrs
= prefix_attrs
;
2531 specs
->attrs
= NULL_TREE
;
2534 struct c_declarator
*declarator
;
2537 tree fnbody
= NULL_TREE
;
2538 tree underspec_name
= NULL_TREE
;
2539 auto_vec
<c_token
> omp_dsimd_idattr_clauses
;
2540 /* Declaring either one or more declarators (in which case we
2541 should diagnose if there were no declaration specifiers) or a
2542 function definition (in which case the diagnostic for
2543 implicit int suffices). */
2544 declarator
= c_parser_declarator (parser
,
2545 specs
->typespec_kind
!= ctsk_none
,
2546 C_DTR_NORMAL
, &dummy
);
2547 if (declarator
== NULL
)
2549 if (omp_declare_simd_clauses
)
2550 c_finish_omp_declare_simd (parser
, NULL_TREE
, NULL_TREE
,
2551 omp_declare_simd_clauses
);
2552 if (oacc_routine_data
)
2553 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2554 c_parser_skip_to_end_of_block_or_statement (parser
);
2557 if (flag_openmp
|| flag_openmp_simd
)
2559 struct c_declarator
*d
= declarator
;
2560 while (d
->kind
!= cdk_id
)
2562 vec
<c_token
> *dummy
= NULL
;
2563 c_parser_handle_directive_omp_attributes (d
->u
.id
.attrs
, dummy
,
2564 &omp_dsimd_idattr_clauses
);
2566 if (gnu_auto_type_p
&& declarator
->kind
!= cdk_id
)
2569 "%<__auto_type%> requires a plain identifier"
2571 c_parser_skip_to_end_of_block_or_statement (parser
);
2574 if (std_auto_type_p
)
2576 struct c_declarator
*d
= declarator
;
2577 while (d
->kind
== cdk_attrs
)
2579 if (d
->kind
!= cdk_id
)
2582 "%<auto%> requires a plain identifier, possibly with"
2583 " attributes, as declarator");
2584 c_parser_skip_to_end_of_block_or_statement (parser
);
2587 underspec_name
= d
->u
.id
.id
;
2589 else if (specs
->constexpr_p
)
2591 struct c_declarator
*d
= declarator
;
2592 while (d
->kind
!= cdk_id
)
2594 underspec_name
= d
->u
.id
.id
;
2596 if (c_parser_next_token_is (parser
, CPP_EQ
)
2597 || c_parser_next_token_is (parser
, CPP_COMMA
)
2598 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
2599 || c_parser_next_token_is_keyword (parser
, RID_ASM
)
2600 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
)
2601 || c_parser_next_token_is_keyword (parser
, RID_IN
))
2603 tree asm_name
= NULL_TREE
;
2604 tree postfix_attrs
= NULL_TREE
;
2605 if (!diagnosed_no_specs
&& !specs
->declspecs_seen_p
)
2607 diagnosed_no_specs
= true;
2608 pedwarn (here
, 0, "data definition has no type or storage class");
2610 /* Having seen a data definition, there cannot now be a
2611 function definition. */
2613 if (c_parser_next_token_is_keyword (parser
, RID_ASM
))
2614 asm_name
= c_parser_simple_asm_expr (parser
);
2615 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2617 postfix_attrs
= c_parser_gnu_attributes (parser
);
2618 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2620 /* This means there is an attribute specifier after
2621 the declarator in a function definition. Provide
2622 some more information for the user. */
2623 error_at (here
, "attributes should be specified before the "
2624 "declarator in a function definition");
2625 c_parser_skip_to_end_of_block_or_statement (parser
);
2629 if (c_parser_next_token_is (parser
, CPP_EQ
))
2633 location_t init_loc
;
2634 c_parser_consume_token (parser
);
2635 if (any_auto_type_p
)
2637 init_loc
= c_parser_peek_token (parser
)->location
;
2638 rich_location
richloc (line_table
, init_loc
);
2639 unsigned int underspec_state
= 0;
2640 if (std_auto_type_p
)
2642 start_underspecified_init (init_loc
, underspec_name
);
2643 start_init (NULL_TREE
, asm_name
,
2644 (global_bindings_p ()
2645 || specs
->storage_class
== csc_static
2646 || specs
->constexpr_p
),
2647 specs
->constexpr_p
, &richloc
);
2648 /* A parameter is initialized, which is invalid. Don't
2649 attempt to instrument the initializer. */
2650 int flag_sanitize_save
= flag_sanitize
;
2651 if (nested
&& !empty_ok
)
2653 init
= c_parser_expr_no_commas (parser
, NULL
);
2654 if (std_auto_type_p
)
2655 finish_underspecified_init (underspec_name
,
2657 flag_sanitize
= flag_sanitize_save
;
2659 && TREE_CODE (init
.value
) == COMPONENT_REF
2660 && DECL_C_BIT_FIELD (TREE_OPERAND (init
.value
, 1)))
2662 "%<__auto_type%> used with a bit-field"
2664 init
= convert_lvalue_to_rvalue (init_loc
, init
, true, true,
2666 tree init_type
= TREE_TYPE (init
.value
);
2667 bool vm_type
= c_type_variably_modified_p (init_type
);
2669 init
.value
= save_expr (init
.value
);
2671 specs
->typespec_kind
= ctsk_typeof
;
2672 specs
->locations
[cdw_typedef
] = init_loc
;
2673 specs
->typedef_p
= true;
2674 specs
->type
= init_type
;
2675 if (specs
->postfix_attrs
)
2677 /* Postfix [[]] attributes are valid with C23
2678 auto, although not with __auto_type, and
2679 modify the type given by the initializer. */
2680 specs
->postfix_attrs
=
2681 c_warn_type_attributes (specs
->postfix_attrs
);
2682 decl_attributes (&specs
->type
, specs
->postfix_attrs
, 0);
2683 specs
->postfix_attrs
= NULL_TREE
;
2687 bool maybe_const
= true;
2688 tree type_expr
= c_fully_fold (init
.value
, false,
2690 specs
->expr_const_operands
&= maybe_const
;
2692 specs
->expr
= build2 (COMPOUND_EXPR
,
2693 TREE_TYPE (type_expr
),
2694 specs
->expr
, type_expr
);
2696 specs
->expr
= type_expr
;
2698 d
= start_decl (declarator
, specs
, true,
2699 chainon (postfix_attrs
, all_prefix_attrs
));
2701 d
= error_mark_node
;
2702 if (omp_declare_simd_clauses
)
2703 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2704 omp_declare_simd_clauses
);
2705 if (!omp_dsimd_idattr_clauses
.is_empty ())
2706 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2707 &omp_dsimd_idattr_clauses
);
2711 /* The declaration of the variable is in effect while
2712 its initializer is parsed, except for a constexpr
2714 init_loc
= c_parser_peek_token (parser
)->location
;
2715 rich_location
richloc (line_table
, init_loc
);
2716 unsigned int underspec_state
= 0;
2717 if (specs
->constexpr_p
)
2719 start_underspecified_init (init_loc
, underspec_name
);
2720 d
= start_decl (declarator
, specs
, true,
2721 chainon (postfix_attrs
,
2723 !specs
->constexpr_p
);
2725 d
= error_mark_node
;
2726 if (!specs
->constexpr_p
&& omp_declare_simd_clauses
)
2727 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2728 omp_declare_simd_clauses
);
2729 if (!specs
->constexpr_p
2730 && !omp_dsimd_idattr_clauses
.is_empty ())
2731 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2732 &omp_dsimd_idattr_clauses
);
2733 start_init (d
, asm_name
,
2734 TREE_STATIC (d
) || specs
->constexpr_p
,
2735 specs
->constexpr_p
, &richloc
);
2736 /* A parameter is initialized, which is invalid. Don't
2737 attempt to instrument the initializer. */
2738 int flag_sanitize_save
= flag_sanitize
;
2739 if (TREE_CODE (d
) == PARM_DECL
)
2741 init
= c_parser_initializer (parser
, d
);
2742 flag_sanitize
= flag_sanitize_save
;
2743 if (specs
->constexpr_p
)
2745 finish_underspecified_init (underspec_name
,
2748 if (omp_declare_simd_clauses
)
2749 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2750 omp_declare_simd_clauses
);
2751 if (!specs
->constexpr_p
2752 && !omp_dsimd_idattr_clauses
.is_empty ())
2753 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2754 &omp_dsimd_idattr_clauses
);
2758 if (oacc_routine_data
)
2759 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2760 if (d
!= error_mark_node
)
2762 maybe_warn_string_init (init_loc
, TREE_TYPE (d
), init
);
2763 finish_decl (d
, init_loc
, init
.value
,
2764 init
.original_type
, asm_name
);
2769 if (any_auto_type_p
|| specs
->constexpr_p
)
2772 "%qs requires an initialized data declaration",
2773 any_auto_type_p
? auto_type_keyword
: "constexpr");
2774 c_parser_skip_to_end_of_block_or_statement (parser
);
2778 location_t lastloc
= UNKNOWN_LOCATION
;
2779 tree attrs
= chainon (postfix_attrs
, all_prefix_attrs
);
2780 tree d
= start_decl (declarator
, specs
, false, attrs
, true,
2782 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2784 /* Find the innermost declarator that is neither cdk_id
2786 const struct c_declarator
*decl
= declarator
;
2787 const struct c_declarator
*last_non_id_attrs
= NULL
;
2795 last_non_id_attrs
= decl
;
2796 decl
= decl
->declarator
;
2800 decl
= decl
->declarator
;
2811 /* If it exists and is cdk_function declaration whose
2812 arguments have not been set yet, use its arguments. */
2813 if (last_non_id_attrs
2814 && last_non_id_attrs
->kind
== cdk_function
)
2816 tree parms
= last_non_id_attrs
->u
.arg_info
->parms
;
2817 if (DECL_ARGUMENTS (d
) == NULL_TREE
2818 && DECL_INITIAL (d
) == NULL_TREE
)
2819 DECL_ARGUMENTS (d
) = parms
;
2821 warn_parm_array_mismatch (lastloc
, d
, parms
);
2824 if (omp_declare_simd_clauses
2825 || !omp_dsimd_idattr_clauses
.is_empty ())
2827 tree parms
= NULL_TREE
;
2828 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2830 struct c_declarator
*ce
= declarator
;
2832 if (ce
->kind
== cdk_function
)
2834 parms
= ce
->u
.arg_info
->parms
;
2838 ce
= ce
->declarator
;
2841 temp_store_parm_decls (d
, parms
);
2842 if (omp_declare_simd_clauses
)
2843 c_finish_omp_declare_simd (parser
, d
, parms
,
2844 omp_declare_simd_clauses
);
2845 if (!specs
->constexpr_p
2846 && !omp_dsimd_idattr_clauses
.is_empty ())
2847 c_finish_omp_declare_simd (parser
, d
, parms
,
2848 &omp_dsimd_idattr_clauses
);
2850 temp_pop_parm_decls ();
2852 if (oacc_routine_data
)
2853 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2855 finish_decl (d
, UNKNOWN_LOCATION
, NULL_TREE
,
2856 NULL_TREE
, asm_name
);
2858 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2861 *objc_foreach_object_declaration
= d
;
2863 *objc_foreach_object_declaration
= error_mark_node
;
2866 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2868 if (any_auto_type_p
|| specs
->constexpr_p
)
2871 "%qs may only be used with a single declarator",
2872 any_auto_type_p
? auto_type_keyword
: "constexpr");
2873 c_parser_skip_to_end_of_block_or_statement (parser
);
2876 c_parser_consume_token (parser
);
2877 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2878 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
2881 all_prefix_attrs
= prefix_attrs
;
2884 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2886 c_parser_consume_token (parser
);
2889 else if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2891 /* This can only happen in Objective-C: we found the
2892 'in' that terminates the declaration inside an
2893 Objective-C foreach statement. Do not consume the
2894 token, so that the caller can use it to determine
2895 that this indeed is a foreach context. */
2900 c_parser_error (parser
, "expected %<,%> or %<;%>");
2901 c_parser_skip_to_end_of_block_or_statement (parser
);
2905 else if (any_auto_type_p
|| specs
->constexpr_p
)
2908 "%qs requires an initialized data declaration",
2909 any_auto_type_p
? auto_type_keyword
: "constexpr");
2910 c_parser_skip_to_end_of_block_or_statement (parser
);
2915 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, "
2916 "%<asm%> or %<__attribute__%>");
2917 c_parser_skip_to_end_of_block_or_statement (parser
);
2920 /* Function definition (nested or otherwise). */
2923 pedwarn (here
, OPT_Wpedantic
, "ISO C forbids nested functions");
2924 c_push_function_context ();
2926 if (!start_function (specs
, declarator
, all_prefix_attrs
))
2928 /* At this point we've consumed:
2929 declaration-specifiers declarator
2930 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2931 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2933 declaration-specifiers declarator
2934 aren't grokkable as a function definition, so we have
2936 gcc_assert (!c_parser_next_token_is (parser
, CPP_SEMICOLON
));
2937 if (c_parser_next_token_starts_declspecs (parser
))
2940 declaration-specifiers declarator decl-specs
2941 then assume we have a missing semicolon, which would
2943 declaration-specifiers declarator decl-specs
2946 <~~~~~~~~~ declaration ~~~~~~~~~~>
2947 Use c_parser_require to get an error with a fix-it hint. */
2948 c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>");
2949 parser
->error
= false;
2953 /* This can appear in many cases looking nothing like a
2954 function definition, so we don't give a more specific
2955 error suggesting there was one. */
2956 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2957 "or %<__attribute__%>");
2960 c_pop_function_context ();
2964 if (DECL_DECLARED_INLINE_P (current_function_decl
))
2965 tv
= TV_PARSE_INLINE
;
2968 auto_timevar
at (g_timer
, tv
);
2970 /* Parse old-style parameter declarations. ??? Attributes are
2971 not allowed to start declaration specifiers here because of a
2972 syntax conflict between a function declaration with attribute
2973 suffix and a function definition with an attribute prefix on
2974 first old-style parameter declaration. Following the old
2975 parser, they are not accepted on subsequent old-style
2976 parameter declarations either. However, there is no
2977 ambiguity after the first declaration, nor indeed on the
2978 first as long as we don't allow postfix attributes after a
2979 declarator with a nonempty identifier list in a definition;
2980 and postfix attributes have never been accepted here in
2981 function definitions either. */
2982 int save_debug_nonbind_markers_p
= debug_nonbind_markers_p
;
2983 debug_nonbind_markers_p
= 0;
2984 while (c_parser_next_token_is_not (parser
, CPP_EOF
)
2985 && c_parser_next_token_is_not (parser
, CPP_OPEN_BRACE
))
2986 c_parser_declaration_or_fndef (parser
, false, false, false,
2988 debug_nonbind_markers_p
= save_debug_nonbind_markers_p
;
2989 store_parm_decls ();
2990 if (omp_declare_simd_clauses
)
2991 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2992 omp_declare_simd_clauses
);
2993 if (!omp_dsimd_idattr_clauses
.is_empty ())
2994 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2995 &omp_dsimd_idattr_clauses
);
2996 if (oacc_routine_data
)
2997 c_finish_oacc_routine (oacc_routine_data
, current_function_decl
, true);
2998 location_t startloc
= c_parser_peek_token (parser
)->location
;
2999 DECL_STRUCT_FUNCTION (current_function_decl
)->function_start_locus
3001 location_t endloc
= startloc
;
3003 /* If the definition was marked with __RTL, use the RTL parser now,
3004 consuming the function body. */
3005 if (specs
->declspec_il
== cdil_rtl
)
3007 endloc
= c_parser_parse_rtl_body (parser
, specs
->gimple_or_rtl_pass
);
3009 /* Normally, store_parm_decls sets next_is_function_body,
3010 anticipating a function body. We need a push_scope/pop_scope
3011 pair to flush out this state, or subsequent function parsing
3016 finish_function (endloc
);
3019 /* If the definition was marked with __GIMPLE then parse the
3020 function body as GIMPLE. */
3021 else if (specs
->declspec_il
!= cdil_none
)
3023 bool saved
= in_late_binary_op
;
3024 in_late_binary_op
= true;
3025 c_parser_parse_gimple_body (parser
, specs
->gimple_or_rtl_pass
,
3027 specs
->entry_bb_count
);
3028 in_late_binary_op
= saved
;
3031 fnbody
= c_parser_compound_statement (parser
, &endloc
);
3032 tree fndecl
= current_function_decl
;
3035 tree decl
= current_function_decl
;
3036 /* Mark nested functions as needing static-chain initially.
3037 lower_nested_functions will recompute it but the
3038 DECL_STATIC_CHAIN flag is also used before that happens,
3039 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
3040 DECL_STATIC_CHAIN (decl
) = 1;
3042 finish_function (endloc
);
3043 c_pop_function_context ();
3044 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl
), DECL_EXPR
, decl
));
3050 finish_function (endloc
);
3052 /* Get rid of the empty stmt list for GIMPLE/RTL. */
3053 if (specs
->declspec_il
!= cdil_none
)
3054 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
3060 /* Parse an asm-definition (asm() outside a function body). This is a
3068 c_parser_asm_definition (c_parser
*parser
)
3070 tree asm_str
= c_parser_simple_asm_expr (parser
);
3072 symtab
->finalize_toplevel_asm (asm_str
);
3073 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
3076 /* Parse a static assertion (C11 6.7.10).
3078 static_assert-declaration:
3079 static_assert-declaration-no-semi ;
3083 c_parser_static_assert_declaration (c_parser
*parser
)
3085 c_parser_static_assert_declaration_no_semi (parser
);
3087 || !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
3088 c_parser_skip_to_end_of_block_or_statement (parser
);
3091 /* Parse a static assertion (C11 6.7.10), without the trailing
3094 static_assert-declaration-no-semi:
3095 _Static_assert ( constant-expression , string-literal )
3098 static_assert-declaration-no-semi:
3099 _Static_assert ( constant-expression )
3103 c_parser_static_assert_declaration_no_semi (c_parser
*parser
)
3105 location_t assert_loc
, value_loc
;
3107 tree string
= NULL_TREE
;
3109 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
));
3110 tree spelling
= c_parser_peek_token (parser
)->value
;
3111 assert_loc
= c_parser_peek_token (parser
)->location
;
3113 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
3114 "ISO C99 does not support %qE", spelling
);
3116 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
3117 "ISO C90 does not support %qE", spelling
);
3118 c_parser_consume_token (parser
);
3119 matching_parens parens
;
3120 if (!parens
.require_open (parser
))
3122 location_t value_tok_loc
= c_parser_peek_token (parser
)->location
;
3123 value
= convert_lvalue_to_rvalue (value_tok_loc
,
3124 c_parser_expr_no_commas (parser
, NULL
),
3126 value_loc
= EXPR_LOC_OR_LOC (value
, value_tok_loc
);
3127 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3129 c_parser_consume_token (parser
);
3130 switch (c_parser_peek_token (parser
)->type
)
3136 case CPP_UTF8STRING
:
3137 string
= c_parser_string_literal (parser
, false, true).value
;
3140 c_parser_error (parser
, "expected string literal");
3144 else if (flag_isoc11
)
3145 /* If pedantic for pre-C11, the use of _Static_assert itself will
3146 have been diagnosed, so do not also diagnose the use of this
3147 new C23 feature of _Static_assert. */
3148 pedwarn_c11 (assert_loc
, OPT_Wpedantic
,
3149 "ISO C11 does not support omitting the string in "
3151 parens
.require_close (parser
);
3153 if (!INTEGRAL_TYPE_P (TREE_TYPE (value
)))
3155 error_at (value_loc
, "expression in static assertion is not an integer");
3158 if (TREE_CODE (value
) != INTEGER_CST
)
3160 value
= c_fully_fold (value
, false, NULL
);
3161 /* Strip no-op conversions. */
3162 STRIP_TYPE_NOPS (value
);
3163 if (TREE_CODE (value
) == INTEGER_CST
)
3164 pedwarn (value_loc
, OPT_Wpedantic
, "expression in static assertion "
3165 "is not an integer constant expression");
3167 if (TREE_CODE (value
) != INTEGER_CST
)
3169 error_at (value_loc
, "expression in static assertion is not constant");
3172 constant_expression_warning (value
);
3173 if (integer_zerop (value
))
3176 error_at (assert_loc
, "static assertion failed: %E", string
);
3178 error_at (assert_loc
, "static assertion failed");
3182 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
3183 6.7, C11 6.7), adding them to SPECS (which may already include some).
3184 Storage class specifiers are accepted iff SCSPEC_OK; type
3185 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
3186 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
3187 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
3188 addition to the syntax shown, standard attributes are accepted at
3189 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
3190 unlike gnu-attributes, they are not accepted in the middle of the
3191 list. (This combines various different syntax productions in the C
3192 standard, and in some cases gnu-attributes and standard attributes
3193 at the start may already have been parsed before this function is
3196 declaration-specifiers:
3197 storage-class-specifier declaration-specifiers[opt]
3198 type-specifier declaration-specifiers[opt]
3199 type-qualifier declaration-specifiers[opt]
3200 function-specifier declaration-specifiers[opt]
3201 alignment-specifier declaration-specifiers[opt]
3203 Function specifiers (inline) are from C99, and are currently
3204 handled as storage class specifiers, as is __thread. Alignment
3205 specifiers are from C11.
3207 C90 6.5.1, C99 6.7.1, C11 6.7.1:
3208 storage-class-specifier:
3216 (_Thread_local is new in C11.)
3218 C99 6.7.4, C11 6.7.4:
3223 (_Noreturn is new in C11.)
3225 C90 6.5.2, C99 6.7.2, C11 6.7.2:
3238 [_Imaginary removed in C99 TC2]
3239 _BitInt ( constant-expression )
3240 struct-or-union-specifier
3243 atomic-type-specifier
3245 (_Bool and _Complex are new in C99.)
3246 (atomic-type-specifier is new in C11.)
3247 (_BitInt is new in C23.)
3249 C90 6.5.3, C99 6.7.3, C11 6.7.3:
3255 address-space-qualifier
3258 (restrict is new in C99.)
3259 (_Atomic is new in C11.)
3263 declaration-specifiers:
3264 gnu-attributes declaration-specifiers[opt]
3270 identifier recognized by the target
3272 storage-class-specifier:
3286 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
3287 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
3289 atomic-type-specifier
3290 _Atomic ( type-name )
3295 class-name objc-protocol-refs[opt]
3296 typedef-name objc-protocol-refs
3301 c_parser_declspecs (c_parser
*parser
, struct c_declspecs
*specs
,
3302 bool scspec_ok
, bool typespec_ok
, bool start_attr_ok
,
3303 bool alignspec_ok
, bool auto_type_ok
,
3304 bool start_std_attr_ok
, bool end_std_attr_ok
,
3305 enum c_lookahead_kind la
)
3307 bool attrs_ok
= start_attr_ok
;
3308 bool seen_type
= specs
->typespec_kind
!= ctsk_none
;
3311 gcc_assert (la
== cla_prefer_id
);
3313 if (start_std_attr_ok
3314 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3316 gcc_assert (!specs
->non_std_attrs_seen_p
);
3317 location_t loc
= c_parser_peek_token (parser
)->location
;
3318 tree attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3319 declspecs_add_attrs (loc
, specs
, attrs
);
3320 specs
->non_std_attrs_seen_p
= false;
3323 while (c_parser_next_token_is (parser
, CPP_NAME
)
3324 || c_parser_next_token_is (parser
, CPP_KEYWORD
)
3325 || (c_dialect_objc () && c_parser_next_token_is (parser
, CPP_LESS
)))
3327 struct c_typespec t
;
3330 location_t loc
= c_parser_peek_token (parser
)->location
;
3332 /* If we cannot accept a type, exit if the next token must start
3333 one. Also, if we already have seen a tagged definition,
3334 a typename would be an error anyway and likely the user
3335 has simply forgotten a semicolon, so we exit. */
3336 if ((!typespec_ok
|| specs
->typespec_kind
== ctsk_tagdef
)
3337 && c_parser_next_tokens_start_typename (parser
, la
)
3338 && !c_parser_next_token_is_qualifier (parser
)
3339 && !c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
))
3342 if (c_parser_next_token_is (parser
, CPP_NAME
))
3344 c_token
*name_token
= c_parser_peek_token (parser
);
3345 tree value
= name_token
->value
;
3346 c_id_kind kind
= name_token
->id_kind
;
3348 if (kind
== C_ID_ADDRSPACE
)
3351 = name_token
->keyword
- RID_FIRST_ADDR_SPACE
;
3352 declspecs_add_addrspace (name_token
->location
, specs
, as
);
3353 c_parser_consume_token (parser
);
3358 gcc_assert (!c_parser_next_token_is_qualifier (parser
));
3360 /* If we cannot accept a type, and the next token must start one,
3361 exit. Do the same if we already have seen a tagged definition,
3362 since it would be an error anyway and likely the user has simply
3363 forgotten a semicolon. */
3364 if (seen_type
|| !c_parser_next_tokens_start_typename (parser
, la
))
3367 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
3368 a C_ID_CLASSNAME. */
3369 c_parser_consume_token (parser
);
3372 if (kind
== C_ID_ID
)
3374 auto_diagnostic_group d
;
3375 name_hint hint
= lookup_name_fuzzy (value
, FUZZY_LOOKUP_TYPENAME
,
3377 if (const char *suggestion
= hint
.suggestion ())
3379 gcc_rich_location
richloc (loc
);
3380 richloc
.add_fixit_replace (suggestion
);
3382 "unknown type name %qE; did you mean %qs?",
3386 error_at (loc
, "unknown type name %qE", value
);
3387 t
.kind
= ctsk_typedef
;
3388 t
.spec
= error_mark_node
;
3390 else if (kind
== C_ID_TYPENAME
3391 && (!c_dialect_objc ()
3392 || c_parser_next_token_is_not (parser
, CPP_LESS
)))
3394 t
.kind
= ctsk_typedef
;
3395 /* For a typedef name, record the meaning, not the name.
3396 In case of 'foo foo, bar;'. */
3397 t
.spec
= lookup_name (value
);
3401 tree proto
= NULL_TREE
;
3402 gcc_assert (c_dialect_objc ());
3404 if (c_parser_next_token_is (parser
, CPP_LESS
))
3405 proto
= c_parser_objc_protocol_refs (parser
);
3406 t
.spec
= objc_get_protocol_qualified_type (value
, proto
);
3409 t
.expr_const_operands
= true;
3410 t
.has_enum_type_specifier
= false;
3411 declspecs_add_type (name_token
->location
, specs
, t
);
3414 if (c_parser_next_token_is (parser
, CPP_LESS
))
3416 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
3417 nisse@lysator.liu.se. */
3419 gcc_assert (c_dialect_objc ());
3420 if (!typespec_ok
|| seen_type
)
3422 proto
= c_parser_objc_protocol_refs (parser
);
3424 t
.spec
= objc_get_protocol_qualified_type (NULL_TREE
, proto
);
3426 t
.expr_const_operands
= true;
3427 t
.has_enum_type_specifier
= false;
3428 declspecs_add_type (loc
, specs
, t
);
3431 gcc_assert (c_parser_next_token_is (parser
, CPP_KEYWORD
));
3432 switch (c_parser_peek_token (parser
)->keyword
)
3446 /* TODO: Distinguish between function specifiers (inline, noreturn)
3447 and storage class specifiers, either here or in
3448 declspecs_add_scspec. */
3449 declspecs_add_scspec (loc
, specs
,
3450 c_parser_peek_token (parser
)->value
);
3451 c_parser_consume_token (parser
);
3483 if (c_dialect_objc ())
3484 parser
->objc_need_raw_identifier
= true;
3485 t
.kind
= ctsk_resword
;
3486 t
.spec
= c_parser_peek_token (parser
)->value
;
3488 t
.expr_const_operands
= true;
3489 t
.has_enum_type_specifier
= false;
3490 declspecs_add_type (loc
, specs
, t
);
3491 c_parser_consume_token (parser
);
3498 t
= c_parser_enum_specifier (parser
);
3499 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
3500 declspecs_add_type (loc
, specs
, t
);
3508 t
= c_parser_struct_or_union_specifier (parser
);
3509 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
3510 declspecs_add_type (loc
, specs
, t
);
3513 case RID_TYPEOF_UNQUAL
:
3514 /* ??? The old parser rejected typeof after other type
3515 specifiers, but is a syntax error the best way of
3517 if (!typespec_ok
|| seen_type
)
3521 t
= c_parser_typeof_specifier (parser
);
3522 declspecs_add_type (loc
, specs
, t
);
3531 t
.kind
= ctsk_resword
;
3532 t
.spec
= c_parser_peek_token (parser
)->value
;
3533 t
.expr
= error_mark_node
;
3534 t
.expr_const_operands
= true;
3535 t
.has_enum_type_specifier
= false;
3536 c_parser_consume_token (parser
);
3537 matching_parens parens
;
3538 if (parens
.require_open (parser
))
3540 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
3541 t
.expr
= convert_lvalue_to_rvalue (loc
, expr
, true,
3543 parens
.skip_until_found_close (parser
);
3545 declspecs_add_type (loc
, specs
, t
);
3549 /* C parser handling of Objective-C constructs needs
3550 checking for correct lvalue-to-rvalue conversions, and
3551 the code in build_modify_expr handling various
3552 Objective-C cases, and that in build_unary_op handling
3553 Objective-C cases for increment / decrement, also needs
3554 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3555 and objc_types_are_equivalent may also need updates. */
3556 if (c_dialect_objc ())
3557 sorry ("%<_Atomic%> in Objective-C");
3559 pedwarn_c99 (loc
, OPT_Wpedantic
,
3560 "ISO C99 does not support the %<_Atomic%> qualifier");
3562 pedwarn_c99 (loc
, OPT_Wpedantic
,
3563 "ISO C90 does not support the %<_Atomic%> qualifier");
3566 value
= c_parser_peek_token (parser
)->value
;
3567 c_parser_consume_token (parser
);
3568 if (typespec_ok
&& c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3570 /* _Atomic ( type-name ). */
3572 c_parser_consume_token (parser
);
3573 struct c_type_name
*type
= c_parser_type_name (parser
);
3574 t
.kind
= ctsk_typeof
;
3575 t
.spec
= error_mark_node
;
3577 t
.expr_const_operands
= true;
3578 t
.has_enum_type_specifier
= false;
3580 t
.spec
= groktypename (type
, &t
.expr
,
3581 &t
.expr_const_operands
);
3582 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3584 if (t
.spec
!= error_mark_node
)
3586 if (TREE_CODE (t
.spec
) == ARRAY_TYPE
)
3587 error_at (loc
, "%<_Atomic%>-qualified array type");
3588 else if (TREE_CODE (t
.spec
) == FUNCTION_TYPE
)
3589 error_at (loc
, "%<_Atomic%>-qualified function type");
3590 else if (TYPE_QUALS (t
.spec
) != TYPE_UNQUALIFIED
)
3591 error_at (loc
, "%<_Atomic%> applied to a qualified type");
3593 t
.spec
= c_build_qualified_type (t
.spec
, TYPE_QUAL_ATOMIC
);
3595 declspecs_add_type (loc
, specs
, t
);
3598 declspecs_add_qual (loc
, specs
, value
);
3604 declspecs_add_qual (loc
, specs
, c_parser_peek_token (parser
)->value
);
3605 c_parser_consume_token (parser
);
3610 attrs
= c_parser_gnu_attributes (parser
);
3611 declspecs_add_attrs (loc
, specs
, attrs
);
3616 align
= c_parser_alignas_specifier (parser
);
3617 declspecs_add_alignas (loc
, specs
, align
);
3621 error_at (loc
, "%<__GIMPLE%> only valid with %<-fgimple%>");
3622 c_parser_consume_token (parser
);
3623 specs
->declspec_il
= cdil_gimple
;
3624 specs
->locations
[cdw_gimple
] = loc
;
3625 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3628 c_parser_consume_token (parser
);
3629 specs
->declspec_il
= cdil_rtl
;
3630 specs
->locations
[cdw_rtl
] = loc
;
3631 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3639 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3640 specs
->postfix_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3643 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3646 enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3647 { enumerator-list } gnu-attributes[opt]
3648 enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3649 { enumerator-list , } gnu-attributes[opt] enum-type-specifier[opt]
3650 enum gnu-attributes[opt] identifier
3652 The form with trailing comma is new in C99; enum-type-specifiers
3653 are new in C23. The forms with gnu-attributes are GNU extensions.
3654 In GNU C, we accept any expression without commas in the syntax
3655 (assignment expressions, not just conditional expressions);
3656 assignment expressions will be diagnosed as non-constant.
3658 enum-type-specifier:
3659 : specifier-qualifier-list
3663 enumerator-list , enumerator
3666 enumeration-constant attribute-specifier-sequence[opt]
3667 enumeration-constant attribute-specifier-sequence[opt]
3668 = constant-expression
3673 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3674 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3675 = constant-expression
3679 static struct c_typespec
3680 c_parser_enum_specifier (c_parser
*parser
)
3682 struct c_typespec ret
;
3683 bool have_std_attrs
;
3684 bool potential_nesting_p
= false;
3685 tree std_attrs
= NULL_TREE
;
3687 tree ident
= NULL_TREE
;
3688 tree fixed_underlying_type
= NULL_TREE
;
3689 location_t enum_loc
;
3690 location_t ident_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3691 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ENUM
));
3692 c_parser_consume_token (parser
);
3693 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3695 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3696 attrs
= c_parser_gnu_attributes (parser
);
3697 enum_loc
= c_parser_peek_token (parser
)->location
;
3698 /* Set the location in case we create a decl now. */
3699 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3700 if (c_parser_next_token_is (parser
, CPP_NAME
))
3702 ident
= c_parser_peek_token (parser
)->value
;
3703 ident_loc
= c_parser_peek_token (parser
)->location
;
3704 enum_loc
= ident_loc
;
3705 c_parser_consume_token (parser
);
3707 if (c_parser_next_token_is (parser
, CPP_COLON
)
3708 /* Distinguish an enum-type-specifier from a bit-field
3709 declaration of the form "enum e : constant-expression;". */
3710 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
3712 pedwarn_c11 (enum_loc
, OPT_Wpedantic
,
3713 "ISO C does not support specifying %<enum%> underlying "
3714 "types before C23");
3717 /* The tag is in scope during the enum-type-specifier (which
3718 may refer to the tag inside typeof). */
3719 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
,
3720 have_std_attrs
, std_attrs
, true);
3721 if (!ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
))
3722 error_at (enum_loc
, "%<enum%> declared both with and without "
3723 "fixed underlying type");
3724 potential_nesting_p
= NULL_TREE
== TYPE_VALUES (ret
.spec
);
3728 /* There must be an enum definition, so this initialization
3729 (to avoid possible warnings about uninitialized data)
3730 will be replaced later (either with the results of that
3731 definition, or with the results of error handling for the
3732 case of no tag and no definition). */
3733 ret
.spec
= NULL_TREE
;
3734 ret
.kind
= ctsk_tagdef
;
3735 ret
.expr
= NULL_TREE
;
3736 ret
.expr_const_operands
= true;
3737 ret
.has_enum_type_specifier
= true;
3739 c_parser_consume_token (parser
);
3740 struct c_declspecs
*specs
= build_null_declspecs ();
3741 c_parser_declspecs (parser
, specs
, false, true, false, false, false,
3742 false, true, cla_prefer_id
);
3743 finish_declspecs (specs
);
3744 if (specs
->default_int_p
)
3745 error_at (enum_loc
, "no %<enum%> underlying type specified");
3746 else if (TREE_CODE (specs
->type
) != INTEGER_TYPE
3747 && TREE_CODE (specs
->type
) != BOOLEAN_TYPE
)
3749 error_at (enum_loc
, "invalid %<enum%> underlying type");
3750 specs
->type
= integer_type_node
;
3752 else if (specs
->restrict_p
)
3753 error_at (enum_loc
, "invalid use of %<restrict%>");
3754 fixed_underlying_type
= TYPE_MAIN_VARIANT (specs
->type
);
3757 /* The type specified must be consistent with any previously
3758 specified underlying type. If this is a newly declared
3759 type, it is now a complete type. */
3760 if (ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
)
3761 && ENUM_UNDERLYING_TYPE (ret
.spec
) == NULL_TREE
)
3763 TYPE_MIN_VALUE (ret
.spec
) =
3764 TYPE_MIN_VALUE (fixed_underlying_type
);
3765 TYPE_MAX_VALUE (ret
.spec
) =
3766 TYPE_MAX_VALUE (fixed_underlying_type
);
3767 TYPE_UNSIGNED (ret
.spec
) = TYPE_UNSIGNED (fixed_underlying_type
);
3768 SET_TYPE_ALIGN (ret
.spec
, TYPE_ALIGN (fixed_underlying_type
));
3769 TYPE_SIZE (ret
.spec
) = NULL_TREE
;
3770 TYPE_PRECISION (ret
.spec
) =
3771 TYPE_PRECISION (fixed_underlying_type
);
3772 ENUM_UNDERLYING_TYPE (ret
.spec
) = fixed_underlying_type
;
3773 layout_type (ret
.spec
);
3775 else if (ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
)
3776 && !comptypes (fixed_underlying_type
,
3777 ENUM_UNDERLYING_TYPE (ret
.spec
)))
3779 error_at (enum_loc
, "%<enum%> underlying type incompatible with "
3780 "previous declaration");
3781 fixed_underlying_type
= ENUM_UNDERLYING_TYPE (ret
.spec
);
3785 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3787 /* Parse an enum definition. */
3788 struct c_enum_contents the_enum
;
3791 /* We chain the enumerators in reverse order, then put them in
3792 forward order at the end. */
3794 timevar_push (TV_PARSE_ENUM
);
3795 type
= start_enum (enum_loc
, &the_enum
, ident
, fixed_underlying_type
,
3796 potential_nesting_p
);
3798 c_parser_consume_token (parser
);
3806 location_t comma_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3807 location_t decl_loc
, value_loc
;
3808 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
3810 /* Give a nicer error for "enum {}". */
3811 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3814 error_at (c_parser_peek_token (parser
)->location
,
3815 "empty enum is invalid");
3816 parser
->error
= true;
3819 c_parser_error (parser
, "expected identifier");
3820 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3821 values
= error_mark_node
;
3824 token
= c_parser_peek_token (parser
);
3825 enum_id
= token
->value
;
3826 /* Set the location in case we create a decl now. */
3827 c_parser_set_source_position_from_token (token
);
3828 decl_loc
= value_loc
= token
->location
;
3829 c_parser_consume_token (parser
);
3830 /* Parse any specified attributes. */
3831 tree std_attrs
= NULL_TREE
;
3832 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3833 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3834 tree enum_attrs
= chainon (std_attrs
,
3835 c_parser_gnu_attributes (parser
));
3836 if (c_parser_next_token_is (parser
, CPP_EQ
))
3838 c_parser_consume_token (parser
);
3839 value_loc
= c_parser_peek_token (parser
)->location
;
3840 enum_value
= convert_lvalue_to_rvalue (value_loc
,
3841 (c_parser_expr_no_commas
3846 enum_value
= NULL_TREE
;
3847 enum_decl
= build_enumerator (decl_loc
, value_loc
,
3848 &the_enum
, enum_id
, enum_value
);
3850 decl_attributes (&TREE_PURPOSE (enum_decl
), enum_attrs
, 0);
3851 TREE_CHAIN (enum_decl
) = values
;
3854 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3856 comma_loc
= c_parser_peek_token (parser
)->location
;
3858 c_parser_consume_token (parser
);
3860 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3863 pedwarn_c90 (comma_loc
, OPT_Wpedantic
,
3864 "comma at end of enumerator list");
3865 c_parser_consume_token (parser
);
3870 c_parser_error (parser
, "expected %<,%> or %<}%>");
3871 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3872 values
= error_mark_node
;
3876 postfix_attrs
= c_parser_gnu_attributes (parser
);
3877 ret
.spec
= finish_enum (type
, nreverse (values
),
3879 chainon (attrs
, postfix_attrs
)));
3880 ret
.kind
= ctsk_tagdef
;
3881 ret
.expr
= NULL_TREE
;
3882 ret
.expr_const_operands
= true;
3883 ret
.has_enum_type_specifier
= fixed_underlying_type
!= NULL_TREE
;
3884 timevar_pop (TV_PARSE_ENUM
);
3889 c_parser_error (parser
, "expected %<{%>");
3890 ret
.spec
= error_mark_node
;
3891 ret
.kind
= ctsk_tagref
;
3892 ret
.expr
= NULL_TREE
;
3893 ret
.expr_const_operands
= true;
3894 ret
.has_enum_type_specifier
= false;
3897 /* Attributes may only appear when the members are defined or in
3898 certain forward declarations (treat enum forward declarations in
3899 GNU C analogously to struct and union forward declarations in
3901 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3902 c_parser_error (parser
, "expected %<;%>");
3903 if (fixed_underlying_type
== NULL_TREE
)
3905 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
, have_std_attrs
,
3907 /* In ISO C, enumerated types without a fixed underlying type
3908 can be referred to only if already defined. */
3909 if (pedantic
&& !COMPLETE_TYPE_P (ret
.spec
))
3912 pedwarn (enum_loc
, OPT_Wpedantic
,
3913 "ISO C forbids forward references to %<enum%> types");
3919 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3921 struct-or-union-specifier:
3922 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3923 identifier[opt] { struct-contents } gnu-attributes[opt]
3924 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3928 struct-declaration-list
3930 struct-declaration-list:
3931 struct-declaration ;
3932 struct-declaration-list struct-declaration ;
3939 struct-declaration-list struct-declaration
3941 struct-declaration-list:
3942 struct-declaration-list ;
3945 (Note that in the syntax here, unlike that in ISO C, the semicolons
3946 are included here rather than in struct-declaration, in order to
3947 describe the syntax with extra semicolons and missing semicolon at
3952 struct-declaration-list:
3953 @defs ( class-name )
3955 (Note this does not include a trailing semicolon, but can be
3956 followed by further declarations, and gets a pedwarn-if-pedantic
3957 when followed by a semicolon.) */
3959 static struct c_typespec
3960 c_parser_struct_or_union_specifier (c_parser
*parser
)
3962 struct c_typespec ret
;
3963 bool have_std_attrs
;
3964 tree std_attrs
= NULL_TREE
;
3966 tree ident
= NULL_TREE
;
3967 location_t struct_loc
;
3968 location_t ident_loc
= UNKNOWN_LOCATION
;
3969 enum tree_code code
;
3970 switch (c_parser_peek_token (parser
)->keyword
)
3981 struct_loc
= c_parser_peek_token (parser
)->location
;
3982 c_parser_consume_token (parser
);
3983 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3985 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3986 attrs
= c_parser_gnu_attributes (parser
);
3988 /* Set the location in case we create a decl now. */
3989 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3991 if (c_parser_next_token_is (parser
, CPP_NAME
))
3993 ident
= c_parser_peek_token (parser
)->value
;
3994 ident_loc
= c_parser_peek_token (parser
)->location
;
3995 struct_loc
= ident_loc
;
3996 c_parser_consume_token (parser
);
3998 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
4000 /* Parse a struct or union definition. Start the scope of the
4001 tag before parsing components. */
4002 class c_struct_parse_info
*struct_info
;
4003 tree type
= start_struct (struct_loc
, code
, ident
, &struct_info
);
4005 /* We chain the components in reverse order, then put them in
4006 forward order at the end. Each struct-declaration may
4007 declare multiple components (comma-separated), so we must use
4008 chainon to join them, although when parsing each
4009 struct-declaration we can use TREE_CHAIN directly.
4011 The theory behind all this is that there will be more
4012 semicolon separated fields than comma separated fields, and
4013 so we'll be minimizing the number of node traversals required
4017 timevar_push (TV_PARSE_STRUCT
);
4018 contents
= NULL_TREE
;
4019 c_parser_consume_token (parser
);
4020 /* Handle the Objective-C @defs construct,
4021 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
4022 if (c_parser_next_token_is_keyword (parser
, RID_AT_DEFS
))
4025 gcc_assert (c_dialect_objc ());
4026 c_parser_consume_token (parser
);
4027 matching_parens parens
;
4028 if (!parens
.require_open (parser
))
4030 if (c_parser_next_token_is (parser
, CPP_NAME
)
4031 && c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
)
4033 name
= c_parser_peek_token (parser
)->value
;
4034 c_parser_consume_token (parser
);
4038 c_parser_error (parser
, "expected class name");
4039 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4042 parens
.skip_until_found_close (parser
);
4043 contents
= nreverse (objc_get_class_ivars (name
));
4046 /* Parse the struct-declarations and semicolons. Problems with
4047 semicolons are diagnosed here; empty structures are diagnosed
4052 /* Parse any stray semicolon. */
4053 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4055 location_t semicolon_loc
4056 = c_parser_peek_token (parser
)->location
;
4057 gcc_rich_location
richloc (semicolon_loc
);
4058 richloc
.add_fixit_remove ();
4059 pedwarn (&richloc
, OPT_Wpedantic
,
4060 "extra semicolon in struct or union specified");
4061 c_parser_consume_token (parser
);
4064 /* Stop if at the end of the struct or union contents. */
4065 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4067 c_parser_consume_token (parser
);
4070 /* Accept #pragmas at struct scope. */
4071 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
4073 c_parser_pragma (parser
, pragma_struct
, NULL
);
4076 /* Parse some comma-separated declarations, but not the
4077 trailing semicolon if any. */
4078 decls
= c_parser_struct_declaration (parser
, &expr
);
4079 contents
= chainon (decls
, contents
);
4080 /* If no semicolon follows, either we have a parse error or
4081 are at the end of the struct or union and should
4083 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4084 c_parser_consume_token (parser
);
4087 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4088 pedwarn (c_parser_peek_token (parser
)->location
, 0,
4089 "no semicolon at end of struct or union");
4090 else if (parser
->error
4091 || !c_parser_next_token_starts_declspecs (parser
))
4093 c_parser_error (parser
, "expected %<;%>");
4094 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
4098 /* If we come here, we have already emitted an error
4099 for an expected `;', identifier or `(', and we also
4100 recovered already. Go on with the next field. */
4103 postfix_attrs
= c_parser_gnu_attributes (parser
);
4104 ret
.spec
= finish_struct (struct_loc
, type
, nreverse (contents
),
4106 chainon (attrs
, postfix_attrs
)),
4107 struct_info
, &expr
);
4108 ret
.kind
= ctsk_tagdef
;
4110 ret
.expr_const_operands
= true;
4111 ret
.has_enum_type_specifier
= false;
4112 timevar_pop (TV_PARSE_STRUCT
);
4117 c_parser_error (parser
, "expected %<{%>");
4118 ret
.spec
= error_mark_node
;
4119 ret
.kind
= ctsk_tagref
;
4120 ret
.expr
= NULL_TREE
;
4121 ret
.expr_const_operands
= true;
4122 ret
.has_enum_type_specifier
= false;
4125 /* Attributes may only appear when the members are defined or in
4126 certain forward declarations. */
4127 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
4128 c_parser_error (parser
, "expected %<;%>");
4129 /* ??? Existing practice is that GNU attributes are ignored after
4130 the struct or union keyword when not defining the members. */
4131 ret
= parser_xref_tag (ident_loc
, code
, ident
, have_std_attrs
, std_attrs
,
4136 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
4137 *without* the trailing semicolon.
4140 attribute-specifier-sequence[opt] specifier-qualifier-list
4141 attribute-specifier-sequence[opt] struct-declarator-list
4142 static_assert-declaration-no-semi
4144 specifier-qualifier-list:
4145 type-specifier specifier-qualifier-list[opt]
4146 type-qualifier specifier-qualifier-list[opt]
4147 alignment-specifier specifier-qualifier-list[opt]
4148 gnu-attributes specifier-qualifier-list[opt]
4150 struct-declarator-list:
4152 struct-declarator-list , gnu-attributes[opt] struct-declarator
4155 declarator gnu-attributes[opt]
4156 declarator[opt] : constant-expression gnu-attributes[opt]
4161 __extension__ struct-declaration
4162 specifier-qualifier-list
4164 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
4165 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
4166 any expression without commas in the syntax (assignment
4167 expressions, not just conditional expressions); assignment
4168 expressions will be diagnosed as non-constant. */
4171 c_parser_struct_declaration (c_parser
*parser
, tree
*expr
)
4173 struct c_declspecs
*specs
;
4175 tree all_prefix_attrs
;
4177 location_t decl_loc
;
4178 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
4182 ext
= disable_extension_diagnostics ();
4183 c_parser_consume_token (parser
);
4184 decl
= c_parser_struct_declaration (parser
, expr
);
4185 restore_extension_diagnostics (ext
);
4188 if (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
4190 c_parser_static_assert_declaration_no_semi (parser
);
4193 specs
= build_null_declspecs ();
4194 decl_loc
= c_parser_peek_token (parser
)->location
;
4195 /* Strictly by the standard, we shouldn't allow _Alignas here,
4196 but it appears to have been intended to allow it there, so
4197 we're keeping it as it is until WG14 reaches a conclusion
4199 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
4200 c_parser_declspecs (parser
, specs
, false, true, true,
4201 true, false, true, true, cla_nonabstract_decl
);
4204 if (!specs
->declspecs_seen_p
)
4206 c_parser_error (parser
, "expected specifier-qualifier-list");
4209 finish_declspecs (specs
);
4210 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
4211 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4214 if (specs
->typespec_kind
== ctsk_none
)
4216 pedwarn (decl_loc
, OPT_Wpedantic
,
4217 "ISO C forbids member declarations with no members");
4218 shadow_tag_warned (specs
, pedantic
);
4223 /* Support for unnamed structs or unions as members of
4224 structs or unions (which is [a] useful and [b] supports
4228 ret
= grokfield (c_parser_peek_token (parser
)->location
,
4229 build_id_declarator (NULL_TREE
), specs
,
4230 NULL_TREE
, &attrs
, expr
);
4232 decl_attributes (&ret
, attrs
, 0);
4237 /* Provide better error recovery. Note that a type name here is valid,
4238 and will be treated as a field name. */
4239 if (specs
->typespec_kind
== ctsk_tagdef
4240 && TREE_CODE (specs
->type
) != ENUMERAL_TYPE
4241 && c_parser_next_token_starts_declspecs (parser
)
4242 && !c_parser_next_token_is (parser
, CPP_NAME
))
4244 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
4245 parser
->error
= false;
4249 pending_xref_error ();
4250 prefix_attrs
= specs
->attrs
;
4251 all_prefix_attrs
= prefix_attrs
;
4252 specs
->attrs
= NULL_TREE
;
4256 /* Declaring one or more declarators or un-named bit-fields. */
4257 struct c_declarator
*declarator
;
4259 if (c_parser_next_token_is (parser
, CPP_COLON
))
4260 declarator
= build_id_declarator (NULL_TREE
);
4262 declarator
= c_parser_declarator (parser
,
4263 specs
->typespec_kind
!= ctsk_none
,
4264 C_DTR_NORMAL
, &dummy
);
4265 if (declarator
== NULL
)
4267 c_parser_skip_to_end_of_block_or_statement (parser
);
4270 if (c_parser_next_token_is (parser
, CPP_COLON
)
4271 || c_parser_next_token_is (parser
, CPP_COMMA
)
4272 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
4273 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
4274 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4276 tree postfix_attrs
= NULL_TREE
;
4277 tree width
= NULL_TREE
;
4279 if (c_parser_next_token_is (parser
, CPP_COLON
))
4281 c_parser_consume_token (parser
);
4282 location_t loc
= c_parser_peek_token (parser
)->location
;
4283 width
= convert_lvalue_to_rvalue (loc
,
4284 (c_parser_expr_no_commas
4288 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4289 postfix_attrs
= c_parser_gnu_attributes (parser
);
4290 d
= grokfield (c_parser_peek_token (parser
)->location
,
4291 declarator
, specs
, width
, &all_prefix_attrs
, expr
);
4292 decl_attributes (&d
, chainon (postfix_attrs
,
4293 all_prefix_attrs
), 0);
4294 DECL_CHAIN (d
) = decls
;
4296 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4297 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
4300 all_prefix_attrs
= prefix_attrs
;
4301 if (c_parser_next_token_is (parser
, CPP_COMMA
))
4302 c_parser_consume_token (parser
);
4303 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
4304 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4306 /* Semicolon consumed in caller. */
4311 c_parser_error (parser
, "expected %<,%>, %<;%> or %<}%>");
4317 c_parser_error (parser
,
4318 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
4319 "%<__attribute__%>");
4326 /* Parse a typeof specifier (a GNU extension adopted in C23).
4329 typeof ( expression )
4330 typeof ( type-name )
4331 typeof_unqual ( expression )
4332 typeof_unqual ( type-name )
4335 static struct c_typespec
4336 c_parser_typeof_specifier (c_parser
*parser
)
4340 struct c_typespec ret
;
4341 ret
.kind
= ctsk_typeof
;
4342 ret
.spec
= error_mark_node
;
4343 ret
.expr
= NULL_TREE
;
4344 ret
.expr_const_operands
= true;
4345 ret
.has_enum_type_specifier
= false;
4346 if (c_parser_next_token_is_keyword (parser
, RID_TYPEOF
))
4349 tree spelling
= c_parser_peek_token (parser
)->value
;
4350 is_std
= (flag_isoc23
4351 && strcmp (IDENTIFIER_POINTER (spelling
), "typeof") == 0);
4355 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TYPEOF_UNQUAL
));
4357 tree spelling
= c_parser_peek_token (parser
)->value
;
4358 is_std
= strcmp (IDENTIFIER_POINTER (spelling
), "typeof_unqual") == 0;
4360 c_parser_consume_token (parser
);
4361 c_inhibit_evaluation_warnings
++;
4363 matching_parens parens
;
4364 if (!parens
.require_open (parser
))
4366 c_inhibit_evaluation_warnings
--;
4370 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
4372 struct c_type_name
*type
= c_parser_type_name (parser
);
4373 c_inhibit_evaluation_warnings
--;
4377 ret
.spec
= groktypename (type
, &ret
.expr
, &ret
.expr_const_operands
);
4378 pop_maybe_used (c_type_variably_modified_p (ret
.spec
));
4384 location_t here
= c_parser_peek_token (parser
)->location
;
4385 struct c_expr expr
= c_parser_expression (parser
);
4386 c_inhibit_evaluation_warnings
--;
4388 if (TREE_CODE (expr
.value
) == COMPONENT_REF
4389 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
4390 error_at (here
, "%<typeof%> applied to a bit-field");
4391 mark_exp_read (expr
.value
);
4392 ret
.spec
= TREE_TYPE (expr
.value
);
4393 was_vm
= c_type_variably_modified_p (ret
.spec
);
4394 /* This is returned with the type so that when the type is
4395 evaluated, this can be evaluated. */
4397 ret
.expr
= c_fully_fold (expr
.value
, false, &ret
.expr_const_operands
);
4398 pop_maybe_used (was_vm
);
4400 parens
.skip_until_found_close (parser
);
4401 if (ret
.spec
!= error_mark_node
)
4403 if (is_unqual
&& TYPE_QUALS (ret
.spec
) != TYPE_UNQUALIFIED
)
4404 ret
.spec
= TYPE_MAIN_VARIANT (ret
.spec
);
4407 /* In ISO C terms, _Noreturn is not part of the type of
4408 expressions such as &abort, but in GCC it is represented
4409 internally as a type qualifier. */
4410 if (TREE_CODE (ret
.spec
) == FUNCTION_TYPE
4411 && TYPE_QUALS (ret
.spec
) != TYPE_UNQUALIFIED
)
4412 ret
.spec
= TYPE_MAIN_VARIANT (ret
.spec
);
4413 else if (FUNCTION_POINTER_TYPE_P (ret
.spec
)
4414 && TYPE_QUALS (TREE_TYPE (ret
.spec
)) != TYPE_UNQUALIFIED
)
4416 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (ret
.spec
)));
4422 /* Parse an alignment-specifier.
4426 alignment-specifier:
4427 _Alignas ( type-name )
4428 _Alignas ( constant-expression )
4432 c_parser_alignas_specifier (c_parser
* parser
)
4434 tree ret
= error_mark_node
;
4435 location_t loc
= c_parser_peek_token (parser
)->location
;
4436 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
));
4437 tree spelling
= c_parser_peek_token (parser
)->value
;
4438 c_parser_consume_token (parser
);
4440 pedwarn_c99 (loc
, OPT_Wpedantic
,
4441 "ISO C99 does not support %qE", spelling
);
4443 pedwarn_c99 (loc
, OPT_Wpedantic
,
4444 "ISO C90 does not support %qE", spelling
);
4445 matching_parens parens
;
4446 if (!parens
.require_open (parser
))
4448 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
4450 struct c_type_name
*type
= c_parser_type_name (parser
);
4452 ret
= c_sizeof_or_alignof_type (loc
, groktypename (type
, NULL
, NULL
),
4456 ret
= convert_lvalue_to_rvalue (loc
,
4457 c_parser_expr_no_commas (parser
, NULL
),
4459 parens
.skip_until_found_close (parser
);
4463 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
4464 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
4465 a typedef name may be redeclared; otherwise it may not. KIND
4466 indicates which kind of declarator is wanted. Returns a valid
4467 declarator except in the case of a syntax error in which case NULL is
4468 returned. *SEEN_ID is set to true if an identifier being declared is
4469 seen; this is used to diagnose bad forms of abstract array declarators
4470 and to determine whether an identifier list is syntactically permitted.
4473 pointer[opt] direct-declarator
4477 ( gnu-attributes[opt] declarator )
4478 direct-declarator array-declarator
4479 direct-declarator ( parameter-type-list )
4480 direct-declarator ( identifier-list[opt] )
4483 * type-qualifier-list[opt]
4484 * type-qualifier-list[opt] pointer
4486 type-qualifier-list:
4489 type-qualifier-list type-qualifier
4490 type-qualifier-list gnu-attributes
4493 [ type-qualifier-list[opt] assignment-expression[opt] ]
4494 [ static type-qualifier-list[opt] assignment-expression ]
4495 [ type-qualifier-list static assignment-expression ]
4496 [ type-qualifier-list[opt] * ]
4498 parameter-type-list:
4500 parameter-list , ...
4503 parameter-declaration
4504 parameter-list , parameter-declaration
4506 parameter-declaration:
4507 declaration-specifiers declarator gnu-attributes[opt]
4508 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
4512 identifier-list , identifier
4514 abstract-declarator:
4516 pointer[opt] direct-abstract-declarator
4518 direct-abstract-declarator:
4519 ( gnu-attributes[opt] abstract-declarator )
4520 direct-abstract-declarator[opt] array-declarator
4521 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
4526 direct-declarator ( parameter-forward-declarations
4527 parameter-type-list[opt] )
4529 direct-abstract-declarator:
4530 direct-abstract-declarator[opt] ( parameter-forward-declarations
4531 parameter-type-list[opt] )
4533 parameter-forward-declarations:
4535 parameter-forward-declarations parameter-list ;
4537 The uses of gnu-attributes shown above are GNU extensions.
4539 Some forms of array declarator are not included in C99 in the
4540 syntax for abstract declarators; these are disallowed elsewhere.
4541 This may be a defect (DR#289).
4543 This function also accepts an omitted abstract declarator as being
4544 an abstract declarator, although not part of the formal syntax. */
4546 struct c_declarator
*
4547 c_parser_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
4550 /* Parse any initial pointer part. */
4551 if (c_parser_next_token_is (parser
, CPP_MULT
))
4553 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4554 struct c_declarator
*inner
;
4555 c_parser_consume_token (parser
);
4556 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4557 false, false, true, false, cla_prefer_id
);
4558 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4562 return make_pointer_declarator (quals_attrs
, inner
);
4564 /* Now we have a direct declarator, direct abstract declarator or
4565 nothing (which counts as a direct abstract declarator here). */
4566 return c_parser_direct_declarator (parser
, type_seen_p
, kind
, seen_id
);
4569 /* Parse a direct declarator or direct abstract declarator; arguments
4570 as c_parser_declarator. */
4572 static struct c_declarator
*
4573 c_parser_direct_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
4576 /* The direct declarator must start with an identifier (possibly
4577 omitted) or a parenthesized declarator (possibly abstract). In
4578 an ordinary declarator, initial parentheses must start a
4579 parenthesized declarator. In an abstract declarator or parameter
4580 declarator, they could start a parenthesized declarator or a
4581 parameter list. To tell which, the open parenthesis and any
4582 following gnu-attributes must be read. If a declaration
4583 specifier or standard attributes follow, then it is a parameter
4584 list; if the specifier is a typedef name, there might be an
4585 ambiguity about redeclaring it, which is resolved in the
4586 direction of treating it as a typedef name. If a close
4587 parenthesis follows, it is also an empty parameter list, as the
4588 syntax does not permit empty abstract declarators. Otherwise, it
4589 is a parenthesized declarator (in which case the analysis may be
4590 repeated inside it, recursively).
4592 ??? There is an ambiguity in a parameter declaration "int
4593 (__attribute__((foo)) x)", where x is not a typedef name: it
4594 could be an abstract declarator for a function, or declare x with
4595 parentheses. The proper resolution of this ambiguity needs
4596 documenting. At present we follow an accident of the old
4597 parser's implementation, whereby the first parameter must have
4598 some declaration specifiers other than just gnu-attributes. Thus as
4599 a parameter declaration it is treated as a parenthesized
4600 parameter named x, and as an abstract declarator it is
4603 ??? Also following the old parser, gnu-attributes inside an empty
4604 parameter list are ignored, making it a list not yielding a
4605 prototype, rather than giving an error or making it have one
4606 parameter with implicit type int.
4608 ??? Also following the old parser, typedef names may be
4609 redeclared in declarators, but not Objective-C class names. */
4611 if (kind
!= C_DTR_ABSTRACT
4612 && c_parser_next_token_is (parser
, CPP_NAME
)
4614 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
4615 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
4616 || c_parser_peek_token (parser
)->id_kind
== C_ID_ID
))
4618 struct c_declarator
*inner
4619 = build_id_declarator (c_parser_peek_token (parser
)->value
);
4621 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
4622 c_parser_consume_token (parser
);
4623 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4624 inner
->u
.id
.attrs
= c_parser_std_attribute_specifier_sequence (parser
);
4625 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4628 if (kind
!= C_DTR_NORMAL
4629 && c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4630 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4632 struct c_declarator
*inner
= build_id_declarator (NULL_TREE
);
4633 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
4634 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4637 /* Either we are at the end of an abstract declarator, or we have
4640 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4643 struct c_declarator
*inner
;
4644 c_parser_consume_token (parser
);
4645 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4647 attrs
= c_parser_gnu_attributes (parser
);
4648 if (kind
!= C_DTR_NORMAL
4649 && (c_parser_next_token_starts_declspecs (parser
)
4651 && (c_parser_nth_token_starts_std_attributes (parser
, 1)
4652 || c_parser_next_token_is (parser
, CPP_ELLIPSIS
)))
4653 || c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
)))
4655 struct c_arg_info
*args
4656 = c_parser_parms_declarator (parser
, kind
== C_DTR_NORMAL
,
4657 attrs
, have_gnu_attrs
);
4662 inner
= build_id_declarator (NULL_TREE
);
4664 && args
->types
!= error_mark_node
4665 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4666 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4669 = c_parser_std_attribute_specifier_sequence (parser
);
4671 inner
= build_attrs_declarator (std_attrs
, inner
);
4673 inner
= build_function_declarator (args
, inner
);
4674 return c_parser_direct_declarator_inner (parser
, *seen_id
,
4678 /* A parenthesized declarator. */
4679 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4680 if (inner
!= NULL
&& attrs
!= NULL
)
4681 inner
= build_attrs_declarator (attrs
, inner
);
4682 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4684 c_parser_consume_token (parser
);
4688 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4692 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4699 if (kind
== C_DTR_NORMAL
)
4701 c_parser_error (parser
, "expected identifier or %<(%>");
4705 return build_id_declarator (NULL_TREE
);
4709 /* Parse part of a direct declarator or direct abstract declarator,
4710 given that some (in INNER) has already been parsed; ID_PRESENT is
4711 true if an identifier is present, false for an abstract
4714 static struct c_declarator
*
4715 c_parser_direct_declarator_inner (c_parser
*parser
, bool id_present
,
4716 struct c_declarator
*inner
)
4718 /* Parse a sequence of array declarators and parameter lists. */
4719 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4720 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4722 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
4723 struct c_declarator
*declarator
;
4724 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4725 struct c_expr dimen
;
4726 dimen
.value
= NULL_TREE
;
4727 dimen
.original_code
= ERROR_MARK
;
4728 dimen
.original_type
= NULL_TREE
;
4729 c_parser_consume_token (parser
);
4730 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4731 false, false, false, false, cla_prefer_id
);
4733 location_t static_loc
= UNKNOWN_LOCATION
;
4734 if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
4736 static_loc
= c_parser_peek_token (parser
)->location
;
4737 c_parser_consume_token (parser
);
4738 if (!quals_attrs
->declspecs_seen_p
)
4739 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4740 false, false, false, false, cla_prefer_id
);
4742 if (!quals_attrs
->declspecs_seen_p
)
4744 /* If "static" is present, there must be an array dimension.
4745 Otherwise, there may be a dimension, "*", or no
4747 const bool static_seen
= (static_loc
!= UNKNOWN_LOCATION
);
4748 bool star_seen
= false;
4749 if (c_parser_next_token_is (parser
, CPP_MULT
)
4750 && c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_SQUARE
)
4753 c_parser_consume_token (parser
);
4755 else if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4756 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4762 error_at (static_loc
,
4763 "%<static%> may not be used with an unspecified "
4764 "variable length array size");
4765 /* Prevent further errors. */
4767 dimen
.value
= error_mark_node
;
4769 else if (!dimen
.value
)
4770 error_at (static_loc
,
4771 "%<static%> may not be used without an array size");
4774 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4775 c_parser_consume_token (parser
);
4778 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4783 dimen
= convert_lvalue_to_rvalue (brace_loc
, dimen
, true, true);
4784 declarator
= build_array_declarator (brace_loc
, dimen
.value
, quals_attrs
,
4785 static_seen
, star_seen
);
4786 if (declarator
== NULL
)
4788 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4791 = c_parser_std_attribute_specifier_sequence (parser
);
4793 inner
= build_attrs_declarator (std_attrs
, inner
);
4795 inner
= set_array_declarator_inner (declarator
, inner
);
4796 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4798 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4801 struct c_arg_info
*args
;
4802 c_parser_consume_token (parser
);
4803 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4805 attrs
= c_parser_gnu_attributes (parser
);
4806 args
= c_parser_parms_declarator (parser
, id_present
, attrs
,
4813 && args
->types
!= error_mark_node
4814 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4815 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4818 = c_parser_std_attribute_specifier_sequence (parser
);
4820 inner
= build_attrs_declarator (std_attrs
, inner
);
4822 inner
= build_function_declarator (args
, inner
);
4823 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4829 /* Parse a parameter list or identifier list, including the closing
4830 parenthesis but not the opening one. ATTRS are the gnu-attributes
4831 at the start of the list. ID_LIST_OK is true if an identifier list
4832 is acceptable; such a list must not have attributes at the start.
4833 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4834 attributes) were present (in which case standard attributes cannot
4837 static struct c_arg_info
*
4838 c_parser_parms_declarator (c_parser
*parser
, bool id_list_ok
, tree attrs
,
4839 bool have_gnu_attrs
)
4842 declare_parm_level ();
4843 /* If the list starts with an identifier, it is an identifier list.
4844 Otherwise, it is either a prototype list or an empty list. */
4847 && c_parser_next_token_is (parser
, CPP_NAME
)
4848 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4850 /* Look ahead to detect typos in type names. */
4851 && c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
4852 && c_parser_peek_2nd_token (parser
)->type
!= CPP_MULT
4853 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
4854 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_SQUARE
4855 && c_parser_peek_2nd_token (parser
)->type
!= CPP_KEYWORD
)
4857 tree list
= NULL_TREE
, *nextp
= &list
;
4858 while (c_parser_next_token_is (parser
, CPP_NAME
)
4859 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
4861 *nextp
= build_tree_list (NULL_TREE
,
4862 c_parser_peek_token (parser
)->value
);
4863 nextp
= & TREE_CHAIN (*nextp
);
4864 c_parser_consume_token (parser
);
4865 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
4867 c_parser_consume_token (parser
);
4868 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4870 c_parser_error (parser
, "expected identifier");
4874 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4876 struct c_arg_info
*ret
= build_arg_info ();
4878 c_parser_consume_token (parser
);
4884 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4892 struct c_arg_info
*ret
4893 = c_parser_parms_list_declarator (parser
, attrs
, NULL
, have_gnu_attrs
);
4899 /* Parse a parameter list (possibly empty), including the closing
4900 parenthesis but not the opening one. ATTRS are the gnu-attributes
4901 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4902 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4903 which means standard attributes cannot start the list. EXPR is
4904 NULL or an expression that needs to be evaluated for the side
4905 effects of array size expressions in the parameters. */
4907 static struct c_arg_info
*
4908 c_parser_parms_list_declarator (c_parser
*parser
, tree attrs
, tree expr
,
4909 bool have_gnu_attrs
)
4911 bool bad_parm
= false;
4913 /* ??? Following the old parser, forward parameter declarations may
4914 use abstract declarators, and if no real parameter declarations
4915 follow the forward declarations then this is not diagnosed. Also
4916 note as above that gnu-attributes are ignored as the only contents of
4917 the parentheses, or as the only contents after forward
4919 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4921 struct c_arg_info
*ret
= build_arg_info ();
4922 c_parser_consume_token (parser
);
4925 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
) && !have_gnu_attrs
)
4927 struct c_arg_info
*ret
= build_arg_info ();
4929 ret
->types
= NULL_TREE
;
4930 pedwarn_c11 (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
4931 "ISO C requires a named argument before %<...%> "
4933 c_parser_consume_token (parser
);
4934 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4936 ret
->no_named_args_stdarg_p
= true;
4937 c_parser_consume_token (parser
);
4942 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4947 /* Nonempty list of parameters, either terminated with semicolon
4948 (forward declarations; recurse) or with close parenthesis (normal
4949 function) or with ", ... )" (variadic function). */
4952 /* Parse a parameter. */
4953 struct c_parm
*parm
= c_parser_parameter_declaration (parser
, attrs
,
4956 have_gnu_attrs
= false;
4960 push_parm_decl (parm
, &expr
);
4961 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4964 c_parser_consume_token (parser
);
4965 mark_forward_parm_decls ();
4966 bool new_have_gnu_attrs
4967 = c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
);
4968 new_attrs
= c_parser_gnu_attributes (parser
);
4969 return c_parser_parms_list_declarator (parser
, new_attrs
, expr
,
4970 new_have_gnu_attrs
);
4972 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4974 c_parser_consume_token (parser
);
4978 return get_parm_info (false, expr
);
4980 if (!c_parser_require (parser
, CPP_COMMA
,
4981 "expected %<;%>, %<,%> or %<)%>",
4982 UNKNOWN_LOCATION
, false))
4984 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4987 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4989 c_parser_consume_token (parser
);
4990 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4992 c_parser_consume_token (parser
);
4996 return get_parm_info (true, expr
);
5000 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5008 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
5009 start of the declaration if it is the first parameter;
5010 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
5013 static struct c_parm
*
5014 c_parser_parameter_declaration (c_parser
*parser
, tree attrs
,
5015 bool have_gnu_attrs
)
5017 struct c_declspecs
*specs
;
5018 struct c_declarator
*declarator
;
5020 tree postfix_attrs
= NULL_TREE
;
5023 /* Accept #pragmas between parameter declarations. */
5024 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
5025 c_parser_pragma (parser
, pragma_param
, NULL
);
5027 if (!c_parser_next_token_starts_declspecs (parser
)
5028 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
5030 c_token
*token
= c_parser_peek_token (parser
);
5033 c_parser_set_source_position_from_token (token
);
5034 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
5036 auto_diagnostic_group d
;
5037 name_hint hint
= lookup_name_fuzzy (token
->value
,
5038 FUZZY_LOOKUP_TYPENAME
,
5040 if (const char *suggestion
= hint
.suggestion ())
5042 gcc_rich_location
richloc (token
->location
);
5043 richloc
.add_fixit_replace (suggestion
);
5045 "unknown type name %qE; did you mean %qs?",
5046 token
->value
, suggestion
);
5049 error_at (token
->location
, "unknown type name %qE", token
->value
);
5050 parser
->error
= true;
5052 /* ??? In some Objective-C cases '...' isn't applicable so there
5053 should be a different message. */
5055 c_parser_error (parser
,
5056 "expected declaration specifiers or %<...%>");
5057 c_parser_skip_to_end_of_parameter (parser
);
5061 location_t start_loc
= c_parser_peek_token (parser
)->location
;
5063 specs
= build_null_declspecs ();
5066 declspecs_add_attrs (input_location
, specs
, attrs
);
5069 c_parser_declspecs (parser
, specs
, true, true, true, true, false,
5070 !have_gnu_attrs
, true, cla_nonabstract_decl
);
5071 finish_declspecs (specs
);
5072 pending_xref_error ();
5073 prefix_attrs
= specs
->attrs
;
5074 specs
->attrs
= NULL_TREE
;
5075 declarator
= c_parser_declarator (parser
,
5076 specs
->typespec_kind
!= ctsk_none
,
5077 C_DTR_PARM
, &dummy
);
5078 if (declarator
== NULL
)
5080 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5083 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
5084 postfix_attrs
= c_parser_gnu_attributes (parser
);
5086 /* Generate a location for the parameter, ranging from the start of the
5087 initial token to the end of the final token.
5089 If we have a identifier, then use it for the caret location, e.g.
5091 extern int callee (int one, int (*two)(int, int), float three);
5092 ~~~~~~^~~~~~~~~~~~~~
5094 otherwise, reuse the start location for the caret location e.g.:
5096 extern int callee (int one, int (*)(int, int), float three);
5099 location_t end_loc
= parser
->last_token_location
;
5101 /* Find any cdk_id declarator; determine if we have an identifier. */
5102 c_declarator
*id_declarator
= declarator
;
5103 while (id_declarator
&& id_declarator
->kind
!= cdk_id
)
5104 id_declarator
= id_declarator
->declarator
;
5105 location_t caret_loc
= (id_declarator
->u
.id
.id
5106 ? id_declarator
->id_loc
5108 location_t param_loc
= make_location (caret_loc
, start_loc
, end_loc
);
5110 return build_c_parm (specs
, chainon (postfix_attrs
, prefix_attrs
),
5111 declarator
, param_loc
);
5114 /* Parse a string literal in an asm expression. It should not be
5115 translated, and wide string literals are an error although
5116 permitted by the syntax. This is a GNU extension.
5123 c_parser_asm_string_literal (c_parser
*parser
)
5126 int save_flag
= warn_overlength_strings
;
5127 warn_overlength_strings
= 0;
5128 str
= c_parser_string_literal (parser
, false, false).value
;
5129 warn_overlength_strings
= save_flag
;
5133 /* Parse a simple asm expression. This is used in restricted
5134 contexts, where a full expression with inputs and outputs does not
5135 make sense. This is a GNU extension.
5138 asm ( asm-string-literal )
5142 c_parser_simple_asm_expr (c_parser
*parser
)
5145 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
5146 c_parser_consume_token (parser
);
5147 matching_parens parens
;
5148 if (!parens
.require_open (parser
))
5150 str
= c_parser_asm_string_literal (parser
);
5151 if (!parens
.require_close (parser
))
5153 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
5160 c_parser_gnu_attribute_any_word (c_parser
*parser
)
5162 tree attr_name
= NULL_TREE
;
5164 if (c_parser_next_token_is (parser
, CPP_KEYWORD
))
5166 /* ??? See comment above about what keywords are accepted here. */
5168 switch (c_parser_peek_token (parser
)->keyword
)
5200 case RID_TRANSACTION_ATOMIC
:
5201 case RID_TRANSACTION_CANCEL
:
5218 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
5219 attr_name
= ridpointers
[(int) c_parser_peek_token (parser
)->keyword
];
5221 else if (c_parser_next_token_is (parser
, CPP_NAME
))
5222 attr_name
= c_parser_peek_token (parser
)->value
;
5227 /* Parse attribute arguments. This is a common form of syntax
5228 covering all currently valid GNU and standard attributes.
5230 gnu-attribute-arguments:
5232 identifier , nonempty-expr-list
5235 where the "identifier" must not be declared as a type. ??? Why not
5236 allow identifiers declared as types to start the arguments? */
5239 c_parser_attribute_arguments (c_parser
*parser
, bool takes_identifier
,
5240 bool require_string
, bool assume_attr
,
5241 bool allow_empty_args
)
5243 vec
<tree
, va_gc
> *expr_list
;
5245 /* Parse the attribute contents. If they start with an
5246 identifier which is followed by a comma or close
5247 parenthesis, then the arguments start with that
5248 identifier; otherwise they are an expression list.
5249 In objective-c the identifier may be a classname. */
5250 if (c_parser_next_token_is (parser
, CPP_NAME
)
5251 && (c_parser_peek_token (parser
)->id_kind
== C_ID_ID
5252 || (c_dialect_objc ()
5253 && c_parser_peek_token (parser
)->id_kind
5255 && ((c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
5256 || (c_parser_peek_2nd_token (parser
)->type
5257 == CPP_CLOSE_PAREN
))
5258 && (takes_identifier
5259 || (c_dialect_objc ()
5261 && c_parser_peek_token (parser
)->id_kind
5262 == C_ID_CLASSNAME
)))
5264 tree arg1
= c_parser_peek_token (parser
)->value
;
5265 c_parser_consume_token (parser
);
5266 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5267 attr_args
= build_tree_list (NULL_TREE
, arg1
);
5271 c_parser_consume_token (parser
);
5272 expr_list
= c_parser_expr_list (parser
, false, true,
5273 NULL
, NULL
, NULL
, NULL
);
5274 tree_list
= build_tree_list_vec (expr_list
);
5275 attr_args
= tree_cons (NULL_TREE
, arg1
, tree_list
);
5276 release_tree_vector (expr_list
);
5281 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5283 if (!allow_empty_args
)
5284 error_at (c_parser_peek_token (parser
)->location
,
5285 "parentheses must be omitted if "
5286 "attribute argument list is empty");
5287 attr_args
= NULL_TREE
;
5289 else if (require_string
)
5291 /* The only valid argument for this attribute is a string
5292 literal. Handle this specially here to avoid accepting
5293 string literals with excess parentheses. */
5294 tree string
= c_parser_string_literal (parser
, false, true).value
;
5295 attr_args
= build_tree_list (NULL_TREE
, string
);
5297 else if (assume_attr
)
5300 = c_parser_conditional_expression (parser
, NULL
, NULL_TREE
).value
;
5301 if (!c_parser_next_token_is (parser
, CPP_COMMA
))
5302 attr_args
= build_tree_list (NULL_TREE
, cond
);
5306 c_parser_consume_token (parser
);
5307 expr_list
= c_parser_expr_list (parser
, false, true,
5308 NULL
, NULL
, NULL
, NULL
);
5309 tree_list
= build_tree_list_vec (expr_list
);
5310 attr_args
= tree_cons (NULL_TREE
, cond
, tree_list
);
5311 release_tree_vector (expr_list
);
5316 expr_list
= c_parser_expr_list (parser
, false, true,
5317 NULL
, NULL
, NULL
, NULL
);
5318 attr_args
= build_tree_list_vec (expr_list
);
5319 release_tree_vector (expr_list
);
5325 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
5329 gnu-attributes gnu-attribute
5332 __attribute__ ( ( gnu-attribute-list ) )
5336 gnu-attribute_list , gnu-attrib
5341 any-word ( gnu-attribute-arguments )
5343 where "any-word" may be any identifier (including one declared as a
5344 type), a reserved word storage class specifier, type specifier or
5345 type qualifier. ??? This still leaves out most reserved keywords
5346 (following the old parser), shouldn't we include them?
5347 When EXPECT_COMMA is true, expect the attribute to be preceded
5348 by a comma and fail if it isn't.
5349 When EMPTY_OK is true, allow and consume any number of consecutive
5350 commas with no attributes in between. */
5353 c_parser_gnu_attribute (c_parser
*parser
, tree attrs
,
5354 bool expect_comma
= false, bool empty_ok
= true)
5356 bool comma_first
= c_parser_next_token_is (parser
, CPP_COMMA
);
5358 && !c_parser_next_token_is (parser
, CPP_NAME
)
5359 && !c_parser_next_token_is (parser
, CPP_KEYWORD
))
5362 while (c_parser_next_token_is (parser
, CPP_COMMA
))
5364 c_parser_consume_token (parser
);
5369 tree attr_name
= c_parser_gnu_attribute_any_word (parser
);
5370 if (attr_name
== NULL_TREE
)
5373 attr_name
= canonicalize_attr_name (attr_name
);
5374 c_parser_consume_token (parser
);
5377 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
5379 if (expect_comma
&& !comma_first
)
5381 /* A comma is missing between the last attribute on the chain
5383 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5385 return error_mark_node
;
5387 attr
= build_tree_list (attr_name
, NULL_TREE
);
5388 /* Add this attribute to the list. */
5389 attrs
= chainon (attrs
, attr
);
5392 c_parser_consume_token (parser
);
5395 = c_parser_attribute_arguments (parser
,
5396 attribute_takes_identifier_p (attr_name
),
5398 is_attribute_p ("assume", attr_name
),
5401 attr
= build_tree_list (attr_name
, attr_args
);
5402 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5403 c_parser_consume_token (parser
);
5406 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5408 return error_mark_node
;
5411 if (expect_comma
&& !comma_first
)
5413 /* A comma is missing between the last attribute on the chain
5415 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5417 return error_mark_node
;
5420 /* Add this attribute to the list. */
5421 attrs
= chainon (attrs
, attr
);
5426 c_parser_gnu_attributes (c_parser
*parser
)
5428 tree attrs
= NULL_TREE
;
5429 while (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
5431 bool save_translate_strings_p
= parser
->translate_strings_p
;
5432 parser
->translate_strings_p
= false;
5433 /* Consume the `__attribute__' keyword. */
5434 c_parser_consume_token (parser
);
5435 /* Look for the two `(' tokens. */
5436 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
5438 parser
->translate_strings_p
= save_translate_strings_p
;
5441 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
5443 parser
->translate_strings_p
= save_translate_strings_p
;
5444 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
5447 /* Parse the attribute list. Require a comma between successive
5448 (possibly empty) attributes. */
5449 for (bool expect_comma
= false; ; expect_comma
= true)
5451 /* Parse a single attribute. */
5452 tree attr
= c_parser_gnu_attribute (parser
, attrs
, expect_comma
);
5453 if (attr
== error_mark_node
)
5460 /* Look for the two `)' tokens. */
5461 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5462 c_parser_consume_token (parser
);
5465 parser
->translate_strings_p
= save_translate_strings_p
;
5466 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5470 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5471 c_parser_consume_token (parser
);
5474 parser
->translate_strings_p
= save_translate_strings_p
;
5475 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5479 parser
->translate_strings_p
= save_translate_strings_p
;
5485 /* Parse an optional balanced token sequence.
5487 balanced-token-sequence:
5489 balanced-token-sequence balanced-token
5492 ( balanced-token-sequence[opt] )
5493 [ balanced-token-sequence[opt] ]
5494 { balanced-token-sequence[opt] }
5495 any token other than ()[]{}
5499 c_parser_balanced_token_sequence (c_parser
*parser
)
5503 c_token
*token
= c_parser_peek_token (parser
);
5504 switch (token
->type
)
5506 case CPP_OPEN_BRACE
:
5508 matching_braces braces
;
5509 braces
.consume_open (parser
);
5510 c_parser_balanced_token_sequence (parser
);
5511 braces
.require_close (parser
);
5515 case CPP_OPEN_PAREN
:
5517 matching_parens parens
;
5518 parens
.consume_open (parser
);
5519 c_parser_balanced_token_sequence (parser
);
5520 parens
.require_close (parser
);
5524 case CPP_OPEN_SQUARE
:
5525 c_parser_consume_token (parser
);
5526 c_parser_balanced_token_sequence (parser
);
5527 c_parser_require (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5530 case CPP_CLOSE_BRACE
:
5531 case CPP_CLOSE_PAREN
:
5532 case CPP_CLOSE_SQUARE
:
5537 c_parser_consume_pragma (parser
);
5538 c_parser_skip_to_pragma_eol (parser
, false);
5542 c_parser_consume_token (parser
);
5548 static bool c_parser_check_balanced_raw_token_sequence (c_parser
*,
5551 /* Parse arguments of omp::directive or omp::decl attribute.
5553 directive-name ,[opt] clause-list[opt]
5555 For directive just remember the tokens in a vector for subsequent
5559 c_parser_omp_directive_args (c_parser
*parser
, tree attribute
, bool decl_p
)
5562 c_token
*first
= c_parser_peek_token (parser
);
5563 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
)
5564 || (c_parser_peek_nth_token_raw (parser
, n
)->type
5565 != CPP_CLOSE_PAREN
))
5567 c_parser_balanced_token_sequence (parser
);
5568 TREE_VALUE (attribute
) = NULL_TREE
;
5573 error_at (first
->location
, "expected OpenMP directive name");
5574 TREE_VALUE (attribute
) = NULL_TREE
;
5577 vec
<c_token
, va_gc
> *v
;
5578 vec_alloc (v
, n
- 1);
5581 c_token
*tok
= c_parser_peek_token (parser
);
5582 v
->quick_push (*tok
);
5583 c_parser_consume_token (parser
);
5585 tree arg
= make_node (C_TOKEN_VEC
);
5586 C_TOKEN_VEC_TOKENS (arg
) = v
;
5588 TREE_PUBLIC (arg
) = 1;
5589 TREE_VALUE (attribute
) = tree_cons (NULL_TREE
, arg
, TREE_VALUE (attribute
));
5592 /* Parse arguments of omp::sequence attribute.
5594 omp::[opt] directive-attr [ , omp::[opt] directive-attr ]... */
5597 c_parser_omp_sequence_args (c_parser
*parser
, tree attribute
)
5601 c_token
*token
= c_parser_peek_token (parser
);
5602 if (token
->type
== CPP_NAME
5603 && strcmp (IDENTIFIER_POINTER (token
->value
), "omp") == 0
5604 && c_parser_peek_2nd_token (parser
)->type
== CPP_SCOPE
)
5606 c_parser_consume_token (parser
);
5607 c_parser_consume_token (parser
);
5608 token
= c_parser_peek_token (parser
);
5610 bool directive
= false;
5612 if (token
->type
!= CPP_NAME
)
5615 p
= IDENTIFIER_POINTER (token
->value
);
5616 if (strcmp (p
, "directive") == 0)
5618 else if (strcmp (p
, "sequence") != 0)
5620 error_at (token
->location
, "expected %<directive%> or %<sequence%>");
5621 unsigned nesting_depth
= 0;
5625 /* Peek at the next token. */
5626 token
= c_parser_peek_token (parser
);
5627 /* If we've reached the token we want, consume it and stop. */
5628 if ((token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_COMMA
)
5631 /* If we've run out of tokens, stop. */
5632 if (token
->type
== CPP_EOF
)
5634 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
5636 if (token
->type
== CPP_OPEN_BRACE
5637 || token
->type
== CPP_OPEN_PAREN
5638 || token
->type
== CPP_OPEN_SQUARE
)
5640 else if (token
->type
== CPP_CLOSE_BRACE
5641 || token
->type
== CPP_CLOSE_PAREN
5642 || token
->type
== CPP_CLOSE_SQUARE
)
5644 if (nesting_depth
-- == 0)
5647 /* Consume this token. */
5648 c_parser_consume_token (parser
);
5650 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5652 c_parser_consume_token (parser
);
5655 c_parser_consume_token (parser
);
5656 matching_parens parens
;
5657 if (parens
.require_open (parser
))
5660 c_parser_omp_directive_args (parser
, attribute
, false);
5662 c_parser_omp_sequence_args (parser
, attribute
);
5663 parens
.skip_until_found_close (parser
);
5664 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5666 c_parser_consume_token (parser
);
5668 else if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5671 c_parser_consume_token (parser
);
5676 /* Parse standard (C23) attributes (including GNU attributes in the
5679 attribute-specifier-sequence:
5680 attribute-specifier-sequence[opt] attribute-specifier
5682 attribute-specifier:
5683 [ [ attribute-list ] ]
5687 attribute-list, attribute[opt]
5690 attribute-token attribute-argument-clause[opt]
5694 attribute-prefixed-token
5699 attribute-prefixed-token:
5700 attribute-prefix :: identifier
5705 attribute-argument-clause:
5706 ( balanced-token-sequence[opt] )
5708 Keywords are accepted as identifiers for this purpose.
5710 As an extension, we permit an attribute-specifier to be:
5712 [ [ __extension__ attribute-list ] ]
5714 Two colons are then accepted as a synonym for ::. No attempt is made
5715 to check whether the colons are immediately adjacent. LOOSE_SCOPE_P
5716 indicates whether this relaxation is in effect. */
5719 c_parser_std_attribute (c_parser
*parser
, bool for_tm
)
5721 c_token
*token
= c_parser_peek_token (parser
);
5722 tree ns
, name
, attribute
;
5724 /* Parse the attribute-token. */
5725 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
5727 c_parser_error (parser
, "expected identifier");
5728 return error_mark_node
;
5730 name
= canonicalize_attr_name (token
->value
);
5731 c_parser_consume_token (parser
);
5732 if (c_parser_next_token_is (parser
, CPP_SCOPE
)
5733 || (c_parser_next_token_is (parser
, CPP_COLON
)
5734 && (c_parser_peek_token (parser
)->flags
& COLON_SCOPE
) != 0
5735 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5738 if (c_parser_next_token_is (parser
, CPP_COLON
))
5739 c_parser_consume_token (parser
);
5740 c_parser_consume_token (parser
);
5741 token
= c_parser_peek_token (parser
);
5742 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
5744 c_parser_error (parser
, "expected identifier");
5745 return error_mark_node
;
5747 name
= canonicalize_attr_name (token
->value
);
5748 c_parser_consume_token (parser
);
5752 attribute
= build_tree_list (build_tree_list (ns
, name
), NULL_TREE
);
5754 /* Parse the arguments, if any. */
5755 const attribute_spec
*as
= lookup_attribute_spec (TREE_PURPOSE (attribute
));
5756 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
5758 if ((flag_openmp
|| flag_openmp_simd
)
5760 && is_attribute_p ("omp", ns
)
5761 && (is_attribute_p ("directive", name
)
5762 || is_attribute_p ("sequence", name
)
5763 || is_attribute_p ("decl", name
)))
5765 error ("%<omp::%E%> attribute requires argument", name
);
5766 return error_mark_node
;
5771 location_t open_loc
= c_parser_peek_token (parser
)->location
;
5772 matching_parens parens
;
5773 parens
.consume_open (parser
);
5774 if ((as
&& as
->max_length
== 0)
5775 /* Special-case the transactional-memory attribute "outer",
5776 which is specially handled but not registered as an
5777 attribute, to avoid allowing arbitrary balanced token
5778 sequences as arguments. */
5779 || is_attribute_p ("outer", name
))
5781 error_at (open_loc
, "%qE attribute does not take any arguments", name
);
5782 parens
.skip_until_found_close (parser
);
5783 return error_mark_node
;
5785 /* If this is a fake attribute created to handle -Wno-attributes,
5786 we must skip parsing the arguments. */
5787 if (as
&& !attribute_ignored_p (as
))
5789 bool takes_identifier
5791 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
5792 && attribute_takes_identifier_p (name
));
5795 && (strcmp (IDENTIFIER_POINTER (name
), "deprecated") == 0
5796 || strcmp (IDENTIFIER_POINTER (name
), "nodiscard") == 0));
5799 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
5800 && strcmp (IDENTIFIER_POINTER (name
), "assume") == 0);
5801 TREE_VALUE (attribute
)
5802 = c_parser_attribute_arguments (parser
, takes_identifier
,
5803 require_string
, assume_attr
, false);
5807 if ((flag_openmp
|| flag_openmp_simd
)
5809 && is_attribute_p ("omp", ns
))
5811 if (is_attribute_p ("directive", name
))
5813 c_parser_omp_directive_args (parser
, attribute
, false);
5814 parens
.skip_until_found_close (parser
);
5817 else if (is_attribute_p ("decl", name
))
5819 TREE_VALUE (TREE_PURPOSE (attribute
))
5820 = get_identifier ("directive");
5821 c_parser_omp_directive_args (parser
, attribute
, true);
5822 parens
.skip_until_found_close (parser
);
5825 else if (is_attribute_p ("sequence", name
))
5827 TREE_VALUE (TREE_PURPOSE (attribute
))
5828 = get_identifier ("directive");
5829 c_parser_omp_sequence_args (parser
, attribute
);
5830 parens
.skip_until_found_close (parser
);
5831 TREE_VALUE (attribute
) = nreverse (TREE_VALUE (attribute
));
5835 c_parser_balanced_token_sequence (parser
);
5837 parens
.require_close (parser
);
5840 if (ns
== NULL_TREE
&& !for_tm
&& !as
)
5842 /* An attribute with standard syntax and no namespace specified
5843 is a constraint violation if it is not one of the known
5844 standard attributes. Diagnose it here with a pedwarn and
5845 then discard it to prevent a duplicate warning later. */
5846 pedwarn (input_location
, OPT_Wattributes
, "%qE attribute ignored",
5848 return error_mark_node
;
5854 c_parser_std_attribute_list (c_parser
*parser
, bool for_tm
)
5856 tree attributes
= NULL_TREE
;
5859 c_token
*token
= c_parser_peek_token (parser
);
5860 if (token
->type
== CPP_CLOSE_SQUARE
)
5862 if (token
->type
== CPP_COMMA
)
5864 c_parser_consume_token (parser
);
5867 tree attribute
= c_parser_std_attribute (parser
, for_tm
);
5868 if (attribute
!= error_mark_node
)
5870 TREE_CHAIN (attribute
) = attributes
;
5871 attributes
= attribute
;
5873 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5880 c_parser_std_attribute_specifier (c_parser
*parser
, bool for_tm
)
5882 location_t loc
= c_parser_peek_token (parser
)->location
;
5883 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
5885 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
5887 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5891 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
5893 auto ext
= disable_extension_diagnostics ();
5894 c_parser_consume_token (parser
);
5895 attributes
= c_parser_std_attribute_list (parser
, for_tm
);
5896 restore_extension_diagnostics (ext
);
5901 pedwarn_c11 (loc
, OPT_Wpedantic
,
5902 "ISO C does not support %<[[]]%> attributes before C23");
5903 attributes
= c_parser_std_attribute_list (parser
, for_tm
);
5905 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5906 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5907 return nreverse (attributes
);
5910 /* Look past an optional balanced token sequence of raw look-ahead
5911 tokens starting with the *Nth token. *N is updated to point to the
5912 following token. Return true if such a sequence was found, false
5913 if the tokens parsed were not balanced. */
5916 c_parser_check_balanced_raw_token_sequence (c_parser
*parser
, unsigned int *n
)
5920 c_token
*token
= c_parser_peek_nth_token_raw (parser
, *n
);
5921 switch (token
->type
)
5923 case CPP_OPEN_BRACE
:
5926 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5928 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5929 if (token
->type
== CPP_CLOSE_BRACE
)
5939 case CPP_OPEN_PAREN
:
5942 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5944 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5945 if (token
->type
== CPP_CLOSE_PAREN
)
5955 case CPP_OPEN_SQUARE
:
5958 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5960 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5961 if (token
->type
== CPP_CLOSE_SQUARE
)
5971 case CPP_CLOSE_BRACE
:
5972 case CPP_CLOSE_PAREN
:
5973 case CPP_CLOSE_SQUARE
:
5984 /* Return whether standard attributes start with the Nth token. */
5987 c_parser_nth_token_starts_std_attributes (c_parser
*parser
, unsigned int n
)
5989 if (!(c_parser_peek_nth_token (parser
, n
)->type
== CPP_OPEN_SQUARE
5990 && c_parser_peek_nth_token (parser
, n
+ 1)->type
== CPP_OPEN_SQUARE
))
5992 /* In C, '[[' must start attributes. In Objective-C, we need to
5993 check whether '[[' is matched by ']]'. */
5994 if (!c_dialect_objc ())
5997 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
5999 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
6000 if (token
->type
!= CPP_CLOSE_SQUARE
)
6002 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
6003 return token
->type
== CPP_CLOSE_SQUARE
;
6006 /* Skip standard attribute tokens starting at Nth token (with 1 as the
6007 next token), return index of the first token after the standard
6008 attribute tokens, or N on failure. */
6011 c_parser_skip_std_attribute_spec_seq (c_parser
*parser
, size_t n
)
6016 if (c_parser_peek_nth_token_raw (parser
, n
)->type
== CPP_OPEN_SQUARE
6017 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
6018 == CPP_OPEN_SQUARE
))
6020 unsigned int m
= n
+ 2;
6021 if (!c_parser_check_balanced_raw_token_sequence (parser
, &m
))
6023 c_token
*token
= c_parser_peek_nth_token_raw (parser
, m
);
6024 if (token
->type
!= CPP_CLOSE_SQUARE
)
6026 token
= c_parser_peek_nth_token_raw (parser
, m
+ 1);
6027 if (token
->type
!= CPP_CLOSE_SQUARE
)
6038 c_parser_std_attribute_specifier_sequence (c_parser
*parser
)
6040 tree attributes
= NULL_TREE
;
6043 tree attrs
= c_parser_std_attribute_specifier (parser
, false);
6044 attributes
= chainon (attributes
, attrs
);
6046 while (c_parser_nth_token_starts_std_attributes (parser
, 1));
6050 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
6051 says whether alignment specifiers are OK (only in cases that might
6052 be the type name of a compound literal).
6055 specifier-qualifier-list abstract-declarator[opt]
6058 struct c_type_name
*
6059 c_parser_type_name (c_parser
*parser
, bool alignas_ok
)
6061 struct c_declspecs
*specs
= build_null_declspecs ();
6062 struct c_declarator
*declarator
;
6063 struct c_type_name
*ret
;
6065 c_parser_declspecs (parser
, specs
, false, true, true, alignas_ok
, false,
6066 false, true, cla_prefer_type
);
6067 if (!specs
->declspecs_seen_p
)
6069 c_parser_error (parser
, "expected specifier-qualifier-list");
6072 if (specs
->type
!= error_mark_node
)
6074 pending_xref_error ();
6075 finish_declspecs (specs
);
6077 declarator
= c_parser_declarator (parser
,
6078 specs
->typespec_kind
!= ctsk_none
,
6079 C_DTR_ABSTRACT
, &dummy
);
6080 if (declarator
== NULL
)
6082 ret
= XOBNEW (&parser_obstack
, struct c_type_name
);
6084 ret
->declarator
= declarator
;
6088 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
6091 assignment-expression
6092 { initializer-list }
6093 { initializer-list , }
6096 designation[opt] initializer
6097 initializer-list , designation[opt] initializer
6104 designator-list designator
6111 [ constant-expression ]
6123 [ constant-expression ... constant-expression ]
6125 Any expression without commas is accepted in the syntax for the
6126 constant-expressions, with non-constant expressions rejected later.
6128 DECL is the declaration we're parsing this initializer for.
6130 This function is only used for top-level initializers; for nested
6131 ones, see c_parser_initval. */
6133 static struct c_expr
6134 c_parser_initializer (c_parser
*parser
, tree decl
)
6136 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6137 return c_parser_braced_init (parser
, NULL_TREE
, false, NULL
, decl
);
6141 location_t loc
= c_parser_peek_token (parser
)->location
;
6142 ret
= c_parser_expr_no_commas (parser
, NULL
);
6143 if (decl
!= error_mark_node
&& C_DECL_VARIABLE_SIZE (decl
))
6146 "variable-sized object may not be initialized except "
6147 "with an empty initializer");
6150 /* This is handled mostly by gimplify.cc, but we have to deal with
6151 not warning about int x = x; as it is a GCC extension to turn off
6152 this warning but only if warn_init_self is zero. */
6154 && !DECL_EXTERNAL (decl
)
6155 && !TREE_STATIC (decl
)
6156 && ret
.value
== decl
6157 && !warning_enabled_at (DECL_SOURCE_LOCATION (decl
), OPT_Winit_self
))
6158 suppress_warning (decl
, OPT_Winit_self
);
6159 if (TREE_CODE (ret
.value
) != STRING_CST
6160 && (TREE_CODE (ret
.value
) != COMPOUND_LITERAL_EXPR
6161 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6163 ret
= convert_lvalue_to_rvalue (loc
, ret
, true, true, true);
6168 /* The location of the last comma within the current initializer list,
6169 or UNKNOWN_LOCATION if not within one. */
6171 location_t last_init_list_comma
;
6173 /* Parse a braced initializer list. TYPE is the type specified for a
6174 compound literal, and NULL_TREE for other initializers and for
6175 nested braced lists. NESTED_P is true for nested braced lists,
6176 false for the list of a compound literal or the list that is the
6177 top-level initializer in a declaration. DECL is the declaration for
6178 the top-level initializer for a declaration, otherwise NULL_TREE. */
6180 static struct c_expr
6181 c_parser_braced_init (c_parser
*parser
, tree type
, bool nested_p
,
6182 struct obstack
*outer_obstack
, tree decl
)
6185 struct obstack braced_init_obstack
;
6186 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
6187 gcc_obstack_init (&braced_init_obstack
);
6188 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
6189 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
6190 c_omp_array_section_p
= false;
6191 matching_braces braces
;
6192 braces
.consume_open (parser
);
6195 finish_implicit_inits (brace_loc
, outer_obstack
);
6196 push_init_level (brace_loc
, 0, &braced_init_obstack
);
6199 really_start_incremental_init (type
);
6200 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
6202 pedwarn_c11 (brace_loc
, OPT_Wpedantic
,
6203 "ISO C forbids empty initializer braces before C23");
6207 if (decl
&& decl
!= error_mark_node
&& C_DECL_VARIABLE_SIZE (decl
))
6208 error_at (brace_loc
,
6209 "variable-sized object may not be initialized except "
6210 "with an empty initializer");
6211 /* Parse a non-empty initializer list, possibly with a trailing
6215 c_parser_initelt (parser
, &braced_init_obstack
);
6218 if (c_parser_next_token_is (parser
, CPP_COMMA
))
6220 last_init_list_comma
= c_parser_peek_token (parser
)->location
;
6221 c_parser_consume_token (parser
);
6225 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
6229 c_omp_array_section_p
= save_c_omp_array_section_p
;
6230 c_token
*next_tok
= c_parser_peek_token (parser
);
6231 if (next_tok
->type
!= CPP_CLOSE_BRACE
)
6234 ret
.original_code
= ERROR_MARK
;
6235 ret
.original_type
= NULL
;
6236 braces
.skip_until_found_close (parser
);
6237 pop_init_level (brace_loc
, 0, &braced_init_obstack
, last_init_list_comma
);
6238 obstack_free (&braced_init_obstack
, NULL
);
6241 location_t close_loc
= next_tok
->location
;
6242 c_parser_consume_token (parser
);
6243 ret
= pop_init_level (brace_loc
, 0, &braced_init_obstack
, close_loc
);
6244 obstack_free (&braced_init_obstack
, NULL
);
6245 set_c_expr_source_range (&ret
, brace_loc
, close_loc
);
6249 /* Parse a nested initializer, including designators. */
6252 c_parser_initelt (c_parser
*parser
, struct obstack
* braced_init_obstack
)
6254 /* Parse any designator or designator list. A single array
6255 designator may have the subsequent "=" omitted in GNU C, but a
6256 longer list or a structure member designator may not. */
6257 if (c_parser_next_token_is (parser
, CPP_NAME
)
6258 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
6260 /* Old-style structure member designator. */
6261 set_init_label (c_parser_peek_token (parser
)->location
,
6262 c_parser_peek_token (parser
)->value
,
6263 c_parser_peek_token (parser
)->location
,
6264 braced_init_obstack
);
6265 /* Use the colon as the error location. */
6266 pedwarn (c_parser_peek_2nd_token (parser
)->location
, OPT_Wpedantic
,
6267 "obsolete use of designated initializer with %<:%>");
6268 c_parser_consume_token (parser
);
6269 c_parser_consume_token (parser
);
6273 /* des_seen is 0 if there have been no designators, 1 if there
6274 has been a single array designator and 2 otherwise. */
6276 /* Location of a designator. */
6277 location_t des_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
6278 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
6279 || c_parser_next_token_is (parser
, CPP_DOT
))
6281 int des_prev
= des_seen
;
6283 des_loc
= c_parser_peek_token (parser
)->location
;
6286 if (c_parser_next_token_is (parser
, CPP_DOT
))
6289 c_parser_consume_token (parser
);
6290 if (c_parser_next_token_is (parser
, CPP_NAME
))
6292 set_init_label (des_loc
, c_parser_peek_token (parser
)->value
,
6293 c_parser_peek_token (parser
)->location
,
6294 braced_init_obstack
);
6295 c_parser_consume_token (parser
);
6301 init
.original_code
= ERROR_MARK
;
6302 init
.original_type
= NULL
;
6303 c_parser_error (parser
, "expected identifier");
6304 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
6305 process_init_element (input_location
, init
, false,
6306 braced_init_obstack
);
6312 struct c_expr first_expr
;
6314 location_t ellipsis_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
6315 location_t array_index_loc
= UNKNOWN_LOCATION
;
6316 /* ??? Following the old parser, [ objc-receiver
6317 objc-message-args ] is accepted as an initializer,
6318 being distinguished from a designator by what follows
6319 the first assignment expression inside the square
6320 brackets, but after a first array designator a
6321 subsequent square bracket is for Objective-C taken to
6322 start an expression, using the obsolete form of
6323 designated initializer without '=', rather than
6324 possibly being a second level of designation: in LALR
6325 terms, the '[' is shifted rather than reducing
6326 designator to designator-list. */
6327 if (des_prev
== 1 && c_dialect_objc ())
6329 des_seen
= des_prev
;
6332 if (des_prev
== 0 && c_dialect_objc ())
6334 /* This might be an array designator or an
6335 Objective-C message expression. If the former,
6336 continue parsing here; if the latter, parse the
6337 remainder of the initializer given the starting
6338 primary-expression. ??? It might make sense to
6339 distinguish when des_prev == 1 as well; see
6340 previous comment. */
6342 struct c_expr mexpr
;
6343 c_parser_consume_token (parser
);
6344 if (c_parser_peek_token (parser
)->type
== CPP_NAME
6345 && ((c_parser_peek_token (parser
)->id_kind
6347 || (c_parser_peek_token (parser
)->id_kind
6348 == C_ID_CLASSNAME
)))
6350 /* Type name receiver. */
6351 tree id
= c_parser_peek_token (parser
)->value
;
6352 c_parser_consume_token (parser
);
6353 rec
= objc_get_class_reference (id
);
6354 goto parse_message_args
;
6356 array_index_loc
= c_parser_peek_token (parser
)->location
;
6357 first_expr
= c_parser_expr_no_commas (parser
, NULL
);
6358 mark_exp_read (first_expr
.value
);
6359 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
)
6360 || c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
6361 goto array_desig_after_first
;
6362 first
= first_expr
.value
;
6363 /* Expression receiver. So far only one part
6364 without commas has been parsed; there might be
6365 more of the expression. */
6367 while (c_parser_next_token_is (parser
, CPP_COMMA
))
6370 location_t comma_loc
, exp_loc
;
6371 comma_loc
= c_parser_peek_token (parser
)->location
;
6372 c_parser_consume_token (parser
);
6373 exp_loc
= c_parser_peek_token (parser
)->location
;
6374 next
= c_parser_expr_no_commas (parser
, NULL
);
6375 next
= convert_lvalue_to_rvalue (exp_loc
, next
,
6377 rec
= build_compound_expr (comma_loc
, rec
, next
.value
);
6380 /* Now parse the objc-message-args. */
6381 args
= c_parser_objc_message_args (parser
);
6382 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
6385 = objc_build_message_expr (rec
, args
);
6386 mexpr
.original_code
= ERROR_MARK
;
6387 mexpr
.original_type
= NULL
;
6388 mexpr
.m_decimal
= 0;
6389 /* Now parse and process the remainder of the
6390 initializer, starting with this message
6391 expression as a primary-expression. */
6392 c_parser_initval (parser
, &mexpr
, braced_init_obstack
);
6395 c_parser_consume_token (parser
);
6396 array_index_loc
= c_parser_peek_token (parser
)->location
;
6397 first_expr
= c_parser_expr_no_commas (parser
, NULL
);
6398 mark_exp_read (first_expr
.value
);
6399 array_desig_after_first
:
6400 first_expr
= convert_lvalue_to_rvalue (array_index_loc
,
6403 first
= first_expr
.value
;
6404 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
6406 ellipsis_loc
= c_parser_peek_token (parser
)->location
;
6407 c_parser_consume_token (parser
);
6408 second
= convert_lvalue_to_rvalue (ellipsis_loc
,
6409 (c_parser_expr_no_commas
6412 mark_exp_read (second
);
6416 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
6418 c_parser_consume_token (parser
);
6419 set_init_index (array_index_loc
, first
, second
,
6420 braced_init_obstack
);
6422 pedwarn (ellipsis_loc
, OPT_Wpedantic
,
6423 "ISO C forbids specifying range of elements to initialize");
6426 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
6432 if (c_parser_next_token_is (parser
, CPP_EQ
))
6434 pedwarn_c90 (des_loc
, OPT_Wpedantic
,
6435 "ISO C90 forbids specifying subobject "
6437 c_parser_consume_token (parser
);
6442 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
6443 "obsolete use of designated initializer without %<=%>");
6448 init
.original_code
= ERROR_MARK
;
6449 init
.original_type
= NULL
;
6450 c_parser_error (parser
, "expected %<=%>");
6451 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
6452 process_init_element (input_location
, init
, false,
6453 braced_init_obstack
);
6459 c_parser_initval (parser
, NULL
, braced_init_obstack
);
6462 /* Parse a nested initializer; as c_parser_initializer but parses
6463 initializers within braced lists, after any designators have been
6464 applied. If AFTER is not NULL then it is an Objective-C message
6465 expression which is the primary-expression starting the
6469 c_parser_initval (c_parser
*parser
, struct c_expr
*after
,
6470 struct obstack
* braced_init_obstack
)
6473 gcc_assert (!after
|| c_dialect_objc ());
6474 location_t loc
= c_parser_peek_token (parser
)->location
;
6476 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
) && !after
)
6477 init
= c_parser_braced_init (parser
, NULL_TREE
, true,
6478 braced_init_obstack
, NULL_TREE
);
6481 init
= c_parser_expr_no_commas (parser
, after
);
6482 if (init
.value
!= NULL_TREE
6483 && TREE_CODE (init
.value
) != STRING_CST
6484 && (TREE_CODE (init
.value
) != COMPOUND_LITERAL_EXPR
6485 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6487 init
= convert_lvalue_to_rvalue (loc
, init
, true, true, true);
6489 process_init_element (loc
, init
, false, braced_init_obstack
);
6492 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
6493 C99 6.8.2, C11 6.8.2, C23 6.8.2).
6496 { block-item-list[opt] }
6497 { label-declarations block-item-list }
6501 block-item-list block-item
6514 { label-declarations block-item-list }
6517 __extension__ nested-declaration
6518 nested-function-definition
6522 label-declarations label-declaration
6525 __label__ identifier-list ;
6527 Allowing the mixing of declarations and code is new in C99. The
6528 GNU syntax also permits (not shown above) labels at the end of
6529 compound statements, which yield an error. We don't allow labels
6530 on declarations; this might seem like a natural extension, but
6531 there would be a conflict between gnu-attributes on the label and
6532 prefix gnu-attributes on the declaration. ??? The syntax follows the
6533 old parser in requiring something after label declarations.
6534 Although they are erroneous if the labels declared aren't defined,
6535 is it useful for the syntax to be this way?
6556 cancellation-point-directive */
6559 c_parser_compound_statement (c_parser
*parser
, location_t
*endlocp
)
6562 location_t brace_loc
;
6563 brace_loc
= c_parser_peek_token (parser
)->location
;
6564 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
6566 /* Ensure a scope is entered and left anyway to avoid confusion
6567 if we have just prepared to enter a function body. */
6568 stmt
= c_begin_compound_stmt (true);
6569 c_end_compound_stmt (brace_loc
, stmt
, true);
6570 return error_mark_node
;
6572 stmt
= c_begin_compound_stmt (true);
6573 location_t end_loc
= c_parser_compound_statement_nostart (parser
);
6577 return c_end_compound_stmt (brace_loc
, stmt
, true);
6580 /* Diagnose errors related to imperfectly nested loops in an OMP
6581 loop construct. This function is called when such code is seen.
6582 Only issue one such diagnostic no matter how much invalid
6583 intervening code there is in the loop.
6584 FIXME: maybe the location associated with the diagnostic should
6585 be the current parser token instead of the location of the outer loop
6589 check_omp_intervening_code (c_parser
*parser
)
6591 struct omp_for_parse_data
*omp_for_parse_state
= parser
->omp_for_parse_state
;
6592 gcc_assert (omp_for_parse_state
);
6594 if (!omp_for_parse_state
->in_intervening_code
)
6596 omp_for_parse_state
->saw_intervening_code
= true;
6598 /* Only diagnose errors related to perfect nesting once. */
6599 if (!omp_for_parse_state
->perfect_nesting_fail
)
6602 /* OpenACC does not (yet) permit intervening code, in
6603 addition to situations forbidden by the OpenMP spec. */
6604 if (omp_for_parse_state
->code
== OACC_LOOP
)
6606 error_at (omp_for_parse_state
->for_loc
,
6607 "inner loops must be perfectly nested in "
6608 "%<#pragma acc loop%>");
6609 omp_for_parse_state
->perfect_nesting_fail
= true;
6611 else if (omp_for_parse_state
->ordered
)
6613 error_at (omp_for_parse_state
->for_loc
,
6614 "inner loops must be perfectly nested with "
6615 "%<ordered%> clause");
6616 omp_for_parse_state
->perfect_nesting_fail
= true;
6618 else if (omp_for_parse_state
->inscan
)
6620 error_at (omp_for_parse_state
->for_loc
,
6621 "inner loops must be perfectly nested with "
6622 "%<reduction%> %<inscan%> clause");
6623 omp_for_parse_state
->perfect_nesting_fail
= true;
6625 else if (omp_for_parse_state
->code
== OMP_TILE
)
6627 error_at (omp_for_parse_state
->for_loc
,
6628 "inner loops must be perfectly nested in "
6629 "%<pragma omp tile%>");
6630 omp_for_parse_state
->perfect_nesting_fail
= true;
6632 if (omp_for_parse_state
->perfect_nesting_fail
)
6633 omp_for_parse_state
->fail
= true;
6637 /* Helper function for below: wrap an OMP_STRUCTURED_BLOCK around SL
6638 and add the statement to the current list. If SL is an empty statement
6639 list, do nothing. */
6641 add_structured_block_stmt (tree sl
)
6643 if (TREE_CODE (sl
) != STATEMENT_LIST
6644 || !tsi_end_p (tsi_start (sl
)))
6645 add_stmt (build1 (OMP_STRUCTURED_BLOCK
, void_type_node
, sl
));
6648 struct c_omp_attribute_data
6650 vec
<c_token
, va_gc
> *tokens
;
6651 const c_omp_directive
*dir
;
6652 c_omp_directive_kind kind
;
6655 /* Handle omp::directive and omp::sequence attributes in ATTRS
6656 (if any) at the start of a statement or in attribute-declaration. */
6659 c_parser_handle_statement_omp_attributes (c_parser
*parser
, tree
&attrs
,
6660 bool *have_std_attrs
)
6662 if (!flag_openmp
&& !flag_openmp_simd
)
6665 auto_vec
<c_omp_attribute_data
, 16> vd
;
6669 for (tree
*pa
= &attrs
; *pa
; )
6670 if (is_attribute_namespace_p ("omp", *pa
)
6671 && is_attribute_p ("directive", get_attribute_name (*pa
)))
6674 for (tree a
= TREE_VALUE (*pa
); a
; a
= TREE_CHAIN (a
))
6676 tree d
= TREE_VALUE (a
);
6677 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
6678 vec
<c_token
, va_gc
> *toks
= C_TOKEN_VEC_TOKENS (d
);
6679 c_token
*first
= toks
->address ();
6680 c_token
*last
= first
+ toks
->length ();
6681 if (parser
->omp_attrs_forbidden_p
)
6683 error_at (first
->location
,
6684 "mixing OpenMP directives with attribute and pragma "
6685 "syntax on the same statement");
6686 parser
->omp_attrs_forbidden_p
= false;
6689 else if (TREE_PUBLIC (d
))
6691 error_at (first
->location
,
6692 "OpenMP %<omp::decl%> attribute on a statement");
6695 const char *directive
[3] = {};
6696 for (int i
= 0; i
< 3; i
++)
6698 tree id
= NULL_TREE
;
6699 if (first
+ i
== last
)
6701 if (first
[i
].type
== CPP_NAME
)
6702 id
= first
[i
].value
;
6703 else if (first
[i
].type
== CPP_KEYWORD
)
6704 id
= ridpointers
[(int) first
[i
].keyword
];
6707 directive
[i
] = IDENTIFIER_POINTER (id
);
6709 const c_omp_directive
*dir
= NULL
;
6711 dir
= c_omp_categorize_directive (directive
[0], directive
[1],
6715 error_at (first
->location
,
6716 "unknown OpenMP directive name in %qs attribute "
6718 TREE_PUBLIC (d
) ? "omp::decl" : "omp::directive");
6721 c_omp_directive_kind kind
= dir
->kind
;
6722 if (dir
->id
== PRAGMA_OMP_ORDERED
)
6724 /* ordered is C_OMP_DIR_CONSTRUCT only if it doesn't contain
6725 depend/doacross clause. */
6727 && (strcmp (directive
[1], "depend") == 0
6728 || strcmp (directive
[1], "doacross") == 0))
6729 kind
= C_OMP_DIR_STANDALONE
;
6730 else if (first
+ 2 < last
6731 && first
[1].type
== CPP_COMMA
6732 && first
[2].type
== CPP_NAME
6733 && (strcmp (IDENTIFIER_POINTER (first
[2].value
),
6735 || strcmp (IDENTIFIER_POINTER (first
[2].value
),
6737 kind
= C_OMP_DIR_STANDALONE
;
6739 else if (dir
->id
== PRAGMA_OMP_ERROR
)
6741 /* error with at(execution) clause is C_OMP_DIR_STANDALONE. */
6742 int paren_depth
= 0;
6743 for (int i
= 1; first
+ i
< last
; i
++)
6744 if (first
[i
].type
== CPP_OPEN_PAREN
)
6746 else if (first
[i
].type
== CPP_CLOSE_PAREN
)
6748 else if (paren_depth
== 0
6749 && first
+ i
+ 2 < last
6750 && first
[i
].type
== CPP_NAME
6751 && first
[i
+ 1].type
== CPP_OPEN_PAREN
6752 && first
[i
+ 2].type
== CPP_NAME
6753 && !strcmp (IDENTIFIER_POINTER (first
[i
].value
),
6755 && !strcmp (IDENTIFIER_POINTER (first
[i
6759 kind
= C_OMP_DIR_STANDALONE
;
6763 c_omp_attribute_data v
= { toks
, dir
, kind
};
6765 if (flag_openmp
|| dir
->simd
)
6766 tokens
+= (last
- first
) + 1;
6768 c_omp_attribute_data v
= {};
6770 *pa
= TREE_CHAIN (*pa
);
6773 pa
= &TREE_CHAIN (*pa
);
6778 if (have_std_attrs
&& attrs
== NULL
)
6779 *have_std_attrs
= false;
6784 c_omp_attribute_data
*v
;
6785 c_omp_attribute_data
*construct_seen
= nullptr;
6786 c_omp_attribute_data
*standalone_seen
= nullptr;
6787 c_omp_attribute_data
*prev_standalone_seen
= nullptr;
6788 FOR_EACH_VEC_ELT (vd
, i
, v
)
6791 if (v
->kind
== C_OMP_DIR_CONSTRUCT
&& !construct_seen
)
6793 else if (v
->kind
== C_OMP_DIR_STANDALONE
&& !standalone_seen
)
6794 standalone_seen
= v
;
6798 if (standalone_seen
&& !prev_standalone_seen
)
6800 prev_standalone_seen
= standalone_seen
;
6801 standalone_seen
= nullptr;
6805 if (cnt
> 1 && construct_seen
)
6807 error_at ((*construct_seen
->tokens
)[0].location
,
6808 "OpenMP construct among %<omp::directive%> attributes"
6809 " requires all %<omp::directive%> attributes on the"
6810 " same statement to be in the same %<omp::sequence%>");
6813 if (cnt
> 1 && standalone_seen
&& prev_standalone_seen
)
6815 error_at ((*standalone_seen
->tokens
)[0].location
,
6816 "multiple OpenMP standalone directives among"
6817 " %<omp::directive%> attributes must be all within the"
6818 " same %<omp::sequence%>");
6822 if (prev_standalone_seen
)
6823 standalone_seen
= prev_standalone_seen
;
6825 && !c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6827 error_at (standalone_seen
->tokens
->address ()->location
,
6828 "standalone OpenMP directives in %<omp::directive%> attribute"
6829 " can only appear on an empty statement");
6832 if (cnt
&& c_parser_next_token_is (parser
, CPP_PRAGMA
))
6834 c_token
*token
= c_parser_peek_token (parser
);
6835 enum pragma_kind kind
= token
->pragma_kind
;
6836 if (kind
>= PRAGMA_OMP__START_
&& kind
<= PRAGMA_OMP__LAST_
)
6838 error_at (token
->location
,
6839 "mixing OpenMP directives with attribute and pragma "
6840 "syntax on the same statement");
6848 unsigned int tokens_avail
= parser
->tokens_avail
;
6849 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
6852 vec
<c_token
, va_gc
> *toks
= NULL
;
6853 vec_safe_reserve (toks
, tokens
, true);
6854 FOR_EACH_VEC_ELT (vd
, i
, v
)
6858 if (!flag_openmp
&& !v
->dir
->simd
)
6860 c_token
*first
= v
->tokens
->address ();
6861 c_token
*last
= first
+ v
->tokens
->length ();
6863 tok
.type
= CPP_PRAGMA
;
6864 tok
.keyword
= RID_MAX
;
6865 tok
.pragma_kind
= pragma_kind (v
->dir
->id
);
6866 tok
.location
= first
->location
;
6867 toks
->quick_push (tok
);
6868 while (++first
< last
)
6869 toks
->quick_push (*first
);
6871 tok
.type
= CPP_PRAGMA_EOL
;
6872 tok
.keyword
= RID_MAX
;
6873 tok
.location
= last
[-1].location
;
6874 toks
->quick_push (tok
);
6879 tok
.keyword
= RID_MAX
;
6880 tok
.location
= toks
->last ().location
;
6881 tok
.flags
= tokens_avail
;
6882 toks
->quick_push (tok
);
6884 parser
->tokens
= toks
->address ();
6885 parser
->tokens_avail
= tokens
;
6886 parser
->in_omp_attribute_pragma
= toks
;
6890 /* Handle omp::directive and omp::sequence attributes in ATTRS
6891 (if any) at the start or after declaration-id of a declaration. */
6894 c_parser_handle_directive_omp_attributes (tree
&attrs
,
6895 vec
<c_token
> *&pragma_clauses
,
6896 vec
<c_token
> *attr_clauses
)
6898 if (!flag_openmp
&& !flag_openmp_simd
)
6901 for (tree
*pa
= &attrs
; *pa
; )
6902 if (is_attribute_namespace_p ("omp", *pa
)
6903 && is_attribute_p ("directive", get_attribute_name (*pa
)))
6906 for (tree
*pa2
= &TREE_VALUE (*pa
); *pa2
; )
6909 tree d
= TREE_VALUE (a
);
6910 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
6911 vec
<c_token
, va_gc
> *toks
= C_TOKEN_VEC_TOKENS (d
);
6912 c_token
*first
= toks
->address ();
6913 c_token
*last
= first
+ toks
->length ();
6914 const char *directive
[3] = {};
6915 for (int i
= 0; i
< 3; i
++)
6917 tree id
= NULL_TREE
;
6918 if (first
+ i
== last
)
6920 if (first
[i
].type
== CPP_NAME
)
6921 id
= first
[i
].value
;
6922 else if (first
[i
].type
== CPP_KEYWORD
)
6923 id
= ridpointers
[(int) first
[i
].keyword
];
6926 directive
[i
] = IDENTIFIER_POINTER (id
);
6928 const c_omp_directive
*dir
= NULL
;
6930 dir
= c_omp_categorize_directive (directive
[0], directive
[1],
6934 error_at (first
->location
,
6935 "unknown OpenMP directive name in "
6936 "%qs attribute argument",
6937 TREE_PUBLIC (d
) ? "omp::decl" : "omp::directive");
6938 *pa2
= TREE_CHAIN (a
);
6940 else if (dir
->id
== PRAGMA_OMP_DECLARE
6941 && (strcmp (directive
[1], "simd") == 0
6942 || strcmp (directive
[1], "variant") == 0))
6946 error_at (first
->location
,
6947 "mixing OpenMP directives with attribute and "
6948 "pragma syntax on the same declaration");
6949 for (pa
= &attrs
; *pa
; )
6950 if (is_attribute_namespace_p ("omp", *pa
)
6951 && is_attribute_p ("directive",
6952 get_attribute_name (*pa
)))
6953 *pa
= TREE_CHAIN (*pa
);
6955 pa
= &TREE_CHAIN (*pa
);
6959 attr_clauses
->reserve (attr_clauses
->length ()
6960 + toks
->length () + 2);
6961 for (++first
; first
< last
; ++first
)
6962 attr_clauses
->quick_push (*first
);
6964 tok
.type
= CPP_PRAGMA_EOL
;
6965 tok
.keyword
= RID_MAX
;
6966 tok
.location
= last
[-1].location
;
6967 attr_clauses
->quick_push (tok
);
6968 *pa2
= TREE_CHAIN (a
);
6971 pa2
= &TREE_CHAIN (a
);
6973 if (cnt
&& TREE_VALUE (*pa
) == NULL_TREE
)
6974 *pa
= TREE_CHAIN (*pa
);
6976 pa
= &TREE_CHAIN (*pa
);
6979 pa
= &TREE_CHAIN (*pa
);
6980 if (attr_clauses
->length ())
6984 tok
.keyword
= RID_MAX
;
6985 tok
.location
= attr_clauses
->last ().location
;
6986 attr_clauses
->quick_push (tok
);
6987 attr_clauses
->quick_push (tok
);
6988 pragma_clauses
= attr_clauses
;
6992 /* Check if STD_ATTR contains a musttail attribute and remove if it
6993 precedes a return. PARSER is the parser and ATTR is the output
6997 c_parser_handle_musttail (c_parser
*parser
, tree std_attrs
, attr_state
&attr
)
6999 if (c_parser_next_token_is_keyword (parser
, RID_RETURN
))
7001 if (lookup_attribute ("gnu", "musttail", std_attrs
))
7003 std_attrs
= remove_attribute ("gnu", "musttail", std_attrs
);
7004 attr
.musttail_p
= true;
7006 if (lookup_attribute ("clang", "musttail", std_attrs
))
7008 std_attrs
= remove_attribute ("clang", "musttail", std_attrs
);
7009 attr
.musttail_p
= true;
7015 /* Parse a compound statement except for the opening brace. This is
7016 used for parsing both compound statements and statement expressions
7017 (which follow different paths to handling the opening). */
7020 c_parser_compound_statement_nostart (c_parser
*parser
)
7022 bool last_stmt
= false;
7023 bool last_label
= false;
7024 bool save_valid_for_pragma
= valid_location_for_stdc_pragma_p ();
7025 location_t label_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
7026 struct omp_for_parse_data
*omp_for_parse_state
7027 = parser
->omp_for_parse_state
;
7028 bool in_omp_loop_block
7029 = omp_for_parse_state
? omp_for_parse_state
->want_nested_loop
: false;
7030 tree sl
= NULL_TREE
;
7033 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
7035 location_t endloc
= c_parser_peek_token (parser
)->location
;
7036 add_debug_begin_stmt (endloc
);
7037 c_parser_consume_token (parser
);
7041 /* If we're parsing a {} sequence in an OMP_FOR body, start a
7042 statement list for intervening code. */
7043 if (in_omp_loop_block
)
7044 sl
= push_stmt_list ();
7046 mark_valid_location_for_stdc_pragma (true);
7047 if (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
7049 /* Read zero or more forward-declarations for labels that nested
7050 functions can jump to. */
7051 mark_valid_location_for_stdc_pragma (false);
7052 if (in_omp_loop_block
)
7053 check_omp_intervening_code (parser
);
7054 while (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
7056 label_loc
= c_parser_peek_token (parser
)->location
;
7057 c_parser_consume_token (parser
);
7058 /* Any identifiers, including those declared as type names,
7063 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
7065 c_parser_error (parser
, "expected identifier");
7069 = declare_label (c_parser_peek_token (parser
)->value
);
7070 C_DECLARED_LABEL_FLAG (label
) = 1;
7071 add_stmt (build_stmt (label_loc
, DECL_EXPR
, label
));
7072 c_parser_consume_token (parser
);
7073 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7074 c_parser_consume_token (parser
);
7078 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
7080 pedwarn (label_loc
, OPT_Wpedantic
, "ISO C forbids label declarations");
7082 /* We must now have at least one statement, label or declaration. */
7083 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
7085 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7086 c_parser_error (parser
, "expected declaration or statement");
7087 location_t endloc
= c_parser_peek_token (parser
)->location
;
7088 c_parser_consume_token (parser
);
7091 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_BRACE
))
7093 location_t loc
= c_parser_peek_token (parser
)->location
;
7094 loc
= expansion_point_location_if_in_system_header (loc
);
7096 bool want_nested_loop
= (omp_for_parse_state
7097 ? omp_for_parse_state
->want_nested_loop
7100 /* First take care of special cases for OpenMP "canonical loop
7101 nest form", that do not allow standard attributes, labels, or
7102 __extension__ before the nested statement. */
7103 if (in_omp_loop_block
&& !last_label
)
7105 tree_code code
= omp_for_parse_state
->code
;
7106 if (want_nested_loop
7107 && c_parser_omp_next_tokens_can_be_canon_loop (parser
, code
,
7110 /* Found the next nested loop. If there were intervening
7111 code statements collected before now, wrap them in an
7112 OMP_STRUCTURED_BLOCK node, and start a new structured
7113 block to hold statements that may come after the FOR. */
7115 add_structured_block_stmt (pop_stmt_list (sl
));
7116 omp_for_parse_state
->depth
++;
7117 add_stmt (c_parser_omp_loop_nest (parser
, NULL
));
7118 omp_for_parse_state
->depth
--;
7119 sl
= push_stmt_list ();
7120 parser
->error
= false;
7123 else if (want_nested_loop
7124 && c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7126 /* If this nested compound statement contains the nested loop,
7127 we need to separate the other statements in the current
7128 statement into separate blocks of intervening code. If
7129 there's no nested loop, it's all part of the same
7130 chunk of intervening code. */
7131 tree pre_sl
= pop_stmt_list (sl
);
7132 tree nested_sl
= push_stmt_list ();
7133 mark_valid_location_for_stdc_pragma (false);
7134 c_parser_statement_after_labels (parser
, NULL
);
7135 nested_sl
= pop_stmt_list (nested_sl
);
7136 if (omp_for_parse_state
->want_nested_loop
)
7138 /* This block didn't contain a loop-nest, so it's
7139 all part of the same chunk of intervening code. */
7140 check_omp_intervening_code (parser
);
7141 sl
= push_stmt_list ();
7143 add_stmt (nested_sl
);
7147 /* It contains the nested loop. */
7148 add_structured_block_stmt (pre_sl
);
7149 add_stmt (nested_sl
);
7150 sl
= push_stmt_list ();
7152 parser
->error
= false;
7155 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7157 /* Prior to implementing the OpenMP 5.1 syntax for canonical
7158 loop form, GCC used to accept an empty statements that
7159 would now be flagged as intervening code. Continue to
7160 do that, as an extension. */
7161 /* FIXME: Maybe issue a warning or something here? */
7162 c_parser_consume_token (parser
);
7167 /* Standard attributes may start a label, statement or declaration. */
7169 = c_parser_nth_token_starts_std_attributes (parser
, 1);
7170 tree std_attrs
= NULL_TREE
;
7173 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
7174 std_attrs
= c_parser_handle_musttail (parser
, std_attrs
, a
);
7176 if (c_parser_next_token_is_keyword (parser
, RID_CASE
)
7177 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
7178 || (c_parser_next_token_is (parser
, CPP_NAME
)
7179 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
7181 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
7182 label_loc
= c_parser_peek_2nd_token (parser
)->location
;
7184 label_loc
= c_parser_peek_token (parser
)->location
;
7187 mark_valid_location_for_stdc_pragma (false);
7188 if (in_omp_loop_block
)
7189 check_omp_intervening_code (parser
);
7190 c_parser_label (parser
, std_attrs
);
7192 else if (c_parser_next_tokens_start_declaration (parser
)
7194 && !c_parser_handle_statement_omp_attributes
7195 (parser
, std_attrs
, &have_std_attrs
)
7196 && c_parser_next_token_is (parser
, CPP_SEMICOLON
)
7197 && (have_std_attrs
= true)))
7200 pedwarn_c11 (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
7201 "a label can only be part of a statement and "
7202 "a declaration is not a statement");
7203 /* It's unlikely we'll see a nested loop in a declaration in
7204 intervening code in an OMP loop, but disallow it anyway. */
7205 if (in_omp_loop_block
)
7207 check_omp_intervening_code (parser
);
7208 omp_for_parse_state
->want_nested_loop
= false;
7210 mark_valid_location_for_stdc_pragma (false);
7211 bool fallthru_attr_p
= false;
7212 c_parser_declaration_or_fndef (parser
, true, !have_std_attrs
,
7213 true, true, true, NULL
,
7214 NULL
, have_std_attrs
, std_attrs
,
7215 NULL
, &fallthru_attr_p
);
7217 if (in_omp_loop_block
)
7218 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7219 if (last_stmt
&& !fallthru_attr_p
)
7220 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
7221 "ISO C90 forbids mixed declarations and code");
7222 last_stmt
= fallthru_attr_p
;
7225 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
7227 /* __extension__ can start a declaration, but is also an
7228 unary operator that can start an expression. Consume all
7229 but the last of a possible series of __extension__ to
7230 determine which. If standard attributes have already
7231 been seen, it must start a statement, not a declaration,
7232 but standard attributes starting a declaration may appear
7233 after __extension__. */
7234 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
7235 && (c_parser_peek_2nd_token (parser
)->keyword
7237 c_parser_consume_token (parser
);
7239 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
7240 || c_parser_nth_token_starts_std_attributes (parser
, 2)))
7243 ext
= disable_extension_diagnostics ();
7244 c_parser_consume_token (parser
);
7246 /* It's unlikely we'll see a nested loop in a declaration in
7247 intervening code in an OMP loop, but disallow it anyway. */
7248 if (in_omp_loop_block
)
7250 check_omp_intervening_code (parser
);
7251 omp_for_parse_state
->want_nested_loop
= false;
7253 mark_valid_location_for_stdc_pragma (false);
7254 c_parser_declaration_or_fndef (parser
, true, true, true, true,
7256 if (in_omp_loop_block
)
7257 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7258 /* Following the old parser, __extension__ does not
7259 disable this diagnostic. */
7260 restore_extension_diagnostics (ext
);
7262 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
7263 "ISO C90 forbids mixed declarations and code");
7269 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
7271 if (have_std_attrs
&& !parser
->in_omp_attribute_pragma
)
7272 c_parser_error (parser
, "expected declaration or statement");
7274 c_warn_unused_attributes (std_attrs
);
7275 /* External pragmas, and some omp pragmas, are not associated
7276 with regular c code, and so are not to be considered statements
7277 syntactically. This ensures that the user doesn't put them
7278 places that would turn into syntax errors if the directive
7280 if (omp_for_parse_state
)
7281 omp_for_parse_state
->want_nested_loop
= false;
7282 if (c_parser_pragma (parser
,
7283 last_label
? pragma_stmt
: pragma_compound
,
7288 if (omp_for_parse_state
)
7289 check_omp_intervening_code (parser
);
7291 if (omp_for_parse_state
)
7292 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7294 else if (c_parser_next_token_is (parser
, CPP_EOF
))
7296 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7297 c_parser_error (parser
, "expected declaration or statement");
7298 return c_parser_peek_token (parser
)->location
;
7300 else if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
7302 if (parser
->in_if_block
)
7304 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7305 error_at (loc
, "expected %<}%> before %<else%>");
7306 return c_parser_peek_token (parser
)->location
;
7310 error_at (loc
, "%<else%> without a previous %<if%>");
7311 c_parser_consume_token (parser
);
7318 c_warn_unused_attributes (std_attrs
);
7321 mark_valid_location_for_stdc_pragma (false);
7322 if (!omp_for_parse_state
)
7323 c_parser_statement_after_labels (parser
, NULL
, NULL
, a
);
7326 /* In canonical loop nest form, nested loops can only appear
7327 directly, or in a directly nested compound statement. We
7328 already took care of those cases above, so now we have
7329 something else. This statement and everything inside
7330 it must be intervening code. */
7331 omp_for_parse_state
->want_nested_loop
= false;
7332 check_omp_intervening_code (parser
);
7333 c_parser_statement_after_labels (parser
, NULL
);
7334 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7338 parser
->error
= false;
7341 pedwarn_c11 (label_loc
, OPT_Wpedantic
, "label at end of compound statement");
7342 location_t endloc
= c_parser_peek_token (parser
)->location
;
7343 c_parser_consume_token (parser
);
7345 /* Restore the value we started with. */
7346 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7348 /* Package leftover intervening code, or the whole contents of the
7349 compound statement if we were looking for a nested loop in an OMP_FOR
7350 construct and didn't find one. */
7353 sl
= pop_stmt_list (sl
);
7354 if (omp_for_parse_state
->want_nested_loop
)
7357 add_structured_block_stmt (sl
);
7362 /* Parse all consecutive labels, possibly preceded by standard
7363 attributes. In this context, a statement is required, not a
7364 declaration, so attributes must be followed by a statement that is
7365 not just a semicolon. Returns an attr_state. */
7368 c_parser_all_labels (c_parser
*parser
)
7370 attr_state attr
= {};
7371 bool have_std_attrs
;
7372 tree std_attrs
= NULL
;
7373 if ((have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1)))
7375 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
7376 std_attrs
= c_parser_handle_musttail (parser
, std_attrs
, attr
);
7379 while (c_parser_next_token_is_keyword (parser
, RID_CASE
)
7380 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
7381 || (c_parser_next_token_is (parser
, CPP_NAME
)
7382 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
7384 c_parser_label (parser
, std_attrs
);
7386 if ((have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
,
7389 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
7390 std_attrs
= c_parser_handle_musttail (parser
, std_attrs
, attr
);
7394 && (!c_parser_handle_statement_omp_attributes (parser
, std_attrs
, &have_std_attrs
)
7397 if (have_std_attrs
&& c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7398 c_parser_error (parser
, "expected statement");
7399 c_warn_unused_attributes (std_attrs
);
7401 else if (have_std_attrs
&& c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7402 c_parser_error (parser
, "expected statement");
7406 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
7409 identifier : gnu-attributes[opt]
7410 case constant-expression :
7416 case constant-expression ... constant-expression :
7418 The use of gnu-attributes on labels is a GNU extension. The syntax in
7419 GNU C accepts any expressions without commas, non-constant
7420 expressions being rejected later. Any standard
7421 attribute-specifier-sequence before the first label has been parsed
7422 in the caller, to distinguish statements from declarations. Any
7423 attribute-specifier-sequence after the label is parsed in this
7426 c_parser_label (c_parser
*parser
, tree std_attrs
)
7428 location_t loc1
= c_parser_peek_token (parser
)->location
;
7429 tree label
= NULL_TREE
;
7431 /* Remember whether this case or a user-defined label is allowed to fall
7433 bool fallthrough_p
= c_parser_peek_token (parser
)->flags
& PREV_FALLTHROUGH
;
7435 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
7438 c_parser_consume_token (parser
);
7439 exp1
= convert_lvalue_to_rvalue (loc1
,
7440 c_parser_expr_no_commas (parser
, NULL
),
7442 if (c_parser_next_token_is (parser
, CPP_COLON
))
7444 c_parser_consume_token (parser
);
7445 label
= do_case (loc1
, exp1
, NULL_TREE
, std_attrs
);
7447 else if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
7449 c_parser_consume_token (parser
);
7450 exp2
= convert_lvalue_to_rvalue (loc1
,
7451 c_parser_expr_no_commas (parser
,
7454 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7455 label
= do_case (loc1
, exp1
, exp2
, std_attrs
);
7458 c_parser_error (parser
, "expected %<:%> or %<...%>");
7460 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
7462 c_parser_consume_token (parser
);
7463 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7464 label
= do_case (loc1
, NULL_TREE
, NULL_TREE
, std_attrs
);
7468 tree name
= c_parser_peek_token (parser
)->value
;
7471 location_t loc2
= c_parser_peek_token (parser
)->location
;
7472 gcc_assert (c_parser_next_token_is (parser
, CPP_NAME
));
7473 c_parser_consume_token (parser
);
7474 gcc_assert (c_parser_next_token_is (parser
, CPP_COLON
));
7475 c_parser_consume_token (parser
);
7476 attrs
= c_parser_gnu_attributes (parser
);
7477 tlab
= define_label (loc2
, name
);
7480 decl_attributes (&tlab
, attrs
, 0);
7481 decl_attributes (&tlab
, std_attrs
, 0);
7482 label
= add_stmt (build_stmt (loc1
, LABEL_EXPR
, tlab
));
7485 && c_parser_next_tokens_start_declaration (parser
))
7486 warning_at (loc2
, OPT_Wattributes
, "GNU-style attribute between"
7487 " label and declaration appertains to the label");
7491 if (TREE_CODE (label
) == LABEL_EXPR
)
7492 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label
)) = fallthrough_p
;
7494 FALLTHROUGH_LABEL_P (CASE_LABEL (label
)) = fallthrough_p
;
7498 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
7502 attribute-specifier-sequence[opt] compound-statement
7503 expression-statement
7504 attribute-specifier-sequence[opt] selection-statement
7505 attribute-specifier-sequence[opt] iteration-statement
7506 attribute-specifier-sequence[opt] jump-statement
7509 attribute-specifier-sequence[opt] label statement
7511 expression-statement:
7513 attribute-specifier-sequence expression ;
7515 selection-statement:
7519 iteration-statement:
7528 return expression[opt] ;
7533 attribute-specifier-sequence[opt] asm-statement
7538 expression-statement:
7544 attribute-specifier-sequence[opt] objc-throw-statement
7545 attribute-specifier-sequence[opt] objc-try-catch-statement
7546 attribute-specifier-sequence[opt] objc-synchronized-statement
7548 objc-throw-statement:
7555 attribute-specifier-sequence[opt] openacc-construct
7564 parallel-directive structured-block
7567 kernels-directive structured-block
7570 data-directive structured-block
7573 loop-directive structured-block
7578 attribute-specifier-sequence[opt] openmp-construct
7587 parallel-for-construct
7588 parallel-for-simd-construct
7589 parallel-sections-construct
7596 parallel-directive structured-block
7599 for-directive iteration-statement
7602 simd-directive iteration-statements
7605 for-simd-directive iteration-statements
7608 sections-directive section-scope
7611 single-directive structured-block
7613 parallel-for-construct:
7614 parallel-for-directive iteration-statement
7616 parallel-for-simd-construct:
7617 parallel-for-simd-directive iteration-statement
7619 parallel-sections-construct:
7620 parallel-sections-directive section-scope
7623 master-directive structured-block
7626 critical-directive structured-block
7629 atomic-directive expression-statement
7632 ordered-directive structured-block
7634 Transactional Memory:
7637 attribute-specifier-sequence[opt] transaction-statement
7638 attribute-specifier-sequence[opt] transaction-cancel-statement
7640 IF_P is used to track whether there's a (possibly labeled) if statement
7641 which is not enclosed in braces and has an else clause. This is used to
7642 implement -Wparentheses. */
7645 c_parser_statement (c_parser
*parser
, bool *if_p
, location_t
*loc_after_labels
)
7647 attr_state a
= c_parser_all_labels (parser
);
7648 if (loc_after_labels
)
7649 *loc_after_labels
= c_parser_peek_token (parser
)->location
;
7650 parser
->omp_attrs_forbidden_p
= false;
7651 c_parser_statement_after_labels (parser
, if_p
, NULL
, a
);
7654 /* Parse a statement, other than a labeled statement. CHAIN is a vector
7655 of if-else-if conditions. All labels and standard attributes have
7656 been parsed in the caller.
7658 IF_P is used to track whether there's a (possibly labeled) if statement
7659 which is not enclosed in braces and has an else clause. This is used to
7660 implement -Wparentheses. ASTATE is an earlier parsed attribute state. */
7663 c_parser_statement_after_labels (c_parser
*parser
, bool *if_p
,
7664 vec
<tree
> *chain
, attr_state astate
)
7666 location_t loc
= c_parser_peek_token (parser
)->location
;
7667 tree stmt
= NULL_TREE
;
7668 bool in_if_block
= parser
->in_if_block
;
7669 parser
->in_if_block
= false;
7673 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_BRACE
)
7674 add_debug_begin_stmt (loc
);
7677 switch (c_parser_peek_token (parser
)->type
)
7679 case CPP_OPEN_BRACE
:
7680 add_stmt (c_parser_compound_statement (parser
));
7683 switch (c_parser_peek_token (parser
)->keyword
)
7686 c_parser_if_statement (parser
, if_p
, chain
);
7689 c_parser_switch_statement (parser
, if_p
);
7692 c_parser_while_statement (parser
, false, 0, false, if_p
);
7695 c_parser_do_statement (parser
, false, 0, false);
7698 c_parser_for_statement (parser
, false, 0, false, if_p
);
7701 c_parser_consume_token (parser
);
7702 if (c_parser_next_token_is (parser
, CPP_NAME
))
7704 stmt
= c_finish_goto_label (loc
,
7705 c_parser_peek_token (parser
)->value
);
7706 c_parser_consume_token (parser
);
7708 else if (c_parser_next_token_is (parser
, CPP_MULT
))
7712 c_parser_consume_token (parser
);
7713 val
= c_parser_expression (parser
);
7714 val
= convert_lvalue_to_rvalue (loc
, val
, false, true);
7715 stmt
= c_finish_goto_ptr (loc
, val
);
7718 c_parser_error (parser
, "expected identifier or %<*%>");
7719 goto expect_semicolon
;
7721 c_parser_consume_token (parser
);
7722 stmt
= c_finish_bc_stmt (loc
, objc_foreach_continue_label
, false);
7723 goto expect_semicolon
;
7725 c_parser_consume_token (parser
);
7726 stmt
= c_finish_bc_stmt (loc
, objc_foreach_break_label
, true);
7727 goto expect_semicolon
;
7729 c_parser_consume_token (parser
);
7730 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7732 stmt
= c_finish_return (loc
, NULL_TREE
, NULL_TREE
,
7734 c_parser_consume_token (parser
);
7738 location_t xloc
= c_parser_peek_token (parser
)->location
;
7739 struct c_expr expr
= c_parser_expression_conv (parser
);
7740 mark_exp_read (expr
.value
);
7741 stmt
= c_finish_return (EXPR_LOC_OR_LOC (expr
.value
, xloc
),
7742 expr
.value
, expr
.original_type
,
7744 goto expect_semicolon
;
7748 stmt
= c_parser_asm_statement (parser
);
7750 case RID_TRANSACTION_ATOMIC
:
7751 case RID_TRANSACTION_RELAXED
:
7752 stmt
= c_parser_transaction (parser
,
7753 c_parser_peek_token (parser
)->keyword
);
7755 case RID_TRANSACTION_CANCEL
:
7756 stmt
= c_parser_transaction_cancel (parser
);
7757 goto expect_semicolon
;
7759 gcc_assert (c_dialect_objc ());
7760 c_parser_consume_token (parser
);
7761 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7763 stmt
= objc_build_throw_stmt (loc
, NULL_TREE
);
7764 c_parser_consume_token (parser
);
7768 struct c_expr expr
= c_parser_expression (parser
);
7769 expr
= convert_lvalue_to_rvalue (loc
, expr
, false, false);
7770 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
7771 stmt
= objc_build_throw_stmt (loc
, expr
.value
);
7772 goto expect_semicolon
;
7776 gcc_assert (c_dialect_objc ());
7777 c_parser_objc_try_catch_finally_statement (parser
);
7779 case RID_AT_SYNCHRONIZED
:
7780 gcc_assert (c_dialect_objc ());
7781 c_parser_objc_synchronized_statement (parser
);
7785 /* Allow '__attribute__((fallthrough));' or
7786 '__attribute__((assume(cond)));'. */
7787 tree attrs
= c_parser_gnu_attributes (parser
);
7788 bool has_assume
= lookup_attribute ("assume", attrs
);
7791 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7792 attrs
= handle_assume_attribute (loc
, attrs
, true);
7795 warning_at (loc
, OPT_Wattributes
,
7796 "%<assume%> attribute not followed by %<;%>");
7800 if (attribute_fallthrough_p (attrs
))
7802 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7804 tree fn
= build_call_expr_internal_loc (loc
,
7809 c_parser_consume_token (parser
);
7812 warning_at (loc
, OPT_Wattributes
,
7813 "%<fallthrough%> attribute not followed "
7816 else if (has_assume
)
7818 c_parser_consume_token (parser
);
7819 else if (attrs
!= NULL_TREE
)
7820 warning_at (loc
, OPT_Wattributes
,
7821 "only attribute %<fallthrough%> or %<assume%> can "
7822 "be applied to a null statement");
7830 c_parser_consume_token (parser
);
7832 case CPP_CLOSE_PAREN
:
7833 case CPP_CLOSE_SQUARE
:
7834 /* Avoid infinite loop in error recovery:
7835 c_parser_skip_until_found stops at a closing nesting
7836 delimiter without consuming it, but here we need to consume
7837 it to proceed further. */
7838 c_parser_error (parser
, "expected statement");
7839 c_parser_consume_token (parser
);
7842 if (!c_parser_pragma (parser
, pragma_stmt
, if_p
))
7847 stmt
= c_finish_expr_stmt (loc
, c_parser_expression_conv (parser
).value
);
7849 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
7852 /* Two cases cannot and do not have line numbers associated: If stmt
7853 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
7854 cannot hold line numbers. But that's OK because the statement
7855 will either be changed to a MODIFY_EXPR during gimplification of
7856 the statement expr, or discarded. If stmt was compound, but
7857 without new variables, we will have skipped the creation of a
7858 BIND and will have a bare STATEMENT_LIST. But that's OK because
7859 (recursively) all of the component statements should already have
7860 line numbers assigned. ??? Can we discard no-op statements
7862 if (EXPR_LOCATION (stmt
) == UNKNOWN_LOCATION
)
7863 protected_set_expr_location (stmt
, loc
);
7865 parser
->in_if_block
= in_if_block
;
7868 /* Parse the condition from an if, do, while or for statements. */
7871 c_parser_condition (c_parser
*parser
)
7873 location_t loc
= c_parser_peek_token (parser
)->location
;
7875 cond
= c_parser_expression_conv (parser
).value
;
7876 cond
= c_objc_common_truthvalue_conversion (loc
, cond
);
7877 cond
= c_fully_fold (cond
, false, NULL
);
7878 if (warn_sequence_point
)
7879 verify_sequence_points (cond
);
7883 /* Parse a parenthesized condition from an if, do or while statement.
7889 c_parser_paren_condition (c_parser
*parser
)
7892 matching_parens parens
;
7893 if (!parens
.require_open (parser
))
7894 return error_mark_node
;
7895 cond
= c_parser_condition (parser
);
7896 parens
.skip_until_found_close (parser
);
7900 /* Parse a statement which is a block in C99.
7902 IF_P is used to track whether there's a (possibly labeled) if statement
7903 which is not enclosed in braces and has an else clause. This is used to
7904 implement -Wparentheses. */
7907 c_parser_c99_block_statement (c_parser
*parser
, bool *if_p
,
7908 location_t
*loc_after_labels
)
7910 tree block
= c_begin_compound_stmt (flag_isoc99
);
7911 location_t loc
= c_parser_peek_token (parser
)->location
;
7912 c_parser_statement (parser
, if_p
, loc_after_labels
);
7913 return c_end_compound_stmt (loc
, block
, flag_isoc99
);
7916 /* Parse the body of an if statement. This is just parsing a
7917 statement but (a) it is a block in C99, (b) we track whether the
7918 body is an if statement for the sake of -Wparentheses warnings, (c)
7919 we handle an empty body specially for the sake of -Wempty-body
7920 warnings, and (d) we call parser_compound_statement directly
7921 because c_parser_statement_after_labels resets
7922 parser->in_if_block.
7924 IF_P is used to track whether there's a (possibly labeled) if statement
7925 which is not enclosed in braces and has an else clause. This is used to
7926 implement -Wparentheses. */
7929 c_parser_if_body (c_parser
*parser
, bool *if_p
,
7930 const token_indent_info
&if_tinfo
)
7932 tree block
= c_begin_compound_stmt (flag_isoc99
);
7933 location_t body_loc
= c_parser_peek_token (parser
)->location
;
7934 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
7935 token_indent_info body_tinfo
7936 = get_token_indent_info (c_parser_peek_token (parser
));
7938 c_parser_all_labels (parser
);
7939 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7941 location_t loc
= c_parser_peek_token (parser
)->location
;
7942 add_stmt (build_empty_stmt (loc
));
7943 c_parser_consume_token (parser
);
7944 if (!c_parser_next_token_is_keyword (parser
, RID_ELSE
))
7945 warning_at (loc
, OPT_Wempty_body
,
7946 "suggest braces around empty body in an %<if%> statement");
7948 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7949 add_stmt (c_parser_compound_statement (parser
));
7952 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
7953 c_parser_statement_after_labels (parser
, if_p
);
7956 token_indent_info next_tinfo
7957 = get_token_indent_info (c_parser_peek_token (parser
));
7958 warn_for_misleading_indentation (if_tinfo
, body_tinfo
, next_tinfo
);
7959 if (body_loc_after_labels
!= UNKNOWN_LOCATION
7960 && next_tinfo
.type
!= CPP_SEMICOLON
)
7961 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
7962 if_tinfo
.location
, RID_IF
);
7964 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
7967 /* Parse the else body of an if statement. This is just parsing a
7968 statement but (a) it is a block in C99, (b) we handle an empty body
7969 specially for the sake of -Wempty-body warnings. CHAIN is a vector
7970 of if-else-if conditions. */
7973 c_parser_else_body (c_parser
*parser
, const token_indent_info
&else_tinfo
,
7976 location_t body_loc
= c_parser_peek_token (parser
)->location
;
7977 tree block
= c_begin_compound_stmt (flag_isoc99
);
7978 token_indent_info body_tinfo
7979 = get_token_indent_info (c_parser_peek_token (parser
));
7980 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
7982 c_parser_all_labels (parser
);
7983 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7985 location_t loc
= c_parser_peek_token (parser
)->location
;
7988 "suggest braces around empty body in an %<else%> statement");
7989 add_stmt (build_empty_stmt (loc
));
7990 c_parser_consume_token (parser
);
7994 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7995 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
7996 c_parser_statement_after_labels (parser
, NULL
, chain
);
7999 token_indent_info next_tinfo
8000 = get_token_indent_info (c_parser_peek_token (parser
));
8001 warn_for_misleading_indentation (else_tinfo
, body_tinfo
, next_tinfo
);
8002 if (body_loc_after_labels
!= UNKNOWN_LOCATION
8003 && next_tinfo
.type
!= CPP_SEMICOLON
)
8004 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
8005 else_tinfo
.location
, RID_ELSE
);
8007 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
8010 /* We might need to reclassify any previously-lexed identifier, e.g.
8011 when we've left a for loop with an if-statement without else in the
8012 body - we might have used a wrong scope for the token. See PR67784. */
8015 c_parser_maybe_reclassify_token (c_parser
*parser
)
8017 if (c_parser_next_token_is (parser
, CPP_NAME
))
8019 c_token
*token
= c_parser_peek_token (parser
);
8021 if (token
->id_kind
!= C_ID_CLASSNAME
)
8023 tree decl
= lookup_name (token
->value
);
8025 token
->id_kind
= C_ID_ID
;
8028 if (TREE_CODE (decl
) == TYPE_DECL
)
8029 token
->id_kind
= C_ID_TYPENAME
;
8031 else if (c_dialect_objc ())
8033 tree objc_interface_decl
= objc_is_class_name (token
->value
);
8034 /* Objective-C class names are in the same namespace as
8035 variables and typedefs, and hence are shadowed by local
8037 if (objc_interface_decl
)
8039 token
->value
= objc_interface_decl
;
8040 token
->id_kind
= C_ID_CLASSNAME
;
8047 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
8050 if ( expression ) statement
8051 if ( expression ) statement else statement
8053 CHAIN is a vector of if-else-if conditions.
8054 IF_P is used to track whether there's a (possibly labeled) if statement
8055 which is not enclosed in braces and has an else clause. This is used to
8056 implement -Wparentheses. */
8059 c_parser_if_statement (c_parser
*parser
, bool *if_p
, vec
<tree
> *chain
)
8064 bool nested_if
= false;
8065 tree first_body
, second_body
;
8068 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_IF
));
8069 token_indent_info if_tinfo
8070 = get_token_indent_info (c_parser_peek_token (parser
));
8071 c_parser_consume_token (parser
);
8072 block
= c_begin_compound_stmt (flag_isoc99
);
8073 loc
= c_parser_peek_token (parser
)->location
;
8074 cond
= c_parser_paren_condition (parser
);
8075 in_if_block
= parser
->in_if_block
;
8076 parser
->in_if_block
= true;
8077 first_body
= c_parser_if_body (parser
, &nested_if
, if_tinfo
);
8078 parser
->in_if_block
= in_if_block
;
8080 if (warn_duplicated_cond
)
8081 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond
), cond
, &chain
);
8083 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
8085 token_indent_info else_tinfo
8086 = get_token_indent_info (c_parser_peek_token (parser
));
8087 c_parser_consume_token (parser
);
8088 if (warn_duplicated_cond
)
8090 if (c_parser_next_token_is_keyword (parser
, RID_IF
)
8093 /* We've got "if (COND) else if (COND2)". Start the
8094 condition chain and add COND as the first element. */
8095 chain
= new vec
<tree
> ();
8096 if (!CONSTANT_CLASS_P (cond
) && !TREE_SIDE_EFFECTS (cond
))
8097 chain
->safe_push (cond
);
8099 else if (!c_parser_next_token_is_keyword (parser
, RID_IF
))
8100 /* This is if-else without subsequent if. Zap the condition
8101 chain; we would have already warned at this point. */
8104 second_body
= c_parser_else_body (parser
, else_tinfo
, chain
);
8105 /* Set IF_P to true to indicate that this if statement has an
8106 else clause. This may trigger the Wparentheses warning
8107 below when we get back up to the parent if statement. */
8113 second_body
= NULL_TREE
;
8115 /* Diagnose an ambiguous else if if-then-else is nested inside
8118 warning_at (loc
, OPT_Wdangling_else
,
8119 "suggest explicit braces to avoid ambiguous %<else%>");
8121 if (warn_duplicated_cond
)
8122 /* This if statement does not have an else clause. We don't
8123 need the condition chain anymore. */
8126 c_finish_if_stmt (loc
, cond
, first_body
, second_body
);
8127 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
8129 c_parser_maybe_reclassify_token (parser
);
8132 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
8135 switch (expression) statement
8139 c_parser_switch_statement (c_parser
*parser
, bool *if_p
)
8142 tree block
, expr
, body
;
8143 unsigned char save_in_statement
;
8144 location_t switch_loc
= c_parser_peek_token (parser
)->location
;
8145 location_t switch_cond_loc
;
8146 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SWITCH
));
8147 c_parser_consume_token (parser
);
8148 block
= c_begin_compound_stmt (flag_isoc99
);
8149 bool explicit_cast_p
= false;
8150 matching_parens parens
;
8151 if (parens
.require_open (parser
))
8153 switch_cond_loc
= c_parser_peek_token (parser
)->location
;
8154 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8155 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8156 explicit_cast_p
= true;
8157 ce
= c_parser_expression (parser
);
8158 ce
= convert_lvalue_to_rvalue (switch_cond_loc
, ce
, true, true);
8160 /* ??? expr has no valid location? */
8161 parens
.skip_until_found_close (parser
);
8165 switch_cond_loc
= UNKNOWN_LOCATION
;
8166 expr
= error_mark_node
;
8167 ce
.original_type
= error_mark_node
;
8169 c_start_switch (switch_loc
, switch_cond_loc
, expr
, explicit_cast_p
);
8170 save_in_statement
= in_statement
;
8171 in_statement
|= IN_SWITCH_STMT
;
8172 location_t loc_after_labels
;
8173 bool open_brace_p
= c_parser_peek_token (parser
)->type
== CPP_OPEN_BRACE
;
8174 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
8175 location_t next_loc
= c_parser_peek_token (parser
)->location
;
8176 if (!open_brace_p
&& c_parser_peek_token (parser
)->type
!= CPP_SEMICOLON
)
8177 warn_for_multistatement_macros (loc_after_labels
, next_loc
, switch_loc
,
8179 c_finish_switch (body
, ce
.original_type
);
8180 in_statement
= save_in_statement
;
8181 add_stmt (c_end_compound_stmt (switch_loc
, block
, flag_isoc99
));
8182 c_parser_maybe_reclassify_token (parser
);
8185 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8188 while (expression) statement
8190 IF_P is used to track whether there's a (possibly labeled) if statement
8191 which is not enclosed in braces and has an else clause. This is used to
8192 implement -Wparentheses. */
8195 c_parser_while_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
8196 bool novector
, bool *if_p
)
8198 tree block
, cond
, body
;
8199 unsigned char save_in_statement
;
8201 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_WHILE
));
8202 token_indent_info while_tinfo
8203 = get_token_indent_info (c_parser_peek_token (parser
));
8205 if (parser
->omp_for_parse_state
)
8207 error_at (c_parser_peek_token (parser
)->location
,
8208 "loop not permitted in intervening code in OpenMP loop body");
8209 parser
->omp_for_parse_state
->fail
= true;
8212 c_parser_consume_token (parser
);
8213 block
= c_begin_compound_stmt (flag_isoc99
);
8214 loc
= c_parser_peek_token (parser
)->location
;
8215 cond
= c_parser_paren_condition (parser
);
8216 if (ivdep
&& cond
!= error_mark_node
)
8217 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8218 build_int_cst (integer_type_node
,
8219 annot_expr_ivdep_kind
),
8221 if (unroll
&& cond
!= error_mark_node
)
8222 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8223 build_int_cst (integer_type_node
,
8224 annot_expr_unroll_kind
),
8225 build_int_cst (integer_type_node
, unroll
));
8226 if (novector
&& cond
!= error_mark_node
)
8227 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8228 build_int_cst (integer_type_node
,
8229 annot_expr_no_vector_kind
),
8231 save_in_statement
= in_statement
;
8232 in_statement
= IN_ITERATION_STMT
;
8234 token_indent_info body_tinfo
8235 = get_token_indent_info (c_parser_peek_token (parser
));
8237 location_t loc_after_labels
;
8238 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
8239 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
8240 add_stmt (build_stmt (loc
, WHILE_STMT
, cond
, body
));
8241 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
8242 c_parser_maybe_reclassify_token (parser
);
8244 token_indent_info next_tinfo
8245 = get_token_indent_info (c_parser_peek_token (parser
));
8246 warn_for_misleading_indentation (while_tinfo
, body_tinfo
, next_tinfo
);
8248 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
8249 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
8250 while_tinfo
.location
, RID_WHILE
);
8252 in_statement
= save_in_statement
;
8255 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8258 do statement while ( expression ) ;
8262 c_parser_do_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
8265 tree block
, cond
, body
;
8266 unsigned char save_in_statement
;
8268 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_DO
));
8270 if (parser
->omp_for_parse_state
)
8272 error_at (c_parser_peek_token (parser
)->location
,
8273 "loop not permitted in intervening code in OpenMP loop body");
8274 parser
->omp_for_parse_state
->fail
= true;
8277 c_parser_consume_token (parser
);
8278 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
8279 warning_at (c_parser_peek_token (parser
)->location
,
8281 "suggest braces around empty body in %<do%> statement");
8282 block
= c_begin_compound_stmt (flag_isoc99
);
8283 loc
= c_parser_peek_token (parser
)->location
;
8284 save_in_statement
= in_statement
;
8285 in_statement
= IN_ITERATION_STMT
;
8286 body
= c_parser_c99_block_statement (parser
, NULL
);
8287 c_parser_require_keyword (parser
, RID_WHILE
, "expected %<while%>");
8288 in_statement
= save_in_statement
;
8289 cond
= c_parser_paren_condition (parser
);
8290 if (ivdep
&& cond
!= error_mark_node
)
8291 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8292 build_int_cst (integer_type_node
,
8293 annot_expr_ivdep_kind
),
8295 if (unroll
&& cond
!= error_mark_node
)
8296 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8297 build_int_cst (integer_type_node
,
8298 annot_expr_unroll_kind
),
8299 build_int_cst (integer_type_node
, unroll
));
8300 if (novector
&& cond
!= error_mark_node
)
8301 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8302 build_int_cst (integer_type_node
,
8303 annot_expr_no_vector_kind
),
8305 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
8306 c_parser_skip_to_end_of_block_or_statement (parser
);
8308 add_stmt (build_stmt (loc
, DO_STMT
, cond
, body
));
8309 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
8312 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8315 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
8316 for ( nested-declaration expression[opt] ; expression[opt] ) statement
8318 The form with a declaration is new in C99.
8320 ??? In accordance with the old parser, the declaration may be a
8321 nested function, which is then rejected in check_for_loop_decls,
8322 but does it make any sense for this to be included in the grammar?
8323 Note in particular that the nested function does not include a
8324 trailing ';', whereas the "declaration" production includes one.
8325 Also, can we reject bad declarations earlier and cheaper than
8326 check_for_loop_decls?
8328 In Objective-C, there are two additional variants:
8331 for ( expression in expresssion ) statement
8332 for ( declaration in expression ) statement
8334 This is inconsistent with C, because the second variant is allowed
8335 even if c99 is not enabled.
8337 The rest of the comment documents these Objective-C foreach-statement.
8339 Here is the canonical example of the first variant:
8340 for (object in array) { do something with object }
8341 we call the first expression ("object") the "object_expression" and
8342 the second expression ("array") the "collection_expression".
8343 object_expression must be an lvalue of type "id" (a generic Objective-C
8344 object) because the loop works by assigning to object_expression the
8345 various objects from the collection_expression. collection_expression
8346 must evaluate to something of type "id" which responds to the method
8347 countByEnumeratingWithState:objects:count:.
8349 The canonical example of the second variant is:
8350 for (id object in array) { do something with object }
8351 which is completely equivalent to
8354 for (object in array) { do something with object }
8356 Note that initizializing 'object' in some way (eg, "for ((object =
8357 xxx) in array) { do something with object }") is possibly
8358 technically valid, but completely pointless as 'object' will be
8359 assigned to something else as soon as the loop starts. We should
8360 most likely reject it (TODO).
8362 The beginning of the Objective-C foreach-statement looks exactly
8363 like the beginning of the for-statement, and we can tell it is a
8364 foreach-statement only because the initial declaration or
8365 expression is terminated by 'in' instead of ';'.
8367 IF_P is used to track whether there's a (possibly labeled) if statement
8368 which is not enclosed in braces and has an else clause. This is used to
8369 implement -Wparentheses. */
8372 c_parser_for_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
8373 bool novector
, bool *if_p
)
8375 tree block
, cond
, incr
, body
;
8376 unsigned char save_in_statement
;
8377 tree save_objc_foreach_break_label
, save_objc_foreach_continue_label
;
8378 /* The following are only used when parsing an ObjC foreach statement. */
8379 tree object_expression
;
8380 /* Silence the bogus uninitialized warning. */
8381 tree collection_expression
= NULL
;
8382 location_t loc
= c_parser_peek_token (parser
)->location
;
8383 location_t for_loc
= loc
;
8384 bool is_foreach_statement
= false;
8385 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
8386 token_indent_info for_tinfo
8387 = get_token_indent_info (c_parser_peek_token (parser
));
8389 if (parser
->omp_for_parse_state
)
8392 "loop not permitted in intervening code in OpenMP loop body");
8393 parser
->omp_for_parse_state
->fail
= true;
8396 c_parser_consume_token (parser
);
8397 /* Open a compound statement in Objective-C as well, just in case this is
8398 as foreach expression. */
8399 block
= c_begin_compound_stmt (flag_isoc99
|| c_dialect_objc ());
8400 cond
= error_mark_node
;
8401 incr
= error_mark_node
;
8402 matching_parens parens
;
8403 if (parens
.require_open (parser
))
8405 /* Parse the initialization declaration or expression. */
8406 object_expression
= error_mark_node
;
8407 parser
->objc_could_be_foreach_context
= c_dialect_objc ();
8408 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
8410 parser
->objc_could_be_foreach_context
= false;
8411 c_parser_consume_token (parser
);
8412 c_finish_expr_stmt (loc
, NULL_TREE
);
8414 else if (c_parser_next_tokens_start_declaration (parser
)
8415 || c_parser_nth_token_starts_std_attributes (parser
, 1))
8417 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
8418 &object_expression
);
8419 parser
->objc_could_be_foreach_context
= false;
8421 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
8423 c_parser_consume_token (parser
);
8424 is_foreach_statement
= true;
8425 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
8426 c_parser_error (parser
, "multiple iterating variables in "
8427 "fast enumeration");
8430 check_for_loop_decls (for_loc
, flag_isoc99
);
8432 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
8434 /* __extension__ can start a declaration, but is also an
8435 unary operator that can start an expression. Consume all
8436 but the last of a possible series of __extension__ to
8438 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
8439 && (c_parser_peek_2nd_token (parser
)->keyword
8441 c_parser_consume_token (parser
);
8442 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
8443 || c_parser_nth_token_starts_std_attributes (parser
, 2))
8446 ext
= disable_extension_diagnostics ();
8447 c_parser_consume_token (parser
);
8448 c_parser_declaration_or_fndef (parser
, true, true, true, true,
8449 true, &object_expression
);
8450 parser
->objc_could_be_foreach_context
= false;
8452 restore_extension_diagnostics (ext
);
8453 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
8455 c_parser_consume_token (parser
);
8456 is_foreach_statement
= true;
8457 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
8458 c_parser_error (parser
, "multiple iterating variables in "
8459 "fast enumeration");
8462 check_for_loop_decls (for_loc
, flag_isoc99
);
8472 tree init_expression
;
8473 ce
= c_parser_expression (parser
);
8474 init_expression
= ce
.value
;
8475 parser
->objc_could_be_foreach_context
= false;
8476 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
8478 c_parser_consume_token (parser
);
8479 is_foreach_statement
= true;
8480 if (! lvalue_p (init_expression
))
8481 c_parser_error (parser
, "invalid iterating variable in "
8482 "fast enumeration");
8484 = c_fully_fold (init_expression
, false, NULL
);
8488 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
8489 init_expression
= ce
.value
;
8490 c_finish_expr_stmt (loc
, init_expression
);
8491 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
8496 /* Parse the loop condition. In the case of a foreach
8497 statement, there is no loop condition. */
8498 gcc_assert (!parser
->objc_could_be_foreach_context
);
8499 if (!is_foreach_statement
)
8501 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
8505 c_parser_error (parser
, "missing loop condition in loop "
8506 "with %<GCC ivdep%> pragma");
8507 cond
= error_mark_node
;
8511 c_parser_error (parser
, "missing loop condition in loop "
8512 "with %<GCC unroll%> pragma");
8513 cond
= error_mark_node
;
8517 c_parser_consume_token (parser
);
8523 cond
= c_parser_condition (parser
);
8524 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
8527 if (ivdep
&& cond
!= error_mark_node
)
8528 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8529 build_int_cst (integer_type_node
,
8530 annot_expr_ivdep_kind
),
8532 if (unroll
&& cond
!= error_mark_node
)
8533 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8534 build_int_cst (integer_type_node
,
8535 annot_expr_unroll_kind
),
8536 build_int_cst (integer_type_node
, unroll
));
8537 if (novector
&& cond
&& cond
!= error_mark_node
)
8538 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8539 build_int_cst (integer_type_node
,
8540 annot_expr_no_vector_kind
),
8543 /* Parse the increment expression (the third expression in a
8544 for-statement). In the case of a foreach-statement, this is
8545 the expression that follows the 'in'. */
8546 loc
= c_parser_peek_token (parser
)->location
;
8547 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8549 if (is_foreach_statement
)
8551 c_parser_error (parser
,
8552 "missing collection in fast enumeration");
8553 collection_expression
= error_mark_node
;
8556 incr
= c_process_expr_stmt (loc
, NULL_TREE
);
8560 if (is_foreach_statement
)
8561 collection_expression
8562 = c_fully_fold (c_parser_expression (parser
).value
, false, NULL
);
8565 struct c_expr ce
= c_parser_expression (parser
);
8566 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
8567 incr
= c_process_expr_stmt (loc
, ce
.value
);
8570 parens
.skip_until_found_close (parser
);
8572 save_in_statement
= in_statement
;
8573 if (is_foreach_statement
)
8575 in_statement
= IN_OBJC_FOREACH
;
8576 save_objc_foreach_break_label
= objc_foreach_break_label
;
8577 save_objc_foreach_continue_label
= objc_foreach_continue_label
;
8578 objc_foreach_break_label
= create_artificial_label (loc
);
8579 objc_foreach_continue_label
= create_artificial_label (loc
);
8582 in_statement
= IN_ITERATION_STMT
;
8584 token_indent_info body_tinfo
8585 = get_token_indent_info (c_parser_peek_token (parser
));
8587 location_t loc_after_labels
;
8588 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
8589 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
8591 if (is_foreach_statement
)
8592 objc_finish_foreach_loop (for_loc
, object_expression
,
8593 collection_expression
, body
,
8594 objc_foreach_break_label
,
8595 objc_foreach_continue_label
);
8597 add_stmt (build_stmt (for_loc
, FOR_STMT
, NULL_TREE
, cond
, incr
,
8599 add_stmt (c_end_compound_stmt (for_loc
, block
,
8600 flag_isoc99
|| c_dialect_objc ()));
8601 c_parser_maybe_reclassify_token (parser
);
8603 token_indent_info next_tinfo
8604 = get_token_indent_info (c_parser_peek_token (parser
));
8605 warn_for_misleading_indentation (for_tinfo
, body_tinfo
, next_tinfo
);
8607 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
8608 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
8609 for_tinfo
.location
, RID_FOR
);
8611 in_statement
= save_in_statement
;
8612 if (is_foreach_statement
)
8614 objc_foreach_break_label
= save_objc_foreach_break_label
;
8615 objc_foreach_continue_label
= save_objc_foreach_continue_label
;
8619 /* Parse an asm statement, a GNU extension. This is a full-blown asm
8620 statement with inputs, outputs, clobbers, and volatile, inline, and goto
8629 asm-qualifier-list asm-qualifier
8633 asm asm-qualifier-list[opt] ( asm-argument ) ;
8637 asm-string-literal : asm-operands[opt]
8638 asm-string-literal : asm-operands[opt] : asm-operands[opt]
8639 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
8641 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
8644 The form with asm-goto-operands is valid if and only if the
8645 asm-qualifier-list contains goto, and is the only allowed form in that case.
8646 Duplicate asm-qualifiers are not allowed.
8648 The :: token is considered equivalent to two consecutive : tokens. */
8651 c_parser_asm_statement (c_parser
*parser
)
8653 tree str
, outputs
, inputs
, clobbers
, labels
, ret
;
8655 location_t asm_loc
= c_parser_peek_token (parser
)->location
;
8656 int section
, nsections
;
8658 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
8659 c_parser_consume_token (parser
);
8661 /* Handle the asm-qualifier-list. */
8662 location_t volatile_loc
= UNKNOWN_LOCATION
;
8663 location_t inline_loc
= UNKNOWN_LOCATION
;
8664 location_t goto_loc
= UNKNOWN_LOCATION
;
8667 c_token
*token
= c_parser_peek_token (parser
);
8668 location_t loc
= token
->location
;
8669 switch (token
->keyword
)
8674 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
8675 inform (volatile_loc
, "first seen here");
8679 c_parser_consume_token (parser
);
8685 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
8686 inform (inline_loc
, "first seen here");
8690 c_parser_consume_token (parser
);
8696 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
8697 inform (goto_loc
, "first seen here");
8701 c_parser_consume_token (parser
);
8706 error_at (loc
, "%qE is not a valid %<asm%> qualifier", token
->value
);
8707 c_parser_consume_token (parser
);
8716 bool is_volatile
= (volatile_loc
!= UNKNOWN_LOCATION
);
8717 bool is_inline
= (inline_loc
!= UNKNOWN_LOCATION
);
8718 bool is_goto
= (goto_loc
!= UNKNOWN_LOCATION
);
8722 matching_parens parens
;
8723 if (!parens
.require_open (parser
))
8726 str
= c_parser_asm_string_literal (parser
);
8727 if (str
== NULL_TREE
)
8728 goto error_close_paren
;
8731 outputs
= NULL_TREE
;
8733 clobbers
= NULL_TREE
;
8736 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
8739 /* Parse each colon-delimited section of operands. */
8740 nsections
= 3 + is_goto
;
8741 for (section
= 0; section
< nsections
; ++section
)
8743 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
8746 if (section
== nsections
)
8748 c_parser_error (parser
, "expected %<)%>");
8749 goto error_close_paren
;
8751 c_parser_consume_token (parser
);
8753 else if (!c_parser_require (parser
, CPP_COLON
,
8755 ? G_("expected %<:%>")
8756 : G_("expected %<:%> or %<)%>"),
8757 UNKNOWN_LOCATION
, is_goto
))
8758 goto error_close_paren
;
8760 /* Once past any colon, we're no longer a simple asm. */
8763 if ((!c_parser_next_token_is (parser
, CPP_COLON
)
8764 && !c_parser_next_token_is (parser
, CPP_SCOPE
)
8765 && !c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8770 outputs
= c_parser_asm_operands (parser
);
8773 inputs
= c_parser_asm_operands (parser
);
8776 clobbers
= c_parser_asm_clobbers (parser
);
8779 labels
= c_parser_asm_goto_operands (parser
);
8785 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
8790 if (!parens
.require_close (parser
))
8792 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8796 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
8797 c_parser_skip_to_end_of_block_or_statement (parser
);
8799 ret
= build_asm_stmt (is_volatile
,
8800 build_asm_expr (asm_loc
, str
, outputs
, inputs
,
8801 clobbers
, labels
, simple
, is_inline
));
8807 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8811 /* Parse asm operands, a GNU extension.
8815 asm-operands , asm-operand
8818 asm-string-literal ( expression )
8819 [ identifier ] asm-string-literal ( expression )
8823 c_parser_asm_operands (c_parser
*parser
)
8825 tree list
= NULL_TREE
;
8830 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
8832 c_parser_consume_token (parser
);
8833 if (c_parser_next_token_is (parser
, CPP_NAME
))
8835 tree id
= c_parser_peek_token (parser
)->value
;
8836 c_parser_consume_token (parser
);
8837 name
= build_string (IDENTIFIER_LENGTH (id
),
8838 IDENTIFIER_POINTER (id
));
8842 c_parser_error (parser
, "expected identifier");
8843 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
8846 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
8851 str
= c_parser_asm_string_literal (parser
);
8852 if (str
== NULL_TREE
)
8854 matching_parens parens
;
8855 if (!parens
.require_open (parser
))
8857 expr
= c_parser_expression (parser
);
8858 mark_exp_read (expr
.value
);
8859 if (!parens
.require_close (parser
))
8861 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8864 list
= chainon (list
, build_tree_list (build_tree_list (name
, str
),
8866 if (c_parser_next_token_is (parser
, CPP_COMMA
))
8867 c_parser_consume_token (parser
);
8874 /* Parse asm clobbers, a GNU extension.
8878 asm-clobbers , asm-string-literal
8882 c_parser_asm_clobbers (c_parser
*parser
)
8884 tree list
= NULL_TREE
;
8887 tree str
= c_parser_asm_string_literal (parser
);
8889 list
= tree_cons (NULL_TREE
, str
, list
);
8892 if (c_parser_next_token_is (parser
, CPP_COMMA
))
8893 c_parser_consume_token (parser
);
8900 /* Parse asm goto labels, a GNU extension.
8904 asm-goto-operands , identifier
8908 c_parser_asm_goto_operands (c_parser
*parser
)
8910 tree list
= NULL_TREE
;
8915 if (c_parser_next_token_is (parser
, CPP_NAME
))
8917 c_token
*tok
= c_parser_peek_token (parser
);
8919 label
= lookup_label_for_goto (tok
->location
, name
);
8920 c_parser_consume_token (parser
);
8921 TREE_USED (label
) = 1;
8925 c_parser_error (parser
, "expected identifier");
8929 name
= build_string (IDENTIFIER_LENGTH (name
),
8930 IDENTIFIER_POINTER (name
));
8931 list
= tree_cons (name
, label
, list
);
8932 if (c_parser_next_token_is (parser
, CPP_COMMA
))
8933 c_parser_consume_token (parser
);
8935 return nreverse (list
);
8939 /* Parse a possibly concatenated sequence of string literals.
8940 TRANSLATE says whether to translate them to the execution character
8941 set; WIDE_OK says whether any kind of prefixed string literal is
8942 permitted in this context. This code is based on that in
8946 c_parser_string_literal (c_parser
*parser
, bool translate
, bool wide_ok
)
8950 struct obstack str_ob
;
8951 struct obstack loc_ob
;
8952 cpp_string str
, istr
, *strs
;
8954 location_t loc
, last_tok_loc
;
8955 enum cpp_ttype type
;
8956 tree value
, string_tree
;
8958 tok
= c_parser_peek_token (parser
);
8959 loc
= tok
->location
;
8960 last_tok_loc
= linemap_resolve_location (line_table
, loc
,
8961 LRK_MACRO_DEFINITION_LOCATION
,
8970 case CPP_UTF8STRING
:
8971 string_tree
= tok
->value
;
8975 c_parser_error (parser
, "expected string literal");
8977 ret
.value
= NULL_TREE
;
8978 ret
.original_code
= ERROR_MARK
;
8979 ret
.original_type
= NULL_TREE
;
8983 /* Try to avoid the overhead of creating and destroying an obstack
8984 for the common case of just one string. */
8985 switch (c_parser_peek_2nd_token (parser
)->type
)
8988 c_parser_consume_token (parser
);
8989 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
8990 str
.len
= TREE_STRING_LENGTH (string_tree
);
8999 case CPP_UTF8STRING
:
9000 gcc_obstack_init (&str_ob
);
9001 gcc_obstack_init (&loc_ob
);
9005 c_parser_consume_token (parser
);
9007 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
9008 str
.len
= TREE_STRING_LENGTH (string_tree
);
9009 if (type
!= tok
->type
)
9011 if (type
== CPP_STRING
)
9013 else if (tok
->type
!= CPP_STRING
)
9014 error ("unsupported non-standard concatenation "
9015 "of string literals");
9017 obstack_grow (&str_ob
, &str
, sizeof (cpp_string
));
9018 obstack_grow (&loc_ob
, &last_tok_loc
, sizeof (location_t
));
9019 tok
= c_parser_peek_token (parser
);
9020 string_tree
= tok
->value
;
9022 = linemap_resolve_location (line_table
, tok
->location
,
9023 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
9025 while (tok
->type
== CPP_STRING
9026 || tok
->type
== CPP_WSTRING
9027 || tok
->type
== CPP_STRING16
9028 || tok
->type
== CPP_STRING32
9029 || tok
->type
== CPP_UTF8STRING
);
9030 strs
= (cpp_string
*) obstack_finish (&str_ob
);
9033 if (count
> 1 && !in_system_header_at (input_location
))
9034 warning (OPT_Wtraditional
,
9035 "traditional C rejects string constant concatenation");
9037 if ((type
== CPP_STRING
|| wide_ok
)
9039 ? cpp_interpret_string
: cpp_interpret_string_notranslate
)
9040 (parse_in
, strs
, count
, &istr
, type
)))
9042 value
= build_string (istr
.len
, (const char *) istr
.text
);
9043 free (CONST_CAST (unsigned char *, istr
.text
));
9046 location_t
*locs
= (location_t
*) obstack_finish (&loc_ob
);
9047 gcc_assert (g_string_concat_db
);
9048 g_string_concat_db
->record_string_concatenation (count
, locs
);
9053 if (type
!= CPP_STRING
&& !wide_ok
)
9055 error_at (loc
, "a wide string is invalid in this context");
9058 /* Callers cannot generally handle error_mark_node in this
9059 context, so return the empty string instead. An error has
9060 been issued, either above or from cpp_interpret_string. */
9065 case CPP_UTF8STRING
:
9066 if (type
== CPP_UTF8STRING
&& flag_char8_t
)
9068 value
= build_string (TYPE_PRECISION (char8_type_node
)
9069 / TYPE_PRECISION (char_type_node
),
9070 ""); /* char8_t is 8 bits */
9073 value
= build_string (1, "");
9076 value
= build_string (TYPE_PRECISION (char16_type_node
)
9077 / TYPE_PRECISION (char_type_node
),
9078 "\0"); /* char16_t is 16 bits */
9081 value
= build_string (TYPE_PRECISION (char32_type_node
)
9082 / TYPE_PRECISION (char_type_node
),
9083 "\0\0\0"); /* char32_t is 32 bits */
9086 value
= build_string (TYPE_PRECISION (wchar_type_node
)
9087 / TYPE_PRECISION (char_type_node
),
9088 "\0\0\0"); /* widest supported wchar_t
9098 TREE_TYPE (value
) = char_array_type_node
;
9100 case CPP_UTF8STRING
:
9102 TREE_TYPE (value
) = char8_array_type_node
;
9104 TREE_TYPE (value
) = char_array_type_node
;
9107 TREE_TYPE (value
) = char16_array_type_node
;
9110 TREE_TYPE (value
) = char32_array_type_node
;
9113 TREE_TYPE (value
) = wchar_array_type_node
;
9115 value
= fix_string_type (value
);
9119 obstack_free (&str_ob
, 0);
9120 obstack_free (&loc_ob
, 0);
9124 ret
.original_code
= STRING_CST
;
9125 ret
.original_type
= NULL_TREE
;
9126 set_c_expr_source_range (&ret
, get_range_from_loc (line_table
, loc
));
9128 parser
->seen_string_literal
= true;
9132 /* Parse an expression other than a compound expression; that is, an
9133 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
9134 AFTER is not NULL then it is an Objective-C message expression which
9135 is the primary-expression starting the expression as an initializer.
9137 assignment-expression:
9138 conditional-expression
9139 unary-expression assignment-operator assignment-expression
9141 assignment-operator: one of
9142 = *= /= %= += -= <<= >>= &= ^= |=
9144 In GNU C we accept any conditional expression on the LHS and
9145 diagnose the invalid lvalue rather than producing a syntax
9148 static struct c_expr
9149 c_parser_expr_no_commas (c_parser
*parser
, struct c_expr
*after
,
9150 tree omp_atomic_lhs
)
9152 struct c_expr lhs
, rhs
, ret
;
9153 enum tree_code code
;
9154 location_t op_location
, exp_location
;
9155 bool save_in_omp_for
= c_in_omp_for
;
9156 c_in_omp_for
= false;
9157 gcc_assert (!after
|| c_dialect_objc ());
9158 lhs
= c_parser_conditional_expression (parser
, after
, omp_atomic_lhs
);
9159 op_location
= c_parser_peek_token (parser
)->location
;
9160 switch (c_parser_peek_token (parser
)->type
)
9169 code
= TRUNC_DIV_EXPR
;
9172 code
= TRUNC_MOD_EXPR
;
9187 code
= BIT_AND_EXPR
;
9190 code
= BIT_XOR_EXPR
;
9193 code
= BIT_IOR_EXPR
;
9196 c_in_omp_for
= save_in_omp_for
;
9199 c_parser_consume_token (parser
);
9200 exp_location
= c_parser_peek_token (parser
)->location
;
9201 rhs
= c_parser_expr_no_commas (parser
, NULL
);
9202 rhs
= convert_lvalue_to_rvalue (exp_location
, rhs
, true, true);
9204 ret
.value
= build_modify_expr (op_location
, lhs
.value
, lhs
.original_type
,
9205 code
, exp_location
, rhs
.value
,
9208 set_c_expr_source_range (&ret
, lhs
.get_start (), rhs
.get_finish ());
9209 if (code
== NOP_EXPR
)
9210 ret
.original_code
= MODIFY_EXPR
;
9213 suppress_warning (ret
.value
, OPT_Wparentheses
);
9214 ret
.original_code
= ERROR_MARK
;
9216 ret
.original_type
= NULL
;
9217 c_in_omp_for
= save_in_omp_for
;
9221 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
9222 AFTER is not NULL then it is an Objective-C message expression which is
9223 the primary-expression starting the expression as an initializer.
9225 conditional-expression:
9226 logical-OR-expression
9227 logical-OR-expression ? expression : conditional-expression
9231 conditional-expression:
9232 logical-OR-expression ? : conditional-expression
9235 static struct c_expr
9236 c_parser_conditional_expression (c_parser
*parser
, struct c_expr
*after
,
9237 tree omp_atomic_lhs
)
9239 struct c_expr cond
, exp1
, exp2
, ret
;
9240 location_t start
, cond_loc
, colon_loc
;
9241 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
9243 gcc_assert (!after
|| c_dialect_objc ());
9245 cond
= c_parser_binary_expression (parser
, after
, omp_atomic_lhs
);
9247 if (c_parser_next_token_is_not (parser
, CPP_QUERY
))
9249 c_omp_array_section_p
= false;
9250 if (cond
.value
!= error_mark_node
)
9251 start
= cond
.get_start ();
9253 start
= UNKNOWN_LOCATION
;
9254 cond_loc
= c_parser_peek_token (parser
)->location
;
9255 cond
= convert_lvalue_to_rvalue (cond_loc
, cond
, true, true);
9256 c_parser_consume_token (parser
);
9257 if (c_parser_next_token_is (parser
, CPP_COLON
))
9259 tree eptype
= NULL_TREE
;
9261 location_t middle_loc
= c_parser_peek_token (parser
)->location
;
9262 pedwarn (middle_loc
, OPT_Wpedantic
,
9263 "ISO C forbids omitting the middle term of a %<?:%> expression");
9264 if (TREE_CODE (cond
.value
) == EXCESS_PRECISION_EXPR
)
9266 eptype
= TREE_TYPE (cond
.value
);
9267 cond
.value
= TREE_OPERAND (cond
.value
, 0);
9269 tree e
= cond
.value
;
9270 while (TREE_CODE (e
) == COMPOUND_EXPR
)
9271 e
= TREE_OPERAND (e
, 1);
9272 warn_for_omitted_condop (middle_loc
, e
);
9273 /* Make sure first operand is calculated only once. */
9274 exp1
.value
= save_expr (default_conversion (cond
.value
));
9276 exp1
.value
= build1 (EXCESS_PRECISION_EXPR
, eptype
, exp1
.value
);
9277 exp1
.original_type
= NULL
;
9278 exp1
.src_range
= cond
.src_range
;
9279 cond
.value
= c_objc_common_truthvalue_conversion (cond_loc
, exp1
.value
);
9280 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_true_node
;
9285 = c_objc_common_truthvalue_conversion
9286 (cond_loc
, default_conversion (cond
.value
));
9287 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_false_node
;
9288 exp1
= c_parser_expression_conv (parser
);
9289 mark_exp_read (exp1
.value
);
9290 c_inhibit_evaluation_warnings
+=
9291 ((cond
.value
== truthvalue_true_node
)
9292 - (cond
.value
== truthvalue_false_node
));
9295 colon_loc
= c_parser_peek_token (parser
)->location
;
9296 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
9298 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
9300 ret
.original_code
= ERROR_MARK
;
9301 ret
.original_type
= NULL
;
9302 c_omp_array_section_p
= save_c_omp_array_section_p
;
9306 location_t exp2_loc
= c_parser_peek_token (parser
)->location
;
9307 exp2
= c_parser_conditional_expression (parser
, NULL
, NULL_TREE
);
9308 exp2
= convert_lvalue_to_rvalue (exp2_loc
, exp2
, true, true);
9310 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
9311 location_t loc1
= make_location (exp1
.get_start (), exp1
.src_range
);
9312 location_t loc2
= make_location (exp2
.get_start (), exp2
.src_range
);
9313 if (UNLIKELY (omp_atomic_lhs
!= NULL
)
9314 && (TREE_CODE (cond
.value
) == GT_EXPR
9315 || TREE_CODE (cond
.value
) == LT_EXPR
9316 || TREE_CODE (cond
.value
) == EQ_EXPR
)
9317 && c_tree_equal (exp2
.value
, omp_atomic_lhs
)
9318 && (c_tree_equal (TREE_OPERAND (cond
.value
, 0), omp_atomic_lhs
)
9319 || c_tree_equal (TREE_OPERAND (cond
.value
, 1), omp_atomic_lhs
)))
9320 ret
.value
= build3_loc (colon_loc
, COND_EXPR
, TREE_TYPE (omp_atomic_lhs
),
9321 cond
.value
, exp1
.value
, exp2
.value
);
9324 = build_conditional_expr (colon_loc
, cond
.value
,
9325 cond
.original_code
== C_MAYBE_CONST_EXPR
,
9326 exp1
.value
, exp1
.original_type
, loc1
,
9327 exp2
.value
, exp2
.original_type
, loc2
);
9328 ret
.original_code
= ERROR_MARK
;
9329 if (exp1
.value
== error_mark_node
|| exp2
.value
== error_mark_node
)
9330 ret
.original_type
= NULL
;
9335 /* If both sides are enum type, the default conversion will have
9336 made the type of the result be an integer type. We want to
9337 remember the enum types we started with. */
9338 t1
= exp1
.original_type
? exp1
.original_type
: TREE_TYPE (exp1
.value
);
9339 t2
= exp2
.original_type
? exp2
.original_type
: TREE_TYPE (exp2
.value
);
9340 ret
.original_type
= ((t1
!= error_mark_node
9341 && t2
!= error_mark_node
9342 && (TYPE_MAIN_VARIANT (t1
)
9343 == TYPE_MAIN_VARIANT (t2
)))
9347 set_c_expr_source_range (&ret
, start
, exp2
.get_finish ());
9349 c_omp_array_section_p
= save_c_omp_array_section_p
;
9353 /* Parse a binary expression; that is, a logical-OR-expression (C90
9354 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
9355 NULL then it is an Objective-C message expression which is the
9356 primary-expression starting the expression as an initializer.
9358 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
9359 when it should be the unfolded lhs. In a valid OpenMP source,
9360 one of the operands of the toplevel binary expression must be equal
9361 to it. In that case, just return a build2 created binary operation
9362 rather than result of parser_build_binary_op.
9364 multiplicative-expression:
9366 multiplicative-expression * cast-expression
9367 multiplicative-expression / cast-expression
9368 multiplicative-expression % cast-expression
9370 additive-expression:
9371 multiplicative-expression
9372 additive-expression + multiplicative-expression
9373 additive-expression - multiplicative-expression
9377 shift-expression << additive-expression
9378 shift-expression >> additive-expression
9380 relational-expression:
9382 relational-expression < shift-expression
9383 relational-expression > shift-expression
9384 relational-expression <= shift-expression
9385 relational-expression >= shift-expression
9387 equality-expression:
9388 relational-expression
9389 equality-expression == relational-expression
9390 equality-expression != relational-expression
9394 AND-expression & equality-expression
9396 exclusive-OR-expression:
9398 exclusive-OR-expression ^ AND-expression
9400 inclusive-OR-expression:
9401 exclusive-OR-expression
9402 inclusive-OR-expression | exclusive-OR-expression
9404 logical-AND-expression:
9405 inclusive-OR-expression
9406 logical-AND-expression && inclusive-OR-expression
9408 logical-OR-expression:
9409 logical-AND-expression
9410 logical-OR-expression || logical-AND-expression
9413 static struct c_expr
9414 c_parser_binary_expression (c_parser
*parser
, struct c_expr
*after
,
9415 tree omp_atomic_lhs
)
9417 /* A binary expression is parsed using operator-precedence parsing,
9418 with the operands being cast expressions. All the binary
9419 operators are left-associative. Thus a binary expression is of
9422 E0 op1 E1 op2 E2 ...
9424 which we represent on a stack. On the stack, the precedence
9425 levels are strictly increasing. When a new operator is
9426 encountered of higher precedence than that at the top of the
9427 stack, it is pushed; its LHS is the top expression, and its RHS
9428 is everything parsed until it is popped. When a new operator is
9429 encountered with precedence less than or equal to that at the top
9430 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
9431 by the result of the operation until the operator at the top of
9432 the stack has lower precedence than the new operator or there is
9433 only one element on the stack; then the top expression is the LHS
9434 of the new operator. In the case of logical AND and OR
9435 expressions, we also need to adjust c_inhibit_evaluation_warnings
9436 as appropriate when the operators are pushed and popped. */
9439 /* The expression at this stack level. */
9441 /* The precedence of the operator on its left, PREC_NONE at the
9442 bottom of the stack. */
9443 enum c_parser_prec prec
;
9444 /* The operation on its left. */
9446 /* The source location of this operation. */
9448 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
9452 /* Location of the binary operator. */
9453 location_t binary_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
9456 switch (stack[sp].op) \
9458 case TRUTH_ANDIF_EXPR: \
9459 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9460 == truthvalue_false_node); \
9462 case TRUTH_ORIF_EXPR: \
9463 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9464 == truthvalue_true_node); \
9466 case TRUNC_DIV_EXPR: \
9467 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
9468 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
9469 && (stack[sp].expr.original_code == SIZEOF_EXPR \
9470 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
9472 tree type0 = stack[sp - 1].sizeof_arg; \
9473 tree type1 = stack[sp].sizeof_arg; \
9474 tree first_arg = type0; \
9475 if (!TYPE_P (type0)) \
9476 type0 = TREE_TYPE (type0); \
9477 if (!TYPE_P (type1)) \
9478 type1 = TREE_TYPE (type1); \
9479 if (POINTER_TYPE_P (type0) \
9480 && comptypes (TREE_TYPE (type0), type1) \
9481 && !(TREE_CODE (first_arg) == PARM_DECL \
9482 && C_ARRAY_PARAMETER (first_arg) \
9483 && warn_sizeof_array_argument)) \
9485 auto_diagnostic_group d; \
9486 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
9487 "division %<sizeof (%T) / sizeof (%T)%> " \
9488 "does not compute the number of array " \
9491 if (DECL_P (first_arg)) \
9492 inform (DECL_SOURCE_LOCATION (first_arg), \
9493 "first %<sizeof%> operand was declared here"); \
9495 else if (TREE_CODE (type0) == ARRAY_TYPE \
9496 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
9497 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
9498 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
9499 stack[sp].sizeof_arg, type1); \
9505 stack[sp - 1].expr \
9506 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
9507 stack[sp - 1].expr, true, true); \
9509 = convert_lvalue_to_rvalue (stack[sp].loc, \
9510 stack[sp].expr, true, true); \
9511 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
9512 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
9513 && ((1 << stack[sp].prec) \
9514 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
9515 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
9516 | (1 << PREC_ADD) | (1 << PREC_MULT) \
9517 | (1 << PREC_EQ)))) \
9518 || ((c_parser_next_token_is (parser, CPP_QUERY) \
9519 || (omp_atomic_lhs == void_list_node \
9520 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
9521 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
9522 && stack[sp].op != TRUNC_MOD_EXPR \
9523 && stack[sp].op != GE_EXPR \
9524 && stack[sp].op != LE_EXPR \
9525 && stack[sp].op != NE_EXPR \
9526 && stack[0].expr.value != error_mark_node \
9527 && stack[1].expr.value != error_mark_node \
9528 && (omp_atomic_lhs == void_list_node \
9529 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
9530 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
9531 || (stack[sp].op == EQ_EXPR \
9532 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
9534 tree t = make_node (stack[1].op); \
9535 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
9536 TREE_OPERAND (t, 0) = stack[0].expr.value; \
9537 TREE_OPERAND (t, 1) = stack[1].expr.value; \
9538 stack[0].expr.value = t; \
9539 stack[0].expr.m_decimal = 0; \
9542 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
9544 stack[sp - 1].expr, \
9548 gcc_assert (!after
|| c_dialect_objc ());
9549 stack
[0].loc
= c_parser_peek_token (parser
)->location
;
9550 stack
[0].expr
= c_parser_cast_expression (parser
, after
);
9551 stack
[0].prec
= PREC_NONE
;
9552 stack
[0].sizeof_arg
= c_last_sizeof_arg
;
9556 enum c_parser_prec oprec
;
9557 enum tree_code ocode
;
9558 source_range src_range
;
9561 switch (c_parser_peek_token (parser
)->type
)
9569 ocode
= TRUNC_DIV_EXPR
;
9573 ocode
= TRUNC_MOD_EXPR
;
9585 ocode
= LSHIFT_EXPR
;
9589 ocode
= RSHIFT_EXPR
;
9603 case CPP_GREATER_EQ
:
9616 oprec
= PREC_BITAND
;
9617 ocode
= BIT_AND_EXPR
;
9620 oprec
= PREC_BITXOR
;
9621 ocode
= BIT_XOR_EXPR
;
9625 ocode
= BIT_IOR_EXPR
;
9628 oprec
= PREC_LOGAND
;
9629 ocode
= TRUTH_ANDIF_EXPR
;
9633 ocode
= TRUTH_ORIF_EXPR
;
9636 /* Not a binary operator, so end of the binary
9640 binary_loc
= c_parser_peek_token (parser
)->location
;
9641 while (oprec
<= stack
[sp
].prec
)
9643 c_parser_consume_token (parser
);
9646 case TRUTH_ANDIF_EXPR
:
9647 src_range
= stack
[sp
].expr
.src_range
;
9649 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
9650 stack
[sp
].expr
, true, true);
9651 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
9652 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
9653 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
9654 == truthvalue_false_node
);
9655 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
9657 case TRUTH_ORIF_EXPR
:
9658 src_range
= stack
[sp
].expr
.src_range
;
9660 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
9661 stack
[sp
].expr
, true, true);
9662 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
9663 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
9664 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
9665 == truthvalue_true_node
);
9666 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
9672 stack
[sp
].loc
= binary_loc
;
9673 stack
[sp
].expr
= c_parser_cast_expression (parser
, NULL
);
9674 stack
[sp
].prec
= oprec
;
9675 stack
[sp
].op
= ocode
;
9676 stack
[sp
].sizeof_arg
= c_last_sizeof_arg
;
9681 return stack
[0].expr
;
9685 /* Parse any storage class specifiers after an open parenthesis in a
9686 context where a compound literal is permitted. */
9688 static struct c_declspecs
*
9689 c_parser_compound_literal_scspecs (c_parser
*parser
)
9691 bool seen_scspec
= false;
9692 struct c_declspecs
*specs
= build_null_declspecs ();
9693 while (c_parser_next_token_is (parser
, CPP_KEYWORD
))
9695 switch (c_parser_peek_token (parser
)->keyword
)
9702 declspecs_add_scspec (c_parser_peek_token (parser
)->location
,
9703 specs
, c_parser_peek_token (parser
)->value
);
9704 c_parser_consume_token (parser
);
9711 return seen_scspec
? specs
: NULL
;
9714 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
9715 is not NULL then it is an Objective-C message expression which is the
9716 primary-expression starting the expression as an initializer.
9720 ( type-name ) unary-expression
9723 static struct c_expr
9724 c_parser_cast_expression (c_parser
*parser
, struct c_expr
*after
)
9726 location_t cast_loc
= c_parser_peek_token (parser
)->location
;
9727 gcc_assert (!after
|| c_dialect_objc ());
9729 return c_parser_postfix_expression_after_primary (parser
,
9731 /* If the expression begins with a parenthesized type name, it may
9732 be either a cast or a compound literal; we need to see whether
9733 the next character is '{' to tell the difference. If not, it is
9734 an unary expression. Full detection of unknown typenames here
9735 would require a 3-token lookahead. */
9736 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
9737 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
9739 struct c_declspecs
*scspecs
;
9740 struct c_type_name
*type_name
;
9743 matching_parens parens
;
9744 parens
.consume_open (parser
);
9745 scspecs
= c_parser_compound_literal_scspecs (parser
);
9746 type_name
= c_parser_type_name (parser
, true);
9747 parens
.skip_until_found_close (parser
);
9748 if (type_name
== NULL
)
9751 ret
.original_code
= ERROR_MARK
;
9752 ret
.original_type
= NULL
;
9756 /* Save casted types in the function's used types hash table. */
9757 used_types_insert (type_name
->specs
->type
);
9759 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
9760 return c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
9764 error_at (cast_loc
, "storage class specifier in cast");
9765 if (type_name
->specs
->alignas_p
)
9766 error_at (type_name
->specs
->locations
[cdw_alignas
],
9767 "alignment specified for type name in cast");
9769 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
9770 expr
= c_parser_cast_expression (parser
, NULL
);
9771 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
9773 ret
.value
= c_cast_expr (cast_loc
, type_name
, expr
.value
);
9774 if (ret
.value
&& expr
.value
)
9775 set_c_expr_source_range (&ret
, cast_loc
, expr
.get_finish ());
9776 ret
.original_code
= ERROR_MARK
;
9777 ret
.original_type
= NULL
;
9782 return c_parser_unary_expression (parser
);
9785 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
9791 unary-operator cast-expression
9792 sizeof unary-expression
9793 sizeof ( type-name )
9795 unary-operator: one of
9801 __alignof__ unary-expression
9802 __alignof__ ( type-name )
9805 (C11 permits _Alignof with type names only.)
9807 unary-operator: one of
9808 __extension__ __real__ __imag__
9810 Transactional Memory:
9813 transaction-expression
9815 In addition, the GNU syntax treats ++ and -- as unary operators, so
9816 they may be applied to cast expressions with errors for non-lvalues
9819 static struct c_expr
9820 c_parser_unary_expression (c_parser
*parser
)
9823 struct c_expr ret
, op
;
9824 location_t op_loc
= c_parser_peek_token (parser
)->location
;
9827 ret
.original_code
= ERROR_MARK
;
9828 ret
.original_type
= NULL
;
9829 switch (c_parser_peek_token (parser
)->type
)
9832 c_parser_consume_token (parser
);
9833 exp_loc
= c_parser_peek_token (parser
)->location
;
9834 op
= c_parser_cast_expression (parser
, NULL
);
9836 op
= default_function_array_read_conversion (exp_loc
, op
);
9837 return parser_build_unary_op (op_loc
, PREINCREMENT_EXPR
, op
);
9838 case CPP_MINUS_MINUS
:
9839 c_parser_consume_token (parser
);
9840 exp_loc
= c_parser_peek_token (parser
)->location
;
9841 op
= c_parser_cast_expression (parser
, NULL
);
9843 op
= default_function_array_read_conversion (exp_loc
, op
);
9844 return parser_build_unary_op (op_loc
, PREDECREMENT_EXPR
, op
);
9846 c_parser_consume_token (parser
);
9847 op
= c_parser_cast_expression (parser
, NULL
);
9848 mark_exp_read (op
.value
);
9849 return parser_build_unary_op (op_loc
, ADDR_EXPR
, op
);
9852 c_parser_consume_token (parser
);
9853 exp_loc
= c_parser_peek_token (parser
)->location
;
9854 op
= c_parser_cast_expression (parser
, NULL
);
9855 finish
= op
.get_finish ();
9856 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9857 location_t combined_loc
= make_location (op_loc
, op_loc
, finish
);
9858 ret
.value
= build_indirect_ref (combined_loc
, op
.value
, RO_UNARY_STAR
);
9859 ret
.src_range
.m_start
= op_loc
;
9860 ret
.src_range
.m_finish
= finish
;
9865 if (!c_dialect_objc () && !in_system_header_at (input_location
))
9868 "traditional C rejects the unary plus operator");
9869 c_parser_consume_token (parser
);
9870 exp_loc
= c_parser_peek_token (parser
)->location
;
9871 op
= c_parser_cast_expression (parser
, NULL
);
9872 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9873 return parser_build_unary_op (op_loc
, CONVERT_EXPR
, op
);
9875 c_parser_consume_token (parser
);
9876 exp_loc
= c_parser_peek_token (parser
)->location
;
9877 op
= c_parser_cast_expression (parser
, NULL
);
9878 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9879 return parser_build_unary_op (op_loc
, NEGATE_EXPR
, op
);
9881 c_parser_consume_token (parser
);
9882 exp_loc
= c_parser_peek_token (parser
)->location
;
9883 op
= c_parser_cast_expression (parser
, NULL
);
9884 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9885 return parser_build_unary_op (op_loc
, BIT_NOT_EXPR
, op
);
9887 c_parser_consume_token (parser
);
9888 exp_loc
= c_parser_peek_token (parser
)->location
;
9889 op
= c_parser_cast_expression (parser
, NULL
);
9890 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9891 return parser_build_unary_op (op_loc
, TRUTH_NOT_EXPR
, op
);
9893 /* Refer to the address of a label as a pointer. */
9894 c_parser_consume_token (parser
);
9895 if (c_parser_next_token_is (parser
, CPP_NAME
))
9897 ret
.value
= finish_label_address_expr
9898 (c_parser_peek_token (parser
)->value
, op_loc
);
9899 set_c_expr_source_range (&ret
, op_loc
,
9900 c_parser_peek_token (parser
)->get_finish ());
9901 c_parser_consume_token (parser
);
9905 c_parser_error (parser
, "expected identifier");
9910 switch (c_parser_peek_token (parser
)->keyword
)
9913 return c_parser_sizeof_expression (parser
);
9915 return c_parser_alignof_expression (parser
);
9916 case RID_BUILTIN_HAS_ATTRIBUTE
:
9917 return c_parser_has_attribute_expression (parser
);
9919 c_parser_consume_token (parser
);
9920 ext
= disable_extension_diagnostics ();
9921 ret
= c_parser_cast_expression (parser
, NULL
);
9922 restore_extension_diagnostics (ext
);
9925 c_parser_consume_token (parser
);
9926 exp_loc
= c_parser_peek_token (parser
)->location
;
9927 op
= c_parser_cast_expression (parser
, NULL
);
9928 op
= default_function_array_conversion (exp_loc
, op
);
9929 return parser_build_unary_op (op_loc
, REALPART_EXPR
, op
);
9931 c_parser_consume_token (parser
);
9932 exp_loc
= c_parser_peek_token (parser
)->location
;
9933 op
= c_parser_cast_expression (parser
, NULL
);
9934 op
= default_function_array_conversion (exp_loc
, op
);
9935 return parser_build_unary_op (op_loc
, IMAGPART_EXPR
, op
);
9936 case RID_TRANSACTION_ATOMIC
:
9937 case RID_TRANSACTION_RELAXED
:
9938 return c_parser_transaction_expression (parser
,
9939 c_parser_peek_token (parser
)->keyword
);
9941 return c_parser_postfix_expression (parser
);
9944 return c_parser_postfix_expression (parser
);
9948 /* Parse a sizeof expression. */
9950 static struct c_expr
9951 c_parser_sizeof_expression (c_parser
*parser
)
9954 struct c_expr result
;
9955 location_t expr_loc
;
9956 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SIZEOF
));
9959 location_t finish
= UNKNOWN_LOCATION
;
9961 start
= c_parser_peek_token (parser
)->location
;
9963 c_parser_consume_token (parser
);
9964 c_inhibit_evaluation_warnings
++;
9966 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
9967 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
9969 /* Either sizeof ( type-name ) or sizeof unary-expression
9970 starting with a compound literal. */
9971 struct c_declspecs
*scspecs
;
9972 struct c_type_name
*type_name
;
9973 matching_parens parens
;
9974 parens
.consume_open (parser
);
9975 expr_loc
= c_parser_peek_token (parser
)->location
;
9976 scspecs
= c_parser_compound_literal_scspecs (parser
);
9977 type_name
= c_parser_type_name (parser
, true);
9978 parens
.skip_until_found_close (parser
);
9979 finish
= parser
->tokens_buf
[0].location
;
9980 if (type_name
== NULL
)
9983 c_inhibit_evaluation_warnings
--;
9986 ret
.original_code
= ERROR_MARK
;
9987 ret
.original_type
= NULL
;
9990 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
9992 expr
= c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
9995 finish
= expr
.get_finish ();
9998 /* sizeof ( type-name ). */
10000 error_at (expr_loc
, "storage class specifier in %<sizeof%>");
10001 if (type_name
->specs
->alignas_p
)
10002 error_at (type_name
->specs
->locations
[cdw_alignas
],
10003 "alignment specified for type name in %<sizeof%>");
10004 c_inhibit_evaluation_warnings
--;
10006 result
= c_expr_sizeof_type (expr_loc
, type_name
);
10010 expr_loc
= c_parser_peek_token (parser
)->location
;
10011 expr
= c_parser_unary_expression (parser
);
10012 finish
= expr
.get_finish ();
10014 c_inhibit_evaluation_warnings
--;
10016 mark_exp_read (expr
.value
);
10017 if (TREE_CODE (expr
.value
) == COMPONENT_REF
10018 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
10019 error_at (expr_loc
, "%<sizeof%> applied to a bit-field");
10020 result
= c_expr_sizeof_expr (expr_loc
, expr
);
10022 if (finish
== UNKNOWN_LOCATION
)
10024 set_c_expr_source_range (&result
, start
, finish
);
10028 /* Parse an alignof expression. */
10030 static struct c_expr
10031 c_parser_alignof_expression (c_parser
*parser
)
10033 struct c_expr expr
;
10034 location_t start_loc
= c_parser_peek_token (parser
)->location
;
10035 location_t end_loc
;
10036 tree alignof_spelling
= c_parser_peek_token (parser
)->value
;
10037 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNOF
));
10038 bool is_c11_alignof
= (strcmp (IDENTIFIER_POINTER (alignof_spelling
),
10040 || strcmp (IDENTIFIER_POINTER (alignof_spelling
),
10042 /* A diagnostic is not required for the use of this identifier in
10043 the implementation namespace; only diagnose it for the C11 or C23
10044 spelling because of existing code using the other spellings. */
10045 if (is_c11_alignof
)
10048 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C99 does not support %qE",
10051 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C90 does not support %qE",
10054 c_parser_consume_token (parser
);
10055 c_inhibit_evaluation_warnings
++;
10057 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
10058 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
10060 /* Either __alignof__ ( type-name ) or __alignof__
10061 unary-expression starting with a compound literal. */
10063 struct c_declspecs
*scspecs
;
10064 struct c_type_name
*type_name
;
10066 matching_parens parens
;
10067 parens
.consume_open (parser
);
10068 loc
= c_parser_peek_token (parser
)->location
;
10069 scspecs
= c_parser_compound_literal_scspecs (parser
);
10070 type_name
= c_parser_type_name (parser
, true);
10071 end_loc
= c_parser_peek_token (parser
)->location
;
10072 parens
.skip_until_found_close (parser
);
10073 if (type_name
== NULL
)
10076 c_inhibit_evaluation_warnings
--;
10079 ret
.original_code
= ERROR_MARK
;
10080 ret
.original_type
= NULL
;
10083 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
10085 expr
= c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
10090 /* alignof ( type-name ). */
10092 error_at (loc
, "storage class specifier in %qE", alignof_spelling
);
10093 if (type_name
->specs
->alignas_p
)
10094 error_at (type_name
->specs
->locations
[cdw_alignas
],
10095 "alignment specified for type name in %qE",
10097 c_inhibit_evaluation_warnings
--;
10099 ret
.value
= c_sizeof_or_alignof_type (loc
, groktypename (type_name
,
10101 false, is_c11_alignof
, 1);
10102 ret
.original_code
= ERROR_MARK
;
10103 ret
.original_type
= NULL
;
10104 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
10111 expr
= c_parser_unary_expression (parser
);
10112 end_loc
= expr
.src_range
.m_finish
;
10114 mark_exp_read (expr
.value
);
10115 c_inhibit_evaluation_warnings
--;
10117 if (is_c11_alignof
)
10118 pedwarn (start_loc
,
10119 OPT_Wpedantic
, "ISO C does not allow %<%E (expression)%>",
10121 ret
.value
= c_alignof_expr (start_loc
, expr
.value
);
10122 ret
.original_code
= ERROR_MARK
;
10123 ret
.original_type
= NULL
;
10124 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
10130 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
10133 static struct c_expr
10134 c_parser_has_attribute_expression (c_parser
*parser
)
10136 gcc_assert (c_parser_next_token_is_keyword (parser
,
10137 RID_BUILTIN_HAS_ATTRIBUTE
));
10138 location_t start
= c_parser_peek_token (parser
)->location
;
10139 c_parser_consume_token (parser
);
10141 c_inhibit_evaluation_warnings
++;
10143 matching_parens parens
;
10144 if (!parens
.require_open (parser
))
10146 c_inhibit_evaluation_warnings
--;
10149 struct c_expr result
;
10150 result
.set_error ();
10151 result
.original_code
= ERROR_MARK
;
10152 result
.original_type
= NULL
;
10156 /* Treat the type argument the same way as in typeof for the purposes
10157 of warnings. FIXME: Generalize this so the warning refers to
10158 __builtin_has_attribute rather than typeof. */
10161 /* The first operand: one of DECL, EXPR, or TYPE. */
10162 tree oper
= NULL_TREE
;
10163 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
10165 struct c_type_name
*tname
= c_parser_type_name (parser
);
10169 oper
= groktypename (tname
, NULL
, NULL
);
10170 pop_maybe_used (c_type_variably_modified_p (oper
));
10175 struct c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
10176 c_inhibit_evaluation_warnings
--;
10178 if (cexpr
.value
!= error_mark_node
)
10180 mark_exp_read (cexpr
.value
);
10181 oper
= cexpr
.value
;
10182 tree etype
= TREE_TYPE (oper
);
10183 bool was_vm
= c_type_variably_modified_p (etype
);
10184 /* This is returned with the type so that when the type is
10185 evaluated, this can be evaluated. */
10187 oper
= c_fully_fold (oper
, false, NULL
);
10188 pop_maybe_used (was_vm
);
10192 struct c_expr result
;
10193 result
.original_code
= ERROR_MARK
;
10194 result
.original_type
= NULL
;
10196 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10198 /* Consume the closing parenthesis if that's the next token
10199 in the likely case the built-in was invoked with fewer
10200 than two arguments. */
10201 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10202 c_parser_consume_token (parser
);
10203 c_inhibit_evaluation_warnings
--;
10204 result
.set_error ();
10208 bool save_translate_strings_p
= parser
->translate_strings_p
;
10210 location_t atloc
= c_parser_peek_token (parser
)->location
;
10211 /* Parse a single attribute. Require no leading comma and do not
10212 allow empty attributes. */
10213 tree attr
= c_parser_gnu_attribute (parser
, NULL_TREE
, false, false);
10215 parser
->translate_strings_p
= save_translate_strings_p
;
10217 location_t finish
= c_parser_peek_token (parser
)->location
;
10218 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10219 c_parser_consume_token (parser
);
10222 c_parser_error (parser
, "expected identifier");
10223 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10225 result
.set_error ();
10231 error_at (atloc
, "expected identifier");
10232 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10234 result
.set_error ();
10238 result
.original_code
= INTEGER_CST
;
10239 result
.original_type
= boolean_type_node
;
10241 if (has_attribute (atloc
, oper
, attr
, default_conversion
))
10242 result
.value
= boolean_true_node
;
10244 result
.value
= boolean_false_node
;
10246 set_c_expr_source_range (&result
, start
, finish
);
10247 result
.m_decimal
= 0;
10251 /* Helper function to read arguments of builtins which are interfaces
10252 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
10253 others. The name of the builtin is passed using BNAME parameter.
10254 Function returns true if there were no errors while parsing and
10255 stores the arguments in CEXPR_LIST. If it returns true,
10256 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
10259 c_parser_get_builtin_args (c_parser
*parser
, const char *bname
,
10260 vec
<c_expr_t
, va_gc
> **ret_cexpr_list
,
10261 bool choose_expr_p
,
10262 location_t
*out_close_paren_loc
)
10264 location_t loc
= c_parser_peek_token (parser
)->location
;
10265 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10267 bool saved_force_folding_builtin_constant_p
;
10269 *ret_cexpr_list
= NULL
;
10270 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
10272 error_at (loc
, "cannot take address of %qs", bname
);
10276 c_parser_consume_token (parser
);
10278 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10280 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
10281 c_parser_consume_token (parser
);
10285 saved_force_folding_builtin_constant_p
10286 = force_folding_builtin_constant_p
;
10287 force_folding_builtin_constant_p
|= choose_expr_p
;
10288 expr
= c_parser_expr_no_commas (parser
, NULL
);
10289 force_folding_builtin_constant_p
10290 = saved_force_folding_builtin_constant_p
;
10291 vec_alloc (cexpr_list
, 1);
10292 vec_safe_push (cexpr_list
, expr
);
10293 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10295 c_parser_consume_token (parser
);
10296 expr
= c_parser_expr_no_commas (parser
, NULL
);
10297 vec_safe_push (cexpr_list
, expr
);
10300 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
10301 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
10304 *ret_cexpr_list
= cexpr_list
;
10308 /* This represents a single generic-association. */
10310 struct c_generic_association
10312 /* The location of the starting token of the type. */
10313 location_t type_location
;
10314 /* The association's type, or NULL_TREE for 'default'. */
10316 /* The association's expression. */
10317 struct c_expr expression
;
10320 /* Parse a generic-selection. (C11 6.5.1.1).
10323 _Generic ( generic-controlling-operand , generic-assoc-list )
10325 generic-controlling-operand:
10326 assignment-expression
10329 (The use of a type-name is new in C2Y.)
10331 generic-assoc-list:
10332 generic-association
10333 generic-assoc-list , generic-association
10335 generic-association:
10336 type-name : assignment-expression
10337 default : assignment-expression
10340 static struct c_expr
10341 c_parser_generic_selection (c_parser
*parser
)
10343 struct c_expr selector
, error_expr
;
10344 tree selector_type
;
10345 struct c_generic_association matched_assoc
;
10346 int match_found
= -1;
10347 location_t generic_loc
, selector_loc
;
10349 error_expr
.original_code
= ERROR_MARK
;
10350 error_expr
.original_type
= NULL
;
10351 error_expr
.set_error ();
10352 matched_assoc
.type_location
= UNKNOWN_LOCATION
;
10353 matched_assoc
.type
= NULL_TREE
;
10354 matched_assoc
.expression
= error_expr
;
10356 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_GENERIC
));
10357 generic_loc
= c_parser_peek_token (parser
)->location
;
10358 c_parser_consume_token (parser
);
10360 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
10361 "ISO C99 does not support %<_Generic%>");
10363 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
10364 "ISO C90 does not support %<_Generic%>");
10366 matching_parens parens
;
10367 if (!parens
.require_open (parser
))
10370 selector_loc
= c_parser_peek_token (parser
)->location
;
10371 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
10373 c_inhibit_evaluation_warnings
++;
10374 pedwarn_c23 (selector_loc
, OPT_Wpedantic
,
10375 "ISO C does not support use of type name as %<_Generic%> "
10376 "controlling operand before C2Y");
10377 struct c_type_name
*type
= c_parser_type_name (parser
);
10378 selector_type
= groktypename (type
, NULL
, NULL
);
10379 c_inhibit_evaluation_warnings
--;
10383 c_inhibit_evaluation_warnings
++;
10384 selector
= c_parser_expr_no_commas (parser
, NULL
);
10385 selector
= default_function_array_conversion (selector_loc
, selector
);
10386 c_inhibit_evaluation_warnings
--;
10388 if (selector
.value
== error_mark_node
)
10390 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10393 mark_exp_read (selector
.value
);
10394 selector_type
= TREE_TYPE (selector
.value
);
10395 /* In ISO C terms, rvalues (including the controlling expression
10396 of _Generic) do not have qualified types. */
10397 if (TREE_CODE (selector_type
) != ARRAY_TYPE
)
10398 selector_type
= TYPE_MAIN_VARIANT (selector_type
);
10399 /* In ISO C terms, _Noreturn is not part of the type of expressions
10400 such as &abort, but in GCC it is represented internally as a type
10402 if (FUNCTION_POINTER_TYPE_P (selector_type
)
10403 && TYPE_QUALS (TREE_TYPE (selector_type
)) != TYPE_UNQUALIFIED
)
10405 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type
)));
10408 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10410 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10414 auto_vec
<c_generic_association
> associations
;
10417 struct c_generic_association assoc
, *iter
;
10419 c_token
*token
= c_parser_peek_token (parser
);
10421 assoc
.type_location
= token
->location
;
10422 if (token
->type
== CPP_KEYWORD
&& token
->keyword
== RID_DEFAULT
)
10424 c_parser_consume_token (parser
);
10425 assoc
.type
= NULL_TREE
;
10429 struct c_type_name
*type_name
;
10431 type_name
= c_parser_type_name (parser
);
10432 if (type_name
== NULL
)
10434 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10437 assoc
.type
= groktypename (type_name
, NULL
, NULL
);
10438 if (assoc
.type
== error_mark_node
)
10440 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10444 if (TREE_CODE (assoc
.type
) == FUNCTION_TYPE
)
10445 pedwarn_c23 (assoc
.type_location
, OPT_Wpedantic
,
10446 "ISO C does not support %<_Generic%> association with "
10447 "function type before C2Y");
10448 else if (!COMPLETE_TYPE_P (assoc
.type
))
10449 pedwarn_c23 (assoc
.type_location
, OPT_Wpedantic
,
10450 "ISO C does not support %<_Generic%> association with "
10451 "incomplete type before C2Y");
10453 if (c_type_variably_modified_p (assoc
.type
))
10454 error_at (assoc
.type_location
,
10455 "%<_Generic%> association has "
10456 "variable length type");
10459 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
10461 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10465 bool match
= assoc
.type
== NULL_TREE
10466 || comptypes (assoc
.type
, selector_type
);
10469 c_inhibit_evaluation_warnings
++;
10471 assoc
.expression
= c_parser_expr_no_commas (parser
, NULL
);
10474 c_inhibit_evaluation_warnings
--;
10476 if (assoc
.expression
.value
== error_mark_node
)
10478 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10482 for (ix
= 0; associations
.iterate (ix
, &iter
); ++ix
)
10484 if (assoc
.type
== NULL_TREE
)
10486 if (iter
->type
== NULL_TREE
)
10488 error_at (assoc
.type_location
,
10489 "duplicate %<default%> case in %<_Generic%>");
10490 inform (iter
->type_location
, "original %<default%> is here");
10493 else if (iter
->type
!= NULL_TREE
)
10495 if (comptypes (assoc
.type
, iter
->type
))
10497 error_at (assoc
.type_location
,
10498 "%<_Generic%> specifies two compatible types");
10499 inform (iter
->type_location
, "compatible type is here");
10504 if (assoc
.type
== NULL_TREE
)
10506 if (match_found
< 0)
10508 matched_assoc
= assoc
;
10509 match_found
= associations
.length ();
10514 if (match_found
< 0 || matched_assoc
.type
== NULL_TREE
)
10516 matched_assoc
= assoc
;
10517 match_found
= associations
.length ();
10521 error_at (assoc
.type_location
,
10522 "%<_Generic%> selector matches multiple associations");
10523 inform (matched_assoc
.type_location
,
10524 "other match is here");
10528 associations
.safe_push (assoc
);
10530 if (c_parser_peek_token (parser
)->type
!= CPP_COMMA
)
10532 c_parser_consume_token (parser
);
10536 struct c_generic_association
*iter
;
10537 FOR_EACH_VEC_ELT (associations
, ix
, iter
)
10538 if (ix
!= (unsigned) match_found
)
10539 mark_exp_read (iter
->expression
.value
);
10541 if (!parens
.require_close (parser
))
10543 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10547 if (match_found
< 0)
10549 error_at (selector_loc
, "%<_Generic%> selector of type %qT is not "
10550 "compatible with any association",
10555 return matched_assoc
.expression
;
10558 /* Check the validity of a function pointer argument *EXPR (argument
10559 position POS) to __builtin_tgmath. Return the number of function
10560 arguments if possibly valid; return 0 having reported an error if
10563 static unsigned int
10564 check_tgmath_function (c_expr
*expr
, unsigned int pos
)
10566 tree type
= TREE_TYPE (expr
->value
);
10567 if (!FUNCTION_POINTER_TYPE_P (type
))
10569 error_at (expr
->get_location (),
10570 "argument %u of %<__builtin_tgmath%> is not a function pointer",
10574 type
= TREE_TYPE (type
);
10575 if (!prototype_p (type
))
10577 error_at (expr
->get_location (),
10578 "argument %u of %<__builtin_tgmath%> is unprototyped", pos
);
10581 if (stdarg_p (type
))
10583 error_at (expr
->get_location (),
10584 "argument %u of %<__builtin_tgmath%> has variable arguments",
10588 unsigned int nargs
= 0;
10589 function_args_iterator iter
;
10591 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
10593 if (t
== void_type_node
)
10599 error_at (expr
->get_location (),
10600 "argument %u of %<__builtin_tgmath%> has no arguments", pos
);
10606 /* Ways in which a parameter or return value of a type-generic macro
10607 may vary between the different functions the macro may call. */
10608 enum tgmath_parm_kind
10610 tgmath_fixed
, tgmath_real
, tgmath_complex
10613 /* Helper function for c_parser_postfix_expression. Parse predefined
10616 static struct c_expr
10617 c_parser_predefined_identifier (c_parser
*parser
)
10619 location_t loc
= c_parser_peek_token (parser
)->location
;
10620 switch (c_parser_peek_token (parser
)->keyword
)
10622 case RID_FUNCTION_NAME
:
10623 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
10624 "identifier", "__FUNCTION__");
10626 case RID_PRETTY_FUNCTION_NAME
:
10627 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
10628 "identifier", "__PRETTY_FUNCTION__");
10630 case RID_C99_FUNCTION_NAME
:
10631 pedwarn_c90 (loc
, OPT_Wpedantic
, "ISO C90 does not support "
10632 "%<__func__%> predefined identifier");
10635 gcc_unreachable ();
10638 struct c_expr expr
;
10639 expr
.original_code
= ERROR_MARK
;
10640 expr
.original_type
= NULL
;
10641 expr
.value
= fname_decl (loc
, c_parser_peek_token (parser
)->keyword
,
10642 c_parser_peek_token (parser
)->value
);
10643 set_c_expr_source_range (&expr
, loc
, loc
);
10644 expr
.m_decimal
= 0;
10645 c_parser_consume_token (parser
);
10649 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
10650 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
10651 call c_parser_postfix_expression_after_paren_type on encountering them.
10653 postfix-expression:
10655 postfix-expression [ expression ]
10656 postfix-expression ( argument-expression-list[opt] )
10657 postfix-expression . identifier
10658 postfix-expression -> identifier
10659 postfix-expression ++
10660 postfix-expression --
10661 ( storage-class-specifiers[opt] type-name ) { initializer-list[opt] }
10662 ( storage-class-specifiers[opt] type-name ) { initializer-list , }
10664 argument-expression-list:
10665 argument-expression
10666 argument-expression-list , argument-expression
10668 primary-expression:
10677 primary-expression:
10679 (treated as a keyword in GNU C)
10681 __PRETTY_FUNCTION__
10682 ( compound-statement )
10683 __builtin_va_arg ( assignment-expression , type-name )
10684 __builtin_offsetof ( type-name , offsetof-member-designator )
10685 __builtin_choose_expr ( assignment-expression ,
10686 assignment-expression ,
10687 assignment-expression )
10688 __builtin_types_compatible_p ( type-name , type-name )
10689 __builtin_tgmath ( expr-list )
10690 __builtin_complex ( assignment-expression , assignment-expression )
10691 __builtin_shuffle ( assignment-expression , assignment-expression )
10692 __builtin_shuffle ( assignment-expression ,
10693 assignment-expression ,
10694 assignment-expression, )
10695 __builtin_convertvector ( assignment-expression , type-name )
10696 __builtin_assoc_barrier ( assignment-expression )
10698 offsetof-member-designator:
10700 offsetof-member-designator . identifier
10701 offsetof-member-designator [ expression ]
10705 primary-expression:
10706 [ objc-receiver objc-message-args ]
10707 @selector ( objc-selector-arg )
10708 @protocol ( identifier )
10709 @encode ( type-name )
10710 objc-string-literal
10711 Classname . identifier
10714 static struct c_expr
10715 c_parser_postfix_expression (c_parser
*parser
)
10717 struct c_expr expr
, e1
;
10718 struct c_type_name
*t1
, *t2
;
10719 location_t loc
= c_parser_peek_token (parser
)->location
;
10720 source_range tok_range
= c_parser_peek_token (parser
)->get_range ();
10721 expr
.original_code
= ERROR_MARK
;
10722 expr
.original_type
= NULL
;
10723 expr
.m_decimal
= 0;
10724 switch (c_parser_peek_token (parser
)->type
)
10727 expr
.value
= c_parser_peek_token (parser
)->value
;
10728 set_c_expr_source_range (&expr
, tok_range
);
10729 loc
= c_parser_peek_token (parser
)->location
;
10730 expr
.m_decimal
= c_parser_peek_token (parser
)->flags
& DECIMAL_INT
;
10731 c_parser_consume_token (parser
);
10732 if (TREE_CODE (expr
.value
) == FIXED_CST
10733 && !targetm
.fixed_point_supported_p ())
10735 error_at (loc
, "fixed-point types not supported for this target");
10744 expr
.value
= c_parser_peek_token (parser
)->value
;
10745 /* For the purpose of warning when a pointer is compared with
10746 a zero character constant. */
10747 expr
.original_type
= char_type_node
;
10748 set_c_expr_source_range (&expr
, tok_range
);
10749 c_parser_consume_token (parser
);
10755 case CPP_UTF8STRING
:
10756 expr
= c_parser_string_literal (parser
, parser
->translate_strings_p
,
10759 case CPP_OBJC_STRING
:
10760 gcc_assert (c_dialect_objc ());
10762 = objc_build_string_object (c_parser_peek_token (parser
)->value
);
10763 set_c_expr_source_range (&expr
, tok_range
);
10764 c_parser_consume_token (parser
);
10767 switch (c_parser_peek_token (parser
)->id_kind
)
10771 tree id
= c_parser_peek_token (parser
)->value
;
10772 c_parser_consume_token (parser
);
10773 expr
.value
= build_external_ref (loc
, id
,
10774 (c_parser_peek_token (parser
)->type
10775 == CPP_OPEN_PAREN
),
10776 &expr
.original_type
);
10777 set_c_expr_source_range (&expr
, tok_range
);
10780 case C_ID_CLASSNAME
:
10782 /* Here we parse the Objective-C 2.0 Class.name dot
10784 tree class_name
= c_parser_peek_token (parser
)->value
;
10786 c_parser_consume_token (parser
);
10787 gcc_assert (c_dialect_objc ());
10788 if (!c_parser_require (parser
, CPP_DOT
, "expected %<.%>"))
10793 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10795 c_parser_error (parser
, "expected identifier");
10799 c_token
*component_tok
= c_parser_peek_token (parser
);
10800 component
= component_tok
->value
;
10801 location_t end_loc
= component_tok
->get_finish ();
10802 c_parser_consume_token (parser
);
10803 expr
.value
= objc_build_class_component_ref (class_name
,
10805 set_c_expr_source_range (&expr
, loc
, end_loc
);
10809 c_parser_error (parser
, "expected expression");
10814 case CPP_OPEN_PAREN
:
10815 /* A parenthesized expression, statement expression or compound
10817 if (c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_BRACE
)
10819 /* A statement expression. */
10821 location_t brace_loc
;
10822 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
10823 c_parser_consume_token (parser
);
10824 brace_loc
= c_parser_peek_token (parser
)->location
;
10825 c_parser_consume_token (parser
);
10826 /* If we've not yet started the current function's statement list,
10827 or we're in the parameter scope of an old-style function
10828 declaration, statement expressions are not allowed. */
10829 if (!building_stmt_list_p () || old_style_parameter_scope ())
10831 error_at (loc
, "braced-group within expression allowed "
10832 "only inside a function");
10833 parser
->error
= true;
10834 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
10835 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10839 c_omp_array_section_p
= false;
10840 stmt
= c_begin_stmt_expr ();
10841 c_parser_compound_statement_nostart (parser
);
10842 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10843 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10845 pedwarn (loc
, OPT_Wpedantic
,
10846 "ISO C forbids braced-groups within expressions");
10847 expr
.value
= c_finish_stmt_expr (brace_loc
, stmt
);
10848 set_c_expr_source_range (&expr
, loc
, close_loc
);
10849 mark_exp_read (expr
.value
);
10850 c_omp_array_section_p
= save_c_omp_array_section_p
;
10854 /* A parenthesized expression. */
10855 location_t loc_open_paren
= c_parser_peek_token (parser
)->location
;
10856 c_parser_consume_token (parser
);
10857 expr
= c_parser_expression (parser
);
10858 if (TREE_CODE (expr
.value
) == MODIFY_EXPR
)
10859 suppress_warning (expr
.value
, OPT_Wparentheses
);
10860 if (expr
.original_code
!= C_MAYBE_CONST_EXPR
10861 && expr
.original_code
!= SIZEOF_EXPR
)
10862 expr
.original_code
= ERROR_MARK
;
10863 /* Remember that we saw ( ) around the sizeof. */
10864 if (expr
.original_code
== SIZEOF_EXPR
)
10865 expr
.original_code
= PAREN_SIZEOF_EXPR
;
10866 /* Don't change EXPR.ORIGINAL_TYPE. */
10867 location_t loc_close_paren
= c_parser_peek_token (parser
)->location
;
10868 set_c_expr_source_range (&expr
, loc_open_paren
, loc_close_paren
);
10869 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10870 "expected %<)%>", loc_open_paren
);
10874 switch (c_parser_peek_token (parser
)->keyword
)
10876 case RID_FUNCTION_NAME
:
10877 case RID_PRETTY_FUNCTION_NAME
:
10878 case RID_C99_FUNCTION_NAME
:
10879 expr
= c_parser_predefined_identifier (parser
);
10883 location_t start_loc
= loc
;
10884 c_parser_consume_token (parser
);
10885 matching_parens parens
;
10886 if (!parens
.require_open (parser
))
10891 e1
= c_parser_expr_no_commas (parser
, NULL
);
10892 mark_exp_read (e1
.value
);
10893 e1
.value
= c_fully_fold (e1
.value
, false, NULL
);
10894 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10896 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10900 loc
= c_parser_peek_token (parser
)->location
;
10901 t1
= c_parser_type_name (parser
);
10902 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10903 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10911 tree type_expr
= NULL_TREE
;
10912 expr
.value
= c_build_va_arg (start_loc
, e1
.value
, loc
,
10913 groktypename (t1
, &type_expr
, NULL
));
10916 expr
.value
= build2 (C_MAYBE_CONST_EXPR
,
10917 TREE_TYPE (expr
.value
), type_expr
,
10919 C_MAYBE_CONST_EXPR_NON_CONST (expr
.value
) = true;
10921 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10927 c_parser_consume_token (parser
);
10928 matching_parens parens
;
10929 if (!parens
.require_open (parser
))
10934 t1
= c_parser_type_name (parser
);
10936 parser
->error
= true;
10937 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10938 gcc_assert (parser
->error
);
10941 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10945 tree type
= groktypename (t1
, NULL
, NULL
);
10947 if (type
== error_mark_node
)
10948 offsetof_ref
= error_mark_node
;
10951 offsetof_ref
= build1 (INDIRECT_REF
, type
, null_pointer_node
);
10952 SET_EXPR_LOCATION (offsetof_ref
, loc
);
10954 /* Parse the second argument to __builtin_offsetof. We
10955 must have one identifier, and beyond that we want to
10956 accept sub structure and sub array references. */
10957 if (c_parser_next_token_is (parser
, CPP_NAME
))
10959 c_token
*comp_tok
= c_parser_peek_token (parser
);
10960 /* Ignore the counted_by attribute for reference inside
10961 offsetof since the information is not useful at all. */
10963 = build_component_ref (loc
, offsetof_ref
, comp_tok
->value
,
10964 comp_tok
->location
, UNKNOWN_LOCATION
,
10966 c_parser_consume_token (parser
);
10967 while (c_parser_next_token_is (parser
, CPP_DOT
)
10968 || c_parser_next_token_is (parser
,
10970 || c_parser_next_token_is (parser
,
10973 if (c_parser_next_token_is (parser
, CPP_DEREF
))
10975 loc
= c_parser_peek_token (parser
)->location
;
10976 offsetof_ref
= build_array_ref (loc
,
10978 integer_zero_node
);
10981 else if (c_parser_next_token_is (parser
, CPP_DOT
))
10984 c_parser_consume_token (parser
);
10985 if (c_parser_next_token_is_not (parser
,
10988 c_parser_error (parser
, "expected identifier");
10991 c_token
*comp_tok
= c_parser_peek_token (parser
);
10992 /* Ignore the counted_by attribute for reference inside
10993 offsetof since the information is not useful. */
10995 = build_component_ref (loc
, offsetof_ref
,
10997 comp_tok
->location
,
11000 c_parser_consume_token (parser
);
11006 loc
= c_parser_peek_token (parser
)->location
;
11007 c_parser_consume_token (parser
);
11008 ce
= c_parser_expression (parser
);
11009 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
11011 idx
= c_fully_fold (idx
, false, NULL
);
11012 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
11014 offsetof_ref
= build_array_ref (loc
, offsetof_ref
, idx
);
11019 c_parser_error (parser
, "expected identifier");
11020 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
11021 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
11023 expr
.value
= fold_offsetof (offsetof_ref
);
11024 set_c_expr_source_range (&expr
, loc
, end_loc
);
11027 case RID_CHOOSE_EXPR
:
11029 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11030 c_expr_t
*e1_p
, *e2_p
, *e3_p
;
11032 location_t close_paren_loc
;
11034 c_parser_consume_token (parser
);
11035 if (!c_parser_get_builtin_args (parser
,
11036 "__builtin_choose_expr",
11044 if (vec_safe_length (cexpr_list
) != 3)
11046 error_at (loc
, "wrong number of arguments to "
11047 "%<__builtin_choose_expr%>");
11052 e1_p
= &(*cexpr_list
)[0];
11053 e2_p
= &(*cexpr_list
)[1];
11054 e3_p
= &(*cexpr_list
)[2];
11057 mark_exp_read (e2_p
->value
);
11058 mark_exp_read (e3_p
->value
);
11059 if (TREE_CODE (c
) != INTEGER_CST
11060 || !INTEGRAL_TYPE_P (TREE_TYPE (c
)))
11062 "first argument to %<__builtin_choose_expr%> not"
11064 constant_expression_warning (c
);
11065 expr
= integer_zerop (c
) ? *e3_p
: *e2_p
;
11066 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11069 case RID_TYPES_COMPATIBLE_P
:
11071 c_parser_consume_token (parser
);
11072 matching_parens parens
;
11073 if (!parens
.require_open (parser
))
11078 t1
= c_parser_type_name (parser
);
11084 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
11086 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
11090 t2
= c_parser_type_name (parser
);
11096 location_t close_paren_loc
= c_parser_peek_token (parser
)->location
;
11097 parens
.skip_until_found_close (parser
);
11099 e1
= groktypename (t1
, NULL
, NULL
);
11100 e2
= groktypename (t2
, NULL
, NULL
);
11101 if (e1
== error_mark_node
|| e2
== error_mark_node
)
11107 e1
= TYPE_MAIN_VARIANT (e1
);
11108 e2
= TYPE_MAIN_VARIANT (e2
);
11111 = comptypes (e1
, e2
) ? integer_one_node
: integer_zero_node
;
11112 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11115 case RID_BUILTIN_TGMATH
:
11117 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11118 location_t close_paren_loc
;
11120 c_parser_consume_token (parser
);
11121 if (!c_parser_get_builtin_args (parser
,
11122 "__builtin_tgmath",
11123 &cexpr_list
, false,
11130 if (vec_safe_length (cexpr_list
) < 3)
11132 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
11139 FOR_EACH_VEC_ELT (*cexpr_list
, i
, p
)
11140 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
11141 unsigned int nargs
= check_tgmath_function (&(*cexpr_list
)[0], 1);
11147 if (vec_safe_length (cexpr_list
) < nargs
)
11149 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
11153 unsigned int num_functions
= vec_safe_length (cexpr_list
) - nargs
;
11154 if (num_functions
< 2)
11156 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
11161 /* The first NUM_FUNCTIONS expressions are the function
11162 pointers. The remaining NARGS expressions are the
11163 arguments that are to be passed to one of those
11164 functions, chosen following <tgmath.h> rules. */
11165 for (unsigned int j
= 1; j
< num_functions
; j
++)
11167 unsigned int this_nargs
11168 = check_tgmath_function (&(*cexpr_list
)[j
], j
+ 1);
11169 if (this_nargs
== 0)
11174 if (this_nargs
!= nargs
)
11176 error_at ((*cexpr_list
)[j
].get_location (),
11177 "argument %u of %<__builtin_tgmath%> has "
11178 "wrong number of arguments", j
+ 1);
11184 /* The functions all have the same number of arguments.
11185 Determine whether arguments and return types vary in
11186 ways permitted for <tgmath.h> functions. */
11187 /* The first entry in each of these vectors is for the
11188 return type, subsequent entries for parameter
11190 auto_vec
<enum tgmath_parm_kind
> parm_kind (nargs
+ 1);
11191 auto_vec
<tree
> parm_first (nargs
+ 1);
11192 auto_vec
<bool> parm_complex (nargs
+ 1);
11193 auto_vec
<bool> parm_varies (nargs
+ 1);
11194 tree first_type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[0].value
));
11195 tree first_ret
= TYPE_MAIN_VARIANT (TREE_TYPE (first_type
));
11196 parm_first
.quick_push (first_ret
);
11197 parm_complex
.quick_push (TREE_CODE (first_ret
) == COMPLEX_TYPE
);
11198 parm_varies
.quick_push (false);
11199 function_args_iterator iter
;
11201 unsigned int argpos
;
11202 FOREACH_FUNCTION_ARGS (first_type
, t
, iter
)
11204 if (t
== void_type_node
)
11206 parm_first
.quick_push (TYPE_MAIN_VARIANT (t
));
11207 parm_complex
.quick_push (TREE_CODE (t
) == COMPLEX_TYPE
);
11208 parm_varies
.quick_push (false);
11210 for (unsigned int j
= 1; j
< num_functions
; j
++)
11212 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
11213 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
11214 if (ret
!= parm_first
[0])
11216 parm_varies
[0] = true;
11217 if (!SCALAR_FLOAT_TYPE_P (parm_first
[0])
11218 && !COMPLEX_FLOAT_TYPE_P (parm_first
[0]))
11220 error_at ((*cexpr_list
)[0].get_location (),
11221 "invalid type-generic return type for "
11222 "argument %u of %<__builtin_tgmath%>",
11227 if (!SCALAR_FLOAT_TYPE_P (ret
)
11228 && !COMPLEX_FLOAT_TYPE_P (ret
))
11230 error_at ((*cexpr_list
)[j
].get_location (),
11231 "invalid type-generic return type for "
11232 "argument %u of %<__builtin_tgmath%>",
11238 if (TREE_CODE (ret
) == COMPLEX_TYPE
)
11239 parm_complex
[0] = true;
11241 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
11243 if (t
== void_type_node
)
11245 t
= TYPE_MAIN_VARIANT (t
);
11246 if (t
!= parm_first
[argpos
])
11248 parm_varies
[argpos
] = true;
11249 if (!SCALAR_FLOAT_TYPE_P (parm_first
[argpos
])
11250 && !COMPLEX_FLOAT_TYPE_P (parm_first
[argpos
]))
11252 error_at ((*cexpr_list
)[0].get_location (),
11253 "invalid type-generic type for "
11254 "argument %u of argument %u of "
11255 "%<__builtin_tgmath%>", argpos
, 1);
11259 if (!SCALAR_FLOAT_TYPE_P (t
)
11260 && !COMPLEX_FLOAT_TYPE_P (t
))
11262 error_at ((*cexpr_list
)[j
].get_location (),
11263 "invalid type-generic type for "
11264 "argument %u of argument %u of "
11265 "%<__builtin_tgmath%>", argpos
, j
+ 1);
11270 if (TREE_CODE (t
) == COMPLEX_TYPE
)
11271 parm_complex
[argpos
] = true;
11275 enum tgmath_parm_kind max_variation
= tgmath_fixed
;
11276 for (unsigned int j
= 0; j
<= nargs
; j
++)
11278 enum tgmath_parm_kind this_kind
;
11279 if (parm_varies
[j
])
11281 if (parm_complex
[j
])
11282 max_variation
= this_kind
= tgmath_complex
;
11285 this_kind
= tgmath_real
;
11286 if (max_variation
!= tgmath_complex
)
11287 max_variation
= tgmath_real
;
11291 this_kind
= tgmath_fixed
;
11292 parm_kind
.quick_push (this_kind
);
11294 if (max_variation
== tgmath_fixed
)
11296 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
11297 "all have the same type");
11302 /* Identify a parameter (not the return type) that varies,
11303 including with complex types if any variation includes
11304 complex types; there must be at least one such
11306 unsigned int tgarg
= 0;
11307 for (unsigned int j
= 1; j
<= nargs
; j
++)
11308 if (parm_kind
[j
] == max_variation
)
11315 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
11316 "lack type-generic parameter");
11321 /* Determine the type of the relevant parameter for each
11323 auto_vec
<tree
> tg_type (num_functions
);
11324 for (unsigned int j
= 0; j
< num_functions
; j
++)
11326 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
11328 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
11330 if (argpos
== tgarg
)
11332 tg_type
.quick_push (TYPE_MAIN_VARIANT (t
));
11339 /* Verify that the corresponding types are different for
11340 all the listed functions. Also determine whether all
11341 the types are complex, whether all the types are
11342 standard or binary, and whether all the types are
11344 bool all_complex
= true;
11345 bool all_binary
= true;
11346 bool all_decimal
= true;
11347 hash_set
<tree
> tg_types
;
11348 FOR_EACH_VEC_ELT (tg_type
, i
, t
)
11350 if (TREE_CODE (t
) == COMPLEX_TYPE
)
11351 all_decimal
= false;
11354 all_complex
= false;
11355 if (DECIMAL_FLOAT_TYPE_P (t
))
11356 all_binary
= false;
11358 all_decimal
= false;
11360 if (tg_types
.add (t
))
11362 error_at ((*cexpr_list
)[i
].get_location (),
11363 "duplicate type-generic parameter type for "
11364 "function argument %u of %<__builtin_tgmath%>",
11371 /* Verify that other parameters and the return type whose
11372 types vary have their types varying in the correct
11374 for (unsigned int j
= 0; j
< num_functions
; j
++)
11376 tree exp_type
= tg_type
[j
];
11377 tree exp_real_type
= exp_type
;
11378 if (TREE_CODE (exp_type
) == COMPLEX_TYPE
)
11379 exp_real_type
= TREE_TYPE (exp_type
);
11380 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
11381 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
11382 if ((parm_kind
[0] == tgmath_complex
&& ret
!= exp_type
)
11383 || (parm_kind
[0] == tgmath_real
&& ret
!= exp_real_type
))
11385 error_at ((*cexpr_list
)[j
].get_location (),
11386 "bad return type for function argument %u "
11387 "of %<__builtin_tgmath%>", j
+ 1);
11392 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
11394 if (t
== void_type_node
)
11396 t
= TYPE_MAIN_VARIANT (t
);
11397 if ((parm_kind
[argpos
] == tgmath_complex
11399 || (parm_kind
[argpos
] == tgmath_real
11400 && t
!= exp_real_type
))
11402 error_at ((*cexpr_list
)[j
].get_location (),
11403 "bad type for argument %u of "
11404 "function argument %u of "
11405 "%<__builtin_tgmath%>", argpos
, j
+ 1);
11413 /* The functions listed are a valid set of functions for a
11414 <tgmath.h> macro to select between. Identify the
11415 matching function, if any. First, the argument types
11416 must be combined following <tgmath.h> rules. Integer
11417 types are treated as _Decimal64 if any type-generic
11418 argument is decimal, or if the only alternatives for
11419 type-generic arguments are of decimal types, and are
11420 otherwise treated as _Float32x (or _Complex _Float32x
11421 for complex integer types) if any type-generic argument
11422 has _FloatNx type, otherwise as double (or _Complex
11423 double for complex integer types). After that
11424 adjustment, types are combined following the usual
11425 arithmetic conversions. If the function only accepts
11426 complex arguments, a complex type is produced. */
11427 bool arg_complex
= all_complex
;
11428 bool arg_binary
= all_binary
;
11429 bool arg_int_decimal
= all_decimal
;
11430 bool arg_int_floatnx
= false;
11431 for (unsigned int j
= 1; j
<= nargs
; j
++)
11433 if (parm_kind
[j
] == tgmath_fixed
)
11435 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
11436 tree type
= TREE_TYPE (ce
->value
);
11437 if (!INTEGRAL_TYPE_P (type
)
11438 && !SCALAR_FLOAT_TYPE_P (type
)
11439 && TREE_CODE (type
) != COMPLEX_TYPE
)
11441 error_at (ce
->get_location (),
11442 "invalid type of argument %u of type-generic "
11447 if (DECIMAL_FLOAT_TYPE_P (type
))
11449 arg_int_decimal
= true;
11452 error_at (ce
->get_location (),
11453 "decimal floating-point argument %u to "
11454 "complex-only type-generic function", j
);
11458 else if (all_binary
)
11460 error_at (ce
->get_location (),
11461 "decimal floating-point argument %u to "
11462 "binary-only type-generic function", j
);
11466 else if (arg_complex
)
11468 error_at (ce
->get_location (),
11469 "both complex and decimal floating-point "
11470 "arguments to type-generic function");
11474 else if (arg_binary
)
11476 error_at (ce
->get_location (),
11477 "both binary and decimal floating-point "
11478 "arguments to type-generic function");
11483 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
11485 arg_complex
= true;
11486 if (COMPLEX_FLOAT_TYPE_P (type
))
11490 error_at (ce
->get_location (),
11491 "complex argument %u to "
11492 "decimal-only type-generic function", j
);
11496 else if (arg_int_decimal
)
11498 error_at (ce
->get_location (),
11499 "both complex and decimal floating-point "
11500 "arguments to type-generic function");
11505 else if (SCALAR_FLOAT_TYPE_P (type
))
11510 error_at (ce
->get_location (),
11511 "binary argument %u to "
11512 "decimal-only type-generic function", j
);
11516 else if (arg_int_decimal
)
11518 error_at (ce
->get_location (),
11519 "both binary and decimal floating-point "
11520 "arguments to type-generic function");
11525 tree rtype
= TYPE_MAIN_VARIANT (type
);
11526 if (TREE_CODE (rtype
) == COMPLEX_TYPE
)
11527 rtype
= TREE_TYPE (rtype
);
11528 if (SCALAR_FLOAT_TYPE_P (rtype
))
11529 for (unsigned int j
= 0; j
< NUM_FLOATNX_TYPES
; j
++)
11530 if (rtype
== FLOATNX_TYPE_NODE (j
))
11532 arg_int_floatnx
= true;
11536 tree arg_real
= NULL_TREE
;
11537 for (unsigned int j
= 1; j
<= nargs
; j
++)
11539 if (parm_kind
[j
] == tgmath_fixed
)
11541 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
11542 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (ce
->value
));
11543 if (TREE_CODE (type
) == COMPLEX_TYPE
)
11544 type
= TREE_TYPE (type
);
11545 if (INTEGRAL_TYPE_P (type
))
11546 type
= (arg_int_decimal
11547 ? dfloat64_type_node
11549 ? float32x_type_node
11550 : double_type_node
);
11551 if (arg_real
== NULL_TREE
)
11554 arg_real
= common_type (arg_real
, type
);
11555 if (arg_real
== error_mark_node
)
11561 tree arg_type
= (arg_complex
11562 ? build_complex_type (arg_real
)
11565 /* Look for a function to call with type-generic parameter
11567 c_expr_t
*fn
= NULL
;
11568 for (unsigned int j
= 0; j
< num_functions
; j
++)
11570 if (tg_type
[j
] == arg_type
)
11572 fn
= &(*cexpr_list
)[j
];
11577 && parm_kind
[0] == tgmath_fixed
11578 && SCALAR_FLOAT_TYPE_P (parm_first
[0]))
11580 /* Presume this is a macro that rounds its result to a
11581 narrower type, and look for the first function with
11582 at least the range and precision of the argument
11584 for (unsigned int j
= 0; j
< num_functions
; j
++)
11587 != (TREE_CODE (tg_type
[j
]) == COMPLEX_TYPE
))
11589 tree real_tg_type
= (arg_complex
11590 ? TREE_TYPE (tg_type
[j
])
11592 if (DECIMAL_FLOAT_TYPE_P (arg_real
)
11593 != DECIMAL_FLOAT_TYPE_P (real_tg_type
))
11595 scalar_float_mode arg_mode
11596 = SCALAR_FLOAT_TYPE_MODE (arg_real
);
11597 scalar_float_mode tg_mode
11598 = SCALAR_FLOAT_TYPE_MODE (real_tg_type
);
11599 const real_format
*arg_fmt
= REAL_MODE_FORMAT (arg_mode
);
11600 const real_format
*tg_fmt
= REAL_MODE_FORMAT (tg_mode
);
11601 if (arg_fmt
->b
== tg_fmt
->b
11602 && arg_fmt
->p
<= tg_fmt
->p
11603 && arg_fmt
->emax
<= tg_fmt
->emax
11604 && (arg_fmt
->emin
- arg_fmt
->p
11605 >= tg_fmt
->emin
- tg_fmt
->p
))
11607 fn
= &(*cexpr_list
)[j
];
11614 error_at (loc
, "no matching function for type-generic call");
11619 /* Construct a call to FN. */
11620 vec
<tree
, va_gc
> *args
;
11621 vec_alloc (args
, nargs
);
11622 vec
<tree
, va_gc
> *origtypes
;
11623 vec_alloc (origtypes
, nargs
);
11624 auto_vec
<location_t
> arg_loc (nargs
);
11625 for (unsigned int j
= 0; j
< nargs
; j
++)
11627 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
];
11628 args
->quick_push (ce
->value
);
11629 arg_loc
.quick_push (ce
->get_location ());
11630 origtypes
->quick_push (ce
->original_type
);
11632 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fn
->value
,
11634 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11637 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN
:
11639 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11642 location_t close_paren_loc
;
11644 c_parser_consume_token (parser
);
11645 if (!c_parser_get_builtin_args (parser
,
11646 "__builtin_call_with_static_chain",
11647 &cexpr_list
, false,
11653 if (vec_safe_length (cexpr_list
) != 2)
11655 error_at (loc
, "wrong number of arguments to "
11656 "%<__builtin_call_with_static_chain%>");
11661 expr
= (*cexpr_list
)[0];
11662 e2_p
= &(*cexpr_list
)[1];
11663 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
11664 chain_value
= e2_p
->value
;
11665 mark_exp_read (chain_value
);
11667 if (TREE_CODE (expr
.value
) != CALL_EXPR
)
11668 error_at (loc
, "first argument to "
11669 "%<__builtin_call_with_static_chain%> "
11670 "must be a call expression");
11671 else if (TREE_CODE (TREE_TYPE (chain_value
)) != POINTER_TYPE
)
11672 error_at (loc
, "second argument to "
11673 "%<__builtin_call_with_static_chain%> "
11674 "must be a pointer type");
11676 CALL_EXPR_STATIC_CHAIN (expr
.value
) = chain_value
;
11677 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11680 case RID_BUILTIN_COMPLEX
:
11682 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11683 c_expr_t
*e1_p
, *e2_p
;
11684 location_t close_paren_loc
;
11686 c_parser_consume_token (parser
);
11687 if (!c_parser_get_builtin_args (parser
,
11688 "__builtin_complex",
11689 &cexpr_list
, false,
11696 if (vec_safe_length (cexpr_list
) != 2)
11698 error_at (loc
, "wrong number of arguments to "
11699 "%<__builtin_complex%>");
11704 e1_p
= &(*cexpr_list
)[0];
11705 e2_p
= &(*cexpr_list
)[1];
11707 *e1_p
= convert_lvalue_to_rvalue (loc
, *e1_p
, true, true);
11708 if (TREE_CODE (e1_p
->value
) == EXCESS_PRECISION_EXPR
)
11709 e1_p
->value
= convert (TREE_TYPE (e1_p
->value
),
11710 TREE_OPERAND (e1_p
->value
, 0));
11711 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
11712 if (TREE_CODE (e2_p
->value
) == EXCESS_PRECISION_EXPR
)
11713 e2_p
->value
= convert (TREE_TYPE (e2_p
->value
),
11714 TREE_OPERAND (e2_p
->value
, 0));
11715 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
11716 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
11717 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
))
11718 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
)))
11720 error_at (loc
, "%<__builtin_complex%> operand "
11721 "not of real binary floating-point type");
11725 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p
->value
))
11726 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p
->value
)))
11729 "%<__builtin_complex%> operands of different types");
11733 pedwarn_c90 (loc
, OPT_Wpedantic
,
11734 "ISO C90 does not support complex types");
11735 expr
.value
= build2_loc (loc
, COMPLEX_EXPR
,
11738 (TREE_TYPE (e1_p
->value
))),
11739 e1_p
->value
, e2_p
->value
);
11740 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11743 case RID_BUILTIN_SHUFFLE
:
11745 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11748 location_t close_paren_loc
;
11750 c_parser_consume_token (parser
);
11751 if (!c_parser_get_builtin_args (parser
,
11752 "__builtin_shuffle",
11753 &cexpr_list
, false,
11760 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
11761 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
11763 if (vec_safe_length (cexpr_list
) == 2)
11764 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
11766 (*cexpr_list
)[1].value
);
11768 else if (vec_safe_length (cexpr_list
) == 3)
11769 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
11770 (*cexpr_list
)[1].value
,
11771 (*cexpr_list
)[2].value
);
11774 error_at (loc
, "wrong number of arguments to "
11775 "%<__builtin_shuffle%>");
11778 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11781 case RID_BUILTIN_SHUFFLEVECTOR
:
11783 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11786 location_t close_paren_loc
;
11788 c_parser_consume_token (parser
);
11789 if (!c_parser_get_builtin_args (parser
,
11790 "__builtin_shufflevector",
11791 &cexpr_list
, false,
11798 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
11799 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
11801 if (vec_safe_length (cexpr_list
) < 3)
11803 error_at (loc
, "wrong number of arguments to "
11804 "%<__builtin_shuffle%>");
11809 auto_vec
<tree
, 16> mask
;
11810 for (i
= 2; i
< cexpr_list
->length (); ++i
)
11811 mask
.safe_push ((*cexpr_list
)[i
].value
);
11812 expr
.value
= c_build_shufflevector (loc
, (*cexpr_list
)[0].value
,
11813 (*cexpr_list
)[1].value
,
11816 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11819 case RID_BUILTIN_CONVERTVECTOR
:
11821 location_t start_loc
= loc
;
11822 c_parser_consume_token (parser
);
11823 matching_parens parens
;
11824 if (!parens
.require_open (parser
))
11829 e1
= c_parser_expr_no_commas (parser
, NULL
);
11830 mark_exp_read (e1
.value
);
11831 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
11833 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
11837 loc
= c_parser_peek_token (parser
)->location
;
11838 t1
= c_parser_type_name (parser
);
11839 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
11840 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
11846 tree type_expr
= NULL_TREE
;
11847 expr
.value
= c_build_vec_convert (start_loc
, e1
.value
, loc
,
11848 groktypename (t1
, &type_expr
,
11850 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
11854 case RID_BUILTIN_ASSOC_BARRIER
:
11856 location_t start_loc
= loc
;
11857 c_parser_consume_token (parser
);
11858 matching_parens parens
;
11859 if (!parens
.require_open (parser
))
11864 e1
= c_parser_expr_no_commas (parser
, NULL
);
11865 mark_exp_read (e1
.value
);
11866 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
11867 parens
.skip_until_found_close (parser
);
11868 expr
= parser_build_unary_op (loc
, PAREN_EXPR
, e1
);
11869 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
11872 case RID_BUILTIN_STDC
:
11874 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11876 location_t close_paren_loc
;
11877 enum c_builtin_stdc
{
11878 C_BUILTIN_STDC_BIT_CEIL
,
11879 C_BUILTIN_STDC_BIT_FLOOR
,
11880 C_BUILTIN_STDC_BIT_WIDTH
,
11881 C_BUILTIN_STDC_COUNT_ONES
,
11882 C_BUILTIN_STDC_COUNT_ZEROS
,
11883 C_BUILTIN_STDC_FIRST_LEADING_ONE
,
11884 C_BUILTIN_STDC_FIRST_LEADING_ZERO
,
11885 C_BUILTIN_STDC_FIRST_TRAILING_ONE
,
11886 C_BUILTIN_STDC_FIRST_TRAILING_ZERO
,
11887 C_BUILTIN_STDC_HAS_SINGLE_BIT
,
11888 C_BUILTIN_STDC_LEADING_ONES
,
11889 C_BUILTIN_STDC_LEADING_ZEROS
,
11890 C_BUILTIN_STDC_TRAILING_ONES
,
11891 C_BUILTIN_STDC_TRAILING_ZEROS
,
11893 } stdc_rid
= C_BUILTIN_STDC_MAX
;
11895 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
11896 switch (name
[sizeof ("__builtin_stdc_") - 1])
11899 switch (name
[sizeof ("__builtin_stdc_bit_") - 1])
11902 stdc_rid
= C_BUILTIN_STDC_BIT_CEIL
;
11905 stdc_rid
= C_BUILTIN_STDC_BIT_FLOOR
;
11908 stdc_rid
= C_BUILTIN_STDC_BIT_WIDTH
;
11913 if (name
[sizeof ("__builtin_stdc_count_") - 1] == 'o')
11914 stdc_rid
= C_BUILTIN_STDC_COUNT_ONES
;
11916 stdc_rid
= C_BUILTIN_STDC_COUNT_ZEROS
;
11919 switch (name
[sizeof ("__builtin_stdc_first_trailing_") - 1])
11922 stdc_rid
= C_BUILTIN_STDC_FIRST_LEADING_ONE
;
11925 stdc_rid
= C_BUILTIN_STDC_FIRST_LEADING_ZERO
;
11928 stdc_rid
= C_BUILTIN_STDC_FIRST_TRAILING_ONE
;
11931 stdc_rid
= C_BUILTIN_STDC_FIRST_TRAILING_ZERO
;
11936 stdc_rid
= C_BUILTIN_STDC_HAS_SINGLE_BIT
;
11939 if (name
[sizeof ("__builtin_stdc_leading_") - 1] == 'o')
11940 stdc_rid
= C_BUILTIN_STDC_LEADING_ONES
;
11942 stdc_rid
= C_BUILTIN_STDC_LEADING_ZEROS
;
11945 if (name
[sizeof ("__builtin_stdc_trailing_") - 1] == 'o')
11946 stdc_rid
= C_BUILTIN_STDC_TRAILING_ONES
;
11948 stdc_rid
= C_BUILTIN_STDC_TRAILING_ZEROS
;
11951 gcc_checking_assert (stdc_rid
!= C_BUILTIN_STDC_MAX
);
11953 c_parser_consume_token (parser
);
11954 if (!c_parser_get_builtin_args (parser
, name
,
11955 &cexpr_list
, false,
11962 if (vec_safe_length (cexpr_list
) != 1)
11964 error_at (loc
, "wrong number of arguments to %qs", name
);
11969 arg_p
= &(*cexpr_list
)[0];
11970 *arg_p
= convert_lvalue_to_rvalue (loc
, *arg_p
, true, true);
11971 if (!INTEGRAL_TYPE_P (TREE_TYPE (arg_p
->value
)))
11973 error_at (loc
, "%qs operand not an integral type", name
);
11977 if (TREE_CODE (TREE_TYPE (arg_p
->value
)) == ENUMERAL_TYPE
)
11979 error_at (loc
, "argument %u in call to function "
11980 "%qs has enumerated type", 1, name
);
11984 if (TREE_CODE (TREE_TYPE (arg_p
->value
)) == BOOLEAN_TYPE
)
11986 error_at (loc
, "argument %u in call to function "
11987 "%qs has boolean type", 1, name
);
11991 if (!TYPE_UNSIGNED (TREE_TYPE (arg_p
->value
)))
11993 error_at (loc
, "argument 1 in call to function "
11994 "%qs has signed type", name
);
11998 tree arg
= arg_p
->value
;
11999 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (arg
));
12001 __builtin_stdc_leading_zeros (arg) as
12002 (unsigned int) __builtin_clzg (arg, prec)
12003 __builtin_stdc_leading_ones (arg) as
12004 (unsigned int) __builtin_clzg ((type) ~arg, prec)
12005 __builtin_stdc_trailing_zeros (arg) as
12006 (unsigned int) __builtin_ctzg (arg, prec)
12007 __builtin_stdc_trailing_ones (arg) as
12008 (unsigned int) __builtin_ctzg ((type) ~arg, prec)
12009 __builtin_stdc_first_leading_zero (arg) as
12010 __builtin_clzg ((type) ~arg, -1) + 1U
12011 __builtin_stdc_first_leading_one (arg) as
12012 __builtin_clzg (arg, -1) + 1U
12013 __builtin_stdc_first_trailing_zero (arg) as
12014 __builtin_ctzg ((type) ~arg, -1) + 1U
12015 __builtin_stdc_first_trailing_one (arg) as
12016 __builtin_ctzg (arg, -1) + 1U
12017 __builtin_stdc_count_zeros (arg) as
12018 (unsigned int) __builtin_popcountg ((type) ~arg)
12019 __builtin_stdc_count_ones (arg) as
12020 (unsigned int) __builtin_popcountg (arg)
12021 __builtin_stdc_has_single_bit (arg) as
12022 (_Bool) (__builtin_popcountg (arg) == 1)
12023 __builtin_stdc_bit_width (arg) as
12024 (unsigned int) (prec - __builtin_clzg (arg, prec))
12025 __builtin_stdc_bit_floor (arg) as
12026 arg == 0 ? (type) 0
12027 : (type) 1 << (prec - 1 - __builtin_clzg (arg))
12028 __builtin_stdc_bit_ceil (arg) as
12029 arg <= 1 ? (type) 1
12030 : (type) 2 << (prec - 1 - __builtin_clzg (arg - 1))
12031 without evaluating arg multiple times, type being
12032 __typeof (arg) and prec __builtin_popcountg ((type) ~0)). */
12033 int prec
= TYPE_PRECISION (type
);
12037 case C_BUILTIN_STDC_BIT_CEIL
:
12038 arg
= save_expr (arg
);
12039 barg1
= build2_loc (loc
, PLUS_EXPR
, type
, arg
,
12040 build_int_cst (type
, -1));
12042 case C_BUILTIN_STDC_BIT_FLOOR
:
12043 barg1
= arg
= save_expr (arg
);
12045 case C_BUILTIN_STDC_COUNT_ZEROS
:
12046 case C_BUILTIN_STDC_FIRST_LEADING_ZERO
:
12047 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO
:
12048 case C_BUILTIN_STDC_LEADING_ONES
:
12049 case C_BUILTIN_STDC_TRAILING_ONES
:
12050 barg1
= build1_loc (loc
, BIT_NOT_EXPR
, type
, arg
);
12055 tree barg2
= NULL_TREE
;
12058 case C_BUILTIN_STDC_BIT_WIDTH
:
12059 case C_BUILTIN_STDC_LEADING_ONES
:
12060 case C_BUILTIN_STDC_LEADING_ZEROS
:
12061 case C_BUILTIN_STDC_TRAILING_ONES
:
12062 case C_BUILTIN_STDC_TRAILING_ZEROS
:
12063 barg2
= build_int_cst (integer_type_node
, prec
);
12065 case C_BUILTIN_STDC_FIRST_LEADING_ONE
:
12066 case C_BUILTIN_STDC_FIRST_LEADING_ZERO
:
12067 case C_BUILTIN_STDC_FIRST_TRAILING_ONE
:
12068 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO
:
12069 barg2
= integer_minus_one_node
;
12074 tree fndecl
= NULL_TREE
;
12077 case C_BUILTIN_STDC_BIT_CEIL
:
12078 case C_BUILTIN_STDC_BIT_FLOOR
:
12079 case C_BUILTIN_STDC_BIT_WIDTH
:
12080 case C_BUILTIN_STDC_FIRST_LEADING_ONE
:
12081 case C_BUILTIN_STDC_FIRST_LEADING_ZERO
:
12082 case C_BUILTIN_STDC_LEADING_ONES
:
12083 case C_BUILTIN_STDC_LEADING_ZEROS
:
12084 fndecl
= builtin_decl_explicit (BUILT_IN_CLZG
);
12086 case C_BUILTIN_STDC_FIRST_TRAILING_ONE
:
12087 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO
:
12088 case C_BUILTIN_STDC_TRAILING_ONES
:
12089 case C_BUILTIN_STDC_TRAILING_ZEROS
:
12090 fndecl
= builtin_decl_explicit (BUILT_IN_CTZG
);
12092 case C_BUILTIN_STDC_COUNT_ONES
:
12093 case C_BUILTIN_STDC_COUNT_ZEROS
:
12094 case C_BUILTIN_STDC_HAS_SINGLE_BIT
:
12095 fndecl
= builtin_decl_explicit (BUILT_IN_POPCOUNTG
);
12098 gcc_unreachable ();
12100 /* Construct a call to __builtin_{clz,ctz,popcount}g. */
12101 int nargs
= barg2
!= NULL_TREE
? 2 : 1;
12102 vec
<tree
, va_gc
> *args
;
12103 vec_alloc (args
, nargs
);
12104 vec
<tree
, va_gc
> *origtypes
;
12105 vec_alloc (origtypes
, nargs
);
12106 auto_vec
<location_t
> arg_loc (nargs
);
12107 args
->quick_push (barg1
);
12108 arg_loc
.quick_push (arg_p
->get_location ());
12109 origtypes
->quick_push (arg_p
->original_type
);
12112 args
->quick_push (barg2
);
12113 arg_loc
.quick_push (loc
);
12114 origtypes
->quick_push (integer_type_node
);
12116 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fndecl
,
12118 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
12119 if (expr
.value
== error_mark_node
)
12123 case C_BUILTIN_STDC_BIT_CEIL
:
12124 case C_BUILTIN_STDC_BIT_FLOOR
:
12127 case C_BUILTIN_STDC_BIT_WIDTH
:
12128 expr
.value
= build2_loc (loc
, MINUS_EXPR
, integer_type_node
,
12129 build_int_cst (integer_type_node
,
12130 prec
), expr
.value
);
12132 case C_BUILTIN_STDC_FIRST_LEADING_ONE
:
12133 case C_BUILTIN_STDC_FIRST_LEADING_ZERO
:
12134 case C_BUILTIN_STDC_FIRST_TRAILING_ONE
:
12135 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO
:
12136 expr
.value
= build2_loc (loc
, PLUS_EXPR
, integer_type_node
,
12137 expr
.value
, integer_one_node
);
12139 case C_BUILTIN_STDC_HAS_SINGLE_BIT
:
12140 expr
.value
= build2_loc (loc
, EQ_EXPR
, boolean_type_node
,
12141 expr
.value
, integer_one_node
);
12147 if (stdc_rid
!= C_BUILTIN_STDC_BIT_CEIL
12148 && stdc_rid
!= C_BUILTIN_STDC_BIT_FLOOR
)
12150 if (stdc_rid
!= C_BUILTIN_STDC_HAS_SINGLE_BIT
)
12151 expr
.value
= fold_convert_loc (loc
, unsigned_type_node
,
12155 /* For __builtin_stdc_bit_ceil (0U) or __builtin_stdc_bit_ceil (1U)
12156 or __builtin_stdc_bit_floor (0U) avoid bogus -Wshift-count-*
12157 warnings. The LSHIFT_EXPR is in dead code in that case. */
12158 if (integer_zerop (arg
)
12159 || (stdc_rid
== C_BUILTIN_STDC_BIT_CEIL
&& integer_onep (arg
)))
12160 expr
.value
= build_int_cst (type
, 0);
12163 = build2_loc (loc
, LSHIFT_EXPR
, type
,
12164 build_int_cst (type
,
12166 == C_BUILTIN_STDC_BIT_CEIL
12167 ? 2 : 1)), expr
.value
);
12168 if (stdc_rid
== C_BUILTIN_STDC_BIT_CEIL
)
12169 expr
.value
= build3_loc (loc
, COND_EXPR
, type
,
12170 build2_loc (loc
, LE_EXPR
,
12171 boolean_type_node
, arg
,
12172 build_int_cst (type
, 1)),
12173 build_int_cst (type
, 1),
12176 expr
.value
= build3_loc (loc
, COND_EXPR
, type
,
12177 build2_loc (loc
, EQ_EXPR
,
12178 boolean_type_node
, arg
,
12179 build_int_cst (type
, 0)),
12180 build_int_cst (type
, 0),
12184 case RID_AT_SELECTOR
:
12186 gcc_assert (c_dialect_objc ());
12187 c_parser_consume_token (parser
);
12188 matching_parens parens
;
12189 if (!parens
.require_open (parser
))
12194 tree sel
= c_parser_objc_selector_arg (parser
);
12195 location_t close_loc
= c_parser_peek_token (parser
)->location
;
12196 parens
.skip_until_found_close (parser
);
12197 expr
.value
= objc_build_selector_expr (loc
, sel
);
12198 set_c_expr_source_range (&expr
, loc
, close_loc
);
12201 case RID_AT_PROTOCOL
:
12203 gcc_assert (c_dialect_objc ());
12204 c_parser_consume_token (parser
);
12205 matching_parens parens
;
12206 if (!parens
.require_open (parser
))
12211 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12213 c_parser_error (parser
, "expected identifier");
12214 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
12218 tree id
= c_parser_peek_token (parser
)->value
;
12219 c_parser_consume_token (parser
);
12220 location_t close_loc
= c_parser_peek_token (parser
)->location
;
12221 parens
.skip_until_found_close (parser
);
12222 expr
.value
= objc_build_protocol_expr (id
);
12223 set_c_expr_source_range (&expr
, loc
, close_loc
);
12226 case RID_AT_ENCODE
:
12228 /* Extension to support C-structures in the archiver. */
12229 gcc_assert (c_dialect_objc ());
12230 c_parser_consume_token (parser
);
12231 matching_parens parens
;
12232 if (!parens
.require_open (parser
))
12237 t1
= c_parser_type_name (parser
);
12241 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
12244 location_t close_loc
= c_parser_peek_token (parser
)->location
;
12245 parens
.skip_until_found_close (parser
);
12246 tree type
= groktypename (t1
, NULL
, NULL
);
12247 expr
.value
= objc_build_encode_expr (type
);
12248 set_c_expr_source_range (&expr
, loc
, close_loc
);
12252 expr
= c_parser_generic_selection (parser
);
12254 case RID_OMP_ALL_MEMORY
:
12255 gcc_assert (flag_openmp
);
12256 c_parser_consume_token (parser
);
12257 error_at (loc
, "%<omp_all_memory%> may only be used in OpenMP "
12258 "%<depend%> clause");
12261 /* C23 'nullptr' literal. */
12263 c_parser_consume_token (parser
);
12264 expr
.value
= nullptr_node
;
12265 set_c_expr_source_range (&expr
, tok_range
);
12266 pedwarn_c11 (loc
, OPT_Wpedantic
,
12267 "ISO C does not support %qs before C23", "nullptr");
12270 c_parser_consume_token (parser
);
12271 expr
.value
= boolean_true_node
;
12272 set_c_expr_source_range (&expr
, tok_range
);
12275 c_parser_consume_token (parser
);
12276 expr
.value
= boolean_false_node
;
12277 set_c_expr_source_range (&expr
, tok_range
);
12280 c_parser_error (parser
, "expected expression");
12285 case CPP_OPEN_SQUARE
:
12286 if (c_dialect_objc ())
12288 tree receiver
, args
;
12289 c_parser_consume_token (parser
);
12290 receiver
= c_parser_objc_receiver (parser
);
12291 args
= c_parser_objc_message_args (parser
);
12292 location_t close_loc
= c_parser_peek_token (parser
)->location
;
12293 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
12295 expr
.value
= objc_build_message_expr (receiver
, args
);
12296 set_c_expr_source_range (&expr
, loc
, close_loc
);
12299 /* Else fall through to report error. */
12302 c_parser_error (parser
, "expected expression");
12307 return c_parser_postfix_expression_after_primary
12308 (parser
, EXPR_LOC_OR_LOC (expr
.value
, loc
), expr
);
12311 /* Parse a postfix expression after a parenthesized type name: the
12312 brace-enclosed initializer of a compound literal, possibly followed
12313 by some postfix operators. This is separate because it is not
12314 possible to tell until after the type name whether a cast
12315 expression has a cast or a compound literal, or whether the operand
12316 of sizeof is a parenthesized type name or starts with a compound
12317 literal. TYPE_LOC is the location where TYPE_NAME starts--the
12318 location of the first token after the parentheses around the type
12321 static struct c_expr
12322 c_parser_postfix_expression_after_paren_type (c_parser
*parser
,
12323 struct c_declspecs
*scspecs
,
12324 struct c_type_name
*type_name
,
12325 location_t type_loc
)
12328 struct c_expr init
;
12330 struct c_expr expr
;
12331 location_t start_loc
;
12332 tree type_expr
= NULL_TREE
;
12333 bool type_expr_const
= true;
12334 bool constexpr_p
= scspecs
? scspecs
->constexpr_p
: false;
12335 unsigned int underspec_state
= 0;
12336 check_compound_literal_type (type_loc
, type_name
);
12337 rich_location
richloc (line_table
, type_loc
);
12338 start_loc
= c_parser_peek_token (parser
)->location
;
12341 underspec_state
= start_underspecified_init (start_loc
, NULL_TREE
);
12342 /* A constexpr compound literal is subject to the constraints on
12343 underspecified declarations, which may not declare tags or
12344 members or structures or unions; it is undefined behavior to
12345 declare the members of an enumeration. Where the structure,
12346 union or enumeration type is declared within the compound
12347 literal initializer, this is diagnosed elsewhere as a result
12348 of the above call to start_underspecified_init. Diagnose
12349 here the case of declaring such a type in the type specifiers
12350 of the compound literal. */
12351 switch (type_name
->specs
->typespec_kind
)
12353 case ctsk_tagfirstref
:
12354 case ctsk_tagfirstref_attrs
:
12355 error_at (type_loc
, "%qT declared in %<constexpr%> compound literal",
12356 type_name
->specs
->type
);
12360 error_at (type_loc
, "%qT defined in %<constexpr%> compound literal",
12361 type_name
->specs
->type
);
12368 start_init (NULL_TREE
, NULL
,
12369 (global_bindings_p ()
12370 || (scspecs
&& scspecs
->storage_class
== csc_static
)
12371 || constexpr_p
), constexpr_p
, &richloc
);
12372 type
= groktypename (type_name
, &type_expr
, &type_expr_const
);
12373 if (type
!= error_mark_node
&& C_TYPE_VARIABLE_SIZE (type
))
12375 error_at (type_loc
, "compound literal has variable size");
12376 type
= error_mark_node
;
12378 else if (TREE_CODE (type
) == FUNCTION_TYPE
)
12380 error_at (type_loc
, "compound literal has function type");
12381 type
= error_mark_node
;
12383 if (constexpr_p
&& type
!= error_mark_node
)
12385 tree type_no_array
= strip_array_types (type
);
12386 /* The type of a constexpr object must not be variably modified
12387 (which applies to all compound literals), volatile, atomic or
12388 restrict qualified or have a member with such a qualifier.
12389 const qualification is implicitly added. */
12390 if (TYPE_QUALS (type_no_array
)
12391 & (TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
| TYPE_QUAL_ATOMIC
))
12392 error_at (type_loc
, "invalid qualifiers for %<constexpr%> object");
12393 else if (RECORD_OR_UNION_TYPE_P (type_no_array
)
12394 && C_TYPE_FIELDS_NON_CONSTEXPR (type_no_array
))
12395 error_at (type_loc
, "invalid qualifiers for field of "
12396 "%<constexpr%> object");
12397 type
= c_build_qualified_type (type
,
12398 (TYPE_QUALS (type_no_array
)
12399 | TYPE_QUAL_CONST
));
12401 init
= c_parser_braced_init (parser
, type
, false, NULL
, NULL_TREE
);
12403 finish_underspecified_init (NULL_TREE
, underspec_state
);
12405 maybe_warn_string_init (type_loc
, type
, init
);
12407 if (type
!= error_mark_node
12408 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type
))
12409 && current_function_decl
)
12411 error ("compound literal qualified by address-space qualifier");
12412 type
= error_mark_node
;
12415 if (!pedwarn_c90 (start_loc
, OPT_Wpedantic
,
12416 "ISO C90 forbids compound literals") && scspecs
)
12417 pedwarn_c11 (start_loc
, OPT_Wpedantic
,
12418 "ISO C forbids storage class specifiers in compound literals "
12420 non_const
= ((init
.value
&& TREE_CODE (init
.value
) == CONSTRUCTOR
)
12421 ? CONSTRUCTOR_NON_CONST (init
.value
)
12422 : init
.original_code
== C_MAYBE_CONST_EXPR
);
12423 non_const
|= !type_expr_const
;
12424 unsigned int alignas_align
= 0;
12425 if (type
!= error_mark_node
12426 && type_name
->specs
->align_log
!= -1)
12428 alignas_align
= 1U << type_name
->specs
->align_log
;
12429 if (alignas_align
< min_align_of_type (type
))
12431 error_at (type_name
->specs
->locations
[cdw_alignas
],
12432 "%<_Alignas%> specifiers cannot reduce "
12433 "alignment of compound literal");
12437 expr
.value
= build_compound_literal (start_loc
, type
, init
.value
, non_const
,
12438 alignas_align
, scspecs
);
12439 set_c_expr_source_range (&expr
, init
.src_range
);
12440 expr
.m_decimal
= 0;
12441 expr
.original_code
= ERROR_MARK
;
12442 expr
.original_type
= NULL
;
12443 if (type
!= error_mark_node
12444 && expr
.value
!= error_mark_node
12447 if (TREE_CODE (expr
.value
) == C_MAYBE_CONST_EXPR
)
12449 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr
.value
) == NULL_TREE
);
12450 C_MAYBE_CONST_EXPR_PRE (expr
.value
) = type_expr
;
12454 gcc_assert (!non_const
);
12455 expr
.value
= build2 (C_MAYBE_CONST_EXPR
, type
,
12456 type_expr
, expr
.value
);
12459 return c_parser_postfix_expression_after_primary (parser
, start_loc
, expr
);
12462 /* Callback function for sizeof_pointer_memaccess_warning to compare
12466 sizeof_ptr_memacc_comptypes (tree type1
, tree type2
)
12468 return comptypes (type1
, type2
) == 1;
12471 /* Warn for patterns where abs-like function appears to be used incorrectly,
12472 gracefully ignore any non-abs-like function. The warning location should
12473 be LOC. FNDECL is the declaration of called function, it must be a
12474 BUILT_IN_NORMAL function. ARG is the first and only argument of the
12478 warn_for_abs (location_t loc
, tree fndecl
, tree arg
)
12480 /* Avoid warning in unreachable subexpressions. */
12481 if (c_inhibit_evaluation_warnings
)
12484 tree atype
= TREE_TYPE (arg
);
12486 /* Casts from pointers (and thus arrays and fndecls) will generate
12487 -Wint-conversion warnings. Most other wrong types hopefully lead to type
12488 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
12489 types and possibly other exotic types. */
12490 if (!INTEGRAL_TYPE_P (atype
)
12491 && !SCALAR_FLOAT_TYPE_P (atype
)
12492 && TREE_CODE (atype
) != COMPLEX_TYPE
)
12495 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
12500 case BUILT_IN_LABS
:
12501 case BUILT_IN_LLABS
:
12502 case BUILT_IN_IMAXABS
:
12503 if (!INTEGRAL_TYPE_P (atype
))
12505 if (SCALAR_FLOAT_TYPE_P (atype
))
12506 warning_at (loc
, OPT_Wabsolute_value
,
12507 "using integer absolute value function %qD when "
12508 "argument is of floating-point type %qT",
12510 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12511 warning_at (loc
, OPT_Wabsolute_value
,
12512 "using integer absolute value function %qD when "
12513 "argument is of complex type %qT", fndecl
, atype
);
12515 gcc_unreachable ();
12518 if (TYPE_UNSIGNED (atype
))
12519 warning_at (loc
, OPT_Wabsolute_value
,
12520 "taking the absolute value of unsigned type %qT "
12521 "has no effect", atype
);
12524 CASE_FLT_FN (BUILT_IN_FABS
):
12525 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS
):
12526 if (!SCALAR_FLOAT_TYPE_P (atype
)
12527 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype
)))
12529 if (INTEGRAL_TYPE_P (atype
))
12530 warning_at (loc
, OPT_Wabsolute_value
,
12531 "using floating-point absolute value function %qD "
12532 "when argument is of integer type %qT", fndecl
, atype
);
12533 else if (DECIMAL_FLOAT_TYPE_P (atype
))
12534 warning_at (loc
, OPT_Wabsolute_value
,
12535 "using floating-point absolute value function %qD "
12536 "when argument is of decimal floating-point type %qT",
12538 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12539 warning_at (loc
, OPT_Wabsolute_value
,
12540 "using floating-point absolute value function %qD when "
12541 "argument is of complex type %qT", fndecl
, atype
);
12543 gcc_unreachable ();
12548 CASE_FLT_FN (BUILT_IN_CABS
):
12549 if (TREE_CODE (atype
) != COMPLEX_TYPE
)
12551 if (INTEGRAL_TYPE_P (atype
))
12552 warning_at (loc
, OPT_Wabsolute_value
,
12553 "using complex absolute value function %qD when "
12554 "argument is of integer type %qT", fndecl
, atype
);
12555 else if (SCALAR_FLOAT_TYPE_P (atype
))
12556 warning_at (loc
, OPT_Wabsolute_value
,
12557 "using complex absolute value function %qD when "
12558 "argument is of floating-point type %qT",
12561 gcc_unreachable ();
12567 case BUILT_IN_FABSD32
:
12568 case BUILT_IN_FABSD64
:
12569 case BUILT_IN_FABSD128
:
12570 if (!DECIMAL_FLOAT_TYPE_P (atype
))
12572 if (INTEGRAL_TYPE_P (atype
))
12573 warning_at (loc
, OPT_Wabsolute_value
,
12574 "using decimal floating-point absolute value "
12575 "function %qD when argument is of integer type %qT",
12577 else if (SCALAR_FLOAT_TYPE_P (atype
))
12578 warning_at (loc
, OPT_Wabsolute_value
,
12579 "using decimal floating-point absolute value "
12580 "function %qD when argument is of floating-point "
12581 "type %qT", fndecl
, atype
);
12582 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12583 warning_at (loc
, OPT_Wabsolute_value
,
12584 "using decimal floating-point absolute value "
12585 "function %qD when argument is of complex type %qT",
12588 gcc_unreachable ();
12597 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl
)))
12600 tree ftype
= TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
12601 if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12603 gcc_assert (TREE_CODE (ftype
) == COMPLEX_TYPE
);
12604 atype
= TREE_TYPE (atype
);
12605 ftype
= TREE_TYPE (ftype
);
12608 if (TYPE_PRECISION (ftype
) < TYPE_PRECISION (atype
))
12609 warning_at (loc
, OPT_Wabsolute_value
,
12610 "absolute value function %qD given an argument of type %qT "
12611 "but has parameter of type %qT which may cause truncation "
12612 "of value", fndecl
, atype
, ftype
);
12616 /* Parse a postfix expression after the initial primary or compound
12617 literal; that is, parse a series of postfix operators.
12619 EXPR_LOC is the location of the primary expression. */
12621 static struct c_expr
12622 c_parser_postfix_expression_after_primary (c_parser
*parser
,
12623 location_t expr_loc
,
12624 struct c_expr expr
)
12626 struct c_expr orig_expr
;
12627 tree ident
, idx
, len
;
12628 location_t sizeof_arg_loc
[6], comp_loc
;
12629 tree sizeof_arg
[6];
12630 unsigned int literal_zero_mask
;
12632 vec
<tree
, va_gc
> *exprlist
;
12633 vec
<tree
, va_gc
> *origtypes
= NULL
;
12634 vec
<location_t
> arg_loc
= vNULL
;
12640 location_t op_loc
= c_parser_peek_token (parser
)->location
;
12641 switch (c_parser_peek_token (parser
)->type
)
12643 case CPP_OPEN_SQUARE
:
12644 /* Array reference. */
12645 c_parser_consume_token (parser
);
12646 idx
= len
= NULL_TREE
;
12647 if (!c_omp_array_section_p
12648 || c_parser_next_token_is_not (parser
, CPP_COLON
))
12649 idx
= c_parser_expression (parser
).value
;
12651 if (c_omp_array_section_p
12652 && c_parser_next_token_is (parser
, CPP_COLON
))
12654 c_parser_consume_token (parser
);
12655 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_SQUARE
))
12656 len
= c_parser_expression (parser
).value
;
12658 expr
.value
= build_omp_array_section (op_loc
, expr
.value
, idx
,
12662 expr
.value
= build_array_ref (op_loc
, expr
.value
, idx
);
12664 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
12667 start
= expr
.get_start ();
12668 finish
= parser
->tokens_buf
[0].location
;
12669 set_c_expr_source_range (&expr
, start
, finish
);
12670 expr
.original_code
= ERROR_MARK
;
12671 expr
.original_type
= NULL
;
12672 expr
.m_decimal
= 0;
12674 case CPP_OPEN_PAREN
:
12675 /* Function call. */
12677 matching_parens parens
;
12678 parens
.consume_open (parser
);
12679 for (i
= 0; i
< 6; i
++)
12681 sizeof_arg
[i
] = NULL_TREE
;
12682 sizeof_arg_loc
[i
] = UNKNOWN_LOCATION
;
12684 literal_zero_mask
= 0;
12685 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
12687 else if (TREE_CODE (expr
.value
) == FUNCTION_DECL
12688 && fndecl_built_in_p (expr
.value
, BUILT_IN_CLASSIFY_TYPE
)
12689 && c_parser_next_tokens_start_typename (parser
,
12692 /* __builtin_classify_type (type) */
12693 c_inhibit_evaluation_warnings
++;
12695 struct c_type_name
*type
= c_parser_type_name (parser
);
12696 c_inhibit_evaluation_warnings
--;
12698 struct c_typespec ret
;
12699 ret
.expr
= NULL_TREE
;
12700 ret
.spec
= error_mark_node
;
12701 ret
.expr_const_operands
= false;
12703 ret
.spec
= groktypename (type
, &ret
.expr
,
12704 &ret
.expr_const_operands
);
12705 parens
.skip_until_found_close (parser
);
12706 expr
.value
= build_int_cst (integer_type_node
,
12707 type_to_class (ret
.spec
));
12711 exprlist
= c_parser_expr_list (parser
, true, false, &origtypes
,
12712 sizeof_arg_loc
, sizeof_arg
,
12713 &arg_loc
, &literal_zero_mask
);
12714 parens
.skip_until_found_close (parser
);
12717 mark_exp_read (expr
.value
);
12718 if (warn_sizeof_pointer_memaccess
)
12719 sizeof_pointer_memaccess_warning (sizeof_arg_loc
,
12720 expr
.value
, exprlist
,
12722 sizeof_ptr_memacc_comptypes
);
12723 if (TREE_CODE (expr
.value
) == FUNCTION_DECL
)
12725 if (fndecl_built_in_p (expr
.value
, BUILT_IN_MEMSET
)
12726 && vec_safe_length (exprlist
) == 3)
12728 tree arg0
= (*exprlist
)[0];
12729 tree arg2
= (*exprlist
)[2];
12730 warn_for_memset (expr_loc
, arg0
, arg2
, literal_zero_mask
);
12732 if (warn_absolute_value
12733 && fndecl_built_in_p (expr
.value
, BUILT_IN_NORMAL
)
12734 && vec_safe_length (exprlist
) == 1)
12735 warn_for_abs (expr_loc
, expr
.value
, (*exprlist
)[0]);
12736 if (parser
->omp_for_parse_state
12737 && parser
->omp_for_parse_state
->in_intervening_code
12738 && omp_runtime_api_call (expr
.value
))
12740 error_at (expr_loc
, "calls to the OpenMP runtime API are "
12741 "not permitted in intervening code");
12742 parser
->omp_for_parse_state
->fail
= true;
12744 if (warn_calloc_transposed_args
)
12745 if (tree attr
= lookup_attribute ("alloc_size",
12747 (TREE_TYPE (expr
.value
))))
12748 if (TREE_VALUE (attr
) && TREE_CHAIN (TREE_VALUE (attr
)))
12749 warn_for_calloc (sizeof_arg_loc
, expr
.value
, exprlist
,
12753 start
= expr
.get_start ();
12754 finish
= parser
->tokens_buf
[0].get_finish ();
12756 = c_build_function_call_vec (expr_loc
, arg_loc
, expr
.value
,
12757 exprlist
, origtypes
);
12758 set_c_expr_source_range (&expr
, start
, finish
);
12759 expr
.m_decimal
= 0;
12761 expr
.original_code
= ERROR_MARK
;
12762 if (TREE_CODE (expr
.value
) == INTEGER_CST
12763 && TREE_CODE (orig_expr
.value
) == FUNCTION_DECL
12764 && fndecl_built_in_p (orig_expr
.value
, BUILT_IN_CONSTANT_P
))
12765 expr
.original_code
= C_MAYBE_CONST_EXPR
;
12766 expr
.original_type
= NULL
;
12769 release_tree_vector (exprlist
);
12770 release_tree_vector (origtypes
);
12772 arg_loc
.release ();
12775 /* Structure element reference. */
12776 c_parser_consume_token (parser
);
12777 expr
= default_function_array_conversion (expr_loc
, expr
);
12778 if (c_parser_next_token_is (parser
, CPP_NAME
))
12780 c_token
*comp_tok
= c_parser_peek_token (parser
);
12781 ident
= comp_tok
->value
;
12782 comp_loc
= comp_tok
->location
;
12786 c_parser_error (parser
, "expected identifier");
12788 expr
.original_code
= ERROR_MARK
;
12789 expr
.original_type
= NULL
;
12792 start
= expr
.get_start ();
12793 finish
= c_parser_peek_token (parser
)->get_finish ();
12794 c_parser_consume_token (parser
);
12795 expr
.value
= build_component_ref (op_loc
, expr
.value
, ident
,
12796 comp_loc
, UNKNOWN_LOCATION
);
12797 set_c_expr_source_range (&expr
, start
, finish
);
12798 expr
.original_code
= ERROR_MARK
;
12799 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
12800 expr
.original_type
= NULL
;
12803 /* Remember the original type of a bitfield. */
12804 tree field
= TREE_OPERAND (expr
.value
, 1);
12805 if (TREE_CODE (field
) != FIELD_DECL
)
12806 expr
.original_type
= NULL
;
12808 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
12810 expr
.m_decimal
= 0;
12813 /* Structure element reference. */
12814 c_parser_consume_token (parser
);
12815 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, false);
12816 if (c_parser_next_token_is (parser
, CPP_NAME
))
12818 c_token
*comp_tok
= c_parser_peek_token (parser
);
12819 ident
= comp_tok
->value
;
12820 comp_loc
= comp_tok
->location
;
12824 c_parser_error (parser
, "expected identifier");
12826 expr
.original_code
= ERROR_MARK
;
12827 expr
.original_type
= NULL
;
12830 start
= expr
.get_start ();
12831 finish
= c_parser_peek_token (parser
)->get_finish ();
12832 c_parser_consume_token (parser
);
12833 expr
.value
= build_component_ref (op_loc
,
12834 build_indirect_ref (op_loc
,
12838 expr
.get_location ());
12839 set_c_expr_source_range (&expr
, start
, finish
);
12840 expr
.original_code
= ERROR_MARK
;
12841 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
12842 expr
.original_type
= NULL
;
12845 /* Remember the original type of a bitfield. */
12846 tree field
= TREE_OPERAND (expr
.value
, 1);
12847 if (TREE_CODE (field
) != FIELD_DECL
)
12848 expr
.original_type
= NULL
;
12850 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
12852 expr
.m_decimal
= 0;
12854 case CPP_PLUS_PLUS
:
12855 /* Postincrement. */
12856 start
= expr
.get_start ();
12857 finish
= c_parser_peek_token (parser
)->get_finish ();
12858 c_parser_consume_token (parser
);
12859 expr
= default_function_array_read_conversion (expr_loc
, expr
);
12860 expr
.value
= build_unary_op (op_loc
, POSTINCREMENT_EXPR
,
12861 expr
.value
, false);
12862 set_c_expr_source_range (&expr
, start
, finish
);
12863 expr
.original_code
= ERROR_MARK
;
12864 expr
.original_type
= NULL
;
12866 case CPP_MINUS_MINUS
:
12867 /* Postdecrement. */
12868 start
= expr
.get_start ();
12869 finish
= c_parser_peek_token (parser
)->get_finish ();
12870 c_parser_consume_token (parser
);
12871 expr
= default_function_array_read_conversion (expr_loc
, expr
);
12872 expr
.value
= build_unary_op (op_loc
, POSTDECREMENT_EXPR
,
12873 expr
.value
, false);
12874 set_c_expr_source_range (&expr
, start
, finish
);
12875 expr
.original_code
= ERROR_MARK
;
12876 expr
.original_type
= NULL
;
12884 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
12887 assignment-expression
12888 expression , assignment-expression
12891 static struct c_expr
12892 c_parser_expression (c_parser
*parser
)
12894 location_t tloc
= c_parser_peek_token (parser
)->location
;
12895 struct c_expr expr
;
12896 expr
= c_parser_expr_no_commas (parser
, NULL
);
12897 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12898 expr
= convert_lvalue_to_rvalue (tloc
, expr
, true, false);
12899 while (c_parser_next_token_is (parser
, CPP_COMMA
))
12901 struct c_expr next
;
12903 location_t loc
= c_parser_peek_token (parser
)->location
;
12904 location_t expr_loc
;
12905 c_parser_consume_token (parser
);
12906 expr_loc
= c_parser_peek_token (parser
)->location
;
12907 lhsval
= expr
.value
;
12908 while (TREE_CODE (lhsval
) == COMPOUND_EXPR
12909 || TREE_CODE (lhsval
) == NOP_EXPR
)
12911 if (TREE_CODE (lhsval
) == COMPOUND_EXPR
)
12912 lhsval
= TREE_OPERAND (lhsval
, 1);
12914 lhsval
= TREE_OPERAND (lhsval
, 0);
12916 if (DECL_P (lhsval
) || handled_component_p (lhsval
))
12917 mark_exp_read (lhsval
);
12918 next
= c_parser_expr_no_commas (parser
, NULL
);
12919 next
= convert_lvalue_to_rvalue (expr_loc
, next
, true, false);
12920 expr
.value
= build_compound_expr (loc
, expr
.value
, next
.value
);
12921 expr
.original_code
= COMPOUND_EXPR
;
12922 expr
.original_type
= next
.original_type
;
12923 expr
.m_decimal
= 0;
12928 /* Parse an expression and convert functions or arrays to pointers and
12929 lvalues to rvalues. */
12931 static struct c_expr
12932 c_parser_expression_conv (c_parser
*parser
)
12934 struct c_expr expr
;
12935 location_t loc
= c_parser_peek_token (parser
)->location
;
12936 expr
= c_parser_expression (parser
);
12937 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, false);
12941 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
12942 argument is a literal zero alone and if so, set it in literal_zero_mask. */
12945 c_parser_check_literal_zero (c_parser
*parser
, unsigned *literal_zero_mask
,
12948 if (idx
>= HOST_BITS_PER_INT
)
12951 c_token
*tok
= c_parser_peek_token (parser
);
12960 /* If a parameter is literal zero alone, remember it
12961 for -Wmemset-transposed-args warning. */
12962 if (integer_zerop (tok
->value
)
12963 && !TREE_OVERFLOW (tok
->value
)
12964 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
12965 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
12966 *literal_zero_mask
|= 1U << idx
;
12972 /* Parse a non-empty list of expressions. If CONVERT_P, convert
12973 functions and arrays to pointers and lvalues to rvalues. If
12974 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
12975 locations of function arguments into this vector.
12977 nonempty-expr-list:
12978 assignment-expression
12979 nonempty-expr-list , assignment-expression
12982 static vec
<tree
, va_gc
> *
12983 c_parser_expr_list (c_parser
*parser
, bool convert_p
, bool fold_p
,
12984 vec
<tree
, va_gc
> **p_orig_types
,
12985 location_t
*sizeof_arg_loc
, tree
*sizeof_arg
,
12986 vec
<location_t
> *locations
,
12987 unsigned int *literal_zero_mask
)
12989 vec
<tree
, va_gc
> *ret
;
12990 vec
<tree
, va_gc
> *orig_types
;
12991 struct c_expr expr
;
12992 unsigned int idx
= 0;
12993 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
12994 c_omp_array_section_p
= false;
12996 ret
= make_tree_vector ();
12997 if (p_orig_types
== NULL
)
13000 orig_types
= make_tree_vector ();
13002 if (literal_zero_mask
)
13003 c_parser_check_literal_zero (parser
, literal_zero_mask
, 0);
13004 expr
= c_parser_expr_no_commas (parser
, NULL
);
13006 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true, true);
13008 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
13009 ret
->quick_push (expr
.value
);
13011 orig_types
->quick_push (expr
.original_type
);
13013 locations
->safe_push (expr
.get_location ());
13014 if (sizeof_arg
!= NULL
13015 && (expr
.original_code
== SIZEOF_EXPR
13016 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
13018 sizeof_arg
[0] = c_last_sizeof_arg
;
13019 sizeof_arg_loc
[0] = c_last_sizeof_loc
;
13021 while (c_parser_next_token_is (parser
, CPP_COMMA
))
13023 c_parser_consume_token (parser
);
13024 if (literal_zero_mask
)
13025 c_parser_check_literal_zero (parser
, literal_zero_mask
, idx
+ 1);
13026 expr
= c_parser_expr_no_commas (parser
, NULL
);
13028 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true,
13031 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
13032 vec_safe_push (ret
, expr
.value
);
13034 vec_safe_push (orig_types
, expr
.original_type
);
13036 locations
->safe_push (expr
.get_location ());
13038 && sizeof_arg
!= NULL
13039 && (expr
.original_code
== SIZEOF_EXPR
13040 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
13042 sizeof_arg
[idx
] = c_last_sizeof_arg
;
13043 sizeof_arg_loc
[idx
] = c_last_sizeof_loc
;
13047 *p_orig_types
= orig_types
;
13048 c_omp_array_section_p
= save_c_omp_array_section_p
;
13052 /* Parse Objective-C-specific constructs. */
13054 /* Parse an objc-class-definition.
13056 objc-class-definition:
13057 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
13058 objc-class-instance-variables[opt] objc-methodprotolist @end
13059 @implementation identifier objc-superclass[opt]
13060 objc-class-instance-variables[opt]
13061 @interface identifier ( identifier ) objc-protocol-refs[opt]
13062 objc-methodprotolist @end
13063 @interface identifier ( ) objc-protocol-refs[opt]
13064 objc-methodprotolist @end
13065 @implementation identifier ( identifier )
13070 "@interface identifier (" must start "@interface identifier (
13071 identifier ) ...": objc-methodprotolist in the first production may
13072 not start with a parenthesized identifier as a declarator of a data
13073 definition with no declaration specifiers if the objc-superclass,
13074 objc-protocol-refs and objc-class-instance-variables are omitted. */
13077 c_parser_objc_class_definition (c_parser
*parser
, tree attributes
)
13082 if (c_parser_next_token_is_keyword (parser
, RID_AT_INTERFACE
))
13084 else if (c_parser_next_token_is_keyword (parser
, RID_AT_IMPLEMENTATION
))
13087 gcc_unreachable ();
13089 c_parser_consume_token (parser
);
13090 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13092 c_parser_error (parser
, "expected identifier");
13095 id1
= c_parser_peek_token (parser
)->value
;
13096 location_t loc1
= c_parser_peek_token (parser
)->location
;
13097 c_parser_consume_token (parser
);
13098 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13100 /* We have a category or class extension. */
13102 tree proto
= NULL_TREE
;
13103 matching_parens parens
;
13104 parens
.consume_open (parser
);
13105 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13107 if (iface_p
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
13109 /* We have a class extension. */
13114 c_parser_error (parser
, "expected identifier or %<)%>");
13115 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
13121 id2
= c_parser_peek_token (parser
)->value
;
13122 c_parser_consume_token (parser
);
13124 parens
.skip_until_found_close (parser
);
13127 objc_start_category_implementation (id1
, id2
);
13130 if (c_parser_next_token_is (parser
, CPP_LESS
))
13131 proto
= c_parser_objc_protocol_refs (parser
);
13132 objc_start_category_interface (id1
, id2
, proto
, attributes
);
13133 c_parser_objc_methodprotolist (parser
);
13134 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
13135 objc_finish_interface ();
13138 if (c_parser_next_token_is (parser
, CPP_COLON
))
13140 c_parser_consume_token (parser
);
13141 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13143 c_parser_error (parser
, "expected identifier");
13146 superclass
= c_parser_peek_token (parser
)->value
;
13147 c_parser_consume_token (parser
);
13150 superclass
= NULL_TREE
;
13153 tree proto
= NULL_TREE
;
13154 if (c_parser_next_token_is (parser
, CPP_LESS
))
13155 proto
= c_parser_objc_protocol_refs (parser
);
13156 objc_start_class_interface (id1
, loc1
, superclass
, proto
, attributes
);
13159 objc_start_class_implementation (id1
, superclass
);
13160 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
13161 c_parser_objc_class_instance_variables (parser
);
13164 objc_continue_interface ();
13165 c_parser_objc_methodprotolist (parser
);
13166 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
13167 objc_finish_interface ();
13171 objc_continue_implementation ();
13176 /* Parse objc-class-instance-variables.
13178 objc-class-instance-variables:
13179 { objc-instance-variable-decl-list[opt] }
13181 objc-instance-variable-decl-list:
13182 objc-visibility-spec
13183 objc-instance-variable-decl ;
13185 objc-instance-variable-decl-list objc-visibility-spec
13186 objc-instance-variable-decl-list objc-instance-variable-decl ;
13187 objc-instance-variable-decl-list ;
13189 objc-visibility-spec:
13194 objc-instance-variable-decl:
13199 c_parser_objc_class_instance_variables (c_parser
*parser
)
13201 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
13202 c_parser_consume_token (parser
);
13203 while (c_parser_next_token_is_not (parser
, CPP_EOF
))
13206 /* Parse any stray semicolon. */
13207 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
13209 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
13210 "extra semicolon");
13211 c_parser_consume_token (parser
);
13214 /* Stop if at the end of the instance variables. */
13215 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
13217 c_parser_consume_token (parser
);
13220 /* Parse any objc-visibility-spec. */
13221 if (c_parser_next_token_is_keyword (parser
, RID_AT_PRIVATE
))
13223 c_parser_consume_token (parser
);
13224 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE
);
13227 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROTECTED
))
13229 c_parser_consume_token (parser
);
13230 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED
);
13233 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PUBLIC
))
13235 c_parser_consume_token (parser
);
13236 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC
);
13239 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PACKAGE
))
13241 c_parser_consume_token (parser
);
13242 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE
);
13245 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
13247 c_parser_pragma (parser
, pragma_external
, NULL
);
13251 /* Parse some comma-separated declarations. */
13252 decls
= c_parser_struct_declaration (parser
, NULL
);
13255 /* There is a syntax error. We want to skip the offending
13256 tokens up to the next ';' (included) or '}'
13259 /* First, skip manually a ')' or ']'. This is because they
13260 reduce the nesting level, so c_parser_skip_until_found()
13261 wouldn't be able to skip past them. */
13262 c_token
*token
= c_parser_peek_token (parser
);
13263 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_CLOSE_SQUARE
)
13264 c_parser_consume_token (parser
);
13266 /* Then, do the standard skipping. */
13267 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
13269 /* We hopefully recovered. Start normal parsing again. */
13270 parser
->error
= false;
13275 /* Comma-separated instance variables are chained together
13276 in reverse order; add them one by one. */
13277 tree ivar
= nreverse (decls
);
13278 for (; ivar
; ivar
= DECL_CHAIN (ivar
))
13279 objc_add_instance_variable (copy_node (ivar
));
13281 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13285 /* Parse an objc-class-declaration.
13287 objc-class-declaration:
13288 @class identifier-list ;
13292 c_parser_objc_class_declaration (c_parser
*parser
)
13294 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_CLASS
));
13295 c_parser_consume_token (parser
);
13296 /* Any identifiers, including those declared as type names, are OK
13301 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13303 c_parser_error (parser
, "expected identifier");
13304 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
13305 parser
->error
= false;
13308 id
= c_parser_peek_token (parser
)->value
;
13309 objc_declare_class (id
);
13310 c_parser_consume_token (parser
);
13311 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13312 c_parser_consume_token (parser
);
13316 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13319 /* Parse an objc-alias-declaration.
13321 objc-alias-declaration:
13322 @compatibility_alias identifier identifier ;
13326 c_parser_objc_alias_declaration (c_parser
*parser
)
13329 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_ALIAS
));
13330 c_parser_consume_token (parser
);
13331 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13333 c_parser_error (parser
, "expected identifier");
13334 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
13337 id1
= c_parser_peek_token (parser
)->value
;
13338 c_parser_consume_token (parser
);
13339 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13341 c_parser_error (parser
, "expected identifier");
13342 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
13345 id2
= c_parser_peek_token (parser
)->value
;
13346 c_parser_consume_token (parser
);
13347 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13348 objc_declare_alias (id1
, id2
);
13351 /* Parse an objc-protocol-definition.
13353 objc-protocol-definition:
13354 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
13355 @protocol identifier-list ;
13357 "@protocol identifier ;" should be resolved as "@protocol
13358 identifier-list ;": objc-methodprotolist may not start with a
13359 semicolon in the first alternative if objc-protocol-refs are
13363 c_parser_objc_protocol_definition (c_parser
*parser
, tree attributes
)
13365 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROTOCOL
));
13367 c_parser_consume_token (parser
);
13368 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13370 c_parser_error (parser
, "expected identifier");
13373 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
13374 || c_parser_peek_2nd_token (parser
)->type
== CPP_SEMICOLON
)
13376 /* Any identifiers, including those declared as type names, are
13381 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13383 c_parser_error (parser
, "expected identifier");
13386 id
= c_parser_peek_token (parser
)->value
;
13387 objc_declare_protocol (id
, attributes
);
13388 c_parser_consume_token (parser
);
13389 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13390 c_parser_consume_token (parser
);
13394 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13398 tree id
= c_parser_peek_token (parser
)->value
;
13399 tree proto
= NULL_TREE
;
13400 c_parser_consume_token (parser
);
13401 if (c_parser_next_token_is (parser
, CPP_LESS
))
13402 proto
= c_parser_objc_protocol_refs (parser
);
13403 parser
->objc_pq_context
= true;
13404 objc_start_protocol (id
, proto
, attributes
);
13405 c_parser_objc_methodprotolist (parser
);
13406 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
13407 parser
->objc_pq_context
= false;
13408 objc_finish_interface ();
13412 /* Parse an objc-method-type.
13418 Return true if it is a class method (+) and false if it is
13419 an instance method (-).
13422 c_parser_objc_method_type (c_parser
*parser
)
13424 switch (c_parser_peek_token (parser
)->type
)
13427 c_parser_consume_token (parser
);
13430 c_parser_consume_token (parser
);
13433 gcc_unreachable ();
13437 /* Parse an objc-method-definition.
13439 objc-method-definition:
13440 objc-method-type objc-method-decl ;[opt] compound-statement
13444 c_parser_objc_method_definition (c_parser
*parser
)
13446 bool is_class_method
= c_parser_objc_method_type (parser
);
13447 tree decl
, attributes
= NULL_TREE
, expr
= NULL_TREE
;
13448 parser
->objc_pq_context
= true;
13449 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
13451 if (decl
== error_mark_node
)
13452 return; /* Bail here. */
13454 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
13456 c_parser_consume_token (parser
);
13457 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
13458 "extra semicolon in method definition specified");
13461 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
13463 c_parser_error (parser
, "expected %<{%>");
13467 parser
->objc_pq_context
= false;
13468 if (objc_start_method_definition (is_class_method
, decl
, attributes
, expr
))
13470 add_stmt (c_parser_compound_statement (parser
));
13471 objc_finish_method_definition (current_function_decl
);
13475 /* This code is executed when we find a method definition
13476 outside of an @implementation context (or invalid for other
13477 reasons). Parse the method (to keep going) but do not emit
13480 c_parser_compound_statement (parser
);
13484 /* Parse an objc-methodprotolist.
13486 objc-methodprotolist:
13488 objc-methodprotolist objc-methodproto
13489 objc-methodprotolist declaration
13490 objc-methodprotolist ;
13494 The declaration is a data definition, which may be missing
13495 declaration specifiers under the same rules and diagnostics as
13496 other data definitions outside functions, and the stray semicolon
13497 is diagnosed the same way as a stray semicolon outside a
13501 c_parser_objc_methodprotolist (c_parser
*parser
)
13505 /* The list is terminated by @end. */
13506 switch (c_parser_peek_token (parser
)->type
)
13508 case CPP_SEMICOLON
:
13509 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
13510 "ISO C does not allow extra %<;%> outside of a function");
13511 c_parser_consume_token (parser
);
13515 c_parser_objc_methodproto (parser
);
13518 c_parser_pragma (parser
, pragma_external
, NULL
);
13523 if (c_parser_next_token_is_keyword (parser
, RID_AT_END
))
13525 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
))
13526 c_parser_objc_at_property_declaration (parser
);
13527 else if (c_parser_next_token_is_keyword (parser
, RID_AT_OPTIONAL
))
13529 objc_set_method_opt (true);
13530 c_parser_consume_token (parser
);
13532 else if (c_parser_next_token_is_keyword (parser
, RID_AT_REQUIRED
))
13534 objc_set_method_opt (false);
13535 c_parser_consume_token (parser
);
13538 c_parser_declaration_or_fndef (parser
, false, false, true,
13545 /* Parse an objc-methodproto.
13548 objc-method-type objc-method-decl ;
13552 c_parser_objc_methodproto (c_parser
*parser
)
13554 bool is_class_method
= c_parser_objc_method_type (parser
);
13555 tree decl
, attributes
= NULL_TREE
;
13557 /* Remember protocol qualifiers in prototypes. */
13558 parser
->objc_pq_context
= true;
13559 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
13561 /* Forget protocol qualifiers now. */
13562 parser
->objc_pq_context
= false;
13564 /* Do not allow the presence of attributes to hide an erroneous
13565 method implementation in the interface section. */
13566 if (!c_parser_next_token_is (parser
, CPP_SEMICOLON
))
13568 c_parser_error (parser
, "expected %<;%>");
13572 if (decl
!= error_mark_node
)
13573 objc_add_method_declaration (is_class_method
, decl
, attributes
);
13575 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13578 /* If we are at a position that method attributes may be present, check that
13579 there are not any parsed already (a syntax error) and then collect any
13580 specified at the current location. Finally, if new attributes were present,
13581 check that the next token is legal ( ';' for decls and '{' for defs). */
13584 c_parser_objc_maybe_method_attributes (c_parser
* parser
, tree
* attributes
)
13589 c_parser_error (parser
,
13590 "method attributes must be specified at the end only");
13591 *attributes
= NULL_TREE
;
13595 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
13596 *attributes
= c_parser_gnu_attributes (parser
);
13598 /* If there were no attributes here, just report any earlier error. */
13599 if (*attributes
== NULL_TREE
|| bad
)
13602 /* If the attributes are followed by a ; or {, then just report any earlier
13604 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
13605 || c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
13608 /* We've got attributes, but not at the end. */
13609 c_parser_error (parser
,
13610 "expected %<;%> or %<{%> after method attribute definition");
13614 /* Parse an objc-method-decl.
13617 ( objc-type-name ) objc-selector
13619 ( objc-type-name ) objc-keyword-selector objc-optparmlist
13620 objc-keyword-selector objc-optparmlist
13623 objc-keyword-selector:
13625 objc-keyword-selector objc-keyword-decl
13628 objc-selector : ( objc-type-name ) identifier
13629 objc-selector : identifier
13630 : ( objc-type-name ) identifier
13634 objc-optparms objc-optellipsis
13638 objc-opt-parms , parameter-declaration
13646 c_parser_objc_method_decl (c_parser
*parser
, bool is_class_method
,
13647 tree
*attributes
, tree
*expr
)
13649 tree type
= NULL_TREE
;
13651 tree parms
= NULL_TREE
;
13652 bool ellipsis
= false;
13653 bool attr_err
= false;
13655 *attributes
= NULL_TREE
;
13656 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13658 matching_parens parens
;
13659 parens
.consume_open (parser
);
13660 type
= c_parser_objc_type_name (parser
);
13661 parens
.skip_until_found_close (parser
);
13663 sel
= c_parser_objc_selector (parser
);
13664 /* If there is no selector, or a colon follows, we have an
13665 objc-keyword-selector. If there is a selector, and a colon does
13666 not follow, that selector ends the objc-method-decl. */
13667 if (!sel
|| c_parser_next_token_is (parser
, CPP_COLON
))
13670 tree list
= NULL_TREE
;
13673 tree atype
= NULL_TREE
, id
, keyworddecl
;
13674 tree param_attr
= NULL_TREE
;
13675 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
13677 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13679 c_parser_consume_token (parser
);
13680 atype
= c_parser_objc_type_name (parser
);
13681 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
13684 /* New ObjC allows attributes on method parameters. */
13685 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
13686 param_attr
= c_parser_gnu_attributes (parser
);
13687 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13689 c_parser_error (parser
, "expected identifier");
13690 return error_mark_node
;
13692 id
= c_parser_peek_token (parser
)->value
;
13693 c_parser_consume_token (parser
);
13694 keyworddecl
= objc_build_keyword_decl (tsel
, atype
, id
, param_attr
);
13695 list
= chainon (list
, keyworddecl
);
13696 tsel
= c_parser_objc_selector (parser
);
13697 if (!tsel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
13701 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
13703 /* Parse the optional parameter list. Optional Objective-C
13704 method parameters follow the C syntax, and may include '...'
13705 to denote a variable number of arguments. */
13706 parms
= make_node (TREE_LIST
);
13707 while (c_parser_next_token_is (parser
, CPP_COMMA
))
13709 struct c_parm
*parm
;
13710 c_parser_consume_token (parser
);
13711 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
13714 c_parser_consume_token (parser
);
13715 attr_err
|= c_parser_objc_maybe_method_attributes
13716 (parser
, attributes
) ;
13719 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
13722 parms
= chainon (parms
,
13723 build_tree_list (NULL_TREE
, grokparm (parm
, expr
)));
13728 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
13732 c_parser_error (parser
, "objective-c method declaration is expected");
13733 return error_mark_node
;
13737 return error_mark_node
;
13739 return objc_build_method_signature (is_class_method
, type
, sel
, parms
, ellipsis
);
13742 /* Parse an objc-type-name.
13745 objc-type-qualifiers[opt] type-name
13746 objc-type-qualifiers[opt]
13748 objc-type-qualifiers:
13749 objc-type-qualifier
13750 objc-type-qualifiers objc-type-qualifier
13752 objc-type-qualifier: one of
13753 in out inout bycopy byref oneway
13757 c_parser_objc_type_name (c_parser
*parser
)
13759 tree quals
= NULL_TREE
;
13760 struct c_type_name
*type_name
= NULL
;
13761 tree type
= NULL_TREE
;
13764 c_token
*token
= c_parser_peek_token (parser
);
13765 if (token
->type
== CPP_KEYWORD
13766 && (token
->keyword
== RID_IN
13767 || token
->keyword
== RID_OUT
13768 || token
->keyword
== RID_INOUT
13769 || token
->keyword
== RID_BYCOPY
13770 || token
->keyword
== RID_BYREF
13771 || token
->keyword
== RID_ONEWAY
))
13773 quals
= chainon (build_tree_list (NULL_TREE
, token
->value
), quals
);
13774 c_parser_consume_token (parser
);
13779 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
13780 type_name
= c_parser_type_name (parser
);
13782 type
= groktypename (type_name
, NULL
, NULL
);
13784 /* If the type is unknown, and error has already been produced and
13785 we need to recover from the error. In that case, use NULL_TREE
13786 for the type, as if no type had been specified; this will use the
13787 default type ('id') which is good for error recovery. */
13788 if (type
== error_mark_node
)
13791 return build_tree_list (quals
, type
);
13794 /* Parse objc-protocol-refs.
13796 objc-protocol-refs:
13797 < identifier-list >
13801 c_parser_objc_protocol_refs (c_parser
*parser
)
13803 tree list
= NULL_TREE
;
13804 gcc_assert (c_parser_next_token_is (parser
, CPP_LESS
));
13805 c_parser_consume_token (parser
);
13806 /* Any identifiers, including those declared as type names, are OK
13811 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13813 c_parser_error (parser
, "expected identifier");
13816 id
= c_parser_peek_token (parser
)->value
;
13817 list
= chainon (list
, build_tree_list (NULL_TREE
, id
));
13818 c_parser_consume_token (parser
);
13819 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13820 c_parser_consume_token (parser
);
13824 c_parser_require (parser
, CPP_GREATER
, "expected %<>%>");
13828 /* Parse an objc-try-catch-finally-statement.
13830 objc-try-catch-finally-statement:
13831 @try compound-statement objc-catch-list[opt]
13832 @try compound-statement objc-catch-list[opt] @finally compound-statement
13835 @catch ( objc-catch-parameter-declaration ) compound-statement
13836 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
13838 objc-catch-parameter-declaration:
13839 parameter-declaration
13842 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
13844 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
13845 for C++. Keep them in sync. */
13848 c_parser_objc_try_catch_finally_statement (c_parser
*parser
)
13850 location_t location
;
13853 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_TRY
));
13854 c_parser_consume_token (parser
);
13855 location
= c_parser_peek_token (parser
)->location
;
13856 objc_maybe_warn_exceptions (location
);
13857 stmt
= c_parser_compound_statement (parser
);
13858 objc_begin_try_stmt (location
, stmt
);
13860 while (c_parser_next_token_is_keyword (parser
, RID_AT_CATCH
))
13862 struct c_parm
*parm
;
13863 tree parameter_declaration
= error_mark_node
;
13864 bool seen_open_paren
= false;
13866 c_parser_consume_token (parser
);
13867 matching_parens parens
;
13868 if (!parens
.require_open (parser
))
13869 seen_open_paren
= true;
13870 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
13872 /* We have "@catch (...)" (where the '...' are literally
13873 what is in the code). Skip the '...'.
13874 parameter_declaration is set to NULL_TREE, and
13875 objc_being_catch_clauses() knows that that means
13877 c_parser_consume_token (parser
);
13878 parameter_declaration
= NULL_TREE
;
13882 /* We have "@catch (NSException *exception)" or something
13883 like that. Parse the parameter declaration. */
13884 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
13886 parameter_declaration
= error_mark_node
;
13888 parameter_declaration
= grokparm (parm
, NULL
);
13890 if (seen_open_paren
)
13891 parens
.require_close (parser
);
13894 /* If there was no open parenthesis, we are recovering from
13895 an error, and we are trying to figure out what mistake
13896 the user has made. */
13898 /* If there is an immediate closing parenthesis, the user
13899 probably forgot the opening one (ie, they typed "@catch
13900 NSException *e)". Parse the closing parenthesis and keep
13902 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
13903 c_parser_consume_token (parser
);
13905 /* If these is no immediate closing parenthesis, the user
13906 probably doesn't know that parenthesis are required at
13907 all (ie, they typed "@catch NSException *e"). So, just
13908 forget about the closing parenthesis and keep going. */
13910 objc_begin_catch_clause (parameter_declaration
);
13911 if (c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
13912 c_parser_compound_statement_nostart (parser
);
13913 objc_finish_catch_clause ();
13915 if (c_parser_next_token_is_keyword (parser
, RID_AT_FINALLY
))
13917 c_parser_consume_token (parser
);
13918 location
= c_parser_peek_token (parser
)->location
;
13919 stmt
= c_parser_compound_statement (parser
);
13920 objc_build_finally_clause (location
, stmt
);
13922 objc_finish_try_stmt ();
13925 /* Parse an objc-synchronized-statement.
13927 objc-synchronized-statement:
13928 @synchronized ( expression ) compound-statement
13932 c_parser_objc_synchronized_statement (c_parser
*parser
)
13936 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNCHRONIZED
));
13937 c_parser_consume_token (parser
);
13938 loc
= c_parser_peek_token (parser
)->location
;
13939 objc_maybe_warn_exceptions (loc
);
13940 matching_parens parens
;
13941 if (parens
.require_open (parser
))
13943 struct c_expr ce
= c_parser_expression (parser
);
13944 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
13946 expr
= c_fully_fold (expr
, false, NULL
);
13947 parens
.skip_until_found_close (parser
);
13950 expr
= error_mark_node
;
13951 stmt
= c_parser_compound_statement (parser
);
13952 objc_build_synchronized (loc
, expr
, stmt
);
13955 /* Parse an objc-selector; return NULL_TREE without an error if the
13956 next token is not an objc-selector.
13961 enum struct union if else while do for switch case default
13962 break continue return goto asm sizeof typeof typeof_unqual __alignof
13963 unsigned long const short volatile signed restrict _Complex
13964 in out inout bycopy byref oneway int char float double void _Bool
13967 ??? Why this selection of keywords but not, for example, storage
13968 class specifiers? */
13971 c_parser_objc_selector (c_parser
*parser
)
13973 c_token
*token
= c_parser_peek_token (parser
);
13974 tree value
= token
->value
;
13975 if (token
->type
== CPP_NAME
)
13977 c_parser_consume_token (parser
);
13980 if (token
->type
!= CPP_KEYWORD
)
13982 switch (token
->keyword
)
14002 case RID_TYPEOF_UNQUAL
:
14022 CASE_RID_FLOATN_NX
:
14026 case RID_AUTO_TYPE
:
14031 c_parser_consume_token (parser
);
14038 /* Parse an objc-selector-arg.
14042 objc-keywordname-list
14044 objc-keywordname-list:
14046 objc-keywordname-list objc-keywordname
14054 c_parser_objc_selector_arg (c_parser
*parser
)
14056 tree sel
= c_parser_objc_selector (parser
);
14057 tree list
= NULL_TREE
;
14059 && c_parser_next_token_is_not (parser
, CPP_COLON
)
14060 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
14064 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
14066 c_parser_consume_token (parser
);
14067 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
14068 list
= chainon (list
, build_tree_list (NULL_TREE
, NULL_TREE
));
14072 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14074 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
14076 sel
= c_parser_objc_selector (parser
);
14078 && c_parser_next_token_is_not (parser
, CPP_COLON
)
14079 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
14085 /* Parse an objc-receiver.
14094 c_parser_objc_receiver (c_parser
*parser
)
14096 location_t loc
= c_parser_peek_token (parser
)->location
;
14098 if (c_parser_peek_token (parser
)->type
== CPP_NAME
14099 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
14100 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
14102 tree id
= c_parser_peek_token (parser
)->value
;
14103 c_parser_consume_token (parser
);
14104 return objc_get_class_reference (id
);
14106 struct c_expr ce
= c_parser_expression (parser
);
14107 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
14108 return c_fully_fold (ce
.value
, false, NULL
);
14111 /* Parse objc-message-args.
14115 objc-keywordarg-list
14117 objc-keywordarg-list:
14119 objc-keywordarg-list objc-keywordarg
14122 objc-selector : objc-keywordexpr
14127 c_parser_objc_message_args (c_parser
*parser
)
14129 tree sel
= c_parser_objc_selector (parser
);
14130 tree list
= NULL_TREE
;
14131 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
14136 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14137 return error_mark_node
;
14138 keywordexpr
= c_parser_objc_keywordexpr (parser
);
14139 list
= chainon (list
, build_tree_list (sel
, keywordexpr
));
14140 sel
= c_parser_objc_selector (parser
);
14141 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
14147 /* Parse an objc-keywordexpr.
14154 c_parser_objc_keywordexpr (c_parser
*parser
)
14157 vec
<tree
, va_gc
> *expr_list
= c_parser_expr_list (parser
, true, true,
14158 NULL
, NULL
, NULL
, NULL
);
14159 if (vec_safe_length (expr_list
) == 1)
14161 /* Just return the expression, remove a level of
14163 ret
= (*expr_list
)[0];
14167 /* We have a comma expression, we will collapse later. */
14168 ret
= build_tree_list_vec (expr_list
);
14170 release_tree_vector (expr_list
);
14174 /* A check, needed in several places, that ObjC interface, implementation or
14175 method definitions are not prefixed by incorrect items. */
14177 c_parser_objc_diagnose_bad_element_prefix (c_parser
*parser
,
14178 struct c_declspecs
*specs
)
14180 if (!specs
->declspecs_seen_p
|| specs
->non_sc_seen_p
14181 || specs
->typespec_kind
!= ctsk_none
)
14183 c_parser_error (parser
,
14184 "no type or storage class may be specified here,");
14185 c_parser_skip_to_end_of_block_or_statement (parser
);
14191 /* Parse an Objective-C @property declaration. The syntax is:
14193 objc-property-declaration:
14194 '@property' objc-property-attributes[opt] struct-declaration ;
14196 objc-property-attributes:
14197 '(' objc-property-attribute-list ')'
14199 objc-property-attribute-list:
14200 objc-property-attribute
14201 objc-property-attribute-list, objc-property-attribute
14203 objc-property-attribute
14204 'getter' = identifier
14205 'setter' = identifier
14214 @property NSString *name;
14215 @property (readonly) id object;
14216 @property (retain, nonatomic, getter=getTheName) id name;
14217 @property int a, b, c;
14219 PS: This function is identical to cp_parser_objc_at_propery_declaration
14220 for C++. Keep them in sync. */
14222 c_parser_objc_at_property_declaration (c_parser
*parser
)
14224 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
));
14225 location_t loc
= c_parser_peek_token (parser
)->location
;
14226 c_parser_consume_token (parser
); /* Eat '@property'. */
14228 /* Parse the optional attribute list.
14230 A list of parsed, but not verified, attributes. */
14231 vec
<property_attribute_info
*> prop_attr_list
= vNULL
;
14233 bool syntax_error
= false;
14234 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14236 matching_parens parens
;
14238 location_t attr_start
= c_parser_peek_token (parser
)->location
;
14240 parens
.consume_open (parser
);
14242 /* Property attribute keywords are valid now. */
14243 parser
->objc_property_attr_context
= true;
14245 /* Allow @property (), with a warning. */
14246 location_t attr_end
= c_parser_peek_token (parser
)->location
;
14248 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
14250 location_t attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
14251 warning_at (attr_comb
, OPT_Wattributes
,
14252 "empty property attribute list");
14257 c_token
*token
= c_parser_peek_token (parser
);
14258 attr_start
= token
->location
;
14259 attr_end
= get_finish (token
->location
);
14260 location_t attr_comb
= make_location (attr_start
, attr_start
,
14263 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_COMMA
)
14265 warning_at (attr_comb
, OPT_Wattributes
,
14266 "missing property attribute");
14267 if (token
->type
== CPP_CLOSE_PAREN
)
14269 c_parser_consume_token (parser
);
14273 tree attr_name
= NULL_TREE
;
14274 enum rid keyword
= RID_MAX
; /* Not a valid property attribute. */
14275 bool add_at
= false;
14276 if (token
->type
== CPP_KEYWORD
)
14278 keyword
= token
->keyword
;
14279 if (OBJC_IS_AT_KEYWORD (keyword
))
14281 /* For '@' keywords the token value has the keyword,
14282 prepend the '@' for diagnostics. */
14283 attr_name
= token
->value
;
14287 attr_name
= ridpointers
[(int)keyword
];
14289 else if (token
->type
== CPP_NAME
)
14290 attr_name
= token
->value
;
14291 c_parser_consume_token (parser
);
14293 enum objc_property_attribute_kind prop_kind
14294 = objc_prop_attr_kind_for_rid (keyword
);
14295 property_attribute_info
*prop
14296 = new property_attribute_info (attr_name
, attr_comb
, prop_kind
);
14297 prop_attr_list
.safe_push (prop
);
14300 switch (prop
->prop_kind
)
14303 case OBJC_PROPERTY_ATTR_UNKNOWN
:
14305 error_at (attr_comb
, "unknown property attribute %<%s%s%>",
14306 add_at
? "@" : "", IDENTIFIER_POINTER (attr_name
));
14308 error_at (attr_comb
, "unknown property attribute");
14309 prop
->parse_error
= syntax_error
= true;
14312 case OBJC_PROPERTY_ATTR_GETTER
:
14313 case OBJC_PROPERTY_ATTR_SETTER
:
14314 if (c_parser_next_token_is_not (parser
, CPP_EQ
))
14316 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
14317 error_at (attr_comb
, "expected %<=%> after Objective-C %qE",
14319 prop
->parse_error
= syntax_error
= true;
14322 token
= c_parser_peek_token (parser
);
14323 attr_end
= token
->location
;
14324 c_parser_consume_token (parser
); /* eat the = */
14325 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14327 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
14328 error_at (attr_comb
, "expected %qE selector name",
14330 prop
->parse_error
= syntax_error
= true;
14333 /* Get the end of the method name, and consume the name. */
14334 token
= c_parser_peek_token (parser
);
14335 attr_end
= get_finish (token
->location
);
14336 meth_name
= token
->value
;
14337 c_parser_consume_token (parser
);
14338 if (prop
->prop_kind
== OBJC_PROPERTY_ATTR_SETTER
)
14340 if (c_parser_next_token_is_not (parser
, CPP_COLON
))
14342 attr_comb
= make_location (attr_end
, attr_start
,
14344 error_at (attr_comb
, "setter method names must"
14345 " terminate with %<:%>");
14346 prop
->parse_error
= syntax_error
= true;
14350 attr_end
= get_finish (c_parser_peek_token
14351 (parser
)->location
);
14352 c_parser_consume_token (parser
);
14354 attr_comb
= make_location (attr_start
, attr_start
,
14358 attr_comb
= make_location (attr_start
, attr_start
,
14360 prop
->ident
= meth_name
;
14361 /* Updated location including all that was successfully
14363 prop
->prop_loc
= attr_comb
;
14367 /* If we see a comma here, then keep going - even if we already
14368 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
14369 this makes a more useful output and avoid spurious warnings about
14370 missing attributes that are, in fact, specified after the one with
14371 the syntax error. */
14372 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14373 c_parser_consume_token (parser
);
14377 parser
->objc_property_attr_context
= false;
14379 if (syntax_error
&& c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
14380 /* We don't really want to chew the whole of the file looking for a
14381 matching closing parenthesis, so we will try to read the decl and
14382 let the error handling for that close out the statement. */
14385 syntax_error
= false, parens
.skip_until_found_close (parser
);
14388 /* 'properties' is the list of properties that we read. Usually a
14389 single one, but maybe more (eg, in "@property int a, b, c;" there
14391 tree properties
= c_parser_struct_declaration (parser
, NULL
);
14393 if (properties
== error_mark_node
)
14394 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
14397 if (properties
== NULL_TREE
)
14398 c_parser_error (parser
, "expected identifier");
14401 /* Comma-separated properties are chained together in reverse order;
14402 add them one by one. */
14403 properties
= nreverse (properties
);
14404 for (; properties
; properties
= TREE_CHAIN (properties
))
14405 objc_add_property_declaration (loc
, copy_node (properties
),
14408 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
14411 while (!prop_attr_list
.is_empty())
14412 delete prop_attr_list
.pop ();
14413 prop_attr_list
.release ();
14414 parser
->error
= false;
14417 /* Parse an Objective-C @synthesize declaration. The syntax is:
14419 objc-synthesize-declaration:
14420 @synthesize objc-synthesize-identifier-list ;
14422 objc-synthesize-identifier-list:
14423 objc-synthesize-identifier
14424 objc-synthesize-identifier-list, objc-synthesize-identifier
14426 objc-synthesize-identifier
14428 identifier = identifier
14431 @synthesize MyProperty;
14432 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
14434 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
14435 for C++. Keep them in sync.
14438 c_parser_objc_at_synthesize_declaration (c_parser
*parser
)
14440 tree list
= NULL_TREE
;
14442 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNTHESIZE
));
14443 loc
= c_parser_peek_token (parser
)->location
;
14445 c_parser_consume_token (parser
);
14448 tree property
, ivar
;
14449 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14451 c_parser_error (parser
, "expected identifier");
14452 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
14453 /* Once we find the semicolon, we can resume normal parsing.
14454 We have to reset parser->error manually because
14455 c_parser_skip_until_found() won't reset it for us if the
14456 next token is precisely a semicolon. */
14457 parser
->error
= false;
14460 property
= c_parser_peek_token (parser
)->value
;
14461 c_parser_consume_token (parser
);
14462 if (c_parser_next_token_is (parser
, CPP_EQ
))
14464 c_parser_consume_token (parser
);
14465 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14467 c_parser_error (parser
, "expected identifier");
14468 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
14469 parser
->error
= false;
14472 ivar
= c_parser_peek_token (parser
)->value
;
14473 c_parser_consume_token (parser
);
14477 list
= chainon (list
, build_tree_list (ivar
, property
));
14478 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14479 c_parser_consume_token (parser
);
14483 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
14484 objc_add_synthesize_declaration (loc
, list
);
14487 /* Parse an Objective-C @dynamic declaration. The syntax is:
14489 objc-dynamic-declaration:
14490 @dynamic identifier-list ;
14493 @dynamic MyProperty;
14494 @dynamic MyProperty, AnotherProperty;
14496 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
14497 for C++. Keep them in sync.
14500 c_parser_objc_at_dynamic_declaration (c_parser
*parser
)
14502 tree list
= NULL_TREE
;
14504 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_DYNAMIC
));
14505 loc
= c_parser_peek_token (parser
)->location
;
14507 c_parser_consume_token (parser
);
14511 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14513 c_parser_error (parser
, "expected identifier");
14514 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
14515 parser
->error
= false;
14518 property
= c_parser_peek_token (parser
)->value
;
14519 list
= chainon (list
, build_tree_list (NULL_TREE
, property
));
14520 c_parser_consume_token (parser
);
14521 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14522 c_parser_consume_token (parser
);
14526 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
14527 objc_add_dynamic_declaration (loc
, list
);
14531 /* Parse a pragma GCC ivdep. */
14534 c_parse_pragma_ivdep (c_parser
*parser
)
14536 c_parser_consume_pragma (parser
);
14537 c_parser_skip_to_pragma_eol (parser
);
14541 /* Parse a pragma GCC novector. */
14544 c_parse_pragma_novector (c_parser
*parser
)
14546 c_parser_consume_pragma (parser
);
14547 c_parser_skip_to_pragma_eol (parser
);
14551 /* Parse a pragma GCC unroll. */
14553 static unsigned short
14554 c_parser_pragma_unroll (c_parser
*parser
)
14556 unsigned short unroll
;
14557 c_parser_consume_pragma (parser
);
14558 location_t location
= c_parser_peek_token (parser
)->location
;
14559 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
14560 mark_exp_read (expr
);
14561 expr
= c_fully_fold (expr
, false, NULL
);
14562 HOST_WIDE_INT lunroll
= 0;
14563 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
14564 || TREE_CODE (expr
) != INTEGER_CST
14565 || (lunroll
= tree_to_shwi (expr
)) < 0
14566 || lunroll
>= USHRT_MAX
)
14568 error_at (location
, "%<#pragma GCC unroll%> requires an"
14569 " assignment-expression that evaluates to a non-negative"
14570 " integral constant less than %u", USHRT_MAX
);
14575 unroll
= (unsigned short)lunroll
;
14580 c_parser_skip_to_pragma_eol (parser
);
14584 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
14585 should be considered, statements. ALLOW_STMT is true if we're within
14586 the context of a function and such pragmas are to be allowed. Returns
14587 true if we actually parsed such a pragma. */
14590 c_parser_pragma (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
14593 const char *construct
= NULL
;
14595 input_location
= c_parser_peek_token (parser
)->location
;
14596 id
= c_parser_peek_token (parser
)->pragma_kind
;
14597 gcc_assert (id
!= PRAGMA_NONE
);
14598 if (parser
->omp_for_parse_state
14599 && parser
->omp_for_parse_state
->in_intervening_code
14600 && id
>= PRAGMA_OMP__START_
14601 && id
<= PRAGMA_OMP__LAST_
)
14603 error_at (input_location
,
14604 "intervening code must not contain OpenMP directives");
14605 parser
->omp_for_parse_state
->fail
= true;
14606 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14612 case PRAGMA_OACC_DECLARE
:
14613 c_parser_oacc_declare (parser
);
14616 case PRAGMA_OACC_ENTER_DATA
:
14617 if (context
!= pragma_compound
)
14619 construct
= "acc enter data";
14621 if (context
== pragma_stmt
)
14623 error_at (c_parser_peek_token (parser
)->location
,
14624 "%<#pragma %s%> may only be used in compound "
14625 "statements", construct
);
14626 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14631 c_parser_oacc_enter_exit_data (parser
, true);
14634 case PRAGMA_OACC_EXIT_DATA
:
14635 if (context
!= pragma_compound
)
14637 construct
= "acc exit data";
14640 c_parser_oacc_enter_exit_data (parser
, false);
14643 case PRAGMA_OACC_ROUTINE
:
14644 if (context
!= pragma_external
)
14646 error_at (c_parser_peek_token (parser
)->location
,
14647 "%<#pragma acc routine%> must be at file scope");
14648 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14651 c_parser_oacc_routine (parser
, context
);
14654 case PRAGMA_OACC_UPDATE
:
14655 if (context
!= pragma_compound
)
14657 construct
= "acc update";
14660 c_parser_oacc_update (parser
);
14663 case PRAGMA_OMP_BARRIER
:
14664 if (context
!= pragma_compound
)
14666 construct
= "omp barrier";
14669 c_parser_omp_barrier (parser
);
14672 case PRAGMA_OMP_DEPOBJ
:
14673 if (context
!= pragma_compound
)
14675 construct
= "omp depobj";
14678 c_parser_omp_depobj (parser
);
14681 case PRAGMA_OMP_FLUSH
:
14682 if (context
!= pragma_compound
)
14684 construct
= "omp flush";
14687 c_parser_omp_flush (parser
);
14690 case PRAGMA_OMP_TASKWAIT
:
14691 if (context
!= pragma_compound
)
14693 construct
= "omp taskwait";
14696 c_parser_omp_taskwait (parser
);
14699 case PRAGMA_OMP_TASKYIELD
:
14700 if (context
!= pragma_compound
)
14702 construct
= "omp taskyield";
14705 c_parser_omp_taskyield (parser
);
14708 case PRAGMA_OMP_CANCEL
:
14709 if (context
!= pragma_compound
)
14711 construct
= "omp cancel";
14714 c_parser_omp_cancel (parser
);
14717 case PRAGMA_OMP_CANCELLATION_POINT
:
14718 return c_parser_omp_cancellation_point (parser
, context
);
14720 case PRAGMA_OMP_THREADPRIVATE
:
14721 c_parser_omp_threadprivate (parser
);
14724 case PRAGMA_OMP_TARGET
:
14725 return c_parser_omp_target (parser
, context
, if_p
);
14727 case PRAGMA_OMP_BEGIN
:
14728 c_parser_omp_begin (parser
);
14731 case PRAGMA_OMP_END
:
14732 c_parser_omp_end (parser
);
14735 case PRAGMA_OMP_SCAN
:
14736 error_at (c_parser_peek_token (parser
)->location
,
14737 "%<#pragma omp scan%> may only be used in "
14738 "a loop construct with %<inscan%> %<reduction%> clause");
14739 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14742 case PRAGMA_OMP_SECTION
:
14743 error_at (c_parser_peek_token (parser
)->location
,
14744 "%<#pragma omp section%> may only be used in "
14745 "%<#pragma omp sections%> construct");
14746 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14749 case PRAGMA_OMP_DECLARE
:
14750 return c_parser_omp_declare (parser
, context
);
14752 case PRAGMA_OMP_REQUIRES
:
14753 if (context
!= pragma_external
)
14755 error_at (c_parser_peek_token (parser
)->location
,
14756 "%<#pragma %s%> may only be used at file scope",
14758 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14761 c_parser_omp_requires (parser
);
14764 case PRAGMA_OMP_ALLOCATE
:
14765 c_parser_omp_allocate (parser
);
14768 case PRAGMA_OMP_ASSUMES
:
14769 if (context
!= pragma_external
)
14771 error_at (c_parser_peek_token (parser
)->location
,
14772 "%<#pragma %s%> may only be used at file scope",
14774 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14777 c_parser_omp_assumes (parser
);
14780 case PRAGMA_OMP_NOTHING
:
14781 c_parser_omp_nothing (parser
);
14784 case PRAGMA_OMP_ERROR
:
14785 return c_parser_omp_error (parser
, context
);
14787 case PRAGMA_OMP_ORDERED
:
14788 return c_parser_omp_ordered (parser
, context
, if_p
);
14790 case PRAGMA_NOVECTOR
:
14791 case PRAGMA_UNROLL
:
14794 bool novector
= false;
14795 unsigned short unroll
= 0;
14796 bool ivdep
= false;
14800 case PRAGMA_NOVECTOR
:
14801 novector
= c_parse_pragma_novector (parser
);
14803 case PRAGMA_UNROLL
:
14804 unroll
= c_parser_pragma_unroll (parser
);
14807 ivdep
= c_parse_pragma_ivdep (parser
);
14810 gcc_unreachable ();
14813 c_token
*tok
= c_parser_peek_token (parser
);
14814 bool has_more
= tok
->type
== CPP_PRAGMA
;
14817 switch (tok
->pragma_kind
)
14820 ivdep
= c_parse_pragma_ivdep (parser
);
14822 case PRAGMA_UNROLL
:
14823 unroll
= c_parser_pragma_unroll (parser
);
14825 case PRAGMA_NOVECTOR
:
14826 novector
= c_parse_pragma_novector (parser
);
14832 tok
= c_parser_peek_token (parser
);
14833 has_more
= has_more
&& tok
->type
== CPP_PRAGMA
;
14835 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
14836 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
14837 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
14839 c_parser_error (parser
, "for, while or do statement expected");
14842 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
14843 c_parser_for_statement (parser
, ivdep
, unroll
, novector
, if_p
);
14844 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
14845 c_parser_while_statement (parser
, ivdep
, unroll
, novector
, if_p
);
14847 c_parser_do_statement (parser
, ivdep
, unroll
, novector
);
14851 case PRAGMA_GCC_PCH_PREPROCESS
:
14852 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
14853 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14856 case PRAGMA_OACC_WAIT
:
14857 if (context
!= pragma_compound
)
14859 construct
= "acc wait";
14862 /* FALL THROUGH. */
14865 if (id
< PRAGMA_FIRST_EXTERNAL
)
14867 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
14870 c_parser_error (parser
, "expected declaration specifiers");
14871 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14874 c_parser_omp_construct (parser
, if_p
);
14880 c_parser_consume_pragma (parser
);
14881 c_invoke_pragma_handler (id
);
14883 /* Skip to EOL, but suppress any error message. Those will have been
14884 generated by the handler routine through calling error, as opposed
14885 to calling c_parser_error. */
14886 parser
->error
= true;
14887 c_parser_skip_to_pragma_eol (parser
);
14892 /* The interface the pragma parsers have to the lexer. */
14895 pragma_lex (tree
*value
, location_t
*loc
)
14897 c_token
*tok
= c_parser_peek_token (the_parser
);
14898 enum cpp_ttype ret
= tok
->type
;
14900 *value
= tok
->value
;
14902 *loc
= tok
->location
;
14904 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
14906 else if (ret
== CPP_STRING
)
14907 *value
= c_parser_string_literal (the_parser
, false, false).value
;
14910 if (ret
== CPP_KEYWORD
)
14912 c_parser_consume_token (the_parser
);
14919 pragma_lex_discard_to_eol ()
14924 type
= c_parser_peek_token (the_parser
)->type
;
14925 gcc_assert (type
!= CPP_EOF
);
14926 c_parser_consume_token (the_parser
);
14927 } while (type
!= CPP_PRAGMA_EOL
);
14931 c_parser_pragma_pch_preprocess (c_parser
*parser
)
14935 parser
->lex_joined_string
= true;
14936 c_parser_consume_pragma (parser
);
14937 if (c_parser_next_token_is (parser
, CPP_STRING
))
14939 name
= c_parser_peek_token (parser
)->value
;
14940 c_parser_consume_token (parser
);
14943 c_parser_error (parser
, "expected string literal");
14944 c_parser_skip_to_pragma_eol (parser
);
14945 parser
->lex_joined_string
= false;
14948 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
14951 /* OpenACC and OpenMP parsing routines. */
14953 /* Returns name of the next clause.
14954 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
14955 the token is not consumed. Otherwise appropriate pragma_omp_clause is
14956 returned and the token is consumed. */
14958 static pragma_omp_clause
14959 c_parser_omp_clause_name (c_parser
*parser
)
14961 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
14963 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
14964 result
= PRAGMA_OACC_CLAUSE_AUTO
;
14965 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
14966 result
= PRAGMA_OMP_CLAUSE_IF
;
14967 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
14968 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
14969 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
14970 result
= PRAGMA_OMP_CLAUSE_FOR
;
14971 else if (c_parser_next_token_is (parser
, CPP_NAME
))
14973 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14978 if (!strcmp ("affinity", p
))
14979 result
= PRAGMA_OMP_CLAUSE_AFFINITY
;
14980 else if (!strcmp ("aligned", p
))
14981 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
14982 else if (!strcmp ("allocate", p
))
14983 result
= PRAGMA_OMP_CLAUSE_ALLOCATE
;
14984 else if (!strcmp ("async", p
))
14985 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
14986 else if (!strcmp ("attach", p
))
14987 result
= PRAGMA_OACC_CLAUSE_ATTACH
;
14990 if (!strcmp ("bind", p
))
14991 result
= PRAGMA_OMP_CLAUSE_BIND
;
14994 if (!strcmp ("collapse", p
))
14995 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
14996 else if (!strcmp ("copy", p
))
14997 result
= PRAGMA_OACC_CLAUSE_COPY
;
14998 else if (!strcmp ("copyin", p
))
14999 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
15000 else if (!strcmp ("copyout", p
))
15001 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
15002 else if (!strcmp ("copyprivate", p
))
15003 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
15004 else if (!strcmp ("create", p
))
15005 result
= PRAGMA_OACC_CLAUSE_CREATE
;
15008 if (!strcmp ("defaultmap", p
))
15009 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
15010 else if (!strcmp ("delete", p
))
15011 result
= PRAGMA_OACC_CLAUSE_DELETE
;
15012 else if (!strcmp ("depend", p
))
15013 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
15014 else if (!strcmp ("detach", p
))
15015 result
= PRAGMA_OACC_CLAUSE_DETACH
;
15016 else if (!strcmp ("device", p
))
15017 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
15018 else if (!strcmp ("deviceptr", p
))
15019 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
15020 else if (!strcmp ("device_resident", p
))
15021 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
15022 else if (!strcmp ("device_type", p
))
15023 result
= PRAGMA_OMP_CLAUSE_DEVICE_TYPE
;
15024 else if (!strcmp ("dist_schedule", p
))
15025 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
15026 else if (!strcmp ("doacross", p
))
15027 result
= PRAGMA_OMP_CLAUSE_DOACROSS
;
15030 if (!strcmp ("enter", p
))
15031 result
= PRAGMA_OMP_CLAUSE_ENTER
;
15034 if (!strcmp ("filter", p
))
15035 result
= PRAGMA_OMP_CLAUSE_FILTER
;
15036 else if (!strcmp ("final", p
))
15037 result
= PRAGMA_OMP_CLAUSE_FINAL
;
15038 else if (!strcmp ("finalize", p
))
15039 result
= PRAGMA_OACC_CLAUSE_FINALIZE
;
15040 else if (!strcmp ("firstprivate", p
))
15041 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
15042 else if (!strcmp ("from", p
))
15043 result
= PRAGMA_OMP_CLAUSE_FROM
;
15044 else if (!strcmp ("full", p
))
15045 result
= PRAGMA_OMP_CLAUSE_FULL
;
15048 if (!strcmp ("gang", p
))
15049 result
= PRAGMA_OACC_CLAUSE_GANG
;
15050 else if (!strcmp ("grainsize", p
))
15051 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
15054 if (!strcmp ("has_device_addr", p
))
15055 result
= PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
;
15056 else if (!strcmp ("hint", p
))
15057 result
= PRAGMA_OMP_CLAUSE_HINT
;
15058 else if (!strcmp ("host", p
))
15059 result
= PRAGMA_OACC_CLAUSE_HOST
;
15062 if (!strcmp ("if_present", p
))
15063 result
= PRAGMA_OACC_CLAUSE_IF_PRESENT
;
15064 else if (!strcmp ("in_reduction", p
))
15065 result
= PRAGMA_OMP_CLAUSE_IN_REDUCTION
;
15066 else if (!strcmp ("inbranch", p
))
15067 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
15068 else if (!strcmp ("independent", p
))
15069 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
15070 else if (!strcmp ("indirect", p
))
15071 result
= PRAGMA_OMP_CLAUSE_INDIRECT
;
15072 else if (!strcmp ("is_device_ptr", p
))
15073 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
15076 if (!strcmp ("lastprivate", p
))
15077 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
15078 else if (!strcmp ("linear", p
))
15079 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
15080 else if (!strcmp ("link", p
))
15081 result
= PRAGMA_OMP_CLAUSE_LINK
;
15084 if (!strcmp ("map", p
))
15085 result
= PRAGMA_OMP_CLAUSE_MAP
;
15086 else if (!strcmp ("mergeable", p
))
15087 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
15090 if (!strcmp ("no_create", p
))
15091 result
= PRAGMA_OACC_CLAUSE_NO_CREATE
;
15092 else if (!strcmp ("nogroup", p
))
15093 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
15094 else if (!strcmp ("nohost", p
))
15095 result
= PRAGMA_OACC_CLAUSE_NOHOST
;
15096 else if (!strcmp ("nontemporal", p
))
15097 result
= PRAGMA_OMP_CLAUSE_NONTEMPORAL
;
15098 else if (!strcmp ("notinbranch", p
))
15099 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
15100 else if (!strcmp ("nowait", p
))
15101 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
15102 else if (!strcmp ("num_gangs", p
))
15103 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
15104 else if (!strcmp ("num_tasks", p
))
15105 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
15106 else if (!strcmp ("num_teams", p
))
15107 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
15108 else if (!strcmp ("num_threads", p
))
15109 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
15110 else if (!strcmp ("num_workers", p
))
15111 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
15114 if (!strcmp ("ordered", p
))
15115 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
15116 else if (!strcmp ("order", p
))
15117 result
= PRAGMA_OMP_CLAUSE_ORDER
;
15120 if (!strcmp ("parallel", p
))
15121 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
15122 else if (!strcmp ("partial", p
))
15123 result
= PRAGMA_OMP_CLAUSE_PARTIAL
;
15124 else if (!strcmp ("present", p
))
15125 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
15126 /* As of OpenACC 2.5, these are now aliases of the non-present_or
15128 else if (!strcmp ("present_or_copy", p
)
15129 || !strcmp ("pcopy", p
))
15130 result
= PRAGMA_OACC_CLAUSE_COPY
;
15131 else if (!strcmp ("present_or_copyin", p
)
15132 || !strcmp ("pcopyin", p
))
15133 result
= PRAGMA_OACC_CLAUSE_COPYIN
;
15134 else if (!strcmp ("present_or_copyout", p
)
15135 || !strcmp ("pcopyout", p
))
15136 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
15137 else if (!strcmp ("present_or_create", p
)
15138 || !strcmp ("pcreate", p
))
15139 result
= PRAGMA_OACC_CLAUSE_CREATE
;
15140 else if (!strcmp ("priority", p
))
15141 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
15142 else if (!strcmp ("private", p
))
15143 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
15144 else if (!strcmp ("proc_bind", p
))
15145 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
15148 if (!strcmp ("reduction", p
))
15149 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
15152 if (!strcmp ("safelen", p
))
15153 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
15154 else if (!strcmp ("schedule", p
))
15155 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
15156 else if (!strcmp ("sections", p
))
15157 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
15158 else if (!strcmp ("self", p
))
15159 result
= PRAGMA_OACC_CLAUSE_SELF
;
15160 else if (!strcmp ("seq", p
))
15161 result
= PRAGMA_OACC_CLAUSE_SEQ
;
15162 else if (!strcmp ("shared", p
))
15163 result
= PRAGMA_OMP_CLAUSE_SHARED
;
15164 else if (!strcmp ("simd", p
))
15165 result
= PRAGMA_OMP_CLAUSE_SIMD
;
15166 else if (!strcmp ("simdlen", p
))
15167 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
15170 if (!strcmp ("task_reduction", p
))
15171 result
= PRAGMA_OMP_CLAUSE_TASK_REDUCTION
;
15172 else if (!strcmp ("taskgroup", p
))
15173 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
15174 else if (!strcmp ("thread_limit", p
))
15175 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
15176 else if (!strcmp ("threads", p
))
15177 result
= PRAGMA_OMP_CLAUSE_THREADS
;
15178 else if (!strcmp ("tile", p
))
15179 result
= PRAGMA_OACC_CLAUSE_TILE
;
15180 else if (!strcmp ("to", p
))
15181 result
= PRAGMA_OMP_CLAUSE_TO
;
15184 if (!strcmp ("uniform", p
))
15185 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
15186 else if (!strcmp ("untied", p
))
15187 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
15188 else if (!strcmp ("use_device", p
))
15189 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
15190 else if (!strcmp ("use_device_addr", p
))
15191 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
;
15192 else if (!strcmp ("use_device_ptr", p
))
15193 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
15196 if (!strcmp ("vector", p
))
15197 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
15198 else if (!strcmp ("vector_length", p
))
15199 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
15202 if (!strcmp ("wait", p
))
15203 result
= PRAGMA_OACC_CLAUSE_WAIT
;
15204 else if (!strcmp ("worker", p
))
15205 result
= PRAGMA_OACC_CLAUSE_WORKER
;
15210 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
15211 c_parser_consume_token (parser
);
15216 /* Validate that a clause of the given type does not already exist. */
15219 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
15222 if (tree c
= omp_find_clause (clauses
, code
))
15223 error_at (OMP_CLAUSE_LOCATION (c
), "too many %qs clauses", name
);
15227 Parse wait clause or wait directive parameters. */
15230 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
15232 vec
<tree
, va_gc
> *args
;
15235 matching_parens parens
;
15236 if (!parens
.require_open (parser
))
15239 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
15240 args_tree
= build_tree_list_vec (args
);
15242 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
15244 tree targ
= TREE_VALUE (t
);
15246 if (targ
!= error_mark_node
)
15248 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
15250 c_parser_error (parser
, "expression must be integral");
15251 targ
= error_mark_node
;
15255 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
15257 OMP_CLAUSE_DECL (c
) = targ
;
15258 OMP_CLAUSE_CHAIN (c
) = list
;
15264 release_tree_vector (args
);
15265 parens
.require_close (parser
);
15269 /* OpenACC 2.0, OpenMP 2.5:
15272 variable-list , identifier
15274 If KIND is nonzero, create the appropriate node and install the
15275 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
15276 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
15278 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
15279 return the list created.
15281 The optional ALLOW_DEREF argument is true if list items can use the deref
15286 tree low_bound
, length
;
15289 omp_dim (tree lb
, tree len
, location_t lo
, bool nc
)
15290 : low_bound (lb
), length (len
), loc (lo
), no_colon (nc
) {}
15294 c_parser_omp_variable_list (c_parser
*parser
,
15295 location_t clause_loc
,
15296 enum omp_clause_code kind
, tree list
,
15297 bool map_lvalue
= false)
15299 auto_vec
<omp_dim
> dims
;
15300 bool array_section_p
;
15301 auto_vec
<c_token
> tokens
;
15302 unsigned int tokens_avail
= 0;
15303 c_token
*saved_tokens
= NULL
;
15308 tree t
= NULL_TREE
;
15310 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
15312 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
15313 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
15315 struct c_expr expr
;
15316 if (kind
== OMP_CLAUSE_DEPEND
15317 && c_parser_next_token_is_keyword (parser
,
15318 RID_OMP_ALL_MEMORY
)
15319 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
15320 || (c_parser_peek_2nd_token (parser
)->type
15321 == CPP_CLOSE_PAREN
)))
15323 expr
.value
= ridpointers
[RID_OMP_ALL_MEMORY
];
15324 c_parser_consume_token (parser
);
15327 expr
= c_parser_expr_no_commas (parser
, NULL
);
15328 if (expr
.value
!= error_mark_node
)
15330 tree u
= build_omp_clause (clause_loc
, kind
);
15331 OMP_CLAUSE_DECL (u
) = expr
.value
;
15332 OMP_CLAUSE_CHAIN (u
) = list
;
15336 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
15339 c_parser_consume_token (parser
);
15344 tokens
.truncate (0);
15345 unsigned int nesting_depth
= 0;
15348 c_token
*token
= c_parser_peek_token (parser
);
15349 switch (token
->type
)
15352 case CPP_PRAGMA_EOL
:
15354 case CPP_OPEN_BRACE
:
15355 case CPP_OPEN_PAREN
:
15356 case CPP_OPEN_SQUARE
:
15359 case CPP_CLOSE_BRACE
:
15360 case CPP_CLOSE_PAREN
:
15361 case CPP_CLOSE_SQUARE
:
15362 if (nesting_depth
-- == 0)
15366 if (nesting_depth
== 0)
15371 tokens
.safe_push (*token
);
15372 c_parser_consume_token (parser
);
15378 /* Make sure nothing tries to read past the end of the tokens. */
15380 memset (&eof_token
, 0, sizeof (eof_token
));
15381 eof_token
.type
= CPP_EOF
;
15382 tokens
.safe_push (eof_token
);
15383 tokens
.safe_push (eof_token
);
15385 saved_tokens
= parser
->tokens
;
15386 tokens_avail
= parser
->tokens_avail
;
15387 parser
->tokens
= tokens
.address ();
15388 parser
->tokens_avail
= tokens
.length ();
15390 else if (map_lvalue
15391 && (kind
== OMP_CLAUSE_MAP
15392 || kind
== OMP_CLAUSE_TO
15393 || kind
== OMP_CLAUSE_FROM
))
15395 location_t loc
= c_parser_peek_token (parser
)->location
;
15396 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
15397 c_omp_array_section_p
= true;
15398 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15399 if (expr
.value
!= error_mark_node
)
15400 mark_exp_read (expr
.value
);
15401 c_omp_array_section_p
= save_c_omp_array_section_p
;
15402 tree decl
= expr
.value
;
15404 /* This code rewrites a parsed expression containing various tree
15405 codes used to represent array accesses into a more uniform nest of
15406 OMP_ARRAY_SECTION nodes before it is processed by
15407 c-typeck.cc:handle_omp_array_sections_1. It might be more
15408 efficient to move this logic to that function instead, analysing
15409 the parsed expression directly rather than this preprocessed
15410 form. (See also equivalent code in cp/parser.cc,
15411 cp/semantics.cc). */
15413 if (TREE_CODE (decl
) == OMP_ARRAY_SECTION
)
15415 while (TREE_CODE (decl
) == OMP_ARRAY_SECTION
)
15417 tree low_bound
= TREE_OPERAND (decl
, 1);
15418 tree length
= TREE_OPERAND (decl
, 2);
15419 dims
.safe_push (omp_dim (low_bound
, length
, loc
, false));
15420 decl
= TREE_OPERAND (decl
, 0);
15423 while (TREE_CODE (decl
) == ARRAY_REF
15424 || TREE_CODE (decl
) == INDIRECT_REF
15425 || TREE_CODE (decl
) == COMPOUND_EXPR
)
15427 if (TREE_CODE (decl
) == COMPOUND_EXPR
)
15429 decl
= TREE_OPERAND (decl
, 1);
15432 else if (TREE_CODE (decl
) == INDIRECT_REF
)
15434 dims
.safe_push (omp_dim (integer_zero_node
,
15435 integer_one_node
, loc
, true));
15436 decl
= TREE_OPERAND (decl
, 0);
15438 else /* ARRAY_REF. */
15440 tree index
= TREE_OPERAND (decl
, 1);
15441 dims
.safe_push (omp_dim (index
, integer_one_node
, loc
,
15443 decl
= TREE_OPERAND (decl
, 0);
15447 for (int i
= dims
.length () - 1; i
>= 0; i
--)
15448 decl
= build_omp_array_section (loc
, decl
, dims
[i
].low_bound
,
15451 else if (TREE_CODE (decl
) == INDIRECT_REF
)
15453 /* Turn indirection of a pointer "*foo" into "foo[0:1]". */
15454 decl
= TREE_OPERAND (decl
, 0);
15457 decl
= build_omp_array_section (loc
, decl
, integer_zero_node
,
15460 else if (TREE_CODE (decl
) == ARRAY_REF
)
15462 tree idx
= TREE_OPERAND (decl
, 1);
15464 decl
= TREE_OPERAND (decl
, 0);
15467 decl
= build_omp_array_section (loc
, decl
, idx
, integer_one_node
);
15469 else if (TREE_CODE (decl
) == NON_LVALUE_EXPR
15470 || CONVERT_EXPR_P (decl
))
15471 decl
= TREE_OPERAND (decl
, 0);
15473 tree u
= build_omp_clause (clause_loc
, kind
);
15474 OMP_CLAUSE_DECL (u
) = decl
;
15475 OMP_CLAUSE_CHAIN (u
) = list
;
15481 if (c_parser_next_token_is (parser
, CPP_NAME
)
15482 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
15484 t
= lookup_name (c_parser_peek_token (parser
)->value
);
15486 if (t
== NULL_TREE
)
15488 undeclared_variable (c_parser_peek_token (parser
)->location
,
15489 c_parser_peek_token (parser
)->value
);
15490 t
= error_mark_node
;
15493 c_parser_consume_token (parser
);
15495 else if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
15496 && (c_parser_peek_token (parser
)->keyword
== RID_FUNCTION_NAME
15497 || (c_parser_peek_token (parser
)->keyword
15498 == RID_PRETTY_FUNCTION_NAME
)
15499 || (c_parser_peek_token (parser
)->keyword
15500 == RID_C99_FUNCTION_NAME
)))
15501 t
= c_parser_predefined_identifier (parser
).value
;
15505 c_parser_error (parser
, "expected identifier");
15509 if (t
== error_mark_node
)
15511 else if (kind
!= 0)
15515 case OMP_CLAUSE__CACHE_
:
15516 /* The OpenACC cache directive explicitly only allows "array
15517 elements or subarrays". */
15518 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
15520 c_parser_error (parser
, "expected %<[%>");
15521 t
= error_mark_node
;
15525 case OMP_CLAUSE_MAP
:
15526 case OMP_CLAUSE_FROM
:
15527 case OMP_CLAUSE_TO
:
15528 start_component_ref
:
15529 while (c_parser_next_token_is (parser
, CPP_DOT
)
15530 || c_parser_next_token_is (parser
, CPP_DEREF
))
15532 location_t op_loc
= c_parser_peek_token (parser
)->location
;
15533 location_t arrow_loc
= UNKNOWN_LOCATION
;
15534 if (c_parser_next_token_is (parser
, CPP_DEREF
))
15538 t_expr
.original_code
= ERROR_MARK
;
15539 t_expr
.original_type
= NULL
;
15540 set_c_expr_source_range (&t_expr
, op_loc
, op_loc
);
15541 t_expr
.m_decimal
= 0;
15542 t_expr
= convert_lvalue_to_rvalue (op_loc
, t_expr
,
15544 t
= build_indirect_ref (op_loc
, t_expr
.value
, RO_ARROW
);
15545 arrow_loc
= t_expr
.get_location ();
15547 c_parser_consume_token (parser
);
15548 if (!c_parser_next_token_is (parser
, CPP_NAME
))
15550 c_parser_error (parser
, "expected identifier");
15551 t
= error_mark_node
;
15555 c_token
*comp_tok
= c_parser_peek_token (parser
);
15556 tree ident
= comp_tok
->value
;
15557 location_t comp_loc
= comp_tok
->location
;
15558 c_parser_consume_token (parser
);
15559 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
,
15563 case OMP_CLAUSE_AFFINITY
:
15564 case OMP_CLAUSE_DEPEND
:
15565 case OMP_CLAUSE_REDUCTION
:
15566 case OMP_CLAUSE_IN_REDUCTION
:
15567 case OMP_CLAUSE_TASK_REDUCTION
:
15568 case OMP_CLAUSE_HAS_DEVICE_ADDR
:
15569 array_section_p
= false;
15571 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
15573 location_t loc
= UNKNOWN_LOCATION
;
15574 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
15575 bool no_colon
= false;
15577 c_parser_consume_token (parser
);
15578 if (!c_parser_next_token_is (parser
, CPP_COLON
))
15580 location_t expr_loc
15581 = c_parser_peek_token (parser
)->location
;
15582 c_expr expr
= c_parser_expression (parser
);
15583 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
15585 low_bound
= expr
.value
;
15588 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
15590 length
= integer_one_node
;
15595 /* Look for `:'. */
15596 if (!c_parser_require (parser
, CPP_COLON
,
15599 t
= error_mark_node
;
15602 array_section_p
= true;
15603 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
15605 location_t expr_loc
15606 = c_parser_peek_token (parser
)->location
;
15607 c_expr expr
= c_parser_expression (parser
);
15608 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
15610 length
= expr
.value
;
15613 /* Look for the closing `]'. */
15614 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
15617 t
= error_mark_node
;
15621 dims
.safe_push (omp_dim (low_bound
, length
, loc
, no_colon
));
15624 if (t
!= error_mark_node
)
15626 if ((kind
== OMP_CLAUSE_MAP
15627 || kind
== OMP_CLAUSE_FROM
15628 || kind
== OMP_CLAUSE_TO
)
15629 && !array_section_p
15630 && (c_parser_next_token_is (parser
, CPP_DOT
)
15631 || c_parser_next_token_is (parser
, CPP_DEREF
)))
15633 for (unsigned i
= 0; i
< dims
.length (); i
++)
15635 gcc_assert (dims
[i
].length
== integer_one_node
);
15636 t
= build_array_ref (dims
[i
].loc
,
15637 t
, dims
[i
].low_bound
);
15639 goto start_component_ref
;
15642 for (unsigned i
= 0; i
< dims
.length (); i
++)
15643 t
= build_omp_array_section (clause_loc
, t
,
15648 if ((kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
15649 && t
!= error_mark_node
15650 && parser
->tokens_avail
!= 2)
15652 if (array_section_p
)
15654 error_at (c_parser_peek_token (parser
)->location
,
15655 "expected %<)%> or %<,%>");
15656 t
= error_mark_node
;
15660 parser
->tokens
= tokens
.address ();
15661 parser
->tokens_avail
= tokens
.length ();
15663 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
15664 if (t
!= error_mark_node
&& parser
->tokens_avail
!= 2)
15666 error_at (c_parser_peek_token (parser
)->location
,
15667 "expected %<)%> or %<,%>");
15668 t
= error_mark_node
;
15677 if (t
!= error_mark_node
)
15679 tree u
= build_omp_clause (clause_loc
, kind
);
15680 OMP_CLAUSE_DECL (u
) = t
;
15681 OMP_CLAUSE_CHAIN (u
) = list
;
15686 list
= tree_cons (t
, NULL_TREE
, list
);
15688 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
15690 parser
->tokens
= saved_tokens
;
15691 parser
->tokens_avail
= tokens_avail
;
15695 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
15698 c_parser_consume_token (parser
);
15705 /* Similarly, but expect leading and trailing parenthesis. This is a very
15706 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
15707 argument is true if list items can use the deref (->) operator. */
15710 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
15711 tree list
, bool map_lvalue
= false)
15713 /* The clauses location. */
15714 location_t loc
= c_parser_peek_token (parser
)->location
;
15716 if (parser
->in_omp_decl_attribute
)
15720 tree u
= build_omp_clause (loc
, kind
);
15721 OMP_CLAUSE_DECL (u
) = parser
->in_omp_decl_attribute
;
15722 OMP_CLAUSE_CHAIN (u
) = list
;
15726 return tree_cons (parser
->in_omp_decl_attribute
, NULL_TREE
, list
);
15729 matching_parens parens
;
15730 if (parens
.require_open (parser
))
15732 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
, map_lvalue
);
15733 parens
.skip_until_found_close (parser
);
15739 copy ( variable-list )
15740 copyin ( variable-list )
15741 copyout ( variable-list )
15742 create ( variable-list )
15743 delete ( variable-list )
15744 present ( variable-list )
15747 no_create ( variable-list )
15748 attach ( variable-list )
15749 detach ( variable-list )
15752 copyin (readonly : variable-list )
15756 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
15759 enum gomp_map_kind kind
;
15762 case PRAGMA_OACC_CLAUSE_ATTACH
:
15763 kind
= GOMP_MAP_ATTACH
;
15765 case PRAGMA_OACC_CLAUSE_COPY
:
15766 kind
= GOMP_MAP_TOFROM
;
15768 case PRAGMA_OACC_CLAUSE_COPYIN
:
15769 kind
= GOMP_MAP_TO
;
15771 case PRAGMA_OACC_CLAUSE_COPYOUT
:
15772 kind
= GOMP_MAP_FROM
;
15774 case PRAGMA_OACC_CLAUSE_CREATE
:
15775 kind
= GOMP_MAP_ALLOC
;
15777 case PRAGMA_OACC_CLAUSE_DELETE
:
15778 kind
= GOMP_MAP_RELEASE
;
15780 case PRAGMA_OACC_CLAUSE_DETACH
:
15781 kind
= GOMP_MAP_DETACH
;
15783 case PRAGMA_OACC_CLAUSE_DEVICE
:
15784 kind
= GOMP_MAP_FORCE_TO
;
15786 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
15787 kind
= GOMP_MAP_DEVICE_RESIDENT
;
15789 case PRAGMA_OACC_CLAUSE_LINK
:
15790 kind
= GOMP_MAP_LINK
;
15792 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
15793 kind
= GOMP_MAP_IF_PRESENT
;
15795 case PRAGMA_OACC_CLAUSE_PRESENT
:
15796 kind
= GOMP_MAP_FORCE_PRESENT
;
15798 case PRAGMA_OACC_CLAUSE_SELF
:
15799 /* "The 'host' clause is a synonym for the 'self' clause." */
15800 case PRAGMA_OACC_CLAUSE_HOST
:
15801 kind
= GOMP_MAP_FORCE_FROM
;
15804 gcc_unreachable ();
15808 bool readonly
= false;
15809 location_t open_loc
= c_parser_peek_token (parser
)->location
;
15810 matching_parens parens
;
15811 if (parens
.require_open (parser
))
15813 /* Turn on readonly modifier parsing for copyin clause. */
15814 if (c_kind
== PRAGMA_OACC_CLAUSE_COPYIN
)
15816 c_token
*token
= c_parser_peek_token (parser
);
15817 if (token
->type
== CPP_NAME
15818 && !strcmp (IDENTIFIER_POINTER (token
->value
), "readonly")
15819 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
15821 c_parser_consume_token (parser
);
15822 c_parser_consume_token (parser
);
15826 nl
= c_parser_omp_variable_list (parser
, open_loc
, OMP_CLAUSE_MAP
, list
,
15828 parens
.skip_until_found_close (parser
);
15831 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15833 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
15835 OMP_CLAUSE_MAP_READONLY (c
) = 1;
15842 deviceptr ( variable-list ) */
15845 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
15847 location_t loc
= c_parser_peek_token (parser
)->location
;
15850 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
15851 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
15852 variable-list must only allow for pointer variables. */
15853 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
15854 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
15856 tree v
= TREE_PURPOSE (t
);
15858 /* FIXME diagnostics: Ideally we should keep individual
15859 locations for all the variables in the var list to make the
15860 following errors more precise. Perhaps
15861 c_parser_omp_var_list_parens() should construct a list of
15862 locations to go along with the var list. */
15864 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
15865 error_at (loc
, "%qD is not a variable", v
);
15866 else if (TREE_TYPE (v
) == error_mark_node
)
15868 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
15869 error_at (loc
, "%qD is not a pointer variable", v
);
15871 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
15872 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
15873 OMP_CLAUSE_DECL (u
) = v
;
15874 OMP_CLAUSE_CHAIN (u
) = list
;
15881 /* OpenACC 2.0, OpenMP 3.0:
15882 collapse ( constant-expression ) */
15885 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
15887 tree c
, num
= error_mark_node
;
15891 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
15892 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
15894 loc
= c_parser_peek_token (parser
)->location
;
15895 matching_parens parens
;
15896 if (parens
.require_open (parser
))
15898 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
15899 parens
.skip_until_found_close (parser
);
15901 if (num
== error_mark_node
)
15903 mark_exp_read (num
);
15904 num
= c_fully_fold (num
, false, NULL
);
15905 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
15906 || !tree_fits_shwi_p (num
)
15907 || (n
= tree_to_shwi (num
)) <= 0
15911 "collapse argument needs positive constant integer expression");
15914 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
15915 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
15916 OMP_CLAUSE_CHAIN (c
) = list
;
15921 copyin ( variable-list ) */
15924 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
15926 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
15930 copyprivate ( variable-list ) */
15933 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
15935 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
15939 default ( none | shared )
15942 default ( private | firstprivate )
15945 default ( none | present ) */
15948 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
15950 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
15951 location_t loc
= c_parser_peek_token (parser
)->location
;
15954 matching_parens parens
;
15955 if (!parens
.require_open (parser
))
15957 if (c_parser_next_token_is (parser
, CPP_NAME
))
15959 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15964 if (strcmp ("none", p
) != 0)
15966 kind
= OMP_CLAUSE_DEFAULT_NONE
;
15972 if (strcmp ("present", p
) != 0)
15974 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
15978 if (strcmp ("private", p
) != 0)
15980 kind
= OMP_CLAUSE_DEFAULT_PRIVATE
;
15985 if (strcmp ("firstprivate", p
) != 0 || is_oacc
)
15987 kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
15991 if (strcmp ("shared", p
) != 0 || is_oacc
)
15993 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
16000 c_parser_consume_token (parser
);
16006 c_parser_error (parser
, "expected %<none%> or %<present%>");
16008 c_parser_error (parser
, "expected %<none%>, %<shared%>, "
16009 "%<private%> or %<firstprivate%>");
16011 parens
.skip_until_found_close (parser
);
16013 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
16016 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
16017 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
16018 OMP_CLAUSE_CHAIN (c
) = list
;
16019 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
16025 firstprivate ( variable-list ) */
16028 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
16030 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
16034 final ( expression ) */
16037 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
16039 location_t loc
= c_parser_peek_token (parser
)->location
;
16040 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
16042 matching_parens parens
;
16044 if (!parens
.require_open (parser
))
16045 t
= error_mark_node
;
16048 location_t eloc
= c_parser_peek_token (parser
)->location
;
16049 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16050 t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
16051 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
16052 t
= c_fully_fold (t
, false, NULL
);
16053 parens
.skip_until_found_close (parser
);
16056 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
16058 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
16059 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
16060 OMP_CLAUSE_CHAIN (c
) = list
;
16064 c_parser_error (parser
, "expected %<(%>");
16070 indirect [( expression )]
16074 c_parser_omp_clause_indirect (c_parser
*parser
, tree list
)
16076 location_t location
= c_parser_peek_token (parser
)->location
;
16079 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
16081 matching_parens parens
;
16082 if (!parens
.require_open (parser
))
16085 location_t loc
= c_parser_peek_token (parser
)->location
;
16086 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16087 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
16088 t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
);
16089 t
= c_fully_fold (t
, false, NULL
);
16090 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
16091 || TREE_CODE (t
) != INTEGER_CST
)
16093 c_parser_error (parser
, "expected constant logical expression");
16096 parens
.skip_until_found_close (parser
);
16099 t
= integer_one_node
;
16101 check_no_duplicate_clause (list
, OMP_CLAUSE_INDIRECT
, "indirect");
16103 tree c
= build_omp_clause (location
, OMP_CLAUSE_INDIRECT
);
16104 OMP_CLAUSE_INDIRECT_EXPR (c
) = t
;
16105 OMP_CLAUSE_CHAIN (c
) = list
;
16110 /* OpenACC, OpenMP 2.5:
16114 if ( directive-name-modifier : expression )
16116 directive-name-modifier:
16117 parallel | task | taskloop | target data | target | target update
16118 | target enter data | target exit data
16121 directive-name-modifier:
16122 ... | simd | cancel */
16125 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
16127 location_t location
= c_parser_peek_token (parser
)->location
;
16128 enum tree_code if_modifier
= ERROR_MARK
;
16130 matching_parens parens
;
16131 if (!parens
.require_open (parser
))
16134 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
16136 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16138 if (strcmp (p
, "cancel") == 0)
16139 if_modifier
= VOID_CST
;
16140 else if (strcmp (p
, "parallel") == 0)
16141 if_modifier
= OMP_PARALLEL
;
16142 else if (strcmp (p
, "simd") == 0)
16143 if_modifier
= OMP_SIMD
;
16144 else if (strcmp (p
, "task") == 0)
16145 if_modifier
= OMP_TASK
;
16146 else if (strcmp (p
, "taskloop") == 0)
16147 if_modifier
= OMP_TASKLOOP
;
16148 else if (strcmp (p
, "target") == 0)
16150 if_modifier
= OMP_TARGET
;
16151 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
16153 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
16154 if (strcmp ("data", p
) == 0)
16155 if_modifier
= OMP_TARGET_DATA
;
16156 else if (strcmp ("update", p
) == 0)
16157 if_modifier
= OMP_TARGET_UPDATE
;
16158 else if (strcmp ("enter", p
) == 0)
16159 if_modifier
= OMP_TARGET_ENTER_DATA
;
16160 else if (strcmp ("exit", p
) == 0)
16161 if_modifier
= OMP_TARGET_EXIT_DATA
;
16162 if (if_modifier
!= OMP_TARGET
)
16165 c_parser_consume_token (parser
);
16169 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
16170 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
16172 if_modifier
= ERROR_MARK
;
16174 if (if_modifier
== OMP_TARGET_ENTER_DATA
16175 || if_modifier
== OMP_TARGET_EXIT_DATA
)
16177 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
16179 p
= IDENTIFIER_POINTER
16180 (c_parser_peek_2nd_token (parser
)->value
);
16181 if (strcmp ("data", p
) == 0)
16185 c_parser_consume_token (parser
);
16189 = c_parser_peek_2nd_token (parser
)->location
;
16190 error_at (loc
, "expected %<data%>");
16191 if_modifier
= ERROR_MARK
;
16196 if (if_modifier
!= ERROR_MARK
)
16198 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16200 c_parser_consume_token (parser
);
16201 c_parser_consume_token (parser
);
16207 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
16208 error_at (loc
, "expected %<:%>");
16210 if_modifier
= ERROR_MARK
;
16215 location_t loc
= c_parser_peek_token (parser
)->location
;
16216 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16217 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
16218 tree t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
), c
;
16219 t
= c_fully_fold (t
, false, NULL
);
16220 parens
.skip_until_found_close (parser
);
16222 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
16223 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
16225 if (if_modifier
!= ERROR_MARK
16226 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
16228 const char *p
= NULL
;
16229 switch (if_modifier
)
16231 case VOID_CST
: p
= "cancel"; break;
16232 case OMP_PARALLEL
: p
= "parallel"; break;
16233 case OMP_SIMD
: p
= "simd"; break;
16234 case OMP_TASK
: p
= "task"; break;
16235 case OMP_TASKLOOP
: p
= "taskloop"; break;
16236 case OMP_TARGET_DATA
: p
= "target data"; break;
16237 case OMP_TARGET
: p
= "target"; break;
16238 case OMP_TARGET_UPDATE
: p
= "target update"; break;
16239 case OMP_TARGET_ENTER_DATA
: p
= "target enter data"; break;
16240 case OMP_TARGET_EXIT_DATA
: p
= "target exit data"; break;
16241 default: gcc_unreachable ();
16243 error_at (location
, "too many %<if%> clauses with %qs modifier",
16247 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
16250 error_at (location
, "too many %<if%> clauses");
16252 error_at (location
, "too many %<if%> clauses without modifier");
16255 else if (if_modifier
== ERROR_MARK
16256 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
16258 error_at (location
, "if any %<if%> clause has modifier, then all "
16259 "%<if%> clauses have to use modifier");
16264 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
16265 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
16266 OMP_CLAUSE_IF_EXPR (c
) = t
;
16267 OMP_CLAUSE_CHAIN (c
) = list
;
16272 lastprivate ( variable-list )
16275 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
16278 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
16280 /* The clauses location. */
16281 location_t loc
= c_parser_peek_token (parser
)->location
;
16283 if (c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
16285 bool conditional
= false;
16286 if (c_parser_next_token_is (parser
, CPP_NAME
)
16287 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16290 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16291 if (strcmp (p
, "conditional") == 0)
16293 conditional
= true;
16294 c_parser_consume_token (parser
);
16295 c_parser_consume_token (parser
);
16298 tree nlist
= c_parser_omp_variable_list (parser
, loc
,
16299 OMP_CLAUSE_LASTPRIVATE
, list
);
16300 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
16302 for (tree c
= nlist
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16303 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 1;
16313 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
16317 /* FIXME: Should we allow duplicates? */
16318 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
16320 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
16321 OMP_CLAUSE_MERGEABLE
);
16322 OMP_CLAUSE_CHAIN (c
) = list
;
16331 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
16334 location_t loc
= c_parser_peek_token (parser
)->location
;
16336 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
16338 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
16339 OMP_CLAUSE_CHAIN (c
) = list
;
16344 num_threads ( expression ) */
16347 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
16349 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
16350 matching_parens parens
;
16351 if (parens
.require_open (parser
))
16353 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16354 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16355 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16356 tree c
, t
= expr
.value
;
16357 t
= c_fully_fold (t
, false, NULL
);
16359 parens
.skip_until_found_close (parser
);
16361 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16363 c_parser_error (parser
, "expected integer expression");
16367 /* Attempt to statically determine when the number isn't positive. */
16368 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
16369 build_int_cst (TREE_TYPE (t
), 0));
16370 protected_set_expr_location (c
, expr_loc
);
16371 if (c
== boolean_true_node
)
16373 warning_at (expr_loc
, OPT_Wopenmp
,
16374 "%<num_threads%> value must be positive");
16375 t
= integer_one_node
;
16378 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
16380 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
16381 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
16382 OMP_CLAUSE_CHAIN (c
) = list
;
16390 num_tasks ( expression )
16393 num_tasks ( strict : expression ) */
16396 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
16398 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
16399 matching_parens parens
;
16400 if (parens
.require_open (parser
))
16402 bool strict
= false;
16403 if (c_parser_next_token_is (parser
, CPP_NAME
)
16404 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
16405 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
16409 c_parser_consume_token (parser
);
16410 c_parser_consume_token (parser
);
16413 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16414 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16415 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16416 tree c
, t
= expr
.value
;
16417 t
= c_fully_fold (t
, false, NULL
);
16419 parens
.skip_until_found_close (parser
);
16421 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16423 c_parser_error (parser
, "expected integer expression");
16427 /* Attempt to statically determine when the number isn't positive. */
16428 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
16429 build_int_cst (TREE_TYPE (t
), 0));
16430 if (CAN_HAVE_LOCATION_P (c
))
16431 SET_EXPR_LOCATION (c
, expr_loc
);
16432 if (c
== boolean_true_node
)
16434 warning_at (expr_loc
, OPT_Wopenmp
,
16435 "%<num_tasks%> value must be positive");
16436 t
= integer_one_node
;
16439 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
16441 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
16442 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
16443 OMP_CLAUSE_NUM_TASKS_STRICT (c
) = strict
;
16444 OMP_CLAUSE_CHAIN (c
) = list
;
16452 grainsize ( expression )
16455 grainsize ( strict : expression ) */
16458 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
16460 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
16461 matching_parens parens
;
16462 if (parens
.require_open (parser
))
16464 bool strict
= false;
16465 if (c_parser_next_token_is (parser
, CPP_NAME
)
16466 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
16467 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
16471 c_parser_consume_token (parser
);
16472 c_parser_consume_token (parser
);
16475 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16476 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16477 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16478 tree c
, t
= expr
.value
;
16479 t
= c_fully_fold (t
, false, NULL
);
16481 parens
.skip_until_found_close (parser
);
16483 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16485 c_parser_error (parser
, "expected integer expression");
16489 /* Attempt to statically determine when the number isn't positive. */
16490 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
16491 build_int_cst (TREE_TYPE (t
), 0));
16492 if (CAN_HAVE_LOCATION_P (c
))
16493 SET_EXPR_LOCATION (c
, expr_loc
);
16494 if (c
== boolean_true_node
)
16496 warning_at (expr_loc
, OPT_Wopenmp
,
16497 "%<grainsize%> value must be positive");
16498 t
= integer_one_node
;
16501 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
16503 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
16504 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
16505 OMP_CLAUSE_GRAINSIZE_STRICT (c
) = strict
;
16506 OMP_CLAUSE_CHAIN (c
) = list
;
16514 priority ( expression ) */
16517 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
16519 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
16520 matching_parens parens
;
16521 if (parens
.require_open (parser
))
16523 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16524 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16525 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16526 tree c
, t
= expr
.value
;
16527 t
= c_fully_fold (t
, false, NULL
);
16529 parens
.skip_until_found_close (parser
);
16531 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16533 c_parser_error (parser
, "expected integer expression");
16537 /* Attempt to statically determine when the number isn't
16539 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
16540 build_int_cst (TREE_TYPE (t
), 0));
16541 if (CAN_HAVE_LOCATION_P (c
))
16542 SET_EXPR_LOCATION (c
, expr_loc
);
16543 if (c
== boolean_true_node
)
16545 warning_at (expr_loc
, OPT_Wopenmp
,
16546 "%<priority%> value must be non-negative");
16547 t
= integer_one_node
;
16550 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
16552 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
16553 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
16554 OMP_CLAUSE_CHAIN (c
) = list
;
16562 hint ( expression ) */
16565 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
16567 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
16568 matching_parens parens
;
16569 if (parens
.require_open (parser
))
16571 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16572 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16573 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16574 tree c
, t
= expr
.value
;
16575 t
= c_fully_fold (t
, false, NULL
);
16576 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
16577 || TREE_CODE (t
) != INTEGER_CST
16578 || tree_int_cst_sgn (t
) == -1)
16580 c_parser_error (parser
, "expected constant integer expression "
16581 "with valid sync-hint value");
16584 parens
.skip_until_found_close (parser
);
16585 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
16587 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
16588 OMP_CLAUSE_HINT_EXPR (c
) = t
;
16589 OMP_CLAUSE_CHAIN (c
) = list
;
16597 filter ( integer-expression ) */
16600 c_parser_omp_clause_filter (c_parser
*parser
, tree list
)
16602 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
16603 matching_parens parens
;
16604 if (parens
.require_open (parser
))
16606 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16607 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16608 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16609 tree c
, t
= expr
.value
;
16610 t
= c_fully_fold (t
, false, NULL
);
16611 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16613 c_parser_error (parser
, "expected integer expression");
16616 parens
.skip_until_found_close (parser
);
16617 check_no_duplicate_clause (list
, OMP_CLAUSE_FILTER
, "filter");
16619 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_FILTER
);
16620 OMP_CLAUSE_FILTER_EXPR (c
) = t
;
16621 OMP_CLAUSE_CHAIN (c
) = list
;
16629 defaultmap ( tofrom : scalar )
16632 defaultmap ( implicit-behavior [ : variable-category ] ) */
16635 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
16637 location_t loc
= c_parser_peek_token (parser
)->location
;
16640 enum omp_clause_defaultmap_kind behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
16641 enum omp_clause_defaultmap_kind category
16642 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
16644 matching_parens parens
;
16645 if (!parens
.require_open (parser
))
16647 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
16649 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
16652 c_parser_error (parser
, "expected %<alloc%>, %<to%>, %<from%>, "
16653 "%<tofrom%>, %<firstprivate%>, %<none%> "
16658 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16663 if (strcmp ("alloc", p
) == 0)
16664 behavior
= OMP_CLAUSE_DEFAULTMAP_ALLOC
;
16666 goto invalid_behavior
;
16670 if (strcmp ("default", p
) == 0)
16671 behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
16673 goto invalid_behavior
;
16677 if (strcmp ("firstprivate", p
) == 0)
16678 behavior
= OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
16679 else if (strcmp ("from", p
) == 0)
16680 behavior
= OMP_CLAUSE_DEFAULTMAP_FROM
;
16682 goto invalid_behavior
;
16686 if (strcmp ("none", p
) == 0)
16687 behavior
= OMP_CLAUSE_DEFAULTMAP_NONE
;
16689 goto invalid_behavior
;
16693 if (strcmp ("present", p
) == 0)
16694 behavior
= OMP_CLAUSE_DEFAULTMAP_PRESENT
;
16696 goto invalid_behavior
;
16700 if (strcmp ("tofrom", p
) == 0)
16701 behavior
= OMP_CLAUSE_DEFAULTMAP_TOFROM
;
16702 else if (strcmp ("to", p
) == 0)
16703 behavior
= OMP_CLAUSE_DEFAULTMAP_TO
;
16705 goto invalid_behavior
;
16709 goto invalid_behavior
;
16711 c_parser_consume_token (parser
);
16713 if (!c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
16715 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16717 if (!c_parser_next_token_is (parser
, CPP_NAME
))
16720 c_parser_error (parser
, "expected %<scalar%>, %<aggregate%>, "
16721 "%<pointer%> or %<all%>");
16724 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16728 if (strcmp ("aggregate", p
) == 0)
16729 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
;
16730 else if (strcmp ("all", p
) == 0)
16731 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
;
16733 goto invalid_category
;
16737 if (strcmp ("pointer", p
) == 0)
16738 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
;
16740 goto invalid_category
;
16744 if (strcmp ("scalar", p
) == 0)
16745 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
;
16747 goto invalid_category
;
16751 goto invalid_category
;
16754 c_parser_consume_token (parser
);
16756 parens
.skip_until_found_close (parser
);
16758 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
16759 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEFAULTMAP
16760 && (category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16761 || category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16762 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
) == category
16763 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
16764 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
16765 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
16766 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
)))
16768 enum omp_clause_defaultmap_kind cat
= category
;
16769 location_t loc
= OMP_CLAUSE_LOCATION (c
);
16770 if (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16771 || (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16772 && (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
16773 != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)))
16774 cat
= OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
);
16778 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
16781 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
:
16784 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
16787 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
16790 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
16794 gcc_unreachable ();
16797 error_at (loc
, "too many %<defaultmap%> clauses with %qs category",
16800 error_at (loc
, "too many %<defaultmap%> clauses with unspecified "
16805 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
16806 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c
, behavior
, category
);
16807 OMP_CLAUSE_CHAIN (c
) = list
;
16811 parens
.skip_until_found_close (parser
);
16816 use_device ( variable-list )
16819 use_device_ptr ( variable-list ) */
16822 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
16824 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
16829 use_device_addr ( variable-list ) */
16832 c_parser_omp_clause_use_device_addr (c_parser
*parser
, tree list
)
16834 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_ADDR
,
16839 has_device_addr ( variable-list ) */
16842 c_parser_omp_clause_has_device_addr (c_parser
*parser
, tree list
)
16844 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_HAS_DEVICE_ADDR
,
16849 is_device_ptr ( variable-list ) */
16852 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
16854 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
16858 num_gangs ( expression )
16859 num_workers ( expression )
16860 vector_length ( expression ) */
16863 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
16866 location_t loc
= c_parser_peek_token (parser
)->location
;
16868 matching_parens parens
;
16869 if (!parens
.require_open (parser
))
16872 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16873 c_expr expr
= c_parser_expression (parser
);
16874 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16875 tree c
, t
= expr
.value
;
16876 t
= c_fully_fold (t
, false, NULL
);
16878 parens
.skip_until_found_close (parser
);
16880 if (t
== error_mark_node
)
16882 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16884 error_at (expr_loc
, "%qs expression must be integral",
16885 omp_clause_code_name
[code
]);
16889 /* Attempt to statically determine when the number isn't positive. */
16890 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
16891 build_int_cst (TREE_TYPE (t
), 0));
16892 protected_set_expr_location (c
, expr_loc
);
16893 if (c
== boolean_true_node
)
16895 warning_at (expr_loc
, 0,
16896 "%qs value must be positive",
16897 omp_clause_code_name
[code
]);
16898 t
= integer_one_node
;
16901 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
16903 c
= build_omp_clause (loc
, code
);
16904 OMP_CLAUSE_OPERAND (c
, 0) = t
;
16905 OMP_CLAUSE_CHAIN (c
) = list
;
16911 gang [( gang-arg-list )]
16912 worker [( [num:] int-expr )]
16913 vector [( [length:] int-expr )]
16915 where gang-arg is one of:
16920 and size-expr may be:
16927 c_parser_oacc_shape_clause (c_parser
*parser
, location_t loc
,
16928 omp_clause_code kind
,
16929 const char *str
, tree list
)
16931 const char *id
= "num";
16932 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
16934 if (kind
== OMP_CLAUSE_VECTOR
)
16937 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
16939 c_parser_consume_token (parser
);
16943 c_token
*next
= c_parser_peek_token (parser
);
16946 /* Gang static argument. */
16947 if (kind
== OMP_CLAUSE_GANG
16948 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
16950 c_parser_consume_token (parser
);
16952 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16953 goto cleanup_error
;
16956 if (ops
[idx
] != NULL_TREE
)
16958 c_parser_error (parser
, "too many %<static%> arguments");
16959 goto cleanup_error
;
16962 /* Check for the '*' argument. */
16963 if (c_parser_next_token_is (parser
, CPP_MULT
)
16964 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
16965 || c_parser_peek_2nd_token (parser
)->type
16966 == CPP_CLOSE_PAREN
))
16968 c_parser_consume_token (parser
);
16969 ops
[idx
] = integer_minus_one_node
;
16971 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16973 c_parser_consume_token (parser
);
16980 /* Worker num: argument and vector length: arguments. */
16981 else if (c_parser_next_token_is (parser
, CPP_NAME
)
16982 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
16983 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16985 c_parser_consume_token (parser
); /* id */
16986 c_parser_consume_token (parser
); /* ':' */
16989 /* Now collect the actual argument. */
16990 if (ops
[idx
] != NULL_TREE
)
16992 c_parser_error (parser
, "unexpected argument");
16993 goto cleanup_error
;
16996 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16997 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
16998 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
16999 tree expr
= cexpr
.value
;
17000 if (expr
== error_mark_node
)
17001 goto cleanup_error
;
17003 expr
= c_fully_fold (expr
, false, NULL
);
17005 /* Attempt to statically determine when the number isn't a
17006 positive integer. */
17008 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
17010 c_parser_error (parser
, "expected integer expression");
17014 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
17015 build_int_cst (TREE_TYPE (expr
), 0));
17016 if (c
== boolean_true_node
)
17018 warning_at (loc
, 0,
17019 "%qs value must be positive", str
);
17020 expr
= integer_one_node
;
17025 if (kind
== OMP_CLAUSE_GANG
17026 && c_parser_next_token_is (parser
, CPP_COMMA
))
17028 c_parser_consume_token (parser
);
17035 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
17036 goto cleanup_error
;
17039 check_no_duplicate_clause (list
, kind
, str
);
17041 c
= build_omp_clause (loc
, kind
);
17044 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
17046 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
17047 OMP_CLAUSE_CHAIN (c
) = list
;
17052 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
17064 c_parser_oacc_simple_clause (location_t loc
, enum omp_clause_code code
,
17067 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
17069 tree c
= build_omp_clause (loc
, code
);
17070 OMP_CLAUSE_CHAIN (c
) = list
;
17076 async [( int-expr )] */
17079 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
17082 location_t loc
= c_parser_peek_token (parser
)->location
;
17084 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
17086 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
17088 c_parser_consume_token (parser
);
17090 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
17091 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
17092 c_parser_error (parser
, "expected integer expression");
17093 else if (t
== error_mark_node
17094 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
17098 t
= c_fully_fold (t
, false, NULL
);
17100 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
17102 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
17103 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
17104 OMP_CLAUSE_CHAIN (c
) = list
;
17111 tile ( size-expr-list ) */
17114 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
17116 tree c
, expr
= error_mark_node
;
17118 tree tile
= NULL_TREE
;
17120 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
17121 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
17123 loc
= c_parser_peek_token (parser
)->location
;
17124 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
17129 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
17132 if (c_parser_next_token_is (parser
, CPP_MULT
)
17133 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
17134 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
17136 c_parser_consume_token (parser
);
17137 expr
= integer_zero_node
;
17141 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17142 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
17143 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
17144 expr
= cexpr
.value
;
17146 if (expr
== error_mark_node
)
17148 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
17153 expr
= c_fully_fold (expr
, false, NULL
);
17155 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
17156 || !tree_fits_shwi_p (expr
)
17157 || tree_to_shwi (expr
) <= 0)
17159 error_at (expr_loc
, "%<tile%> argument needs positive"
17160 " integral constant");
17161 expr
= integer_zero_node
;
17165 tile
= tree_cons (NULL_TREE
, expr
, tile
);
17167 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
17169 /* Consume the trailing ')'. */
17170 c_parser_consume_token (parser
);
17172 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
17173 tile
= nreverse (tile
);
17174 OMP_CLAUSE_TILE_LIST (c
) = tile
;
17175 OMP_CLAUSE_CHAIN (c
) = list
;
17180 wait [( int-expr-list )] */
17183 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
17185 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17187 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
17188 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
17191 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
17193 OMP_CLAUSE_DECL (c
) = build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
17194 OMP_CLAUSE_CHAIN (c
) = list
;
17202 self [( expression )] */
17205 c_parser_oacc_compute_clause_self (c_parser
*parser
, tree list
)
17208 location_t location
= c_parser_peek_token (parser
)->location
;
17209 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
17211 matching_parens parens
;
17212 parens
.consume_open (parser
);
17214 location_t loc
= c_parser_peek_token (parser
)->location
;
17215 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17216 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
17217 t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
);
17218 t
= c_fully_fold (t
, false, NULL
);
17219 parens
.skip_until_found_close (parser
);
17222 t
= truthvalue_true_node
;
17224 for (tree c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
17225 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SELF
)
17227 error_at (location
, "too many %<self%> clauses");
17231 tree c
= build_omp_clause (location
, OMP_CLAUSE_SELF
);
17232 OMP_CLAUSE_SELF_EXPR (c
) = t
;
17233 OMP_CLAUSE_CHAIN (c
) = list
;
17238 order ( concurrent )
17241 order ( order-modifier : concurrent )
17248 c_parser_omp_clause_order (c_parser
*parser
, tree list
)
17250 location_t loc
= c_parser_peek_token (parser
)->location
;
17253 bool unconstrained
= false;
17254 bool reproducible
= false;
17256 matching_parens parens
;
17257 if (!parens
.require_open (parser
))
17259 if (c_parser_next_token_is (parser
, CPP_NAME
)
17260 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
17262 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17263 if (strcmp (p
, "unconstrained") == 0)
17264 unconstrained
= true;
17265 else if (strcmp (p
, "reproducible") == 0)
17266 reproducible
= true;
17269 c_parser_error (parser
, "expected %<reproducible%> or "
17270 "%<unconstrained%>");
17273 c_parser_consume_token (parser
);
17274 c_parser_consume_token (parser
);
17276 if (!c_parser_next_token_is (parser
, CPP_NAME
))
17278 c_parser_error (parser
, "expected %<concurrent%>");
17281 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17282 if (strcmp (p
, "concurrent") != 0)
17284 c_parser_error (parser
, "expected %<concurrent%>");
17287 c_parser_consume_token (parser
);
17288 parens
.skip_until_found_close (parser
);
17289 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDER
, "order");
17290 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDER
);
17291 OMP_CLAUSE_ORDER_UNCONSTRAINED (c
) = unconstrained
;
17292 OMP_CLAUSE_ORDER_REPRODUCIBLE (c
) = reproducible
;
17293 OMP_CLAUSE_CHAIN (c
) = list
;
17297 parens
.skip_until_found_close (parser
);
17303 bind ( teams | parallel | thread ) */
17306 c_parser_omp_clause_bind (c_parser
*parser
, tree list
)
17308 location_t loc
= c_parser_peek_token (parser
)->location
;
17311 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
17313 matching_parens parens
;
17314 if (!parens
.require_open (parser
))
17316 if (!c_parser_next_token_is (parser
, CPP_NAME
))
17319 c_parser_error (parser
,
17320 "expected %<teams%>, %<parallel%> or %<thread%>");
17321 parens
.skip_until_found_close (parser
);
17324 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17325 if (strcmp (p
, "teams") == 0)
17326 kind
= OMP_CLAUSE_BIND_TEAMS
;
17327 else if (strcmp (p
, "parallel") == 0)
17328 kind
= OMP_CLAUSE_BIND_PARALLEL
;
17329 else if (strcmp (p
, "thread") != 0)
17331 c_parser_consume_token (parser
);
17332 parens
.skip_until_found_close (parser
);
17333 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
17334 c
= build_omp_clause (loc
, OMP_CLAUSE_BIND
);
17335 OMP_CLAUSE_BIND_KIND (c
) = kind
;
17336 OMP_CLAUSE_CHAIN (c
) = list
;
17345 ordered ( constant-expression ) */
17348 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
17350 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
17352 tree c
, num
= NULL_TREE
;
17354 location_t loc
= c_parser_peek_token (parser
)->location
;
17355 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17357 matching_parens parens
;
17358 parens
.consume_open (parser
);
17359 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
17360 parens
.skip_until_found_close (parser
);
17362 if (num
== error_mark_node
)
17366 mark_exp_read (num
);
17367 num
= c_fully_fold (num
, false, NULL
);
17368 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
17369 || !tree_fits_shwi_p (num
)
17370 || (n
= tree_to_shwi (num
)) <= 0
17373 error_at (loc
, "ordered argument needs positive "
17374 "constant integer expression");
17378 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
17379 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
17380 OMP_CLAUSE_CHAIN (c
) = list
;
17385 private ( variable-list ) */
17388 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
17390 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
17394 reduction ( reduction-operator : variable-list )
17396 reduction-operator:
17397 One of: + * - & ^ | && ||
17401 reduction-operator:
17402 One of: + * - & ^ | && || max min
17406 reduction-operator:
17407 One of: + * - & ^ | && ||
17411 reduction ( reduction-modifier, reduction-operator : variable-list )
17412 in_reduction ( reduction-operator : variable-list )
17413 task_reduction ( reduction-operator : variable-list ) */
17416 c_parser_omp_clause_reduction (c_parser
*parser
, enum omp_clause_code kind
,
17417 bool is_omp
, tree list
)
17419 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17420 matching_parens parens
;
17421 if (parens
.require_open (parser
))
17424 bool inscan
= false;
17425 enum tree_code code
= ERROR_MARK
;
17426 tree reduc_id
= NULL_TREE
;
17428 if (kind
== OMP_CLAUSE_REDUCTION
&& is_omp
)
17430 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
17431 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
17433 c_parser_consume_token (parser
);
17434 c_parser_consume_token (parser
);
17436 else if (c_parser_next_token_is (parser
, CPP_NAME
)
17437 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
17440 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17441 if (strcmp (p
, "task") == 0)
17443 else if (strcmp (p
, "inscan") == 0)
17445 if (task
|| inscan
)
17447 c_parser_consume_token (parser
);
17448 c_parser_consume_token (parser
);
17453 switch (c_parser_peek_token (parser
)->type
)
17465 code
= BIT_AND_EXPR
;
17468 code
= BIT_XOR_EXPR
;
17471 code
= BIT_IOR_EXPR
;
17474 code
= TRUTH_ANDIF_EXPR
;
17477 code
= TRUTH_ORIF_EXPR
;
17482 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17483 if (strcmp (p
, "min") == 0)
17488 if (strcmp (p
, "max") == 0)
17493 reduc_id
= c_parser_peek_token (parser
)->value
;
17497 c_parser_error (parser
,
17498 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
17499 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
17500 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
17503 c_parser_consume_token (parser
);
17504 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
17505 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
17509 nl
= c_parser_omp_variable_list (parser
, clause_loc
, kind
, list
);
17510 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
17512 tree d
= OMP_CLAUSE_DECL (c
), type
;
17513 if (TREE_CODE (d
) != OMP_ARRAY_SECTION
)
17514 type
= TREE_TYPE (d
);
17520 TREE_CODE (t
) == OMP_ARRAY_SECTION
;
17521 t
= TREE_OPERAND (t
, 0))
17523 type
= TREE_TYPE (t
);
17526 if (TREE_CODE (type
) != POINTER_TYPE
17527 && TREE_CODE (type
) != ARRAY_TYPE
)
17529 type
= TREE_TYPE (type
);
17533 while (TREE_CODE (type
) == ARRAY_TYPE
)
17534 type
= TREE_TYPE (type
);
17535 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
17537 OMP_CLAUSE_REDUCTION_TASK (c
) = 1;
17539 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 1;
17540 if (code
== ERROR_MARK
17541 || !(INTEGRAL_TYPE_P (type
)
17542 || SCALAR_FLOAT_TYPE_P (type
)
17543 || TREE_CODE (type
) == COMPLEX_TYPE
))
17544 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
17545 = c_omp_reduction_lookup (reduc_id
,
17546 TYPE_MAIN_VARIANT (type
));
17551 parens
.skip_until_found_close (parser
);
17557 schedule ( schedule-kind )
17558 schedule ( schedule-kind , expression )
17561 static | dynamic | guided | runtime | auto
17564 schedule ( schedule-modifier : schedule-kind )
17565 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
17573 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
17576 location_t loc
= c_parser_peek_token (parser
)->location
;
17577 int modifiers
= 0, nmodifiers
= 0;
17579 matching_parens parens
;
17580 if (!parens
.require_open (parser
))
17583 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
17585 location_t comma
= UNKNOWN_LOCATION
;
17586 while (c_parser_next_token_is (parser
, CPP_NAME
))
17588 tree kind
= c_parser_peek_token (parser
)->value
;
17589 const char *p
= IDENTIFIER_POINTER (kind
);
17590 if (strcmp ("simd", p
) == 0)
17591 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
17592 else if (strcmp ("monotonic", p
) == 0)
17593 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
17594 else if (strcmp ("nonmonotonic", p
) == 0)
17595 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
17598 comma
= UNKNOWN_LOCATION
;
17599 c_parser_consume_token (parser
);
17600 if (nmodifiers
++ == 0
17601 && c_parser_next_token_is (parser
, CPP_COMMA
))
17603 comma
= c_parser_peek_token (parser
)->location
;
17604 c_parser_consume_token (parser
);
17608 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
17612 if (comma
!= UNKNOWN_LOCATION
)
17613 error_at (comma
, "expected %<:%>");
17615 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
17616 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
17617 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
17618 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
17620 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
17625 if (c_parser_next_token_is (parser
, CPP_NAME
))
17627 tree kind
= c_parser_peek_token (parser
)->value
;
17628 const char *p
= IDENTIFIER_POINTER (kind
);
17633 if (strcmp ("dynamic", p
) != 0)
17635 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
17639 if (strcmp ("guided", p
) != 0)
17641 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
17645 if (strcmp ("runtime", p
) != 0)
17647 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
17654 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
17655 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
17656 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
17657 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
17661 c_parser_consume_token (parser
);
17662 if (c_parser_next_token_is (parser
, CPP_COMMA
))
17665 c_parser_consume_token (parser
);
17667 here
= c_parser_peek_token (parser
)->location
;
17668 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17669 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
17671 t
= c_fully_fold (t
, false, NULL
);
17673 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
17674 error_at (here
, "schedule %<runtime%> does not take "
17675 "a %<chunk_size%> parameter");
17676 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
17678 "schedule %<auto%> does not take "
17679 "a %<chunk_size%> parameter");
17680 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
17681 || TREE_CODE (TREE_TYPE (t
)) == BITINT_TYPE
)
17683 /* Attempt to statically determine when the number isn't
17685 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
17686 build_int_cst (TREE_TYPE (t
), 0));
17687 protected_set_expr_location (s
, loc
);
17688 if (s
== boolean_true_node
)
17690 warning_at (loc
, OPT_Wopenmp
,
17691 "chunk size value must be positive");
17692 t
= integer_one_node
;
17694 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
17697 c_parser_error (parser
, "expected integer expression");
17699 parens
.skip_until_found_close (parser
);
17702 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
17703 "expected %<,%> or %<)%>");
17705 OMP_CLAUSE_SCHEDULE_KIND (c
)
17706 = (enum omp_clause_schedule_kind
)
17707 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
17709 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
17710 OMP_CLAUSE_CHAIN (c
) = list
;
17714 c_parser_error (parser
, "invalid schedule kind");
17715 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
17720 shared ( variable-list ) */
17723 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
17725 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
17732 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
17736 /* FIXME: Should we allow duplicates? */
17737 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
17739 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
17740 OMP_CLAUSE_UNTIED
);
17741 OMP_CLAUSE_CHAIN (c
) = list
;
17751 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
17752 enum omp_clause_code code
, tree list
)
17754 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
17756 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
17757 OMP_CLAUSE_CHAIN (c
) = list
;
17769 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
17770 enum omp_clause_code code
, tree list
)
17772 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
17773 OMP_CLAUSE_CHAIN (c
) = list
;
17782 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
17784 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
17785 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
17786 OMP_CLAUSE_NOGROUP
);
17787 OMP_CLAUSE_CHAIN (c
) = list
;
17796 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
17797 enum omp_clause_code code
, tree list
)
17799 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
17800 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
17801 OMP_CLAUSE_CHAIN (c
) = list
;
17806 num_teams ( expression )
17809 num_teams ( expression : expression ) */
17812 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
17814 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
17815 matching_parens parens
;
17816 if (parens
.require_open (parser
))
17818 location_t upper_loc
= c_parser_peek_token (parser
)->location
;
17819 location_t lower_loc
= UNKNOWN_LOCATION
;
17820 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17821 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
17822 tree c
, upper
= expr
.value
, lower
= NULL_TREE
;
17823 upper
= c_fully_fold (upper
, false, NULL
);
17825 if (c_parser_next_token_is (parser
, CPP_COLON
))
17827 c_parser_consume_token (parser
);
17828 lower_loc
= upper_loc
;
17830 upper_loc
= c_parser_peek_token (parser
)->location
;
17831 expr
= c_parser_expr_no_commas (parser
, NULL
);
17832 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
17833 upper
= expr
.value
;
17834 upper
= c_fully_fold (upper
, false, NULL
);
17837 parens
.skip_until_found_close (parser
);
17839 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper
))
17840 || (lower
&& !INTEGRAL_TYPE_P (TREE_TYPE (lower
))))
17842 c_parser_error (parser
, "expected integer expression");
17846 /* Attempt to statically determine when the number isn't positive. */
17847 c
= fold_build2_loc (upper_loc
, LE_EXPR
, boolean_type_node
, upper
,
17848 build_int_cst (TREE_TYPE (upper
), 0));
17849 protected_set_expr_location (c
, upper_loc
);
17850 if (c
== boolean_true_node
)
17852 warning_at (upper_loc
, OPT_Wopenmp
,
17853 "%<num_teams%> value must be positive");
17854 upper
= integer_one_node
;
17858 c
= fold_build2_loc (lower_loc
, LE_EXPR
, boolean_type_node
, lower
,
17859 build_int_cst (TREE_TYPE (lower
), 0));
17860 protected_set_expr_location (c
, lower_loc
);
17861 if (c
== boolean_true_node
)
17863 warning_at (lower_loc
, OPT_Wopenmp
,
17864 "%<num_teams%> value must be positive");
17867 else if (TREE_CODE (lower
) == INTEGER_CST
17868 && TREE_CODE (upper
) == INTEGER_CST
17869 && tree_int_cst_lt (upper
, lower
))
17871 warning_at (lower_loc
, OPT_Wopenmp
,
17872 "%<num_teams%> lower bound %qE bigger than upper "
17873 "bound %qE", lower
, upper
);
17878 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
17880 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
17881 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c
) = upper
;
17882 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
) = lower
;
17883 OMP_CLAUSE_CHAIN (c
) = list
;
17891 thread_limit ( expression ) */
17894 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
17896 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
17897 matching_parens parens
;
17898 if (parens
.require_open (parser
))
17900 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17901 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17902 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17903 tree c
, t
= expr
.value
;
17904 t
= c_fully_fold (t
, false, NULL
);
17906 parens
.skip_until_found_close (parser
);
17908 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
17910 c_parser_error (parser
, "expected integer expression");
17914 /* Attempt to statically determine when the number isn't positive. */
17915 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
17916 build_int_cst (TREE_TYPE (t
), 0));
17917 protected_set_expr_location (c
, expr_loc
);
17918 if (c
== boolean_true_node
)
17920 warning_at (expr_loc
, OPT_Wopenmp
,
17921 "%<thread_limit%> value must be positive");
17922 t
= integer_one_node
;
17925 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
17928 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
17929 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
17930 OMP_CLAUSE_CHAIN (c
) = list
;
17938 aligned ( variable-list )
17939 aligned ( variable-list : constant-expression ) */
17942 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
17944 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17947 matching_parens parens
;
17948 if (!parens
.require_open (parser
))
17951 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
17952 OMP_CLAUSE_ALIGNED
, list
);
17954 if (c_parser_next_token_is (parser
, CPP_COLON
))
17956 c_parser_consume_token (parser
);
17957 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17958 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17959 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17960 tree alignment
= expr
.value
;
17961 alignment
= c_fully_fold (alignment
, false, NULL
);
17962 if (TREE_CODE (alignment
) != INTEGER_CST
17963 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
17964 || tree_int_cst_sgn (alignment
) != 1)
17966 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
17967 "be positive constant integer expression");
17968 alignment
= NULL_TREE
;
17971 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
17972 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
17975 parens
.skip_until_found_close (parser
);
17980 allocate ( variable-list )
17981 allocate ( expression : variable-list )
17984 allocate ( allocator-modifier : variable-list )
17985 allocate ( allocator-modifier , allocator-modifier : variable-list )
17987 allocator-modifier:
17988 allocator ( expression )
17989 align ( expression ) */
17992 c_parser_omp_clause_allocate (c_parser
*parser
, tree list
)
17994 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17996 tree allocator
= NULL_TREE
;
17997 tree align
= NULL_TREE
;
17999 matching_parens parens
;
18000 if (!parens
.require_open (parser
))
18003 if ((c_parser_next_token_is_not (parser
, CPP_NAME
)
18004 && c_parser_next_token_is_not (parser
, CPP_KEYWORD
))
18005 || (c_parser_peek_2nd_token (parser
)->type
!= CPP_COMMA
18006 && c_parser_peek_2nd_token (parser
)->type
!= CPP_CLOSE_PAREN
))
18008 bool has_modifiers
= false;
18009 tree orig_type
= NULL_TREE
;
18010 if (c_parser_next_token_is (parser
, CPP_NAME
)
18011 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
18013 unsigned int n
= 3;
18015 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18016 if ((strcmp (p
, "allocator") == 0 || strcmp (p
, "align") == 0)
18017 && c_parser_check_balanced_raw_token_sequence (parser
, &n
)
18018 && (c_parser_peek_nth_token_raw (parser
, n
)->type
18019 == CPP_CLOSE_PAREN
))
18021 if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
18023 has_modifiers
= true;
18024 else if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
18026 && (c_parser_peek_nth_token_raw (parser
, n
+ 2)->type
18028 && (c_parser_peek_nth_token_raw (parser
, n
+ 3)->type
18029 == CPP_OPEN_PAREN
))
18031 c_token
*tok
= c_parser_peek_nth_token_raw (parser
, n
+ 2);
18032 const char *q
= IDENTIFIER_POINTER (tok
->value
);
18034 if ((strcmp (q
, "allocator") == 0
18035 || strcmp (q
, "align") == 0)
18036 && c_parser_check_balanced_raw_token_sequence (parser
,
18038 && (c_parser_peek_nth_token_raw (parser
, n
)->type
18039 == CPP_CLOSE_PAREN
)
18040 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
18042 has_modifiers
= true;
18047 c_parser_consume_token (parser
);
18048 matching_parens parens2
;
18049 parens2
.require_open (parser
);
18050 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18051 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18052 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18053 if (expr
.value
== error_mark_node
)
18055 else if (strcmp (p
, "allocator") == 0)
18057 allocator
= expr
.value
;
18058 allocator
= c_fully_fold (allocator
, false, NULL
);
18059 orig_type
= expr
.original_type
18060 ? expr
.original_type
: TREE_TYPE (allocator
);
18061 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
18065 align
= expr
.value
;
18066 align
= c_fully_fold (align
, false, NULL
);
18068 parens2
.skip_until_found_close (parser
);
18069 if (c_parser_next_token_is (parser
, CPP_COMMA
))
18071 c_parser_consume_token (parser
);
18072 c_token
*tok
= c_parser_peek_token (parser
);
18073 const char *q
= "";
18074 if (c_parser_next_token_is (parser
, CPP_NAME
))
18075 q
= IDENTIFIER_POINTER (tok
->value
);
18076 if (strcmp (q
, "allocator") != 0 && strcmp (q
, "align") != 0)
18078 c_parser_error (parser
, "expected %<allocator%> or "
18080 parens
.skip_until_found_close (parser
);
18083 else if (strcmp (p
, q
) == 0)
18085 error_at (tok
->location
, "duplicate %qs modifier", p
);
18086 parens
.skip_until_found_close (parser
);
18089 c_parser_consume_token (parser
);
18090 if (!parens2
.require_open (parser
))
18092 parens
.skip_until_found_close (parser
);
18095 expr_loc
= c_parser_peek_token (parser
)->location
;
18096 expr
= c_parser_expr_no_commas (parser
, NULL
);
18097 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
18099 if (strcmp (q
, "allocator") == 0)
18101 allocator
= expr
.value
;
18102 allocator
= c_fully_fold (allocator
, false, NULL
);
18103 orig_type
= expr
.original_type
18104 ? expr
.original_type
: TREE_TYPE (allocator
);
18105 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
18109 align
= expr
.value
;
18110 align
= c_fully_fold (align
, false, NULL
);
18112 parens2
.skip_until_found_close (parser
);
18116 if (!has_modifiers
)
18118 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18119 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18120 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18121 allocator
= expr
.value
;
18122 allocator
= c_fully_fold (allocator
, false, NULL
);
18123 orig_type
= expr
.original_type
18124 ? expr
.original_type
: TREE_TYPE (allocator
);
18125 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
18128 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
18129 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
18130 || (TYPE_NAME (orig_type
)
18131 != get_identifier ("omp_allocator_handle_t"))))
18133 error_at (clause_loc
, "%<allocate%> clause allocator expression "
18134 "has type %qT rather than "
18135 "%<omp_allocator_handle_t%>",
18136 TREE_TYPE (allocator
));
18137 allocator
= NULL_TREE
;
18140 && (!INTEGRAL_TYPE_P (TREE_TYPE (align
))
18141 || !tree_fits_uhwi_p (align
)
18142 || !integer_pow2p (align
)))
18144 error_at (clause_loc
, "%<allocate%> clause %<align%> modifier "
18145 "argument needs to be positive constant "
18146 "power of two integer expression");
18149 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18151 parens
.skip_until_found_close (parser
);
18156 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
18157 OMP_CLAUSE_ALLOCATE
, list
);
18159 if (allocator
|| align
)
18160 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18162 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
18163 OMP_CLAUSE_ALLOCATE_ALIGN (c
) = align
;
18166 parens
.skip_until_found_close (parser
);
18171 linear ( variable-list )
18172 linear ( variable-list : expression )
18175 linear ( modifier ( variable-list ) )
18176 linear ( modifier ( variable-list ) : expression )
18182 linear ( variable-list : modifiers-list )
18186 step ( expression ) */
18189 c_parser_omp_clause_linear (c_parser
*parser
, tree list
)
18191 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18193 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
18194 bool old_linear_modifier
= false;
18196 matching_parens parens
;
18197 if (!parens
.require_open (parser
))
18200 if (c_parser_next_token_is (parser
, CPP_NAME
))
18202 c_token
*tok
= c_parser_peek_token (parser
);
18203 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18204 if (strcmp ("val", p
) == 0)
18205 kind
= OMP_CLAUSE_LINEAR_VAL
;
18206 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
18207 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
18208 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
18210 old_linear_modifier
= true;
18211 c_parser_consume_token (parser
);
18212 c_parser_consume_token (parser
);
18216 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
18217 OMP_CLAUSE_LINEAR
, list
);
18219 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
18220 parens
.skip_until_found_close (parser
);
18222 if (c_parser_next_token_is (parser
, CPP_COLON
))
18224 c_parser_consume_token (parser
);
18225 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18226 bool has_modifiers
= false;
18227 if (kind
== OMP_CLAUSE_LINEAR_DEFAULT
18228 && c_parser_next_token_is (parser
, CPP_NAME
))
18230 c_token
*tok
= c_parser_peek_token (parser
);
18231 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18232 unsigned int pos
= 0;
18233 if (strcmp ("val", p
) == 0)
18235 else if (strcmp ("step", p
) == 0
18236 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
18239 if (c_parser_check_balanced_raw_token_sequence (parser
, &pos
)
18240 && (c_parser_peek_nth_token_raw (parser
, pos
)->type
18241 == CPP_CLOSE_PAREN
))
18248 tok
= c_parser_peek_nth_token_raw (parser
, pos
);
18249 if (tok
->type
== CPP_COMMA
|| tok
->type
== CPP_CLOSE_PAREN
)
18250 has_modifiers
= true;
18256 while (c_parser_next_token_is (parser
, CPP_NAME
))
18258 c_token
*tok
= c_parser_peek_token (parser
);
18259 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18260 if (strcmp ("val", p
) == 0)
18262 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
18263 error_at (tok
->location
, "multiple linear modifiers");
18264 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
18265 c_parser_consume_token (parser
);
18267 else if (strcmp ("step", p
) == 0)
18269 c_parser_consume_token (parser
);
18270 matching_parens parens2
;
18271 if (parens2
.require_open (parser
))
18274 error_at (tok
->location
,
18275 "multiple %<step%> modifiers");
18276 expr_loc
= c_parser_peek_token (parser
)->location
;
18277 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18278 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
18280 step
= c_fully_fold (expr
.value
, false, NULL
);
18281 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
18283 error_at (clause_loc
, "%<linear%> clause step "
18284 "expression must be integral");
18285 step
= integer_one_node
;
18287 parens2
.skip_until_found_close (parser
);
18294 if (c_parser_next_token_is (parser
, CPP_COMMA
))
18296 c_parser_consume_token (parser
);
18302 step
= integer_one_node
;
18306 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18307 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18308 step
= c_fully_fold (expr
.value
, false, NULL
);
18309 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
18311 error_at (clause_loc
, "%<linear%> clause step expression must "
18313 step
= integer_one_node
;
18319 step
= integer_one_node
;
18321 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18323 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
18324 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
18325 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c
) = old_linear_modifier
;
18328 parens
.skip_until_found_close (parser
);
18333 nontemporal ( variable-list ) */
18336 c_parser_omp_clause_nontemporal (c_parser
*parser
, tree list
)
18338 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_NONTEMPORAL
, list
);
18342 safelen ( constant-expression ) */
18345 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
18347 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18350 matching_parens parens
;
18351 if (!parens
.require_open (parser
))
18354 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18355 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18356 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18358 t
= c_fully_fold (t
, false, NULL
);
18359 if (TREE_CODE (t
) != INTEGER_CST
18360 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
18361 || tree_int_cst_sgn (t
) != 1)
18363 error_at (clause_loc
, "%<safelen%> clause expression must "
18364 "be positive constant integer expression");
18368 parens
.skip_until_found_close (parser
);
18369 if (t
== NULL_TREE
|| t
== error_mark_node
)
18372 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
18374 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
18375 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
18376 OMP_CLAUSE_CHAIN (c
) = list
;
18381 simdlen ( constant-expression ) */
18384 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
18386 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18389 matching_parens parens
;
18390 if (!parens
.require_open (parser
))
18393 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18394 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18395 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18397 t
= c_fully_fold (t
, false, NULL
);
18398 if (TREE_CODE (t
) != INTEGER_CST
18399 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
18400 || tree_int_cst_sgn (t
) != 1)
18402 error_at (clause_loc
, "%<simdlen%> clause expression must "
18403 "be positive constant integer expression");
18407 parens
.skip_until_found_close (parser
);
18408 if (t
== NULL_TREE
|| t
== error_mark_node
)
18411 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
18413 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
18414 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
18415 OMP_CLAUSE_CHAIN (c
) = list
;
18421 identifier [+/- integer]
18422 vec , identifier [+/- integer]
18426 c_parser_omp_clause_doacross_sink (c_parser
*parser
, location_t clause_loc
,
18427 tree list
, bool depend_p
)
18430 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
18431 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
18433 c_parser_error (parser
, "expected identifier");
18439 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18440 if (strcmp (p
, "omp_cur_iteration") == 0
18441 && c_parser_peek_2nd_token (parser
)->type
== CPP_MINUS
18442 && c_parser_peek_nth_token (parser
, 3)->type
== CPP_NUMBER
18443 && c_parser_peek_nth_token (parser
, 4)->type
== CPP_CLOSE_PAREN
)
18445 tree val
= c_parser_peek_nth_token (parser
, 3)->value
;
18446 if (integer_onep (val
))
18448 c_parser_consume_token (parser
);
18449 c_parser_consume_token (parser
);
18450 c_parser_consume_token (parser
);
18451 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
18452 OMP_CLAUSE_DOACROSS_KIND (u
) = OMP_CLAUSE_DOACROSS_SINK
;
18453 OMP_CLAUSE_CHAIN (u
) = list
;
18461 while (c_parser_next_token_is (parser
, CPP_NAME
)
18462 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
18464 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
18465 tree addend
= NULL
;
18467 if (t
== NULL_TREE
)
18469 undeclared_variable (c_parser_peek_token (parser
)->location
,
18470 c_parser_peek_token (parser
)->value
);
18471 t
= error_mark_node
;
18474 c_parser_consume_token (parser
);
18477 if (c_parser_next_token_is (parser
, CPP_MINUS
))
18479 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
18481 addend
= integer_zero_node
;
18483 goto add_to_vector
;
18485 c_parser_consume_token (parser
);
18487 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
18489 c_parser_error (parser
, "expected integer");
18493 addend
= c_parser_peek_token (parser
)->value
;
18494 if (TREE_CODE (addend
) != INTEGER_CST
)
18496 c_parser_error (parser
, "expected integer");
18499 c_parser_consume_token (parser
);
18502 if (t
!= error_mark_node
)
18504 vec
= tree_cons (addend
, t
, vec
);
18506 OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec
) = 1;
18509 if (c_parser_next_token_is_not (parser
, CPP_COMMA
)
18510 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
18511 || c_parser_peek_2nd_token (parser
)->id_kind
!= C_ID_ID
)
18514 c_parser_consume_token (parser
);
18517 if (vec
== NULL_TREE
)
18520 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
18521 OMP_CLAUSE_DOACROSS_KIND (u
) = OMP_CLAUSE_DOACROSS_SINK
;
18522 OMP_CLAUSE_DOACROSS_DEPEND (u
) = depend_p
;
18523 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
18524 OMP_CLAUSE_CHAIN (u
) = list
;
18529 iterators ( iterators-definition )
18531 iterators-definition:
18533 iterator-specifier , iterators-definition
18535 iterator-specifier:
18536 identifier = range-specification
18537 iterator-type identifier = range-specification
18539 range-specification:
18541 begin : end : step */
18544 c_parser_omp_iterators (c_parser
*parser
)
18546 tree ret
= NULL_TREE
, *last
= &ret
;
18547 c_parser_consume_token (parser
);
18551 matching_parens parens
;
18552 if (!parens
.require_open (parser
))
18553 return error_mark_node
;
18557 tree iter_type
= NULL_TREE
, type_expr
= NULL_TREE
;
18558 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
18560 struct c_type_name
*type
= c_parser_type_name (parser
);
18562 iter_type
= groktypename (type
, &type_expr
, NULL
);
18564 if (iter_type
== NULL_TREE
)
18565 iter_type
= integer_type_node
;
18567 location_t loc
= c_parser_peek_token (parser
)->location
;
18568 if (!c_parser_next_token_is (parser
, CPP_NAME
))
18570 c_parser_error (parser
, "expected identifier");
18574 tree id
= c_parser_peek_token (parser
)->value
;
18575 c_parser_consume_token (parser
);
18577 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18580 location_t eloc
= c_parser_peek_token (parser
)->location
;
18581 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18582 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
18583 tree begin
= expr
.value
;
18585 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18588 eloc
= c_parser_peek_token (parser
)->location
;
18589 expr
= c_parser_expr_no_commas (parser
, NULL
);
18590 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
18591 tree end
= expr
.value
;
18593 tree step
= integer_one_node
;
18594 if (c_parser_next_token_is (parser
, CPP_COLON
))
18596 c_parser_consume_token (parser
);
18597 eloc
= c_parser_peek_token (parser
)->location
;
18598 expr
= c_parser_expr_no_commas (parser
, NULL
);
18599 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
18603 tree iter_var
= build_decl (loc
, VAR_DECL
, id
, iter_type
);
18604 DECL_ARTIFICIAL (iter_var
) = 1;
18605 DECL_CONTEXT (iter_var
) = current_function_decl
;
18606 pushdecl (iter_var
);
18608 *last
= make_tree_vec (6);
18609 TREE_VEC_ELT (*last
, 0) = iter_var
;
18610 TREE_VEC_ELT (*last
, 1) = begin
;
18611 TREE_VEC_ELT (*last
, 2) = end
;
18612 TREE_VEC_ELT (*last
, 3) = step
;
18613 last
= &TREE_CHAIN (*last
);
18615 if (c_parser_next_token_is (parser
, CPP_COMMA
))
18617 c_parser_consume_token (parser
);
18624 parens
.skip_until_found_close (parser
);
18625 return ret
? ret
: error_mark_node
;
18629 affinity ( [aff-modifier :] variable-list )
18631 iterator ( iterators-definition ) */
18634 c_parser_omp_clause_affinity (c_parser
*parser
, tree list
)
18636 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18637 tree nl
, iterators
= NULL_TREE
;
18639 matching_parens parens
;
18640 if (!parens
.require_open (parser
))
18643 if (c_parser_next_token_is (parser
, CPP_NAME
))
18645 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18646 bool parse_iter
= ((strcmp ("iterator", p
) == 0)
18647 && (c_parser_peek_2nd_token (parser
)->type
18648 == CPP_OPEN_PAREN
));
18652 parse_iter
= (c_parser_check_balanced_raw_token_sequence (parser
, &n
)
18653 && (c_parser_peek_nth_token_raw (parser
, n
)->type
18654 == CPP_CLOSE_PAREN
)
18655 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
18660 iterators
= c_parser_omp_iterators (parser
);
18661 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18665 parens
.skip_until_found_close (parser
);
18670 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_AFFINITY
,
18674 tree block
= pop_scope ();
18675 if (iterators
!= error_mark_node
)
18677 TREE_VEC_ELT (iterators
, 5) = block
;
18678 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18679 OMP_CLAUSE_DECL (c
) = build_tree_list (iterators
,
18680 OMP_CLAUSE_DECL (c
));
18684 parens
.skip_until_found_close (parser
);
18690 depend ( depend-kind: variable-list )
18698 depend ( sink : vec )
18701 depend ( depend-modifier , depend-kind: variable-list )
18704 in | out | inout | mutexinoutset | depobj | inoutset
18707 iterator ( iterators-definition ) */
18710 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
18712 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18713 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_LAST
;
18714 enum omp_clause_doacross_kind dkind
= OMP_CLAUSE_DOACROSS_LAST
;
18715 tree nl
, c
, iterators
= NULL_TREE
;
18717 matching_parens parens
;
18718 if (!parens
.require_open (parser
))
18723 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
18726 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18727 if (strcmp ("iterator", p
) == 0 && iterators
== NULL_TREE
)
18729 iterators
= c_parser_omp_iterators (parser
);
18730 c_parser_require (parser
, CPP_COMMA
, "expected %<,%>");
18733 if (strcmp ("in", p
) == 0)
18734 kind
= OMP_CLAUSE_DEPEND_IN
;
18735 else if (strcmp ("inout", p
) == 0)
18736 kind
= OMP_CLAUSE_DEPEND_INOUT
;
18737 else if (strcmp ("inoutset", p
) == 0)
18738 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
18739 else if (strcmp ("mutexinoutset", p
) == 0)
18740 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
18741 else if (strcmp ("out", p
) == 0)
18742 kind
= OMP_CLAUSE_DEPEND_OUT
;
18743 else if (strcmp ("depobj", p
) == 0)
18744 kind
= OMP_CLAUSE_DEPEND_DEPOBJ
;
18745 else if (strcmp ("sink", p
) == 0)
18746 dkind
= OMP_CLAUSE_DOACROSS_SINK
;
18747 else if (strcmp ("source", p
) == 0)
18748 dkind
= OMP_CLAUSE_DOACROSS_SOURCE
;
18755 c_parser_consume_token (parser
);
18758 && (dkind
== OMP_CLAUSE_DOACROSS_SOURCE
18759 || dkind
== OMP_CLAUSE_DOACROSS_SINK
))
18762 error_at (clause_loc
, "%<iterator%> modifier incompatible with %qs",
18763 dkind
== OMP_CLAUSE_DOACROSS_SOURCE
? "source" : "sink");
18764 iterators
= NULL_TREE
;
18767 if (dkind
== OMP_CLAUSE_DOACROSS_SOURCE
)
18769 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
18770 OMP_CLAUSE_DOACROSS_KIND (c
) = dkind
;
18771 OMP_CLAUSE_DOACROSS_DEPEND (c
) = 1;
18772 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
18773 OMP_CLAUSE_CHAIN (c
) = list
;
18774 parens
.skip_until_found_close (parser
);
18778 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18781 if (dkind
== OMP_CLAUSE_DOACROSS_SINK
)
18782 nl
= c_parser_omp_clause_doacross_sink (parser
, clause_loc
, list
, true);
18785 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
18786 OMP_CLAUSE_DEPEND
, list
);
18790 tree block
= pop_scope ();
18791 if (iterators
== error_mark_node
)
18792 iterators
= NULL_TREE
;
18794 TREE_VEC_ELT (iterators
, 5) = block
;
18797 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18799 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
18801 OMP_CLAUSE_DECL (c
)
18802 = build_tree_list (iterators
, OMP_CLAUSE_DECL (c
));
18806 parens
.skip_until_found_close (parser
);
18810 c_parser_error (parser
, "invalid depend kind");
18812 parens
.skip_until_found_close (parser
);
18819 doacross ( source : )
18820 doacross ( source : omp_cur_iteration )
18822 doacross ( sink : vec )
18823 doacross ( sink : omp_cur_iteration - logical_iteration ) */
18826 c_parser_omp_clause_doacross (c_parser
*parser
, tree list
)
18828 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18829 enum omp_clause_doacross_kind kind
= OMP_CLAUSE_DOACROSS_LAST
;
18833 matching_parens parens
;
18834 if (!parens
.require_open (parser
))
18837 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
18840 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18841 if (strcmp ("sink", p
) == 0)
18842 kind
= OMP_CLAUSE_DOACROSS_SINK
;
18843 else if (strcmp ("source", p
) == 0)
18844 kind
= OMP_CLAUSE_DOACROSS_SOURCE
;
18848 c_parser_consume_token (parser
);
18850 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18853 if (kind
== OMP_CLAUSE_DOACROSS_SOURCE
)
18855 if (c_parser_next_token_is (parser
, CPP_NAME
)
18856 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
18857 "omp_cur_iteration") == 0)
18858 c_parser_consume_token (parser
);
18859 nl
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
18860 OMP_CLAUSE_DOACROSS_KIND (nl
) = OMP_CLAUSE_DOACROSS_SOURCE
;
18861 OMP_CLAUSE_DECL (nl
) = NULL_TREE
;
18862 OMP_CLAUSE_CHAIN (nl
) = list
;
18865 nl
= c_parser_omp_clause_doacross_sink (parser
, clause_loc
, list
, false);
18867 parens
.skip_until_found_close (parser
);
18871 c_parser_error (parser
, "invalid doacross kind");
18873 parens
.skip_until_found_close (parser
);
18878 map ( map-kind: variable-list )
18879 map ( variable-list )
18882 alloc | to | from | tofrom
18886 alloc | to | from | tofrom | release | delete
18888 map ( always [,] map-kind: variable-list )
18891 map ( [map-type-modifier[,] ...] map-kind: variable-list )
18897 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
18899 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18900 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
18903 matching_parens parens
;
18904 if (!parens
.require_open (parser
))
18908 int map_kind_pos
= 0;
18909 while (c_parser_peek_nth_token_raw (parser
, pos
)->type
== CPP_NAME
)
18911 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COLON
)
18913 map_kind_pos
= pos
;
18917 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COMMA
)
18922 int always_modifier
= 0;
18923 int close_modifier
= 0;
18924 int present_modifier
= 0;
18925 for (int pos
= 1; pos
< map_kind_pos
; ++pos
)
18927 c_token
*tok
= c_parser_peek_token (parser
);
18929 if (tok
->type
== CPP_COMMA
)
18931 c_parser_consume_token (parser
);
18935 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18936 if (strcmp ("always", p
) == 0)
18938 if (always_modifier
)
18940 c_parser_error (parser
, "too many %<always%> modifiers");
18941 parens
.skip_until_found_close (parser
);
18946 else if (strcmp ("close", p
) == 0)
18948 if (close_modifier
)
18950 c_parser_error (parser
, "too many %<close%> modifiers");
18951 parens
.skip_until_found_close (parser
);
18956 else if (strcmp ("present", p
) == 0)
18958 if (present_modifier
)
18960 c_parser_error (parser
, "too many %<present%> modifiers");
18961 parens
.skip_until_found_close (parser
);
18964 present_modifier
++;
18968 c_parser_error (parser
, "%<map%> clause with map-type modifier other "
18969 "than %<always%>, %<close%> or %<present%>");
18970 parens
.skip_until_found_close (parser
);
18974 c_parser_consume_token (parser
);
18977 if (c_parser_next_token_is (parser
, CPP_NAME
)
18978 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
18980 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18981 int always_present_modifier
= always_modifier
&& present_modifier
;
18983 if (strcmp ("alloc", p
) == 0)
18984 kind
= present_modifier
? GOMP_MAP_PRESENT_ALLOC
: GOMP_MAP_ALLOC
;
18985 else if (strcmp ("to", p
) == 0)
18986 kind
= (always_present_modifier
? GOMP_MAP_ALWAYS_PRESENT_TO
18987 : present_modifier
? GOMP_MAP_PRESENT_TO
18988 : always_modifier
? GOMP_MAP_ALWAYS_TO
18990 else if (strcmp ("from", p
) == 0)
18991 kind
= (always_present_modifier
? GOMP_MAP_ALWAYS_PRESENT_FROM
18992 : present_modifier
? GOMP_MAP_PRESENT_FROM
18993 : always_modifier
? GOMP_MAP_ALWAYS_FROM
18995 else if (strcmp ("tofrom", p
) == 0)
18996 kind
= (always_present_modifier
? GOMP_MAP_ALWAYS_PRESENT_TOFROM
18997 : present_modifier
? GOMP_MAP_PRESENT_TOFROM
18998 : always_modifier
? GOMP_MAP_ALWAYS_TOFROM
18999 : GOMP_MAP_TOFROM
);
19000 else if (strcmp ("release", p
) == 0)
19001 kind
= GOMP_MAP_RELEASE
;
19002 else if (strcmp ("delete", p
) == 0)
19003 kind
= GOMP_MAP_DELETE
;
19006 c_parser_error (parser
, "invalid map kind");
19007 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
19011 c_parser_consume_token (parser
);
19012 c_parser_consume_token (parser
);
19015 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
,
19018 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
19019 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
19021 parens
.skip_until_found_close (parser
);
19026 device ( expression )
19029 device ( [device-modifier :] integer-expression )
19032 ancestor | device_num */
19035 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
19037 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
19038 location_t expr_loc
;
19041 bool ancestor
= false;
19043 matching_parens parens
;
19044 if (!parens
.require_open (parser
))
19047 if (c_parser_next_token_is (parser
, CPP_NAME
)
19048 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
19050 c_token
*tok
= c_parser_peek_token (parser
);
19051 const char *p
= IDENTIFIER_POINTER (tok
->value
);
19052 if (strcmp ("ancestor", p
) == 0)
19054 /* A requires directive with the reverse_offload clause must be
19056 if ((omp_requires_mask
& OMP_REQUIRES_REVERSE_OFFLOAD
) == 0)
19058 error_at (tok
->location
, "%<ancestor%> device modifier not "
19059 "preceded by %<requires%> directive "
19060 "with %<reverse_offload%> clause");
19061 parens
.skip_until_found_close (parser
);
19066 else if (strcmp ("device_num", p
) == 0)
19070 error_at (tok
->location
, "expected %<ancestor%> or %<device_num%>");
19071 parens
.skip_until_found_close (parser
);
19074 c_parser_consume_token (parser
);
19075 c_parser_consume_token (parser
);
19078 expr_loc
= c_parser_peek_token (parser
)->location
;
19079 expr
= c_parser_expr_no_commas (parser
, NULL
);
19080 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
19082 t
= c_fully_fold (t
, false, NULL
);
19084 parens
.skip_until_found_close (parser
);
19086 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
19088 c_parser_error (parser
, "expected integer expression");
19091 if (ancestor
&& TREE_CODE (t
) == INTEGER_CST
&& !integer_onep (t
))
19093 error_at (expr_loc
, "the %<device%> clause expression must evaluate to "
19098 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
19100 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
19102 OMP_CLAUSE_DEVICE_ID (c
) = t
;
19103 OMP_CLAUSE_CHAIN (c
) = list
;
19104 OMP_CLAUSE_DEVICE_ANCESTOR (c
) = ancestor
;
19111 dist_schedule ( static )
19112 dist_schedule ( static , expression ) */
19115 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
19117 tree c
, t
= NULL_TREE
;
19118 location_t loc
= c_parser_peek_token (parser
)->location
;
19120 matching_parens parens
;
19121 if (!parens
.require_open (parser
))
19124 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
19126 c_parser_error (parser
, "invalid dist_schedule kind");
19127 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
19132 c_parser_consume_token (parser
);
19133 if (c_parser_next_token_is (parser
, CPP_COMMA
))
19135 c_parser_consume_token (parser
);
19137 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
19138 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
19139 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
19141 t
= c_fully_fold (t
, false, NULL
);
19142 parens
.skip_until_found_close (parser
);
19145 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
19146 "expected %<,%> or %<)%>");
19148 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
19149 "dist_schedule"); */
19150 if (omp_find_clause (list
, OMP_CLAUSE_DIST_SCHEDULE
))
19151 warning_at (loc
, OPT_Wopenmp
, "too many %qs clauses", "dist_schedule");
19152 if (t
== error_mark_node
)
19155 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
19156 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
19157 OMP_CLAUSE_CHAIN (c
) = list
;
19162 proc_bind ( proc-bind-kind )
19165 primary | master | close | spread
19166 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
19169 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
19171 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
19172 enum omp_clause_proc_bind_kind kind
;
19175 matching_parens parens
;
19176 if (!parens
.require_open (parser
))
19179 if (c_parser_next_token_is (parser
, CPP_NAME
))
19181 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19182 if (strcmp ("primary", p
) == 0)
19183 kind
= OMP_CLAUSE_PROC_BIND_PRIMARY
;
19184 else if (strcmp ("master", p
) == 0)
19185 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
19186 else if (strcmp ("close", p
) == 0)
19187 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
19188 else if (strcmp ("spread", p
) == 0)
19189 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
19196 check_no_duplicate_clause (list
, OMP_CLAUSE_PROC_BIND
, "proc_bind");
19197 c_parser_consume_token (parser
);
19198 parens
.skip_until_found_close (parser
);
19199 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
19200 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
19201 OMP_CLAUSE_CHAIN (c
) = list
;
19205 c_parser_error (parser
, "invalid proc_bind kind");
19206 parens
.skip_until_found_close (parser
);
19211 device_type ( host | nohost | any ) */
19214 c_parser_omp_clause_device_type (c_parser
*parser
, tree list
)
19216 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
19217 enum omp_clause_device_type_kind kind
;
19220 matching_parens parens
;
19221 if (!parens
.require_open (parser
))
19224 if (c_parser_next_token_is (parser
, CPP_NAME
))
19226 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19227 if (strcmp ("host", p
) == 0)
19228 kind
= OMP_CLAUSE_DEVICE_TYPE_HOST
;
19229 else if (strcmp ("nohost", p
) == 0)
19230 kind
= OMP_CLAUSE_DEVICE_TYPE_NOHOST
;
19231 else if (strcmp ("any", p
) == 0)
19232 kind
= OMP_CLAUSE_DEVICE_TYPE_ANY
;
19239 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE_TYPE
,
19241 c_parser_consume_token (parser
);
19242 parens
.skip_until_found_close (parser
);
19243 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE_TYPE
);
19244 OMP_CLAUSE_DEVICE_TYPE_KIND (c
) = kind
;
19245 OMP_CLAUSE_CHAIN (c
) = list
;
19249 c_parser_error (parser
, "expected %<host%>, %<nohost%> or %<any%>");
19250 parens
.skip_until_found_close (parser
);
19255 from ( variable-list )
19256 to ( variable-list )
19259 from ( [present :] variable-list )
19260 to ( [present :] variable-list ) */
19263 c_parser_omp_clause_from_to (c_parser
*parser
, enum omp_clause_code kind
,
19266 location_t loc
= c_parser_peek_token (parser
)->location
;
19267 matching_parens parens
;
19268 if (!parens
.require_open (parser
))
19271 bool present
= false;
19272 c_token
*token
= c_parser_peek_token (parser
);
19274 if (token
->type
== CPP_NAME
19275 && strcmp (IDENTIFIER_POINTER (token
->value
), "present") == 0
19276 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
19279 c_parser_consume_token (parser
);
19280 c_parser_consume_token (parser
);
19283 tree nl
= c_parser_omp_variable_list (parser
, loc
, kind
, list
);
19284 parens
.skip_until_found_close (parser
);
19287 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
19288 OMP_CLAUSE_MOTION_PRESENT (c
) = 1;
19294 uniform ( variable-list ) */
19297 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
19299 /* The clauses location. */
19300 location_t loc
= c_parser_peek_token (parser
)->location
;
19302 matching_parens parens
;
19303 if (parens
.require_open (parser
))
19305 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
19307 parens
.skip_until_found_close (parser
);
19316 c_parser_omp_clause_full (c_parser
*parser
, tree list
)
19318 check_no_duplicate_clause (list
, OMP_CLAUSE_FULL
, "full");
19320 location_t loc
= c_parser_peek_token (parser
)->location
;
19321 tree c
= build_omp_clause (loc
, OMP_CLAUSE_FULL
);
19322 OMP_CLAUSE_CHAIN (c
) = list
;
19327 partial ( constant-expression ) */
19330 c_parser_omp_clause_partial (c_parser
*parser
, tree list
)
19332 tree num
= NULL_TREE
;
19333 location_t loc
= c_parser_peek_token (parser
)->location
;
19335 check_no_duplicate_clause (list
, OMP_CLAUSE_PARTIAL
, "partial");
19337 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
19339 matching_parens parens
;
19340 parens
.consume_open (parser
);
19341 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
19342 parens
.skip_until_found_close (parser
);
19344 if (num
== error_mark_node
)
19347 mark_exp_read (num
);
19348 num
= c_fully_fold (num
, false, NULL
);
19350 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
19351 || !tree_fits_shwi_p (num
)
19352 || (n
= tree_to_shwi (num
)) <= 0
19355 error_at (loc
, "%<partial%> argument needs positive constant "
19356 "integer expression");
19361 tree c
= build_omp_clause (loc
, OMP_CLAUSE_PARTIAL
);
19362 OMP_CLAUSE_PARTIAL_EXPR (c
) = num
;
19363 OMP_CLAUSE_CHAIN (c
) = list
;
19368 detach ( event-handle ) */
19371 c_parser_omp_clause_detach (c_parser
*parser
, tree list
)
19373 matching_parens parens
;
19374 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
19376 if (!parens
.require_open (parser
))
19379 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
19380 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
19382 c_parser_error (parser
, "expected identifier");
19383 parens
.skip_until_found_close (parser
);
19387 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
19388 if (t
== NULL_TREE
)
19390 undeclared_variable (c_parser_peek_token (parser
)->location
,
19391 c_parser_peek_token (parser
)->value
);
19392 parens
.skip_until_found_close (parser
);
19395 c_parser_consume_token (parser
);
19397 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (t
));
19398 if (!INTEGRAL_TYPE_P (type
)
19399 || TREE_CODE (type
) != ENUMERAL_TYPE
19400 || TYPE_NAME (type
) != get_identifier ("omp_event_handle_t"))
19402 error_at (clause_loc
, "%<detach%> clause event handle "
19403 "has type %qT rather than "
19404 "%<omp_event_handle_t%>",
19406 parens
.skip_until_found_close (parser
);
19410 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DETACH
);
19411 OMP_CLAUSE_DECL (u
) = t
;
19412 OMP_CLAUSE_CHAIN (u
) = list
;
19413 parens
.skip_until_found_close (parser
);
19417 /* Parse all OpenACC clauses. The set clauses allowed by the directive
19418 is a bitmask in MASK. Return the list of clauses found. */
19421 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
19422 const char *where
, bool finish_p
= true,
19423 bool target_p
= false)
19425 tree clauses
= NULL
;
19428 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19431 pragma_omp_clause c_kind
;
19432 const char *c_name
;
19433 tree prev
= clauses
;
19435 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
19436 c_parser_consume_token (parser
);
19438 here
= c_parser_peek_token (parser
)->location
;
19439 c_kind
= c_parser_omp_clause_name (parser
);
19443 case PRAGMA_OACC_CLAUSE_ASYNC
:
19444 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
19447 case PRAGMA_OACC_CLAUSE_AUTO
:
19448 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_AUTO
,
19452 case PRAGMA_OACC_CLAUSE_ATTACH
:
19453 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19456 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
19457 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
19458 c_name
= "collapse";
19460 case PRAGMA_OACC_CLAUSE_COPY
:
19461 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19464 case PRAGMA_OACC_CLAUSE_COPYIN
:
19465 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19468 case PRAGMA_OACC_CLAUSE_COPYOUT
:
19469 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19470 c_name
= "copyout";
19472 case PRAGMA_OACC_CLAUSE_CREATE
:
19473 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19476 case PRAGMA_OACC_CLAUSE_DELETE
:
19477 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19480 case PRAGMA_OMP_CLAUSE_DEFAULT
:
19481 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
19482 c_name
= "default";
19484 case PRAGMA_OACC_CLAUSE_DETACH
:
19485 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19488 case PRAGMA_OACC_CLAUSE_DEVICE
:
19489 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19492 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
19493 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
19494 c_name
= "deviceptr";
19496 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
19497 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19498 c_name
= "device_resident";
19500 case PRAGMA_OACC_CLAUSE_FINALIZE
:
19501 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_FINALIZE
,
19503 c_name
= "finalize";
19505 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
19506 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
19507 c_name
= "firstprivate";
19509 case PRAGMA_OACC_CLAUSE_GANG
:
19511 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_GANG
,
19514 case PRAGMA_OACC_CLAUSE_HOST
:
19515 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19518 case PRAGMA_OACC_CLAUSE_IF
:
19519 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
19522 case PRAGMA_OACC_CLAUSE_IF_PRESENT
:
19523 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_IF_PRESENT
,
19525 c_name
= "if_present";
19527 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
19528 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_INDEPENDENT
,
19530 c_name
= "independent";
19532 case PRAGMA_OACC_CLAUSE_LINK
:
19533 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19536 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
19537 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19538 c_name
= "no_create";
19540 case PRAGMA_OACC_CLAUSE_NOHOST
:
19541 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_NOHOST
,
19545 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
19546 clauses
= c_parser_oacc_single_int_clause (parser
,
19547 OMP_CLAUSE_NUM_GANGS
,
19549 c_name
= "num_gangs";
19551 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
19552 clauses
= c_parser_oacc_single_int_clause (parser
,
19553 OMP_CLAUSE_NUM_WORKERS
,
19555 c_name
= "num_workers";
19557 case PRAGMA_OACC_CLAUSE_PRESENT
:
19558 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19559 c_name
= "present";
19561 case PRAGMA_OACC_CLAUSE_PRIVATE
:
19562 clauses
= c_parser_omp_clause_private (parser
, clauses
);
19563 c_name
= "private";
19565 case PRAGMA_OACC_CLAUSE_REDUCTION
:
19567 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
19569 c_name
= "reduction";
19571 case PRAGMA_OACC_CLAUSE_SELF
:
19572 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OACC_CLAUSE_HOST
)) == 0)
19573 /* OpenACC compute construct */
19574 clauses
= c_parser_oacc_compute_clause_self (parser
, clauses
);
19576 /* OpenACC 'update' directive */
19577 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19580 case PRAGMA_OACC_CLAUSE_SEQ
:
19581 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_SEQ
,
19585 case PRAGMA_OACC_CLAUSE_TILE
:
19586 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
19589 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
19590 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
19591 c_name
= "use_device";
19593 case PRAGMA_OACC_CLAUSE_VECTOR
:
19595 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_VECTOR
,
19598 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
19599 clauses
= c_parser_oacc_single_int_clause (parser
,
19600 OMP_CLAUSE_VECTOR_LENGTH
,
19602 c_name
= "vector_length";
19604 case PRAGMA_OACC_CLAUSE_WAIT
:
19605 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
19608 case PRAGMA_OACC_CLAUSE_WORKER
:
19610 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_WORKER
,
19614 c_parser_error (parser
, "expected an OpenACC clause");
19620 if (((mask
>> c_kind
) & 1) == 0)
19622 /* Remove the invalid clause(s) from the list to avoid
19623 confusing the rest of the compiler. */
19625 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
19630 c_parser_skip_to_pragma_eol (parser
);
19633 return c_finish_omp_clauses (clauses
, target_p
? C_ORT_ACC_TARGET
19639 /* Parse all OpenMP clauses. The set clauses allowed by the directive
19640 is a bitmask in MASK. Return the list of clauses found.
19641 FINISH_P set if c_finish_omp_clauses should be called.
19642 NESTED non-zero if clauses should be terminated by closing paren instead
19643 of end of pragma. If it is 2, additionally commas are required in between
19647 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
19648 const char *where
, bool finish_p
= true,
19651 tree clauses
= NULL
;
19654 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19657 pragma_omp_clause c_kind
;
19658 const char *c_name
;
19659 tree prev
= clauses
;
19661 if (nested
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
19664 if (!first
|| nested
!= 2)
19666 if (c_parser_next_token_is (parser
, CPP_COMMA
))
19667 c_parser_consume_token (parser
);
19668 else if (nested
== 2)
19669 error_at (c_parser_peek_token (parser
)->location
,
19670 "clauses in %<simd%> trait should be separated "
19674 here
= c_parser_peek_token (parser
)->location
;
19675 c_kind
= c_parser_omp_clause_name (parser
);
19679 case PRAGMA_OMP_CLAUSE_BIND
:
19680 clauses
= c_parser_omp_clause_bind (parser
, clauses
);
19683 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
19684 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
19685 c_name
= "collapse";
19687 case PRAGMA_OMP_CLAUSE_COPYIN
:
19688 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
19691 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
19692 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
19693 c_name
= "copyprivate";
19695 case PRAGMA_OMP_CLAUSE_DEFAULT
:
19696 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
19697 c_name
= "default";
19699 case PRAGMA_OMP_CLAUSE_DETACH
:
19700 clauses
= c_parser_omp_clause_detach (parser
, clauses
);
19703 case PRAGMA_OMP_CLAUSE_FILTER
:
19704 clauses
= c_parser_omp_clause_filter (parser
, clauses
);
19707 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
19708 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
19709 c_name
= "firstprivate";
19711 case PRAGMA_OMP_CLAUSE_FINAL
:
19712 clauses
= c_parser_omp_clause_final (parser
, clauses
);
19715 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
19716 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
19717 c_name
= "grainsize";
19719 case PRAGMA_OMP_CLAUSE_HINT
:
19720 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
19723 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
19724 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
19725 c_name
= "defaultmap";
19727 case PRAGMA_OMP_CLAUSE_IF
:
19728 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
19731 case PRAGMA_OMP_CLAUSE_IN_REDUCTION
:
19733 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_IN_REDUCTION
,
19735 c_name
= "in_reduction";
19737 case PRAGMA_OMP_CLAUSE_INDIRECT
:
19738 clauses
= c_parser_omp_clause_indirect (parser
, clauses
);
19739 c_name
= "indirect";
19741 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
19742 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
19743 c_name
= "lastprivate";
19745 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
19746 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
19747 c_name
= "mergeable";
19749 case PRAGMA_OMP_CLAUSE_NOWAIT
:
19750 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
19753 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
19754 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
19755 c_name
= "num_tasks";
19757 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
19758 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
19759 c_name
= "num_threads";
19761 case PRAGMA_OMP_CLAUSE_ORDER
:
19762 clauses
= c_parser_omp_clause_order (parser
, clauses
);
19765 case PRAGMA_OMP_CLAUSE_ORDERED
:
19766 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
19767 c_name
= "ordered";
19769 case PRAGMA_OMP_CLAUSE_PRIORITY
:
19770 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
19771 c_name
= "priority";
19773 case PRAGMA_OMP_CLAUSE_PRIVATE
:
19774 clauses
= c_parser_omp_clause_private (parser
, clauses
);
19775 c_name
= "private";
19777 case PRAGMA_OMP_CLAUSE_REDUCTION
:
19779 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
19781 c_name
= "reduction";
19783 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
19784 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
19785 c_name
= "schedule";
19787 case PRAGMA_OMP_CLAUSE_SHARED
:
19788 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
19791 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION
:
19793 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_TASK_REDUCTION
,
19795 c_name
= "task_reduction";
19797 case PRAGMA_OMP_CLAUSE_UNTIED
:
19798 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
19801 case PRAGMA_OMP_CLAUSE_INBRANCH
:
19802 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
19804 c_name
= "inbranch";
19806 case PRAGMA_OMP_CLAUSE_NONTEMPORAL
:
19807 clauses
= c_parser_omp_clause_nontemporal (parser
, clauses
);
19808 c_name
= "nontemporal";
19810 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
19811 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
19813 c_name
= "notinbranch";
19815 case PRAGMA_OMP_CLAUSE_PARALLEL
:
19817 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
19819 c_name
= "parallel";
19823 error_at (here
, "%qs must be the first clause of %qs",
19828 case PRAGMA_OMP_CLAUSE_FOR
:
19830 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
19834 goto clause_not_first
;
19836 case PRAGMA_OMP_CLAUSE_SECTIONS
:
19838 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
19840 c_name
= "sections";
19842 goto clause_not_first
;
19844 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
19846 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
19848 c_name
= "taskgroup";
19850 goto clause_not_first
;
19852 case PRAGMA_OMP_CLAUSE_LINK
:
19854 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
19857 case PRAGMA_OMP_CLAUSE_TO
:
19858 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
19860 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
19862 for (tree c
= nl
; c
!= clauses
; c
= OMP_CLAUSE_CHAIN (c
))
19863 OMP_CLAUSE_ENTER_TO (c
) = 1;
19867 clauses
= c_parser_omp_clause_from_to (parser
, OMP_CLAUSE_TO
,
19871 case PRAGMA_OMP_CLAUSE_FROM
:
19872 clauses
= c_parser_omp_clause_from_to (parser
, OMP_CLAUSE_FROM
,
19876 case PRAGMA_OMP_CLAUSE_UNIFORM
:
19877 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
19878 c_name
= "uniform";
19880 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
19881 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
19882 c_name
= "num_teams";
19884 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
19885 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
19886 c_name
= "thread_limit";
19888 case PRAGMA_OMP_CLAUSE_ALIGNED
:
19889 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
19890 c_name
= "aligned";
19892 case PRAGMA_OMP_CLAUSE_ALLOCATE
:
19893 clauses
= c_parser_omp_clause_allocate (parser
, clauses
);
19894 c_name
= "allocate";
19896 case PRAGMA_OMP_CLAUSE_LINEAR
:
19897 clauses
= c_parser_omp_clause_linear (parser
, clauses
);
19900 case PRAGMA_OMP_CLAUSE_AFFINITY
:
19901 clauses
= c_parser_omp_clause_affinity (parser
, clauses
);
19902 c_name
= "affinity";
19904 case PRAGMA_OMP_CLAUSE_DEPEND
:
19905 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
19908 case PRAGMA_OMP_CLAUSE_DOACROSS
:
19909 clauses
= c_parser_omp_clause_doacross (parser
, clauses
);
19910 c_name
= "doacross";
19912 case PRAGMA_OMP_CLAUSE_MAP
:
19913 clauses
= c_parser_omp_clause_map (parser
, clauses
);
19916 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
19917 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
19918 c_name
= "use_device_ptr";
19920 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
:
19921 clauses
= c_parser_omp_clause_use_device_addr (parser
, clauses
);
19922 c_name
= "use_device_addr";
19924 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
:
19925 clauses
= c_parser_omp_clause_has_device_addr (parser
, clauses
);
19926 c_name
= "has_device_addr";
19928 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
19929 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
19930 c_name
= "is_device_ptr";
19932 case PRAGMA_OMP_CLAUSE_DEVICE
:
19933 clauses
= c_parser_omp_clause_device (parser
, clauses
);
19936 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
19937 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
19938 c_name
= "dist_schedule";
19940 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
19941 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
19942 c_name
= "proc_bind";
19944 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE
:
19945 clauses
= c_parser_omp_clause_device_type (parser
, clauses
);
19946 c_name
= "device_type";
19948 case PRAGMA_OMP_CLAUSE_SAFELEN
:
19949 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
19950 c_name
= "safelen";
19952 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
19953 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
19954 c_name
= "simdlen";
19956 case PRAGMA_OMP_CLAUSE_NOGROUP
:
19957 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
19958 c_name
= "nogroup";
19960 case PRAGMA_OMP_CLAUSE_THREADS
:
19962 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
19964 c_name
= "threads";
19966 case PRAGMA_OMP_CLAUSE_SIMD
:
19968 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
19972 case PRAGMA_OMP_CLAUSE_ENTER
:
19974 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
19978 case PRAGMA_OMP_CLAUSE_FULL
:
19980 clauses
= c_parser_omp_clause_full (parser
, clauses
);
19982 case PRAGMA_OMP_CLAUSE_PARTIAL
:
19983 c_name
= "partial";
19984 clauses
= c_parser_omp_clause_partial (parser
, clauses
);
19987 c_parser_error (parser
, "expected an OpenMP clause");
19993 if (((mask
>> c_kind
) & 1) == 0)
19995 /* Remove the invalid clause(s) from the list to avoid
19996 confusing the rest of the compiler. */
19998 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
20004 c_parser_skip_to_pragma_eol (parser
);
20008 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
20009 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
20010 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
20016 /* OpenACC 2.0, OpenMP 2.5:
20020 In practice, we're also interested in adding the statement to an
20021 outer node. So it is convenient if we work around the fact that
20022 c_parser_statement calls add_stmt. */
20025 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
20027 tree stmt
= push_stmt_list ();
20028 parser
->omp_attrs_forbidden_p
= true;
20029 c_parser_statement (parser
, if_p
);
20030 return pop_stmt_list (stmt
);
20034 # pragma acc cache (variable-list) new-line
20037 # pragma acc cache (readonly: variable-list) new-line
20039 LOC is the location of the #pragma token.
20043 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
20045 tree stmt
, clauses
= NULL_TREE
;
20046 bool readonly
= false;
20047 location_t open_loc
= c_parser_peek_token (parser
)->location
;
20048 matching_parens parens
;
20049 if (parens
.require_open (parser
))
20051 c_token
*token
= c_parser_peek_token (parser
);
20052 if (token
->type
== CPP_NAME
20053 && !strcmp (IDENTIFIER_POINTER (token
->value
), "readonly")
20054 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
20056 c_parser_consume_token (parser
);
20057 c_parser_consume_token (parser
);
20060 clauses
= c_parser_omp_variable_list (parser
, open_loc
,
20061 OMP_CLAUSE__CACHE_
, NULL_TREE
);
20062 parens
.skip_until_found_close (parser
);
20066 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
20067 OMP_CLAUSE__CACHE__READONLY (c
) = 1;
20069 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
20071 c_parser_skip_to_pragma_eol (parser
);
20073 stmt
= make_node (OACC_CACHE
);
20074 TREE_TYPE (stmt
) = void_type_node
;
20075 OACC_CACHE_CLAUSES (stmt
) = clauses
;
20076 SET_EXPR_LOCATION (stmt
, loc
);
20083 # pragma acc data oacc-data-clause[optseq] new-line
20086 LOC is the location of the #pragma token.
20089 #define OACC_DATA_CLAUSE_MASK \
20090 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20091 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20092 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20093 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20094 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20095 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20096 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20097 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20098 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20099 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
20102 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
20104 tree stmt
, clauses
, block
;
20106 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
20107 "#pragma acc data");
20109 block
= c_begin_omp_parallel ();
20110 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
20112 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
20118 # pragma acc declare oacc-data-clause[optseq] new-line
20121 #define OACC_DECLARE_CLAUSE_MASK \
20122 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20123 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20124 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20125 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20126 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20127 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
20128 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
20129 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
20132 c_parser_oacc_declare (c_parser
*parser
)
20134 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
20135 tree clauses
, stmt
, t
, decl
;
20137 bool error
= false;
20139 c_parser_consume_pragma (parser
);
20141 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
20142 "#pragma acc declare");
20145 error_at (pragma_loc
,
20146 "no valid clauses specified in %<#pragma acc declare%>");
20150 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
20152 location_t loc
= OMP_CLAUSE_LOCATION (t
);
20153 decl
= OMP_CLAUSE_DECL (t
);
20154 if (!DECL_P (decl
))
20156 error_at (loc
, "array section in %<#pragma acc declare%>");
20161 switch (OMP_CLAUSE_MAP_KIND (t
))
20163 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
20164 case GOMP_MAP_ALLOC
:
20166 case GOMP_MAP_FORCE_DEVICEPTR
:
20167 case GOMP_MAP_DEVICE_RESIDENT
:
20170 case GOMP_MAP_LINK
:
20171 if (!global_bindings_p ()
20172 && (TREE_STATIC (decl
)
20173 || !DECL_EXTERNAL (decl
)))
20176 "%qD must be a global variable in "
20177 "%<#pragma acc declare link%>",
20185 if (global_bindings_p ())
20187 error_at (loc
, "invalid OpenACC clause at file scope");
20191 if (DECL_EXTERNAL (decl
))
20194 "invalid use of %<extern%> variable %qD "
20195 "in %<#pragma acc declare%>", decl
);
20199 else if (TREE_PUBLIC (decl
))
20202 "invalid use of %<global%> variable %qD "
20203 "in %<#pragma acc declare%>", decl
);
20210 if (!c_check_in_current_scope (decl
))
20213 "%qD must be a variable declared in the same scope as "
20214 "%<#pragma acc declare%>", decl
);
20219 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
20220 || lookup_attribute ("omp declare target link",
20221 DECL_ATTRIBUTES (decl
)))
20223 error_at (loc
, "variable %qD used more than once with "
20224 "%<#pragma acc declare%>", decl
);
20233 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
20234 id
= get_identifier ("omp declare target link");
20236 id
= get_identifier ("omp declare target");
20238 DECL_ATTRIBUTES (decl
)
20239 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
20241 if (global_bindings_p ())
20243 symtab_node
*node
= symtab_node::get (decl
);
20246 node
->offloadable
= 1;
20247 if (ENABLE_OFFLOADING
)
20249 g
->have_offload
= true;
20250 if (is_a
<varpool_node
*> (node
))
20251 vec_safe_push (offload_vars
, decl
);
20258 if (error
|| global_bindings_p ())
20261 stmt
= make_node (OACC_DECLARE
);
20262 TREE_TYPE (stmt
) = void_type_node
;
20263 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
20264 SET_EXPR_LOCATION (stmt
, pragma_loc
);
20272 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
20276 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
20279 LOC is the location of the #pragma token.
20282 #define OACC_ENTER_DATA_CLAUSE_MASK \
20283 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20284 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20285 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20286 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20287 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20288 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20290 #define OACC_EXIT_DATA_CLAUSE_MASK \
20291 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20292 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20293 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20294 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
20295 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
20296 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
20297 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20300 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
20302 location_t loc
= c_parser_peek_token (parser
)->location
;
20303 tree clauses
, stmt
;
20304 const char *p
= "";
20306 c_parser_consume_pragma (parser
);
20308 if (c_parser_next_token_is (parser
, CPP_NAME
))
20310 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20311 c_parser_consume_token (parser
);
20314 if (strcmp (p
, "data") != 0)
20316 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
20317 enter
? "enter" : "exit");
20318 parser
->error
= true;
20319 c_parser_skip_to_pragma_eol (parser
);
20324 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
20325 "#pragma acc enter data");
20327 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
20328 "#pragma acc exit data");
20330 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
20332 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
20333 enter
? "enter" : "exit");
20337 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
20338 TREE_TYPE (stmt
) = void_type_node
;
20339 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
20340 SET_EXPR_LOCATION (stmt
, loc
);
20346 # pragma acc host_data oacc-data-clause[optseq] new-line
20350 #define OACC_HOST_DATA_CLAUSE_MASK \
20351 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
20352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
20356 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
20358 tree stmt
, clauses
, block
;
20360 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
20361 "#pragma acc host_data", false);
20362 if (!omp_find_clause (clauses
, OMP_CLAUSE_USE_DEVICE_PTR
))
20364 error_at (loc
, "%<host_data%> construct requires %<use_device%> clause");
20365 return error_mark_node
;
20367 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
20368 block
= c_begin_omp_parallel ();
20369 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
20370 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
20377 # pragma acc loop oacc-loop-clause[optseq] new-line
20380 LOC is the location of the #pragma token.
20383 #define OACC_LOOP_CLAUSE_MASK \
20384 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
20385 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20386 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20387 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
20388 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
20389 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
20390 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
20391 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
20392 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
20393 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
20395 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
20396 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
20398 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
20400 strcat (p_name
, " loop");
20401 mask
|= OACC_LOOP_CLAUSE_MASK
;
20403 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
20404 /*finish_p=*/cclauses
== NULL
,
20405 /*target=*/is_parallel
);
20408 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
20410 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC_TARGET
);
20412 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
20415 tree block
= c_begin_compound_stmt (true);
20416 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
20418 block
= c_end_compound_stmt (loc
, block
, true);
20425 # pragma acc kernels oacc-kernels-clause[optseq] new-line
20430 # pragma acc parallel oacc-parallel-clause[optseq] new-line
20435 # pragma acc serial oacc-serial-clause[optseq] new-line
20438 LOC is the location of the #pragma token.
20441 #define OACC_KERNELS_CLAUSE_MASK \
20442 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20443 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20444 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20445 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20446 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20447 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20448 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20449 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20450 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20451 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20452 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
20453 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
20454 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20455 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20456 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
20457 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20459 #define OACC_PARALLEL_CLAUSE_MASK \
20460 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20461 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20462 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20463 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20464 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20465 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20466 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20467 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20468 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20469 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20470 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20471 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
20472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
20473 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
20474 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20475 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20476 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20477 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
20478 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20480 #define OACC_SERIAL_CLAUSE_MASK \
20481 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20484 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20485 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20486 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20487 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20488 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20489 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20490 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20491 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20492 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
20493 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20494 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20495 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20499 c_parser_oacc_compute (location_t loc
, c_parser
*parser
,
20500 enum pragma_kind p_kind
, char *p_name
, bool *if_p
)
20502 omp_clause_mask mask
;
20503 enum tree_code code
;
20506 case PRAGMA_OACC_KERNELS
:
20507 strcat (p_name
, " kernels");
20508 mask
= OACC_KERNELS_CLAUSE_MASK
;
20509 code
= OACC_KERNELS
;
20511 case PRAGMA_OACC_PARALLEL
:
20512 strcat (p_name
, " parallel");
20513 mask
= OACC_PARALLEL_CLAUSE_MASK
;
20514 code
= OACC_PARALLEL
;
20516 case PRAGMA_OACC_SERIAL
:
20517 strcat (p_name
, " serial");
20518 mask
= OACC_SERIAL_CLAUSE_MASK
;
20519 code
= OACC_SERIAL
;
20522 gcc_unreachable ();
20525 if (c_parser_next_token_is (parser
, CPP_NAME
))
20527 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20528 if (strcmp (p
, "loop") == 0)
20530 c_parser_consume_token (parser
);
20531 tree block
= c_begin_omp_parallel ();
20533 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
20534 return c_finish_omp_construct (loc
, code
, block
, clauses
);
20538 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
20542 tree block
= c_begin_omp_parallel ();
20543 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
20545 return c_finish_omp_construct (loc
, code
, block
, clauses
);
20549 # pragma acc routine oacc-routine-clause[optseq] new-line
20550 function-definition
20552 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
20555 #define OACC_ROUTINE_CLAUSE_MASK \
20556 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
20557 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
20558 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
20559 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
20560 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
20562 /* Parse an OpenACC routine directive. For named directives, we apply
20563 immediately to the named function. For unnamed ones we then parse
20564 a declaration or definition, which must be for a function. */
20567 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
20569 gcc_checking_assert (context
== pragma_external
);
20571 oacc_routine_data data
;
20572 data
.error_seen
= false;
20573 data
.fndecl_seen
= false;
20574 data
.loc
= c_parser_peek_token (parser
)->location
;
20576 c_parser_consume_pragma (parser
);
20578 /* Look for optional '( name )'. */
20579 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
20581 c_parser_consume_token (parser
); /* '(' */
20583 tree decl
= NULL_TREE
;
20584 c_token
*name_token
= c_parser_peek_token (parser
);
20585 location_t name_loc
= name_token
->location
;
20586 if (name_token
->type
== CPP_NAME
20587 && (name_token
->id_kind
== C_ID_ID
20588 || name_token
->id_kind
== C_ID_TYPENAME
))
20590 decl
= lookup_name (name_token
->value
);
20592 error_at (name_loc
,
20593 "%qE has not been declared", name_token
->value
);
20594 c_parser_consume_token (parser
);
20597 c_parser_error (parser
, "expected function name");
20600 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
20602 c_parser_skip_to_pragma_eol (parser
, false);
20607 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
20608 "#pragma acc routine");
20609 /* The clauses are in reverse order; fix that to make later diagnostic
20610 emission easier. */
20611 data
.clauses
= nreverse (data
.clauses
);
20613 if (TREE_CODE (decl
) != FUNCTION_DECL
)
20615 error_at (name_loc
, "%qD does not refer to a function", decl
);
20619 c_finish_oacc_routine (&data
, decl
, false);
20621 else /* No optional '( name )'. */
20624 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
20625 "#pragma acc routine");
20626 /* The clauses are in reverse order; fix that to make later diagnostic
20627 emission easier. */
20628 data
.clauses
= nreverse (data
.clauses
);
20630 /* Emit a helpful diagnostic if there's another pragma following this
20631 one. Also don't allow a static assertion declaration, as in the
20632 following we'll just parse a *single* "declaration or function
20633 definition", and the static assertion counts an one. */
20634 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
20635 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
20637 error_at (data
.loc
,
20638 "%<#pragma acc routine%> not immediately followed by"
20639 " function declaration or definition");
20640 /* ..., and then just keep going. */
20644 /* We only have to consider the pragma_external case here. */
20645 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20646 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
20648 int ext
= disable_extension_diagnostics ();
20650 c_parser_consume_token (parser
);
20651 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20652 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
20653 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
20654 NULL
, NULL
, false, NULL
, &data
);
20655 restore_extension_diagnostics (ext
);
20658 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
20659 NULL
, NULL
, false, NULL
, &data
);
20663 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
20664 IS_DEFN is true if we're applying it to the definition. */
20667 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
20670 /* Keep going if we're in error reporting mode. */
20671 if (data
->error_seen
20672 || fndecl
== error_mark_node
)
20675 if (data
->fndecl_seen
)
20677 error_at (data
->loc
,
20678 "%<#pragma acc routine%> not immediately followed by"
20679 " a single function declaration or definition");
20680 data
->error_seen
= true;
20683 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
20685 error_at (data
->loc
,
20686 "%<#pragma acc routine%> not immediately followed by"
20687 " function declaration or definition");
20688 data
->error_seen
= true;
20693 = oacc_verify_routine_clauses (fndecl
, &data
->clauses
, data
->loc
,
20694 "#pragma acc routine");
20695 if (compatible
< 0)
20697 data
->error_seen
= true;
20700 if (compatible
> 0)
20705 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
20707 error_at (data
->loc
,
20709 ? G_("%<#pragma acc routine%> must be applied before use")
20710 : G_("%<#pragma acc routine%> must be applied before"
20712 data
->error_seen
= true;
20716 /* Set the routine's level of parallelism. */
20717 tree dims
= oacc_build_routine_dims (data
->clauses
);
20718 oacc_replace_fn_attrib (fndecl
, dims
);
20720 /* Add an "omp declare target" attribute. */
20721 DECL_ATTRIBUTES (fndecl
)
20722 = tree_cons (get_identifier ("omp declare target"),
20723 data
->clauses
, DECL_ATTRIBUTES (fndecl
));
20726 /* Remember that we've used this "#pragma acc routine". */
20727 data
->fndecl_seen
= true;
20731 # pragma acc update oacc-update-clause[optseq] new-line
20734 #define OACC_UPDATE_CLAUSE_MASK \
20735 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
20737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
20738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
20740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20744 c_parser_oacc_update (c_parser
*parser
)
20746 location_t loc
= c_parser_peek_token (parser
)->location
;
20748 c_parser_consume_pragma (parser
);
20750 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
20751 "#pragma acc update");
20752 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
20755 "%<#pragma acc update%> must contain at least one "
20756 "%<device%> or %<host%> or %<self%> clause");
20763 tree stmt
= make_node (OACC_UPDATE
);
20764 TREE_TYPE (stmt
) = void_type_node
;
20765 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
20766 SET_EXPR_LOCATION (stmt
, loc
);
20771 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
20773 LOC is the location of the #pragma token.
20776 #define OACC_WAIT_CLAUSE_MASK \
20777 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
20780 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
20782 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
20784 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
20785 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
20787 strcpy (p_name
, " wait");
20788 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
20789 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
20795 struct c_omp_loc_tree
20801 /* Check whether the expression used in the allocator clause is declared or
20802 modified between the variable declaration and its allocate directive. */
20804 c_check_omp_allocate_allocator_r (tree
*tp
, int *, void *data
)
20806 tree var
= ((struct c_omp_loc_tree
*) data
)->var
;
20807 location_t loc
= ((struct c_omp_loc_tree
*) data
)->loc
;
20808 if (TREE_CODE (*tp
) == VAR_DECL
&& c_check_in_current_scope (*tp
))
20810 if (linemap_location_before_p (line_table
, DECL_SOURCE_LOCATION (var
),
20811 DECL_SOURCE_LOCATION (*tp
)))
20813 error_at (loc
, "variable %qD used in the %<allocator%> clause must "
20814 "be declared before %qD", *tp
, var
);
20815 inform (DECL_SOURCE_LOCATION (*tp
), "declared here");
20816 inform (DECL_SOURCE_LOCATION (var
),
20817 "to be allocated variable declared here");
20822 gcc_assert (cur_stmt_list
20823 && TREE_CODE (cur_stmt_list
) == STATEMENT_LIST
);
20825 tree_stmt_iterator l
= tsi_last (cur_stmt_list
);
20826 while (!tsi_end_p (l
))
20828 if (linemap_location_before_p (line_table
, EXPR_LOCATION (*l
),
20829 DECL_SOURCE_LOCATION (var
)))
20831 if (TREE_CODE (*l
) == MODIFY_EXPR
20832 && TREE_OPERAND (*l
, 0) == *tp
)
20835 "variable %qD used in the %<allocator%> clause "
20836 "must not be modified between declaration of %qD "
20837 "and its %<allocate%> directive", *tp
, var
);
20838 inform (EXPR_LOCATION (*l
), "modified here");
20839 inform (DECL_SOURCE_LOCATION (var
),
20840 "to be allocated variable declared here");
20851 # pragma omp allocate (list) clauses
20854 allocator (omp_allocator_handle_t expression)
20856 OpenMP 5.1 additional clause:
20857 align (constant-expression)] */
20860 c_parser_omp_allocate (c_parser
*parser
)
20862 tree alignment
= NULL_TREE
;
20863 tree allocator
= NULL_TREE
;
20864 c_parser_consume_pragma (parser
);
20865 location_t loc
= c_parser_peek_token (parser
)->location
;
20866 location_t allocator_loc
= UNKNOWN_LOCATION
;
20867 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ALLOCATE
, NULL_TREE
);
20870 if (c_parser_next_token_is (parser
, CPP_COMMA
)
20871 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
20872 c_parser_consume_token (parser
);
20873 if (!c_parser_next_token_is (parser
, CPP_NAME
))
20875 matching_parens parens
;
20876 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20877 c_parser_consume_token (parser
);
20878 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
20879 if (strcmp ("align", p
) != 0 && strcmp ("allocator", p
) != 0)
20881 error_at (c_parser_peek_token (parser
)->location
,
20882 "expected %<allocator%> or %<align%>");
20885 if (!parens
.require_open (parser
))
20888 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
20889 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
20890 expr_loc
= c_parser_peek_token (parser
)->location
;
20891 if (expr
.value
== error_mark_node
)
20893 else if (p
[2] == 'i' && alignment
)
20895 error_at (expr_loc
, "too many %qs clauses", "align");
20898 else if (p
[2] == 'i')
20900 alignment
= c_fully_fold (expr
.value
, false, NULL
);
20901 if (TREE_CODE (alignment
) != INTEGER_CST
20902 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
20903 || tree_int_cst_sgn (alignment
) != 1
20904 || !integer_pow2p (alignment
))
20906 error_at (expr_loc
, "%<align%> clause argument needs to be "
20907 "positive constant power of two integer "
20909 alignment
= NULL_TREE
;
20912 else if (allocator
)
20914 error_at (expr_loc
, "too many %qs clauses", "allocator");
20919 allocator
= c_fully_fold (expr
.value
, false, NULL
);
20920 allocator_loc
= expr_loc
;
20922 = expr
.original_type
? expr
.original_type
: TREE_TYPE (allocator
);
20923 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
20924 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
20925 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
20926 || TYPE_NAME (orig_type
)
20927 != get_identifier ("omp_allocator_handle_t"))
20929 error_at (expr_loc
,
20930 "%<allocator%> clause allocator expression has type "
20931 "%qT rather than %<omp_allocator_handle_t%>",
20932 TREE_TYPE (allocator
));
20933 allocator
= NULL_TREE
;
20936 parens
.skip_until_found_close (parser
);
20938 c_parser_skip_to_pragma_eol (parser
);
20940 c_mark_decl_jump_unsafe_in_current_scope ();
20941 for (tree c
= nl
; c
!= NULL_TREE
; c
= OMP_CLAUSE_CHAIN (c
))
20943 tree var
= OMP_CLAUSE_DECL (c
);
20944 if (TREE_CODE (var
) == PARM_DECL
)
20946 error_at (OMP_CLAUSE_LOCATION (nl
),
20947 "function parameter %qD may not appear as list item in an "
20948 "%<allocate%> directive", var
);
20951 if (!c_check_in_current_scope (var
))
20953 error_at (OMP_CLAUSE_LOCATION (nl
),
20954 "%<allocate%> directive must be in the same scope as %qD",
20956 inform (DECL_SOURCE_LOCATION (var
), "declared here");
20959 if (lookup_attribute ("omp allocate", DECL_ATTRIBUTES (var
)))
20961 error_at (OMP_CLAUSE_LOCATION (nl
),
20962 "%qD already appeared as list item in an "
20963 "%<allocate%> directive", var
);
20966 if (TREE_STATIC (var
))
20968 if (allocator
== NULL_TREE
&& allocator_loc
== UNKNOWN_LOCATION
)
20969 error_at (loc
, "%<allocator%> clause required for "
20970 "static variable %qD", var
);
20972 && (wi::to_widest (allocator
) < 1
20973 || wi::to_widest (allocator
) > 8))
20974 /* 8 = largest predefined memory allocator. */
20975 error_at (allocator_loc
,
20976 "%<allocator%> clause requires a predefined allocator as "
20977 "%qD is static", var
);
20979 sorry_at (OMP_CLAUSE_LOCATION (nl
),
20980 "%<#pragma omp allocate%> for static variables like "
20981 "%qD not yet supported", var
);
20986 struct c_omp_loc_tree data
20987 = {EXPR_LOC_OR_LOC (allocator
, OMP_CLAUSE_LOCATION (nl
)), var
};
20988 walk_tree (&allocator
, c_check_omp_allocate_allocator_r
, &data
, NULL
);
20990 DECL_ATTRIBUTES (var
) = tree_cons (get_identifier ("omp allocate"),
20991 build_tree_list (allocator
, alignment
),
20992 DECL_ATTRIBUTES (var
));
20997 # pragma omp atomic new-line
21001 x binop= expr | x++ | ++x | x-- | --x
21003 +, *, -, /, &, ^, |, <<, >>
21005 where x is an lvalue expression with scalar type.
21008 # pragma omp atomic new-line
21011 # pragma omp atomic read new-line
21014 # pragma omp atomic write new-line
21017 # pragma omp atomic update new-line
21020 # pragma omp atomic capture new-line
21023 # pragma omp atomic capture new-line
21031 expression-stmt | x = x binop expr
21033 v = expression-stmt
21035 { v = x; update-stmt; } | { update-stmt; v = x; }
21039 expression-stmt | x = x binop expr | x = expr binop x
21043 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
21046 # pragma omp atomic compare new-line
21047 conditional-update-atomic
21049 # pragma omp atomic compare capture new-line
21050 conditional-update-capture-atomic
21052 conditional-update-atomic:
21053 cond-expr-stmt | cond-update-stmt
21055 x = expr ordop x ? expr : x;
21056 x = x ordop expr ? expr : x;
21057 x = x == e ? d : x;
21059 if (expr ordop x) { x = expr; }
21060 if (x ordop expr) { x = expr; }
21061 if (x == e) { x = d; }
21064 conditional-update-capture-atomic:
21066 { v = x; cond-expr-stmt }
21067 { cond-expr-stmt v = x; }
21068 { v = x; cond-update-stmt }
21069 { cond-update-stmt v = x; }
21070 if (x == e) { x = d; } else { v = x; }
21071 { r = x == e; if (r) { x = d; } }
21072 { r = x == e; if (r) { x = d; } else { v = x; } }
21074 where x, r and v are lvalue expressions with scalar type,
21075 expr, e and d are expressions with scalar type and e might be
21078 LOC is the location of the #pragma token. */
21081 c_parser_omp_atomic (location_t loc
, c_parser
*parser
, bool openacc
)
21083 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
, r
= NULL_TREE
;
21084 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
21085 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
21086 enum tree_code code
= ERROR_MARK
, opcode
= NOP_EXPR
;
21087 enum omp_memory_order memory_order
= OMP_MEMORY_ORDER_UNSPECIFIED
;
21088 struct c_expr expr
;
21090 bool structured_block
= false;
21091 bool swapped
= false;
21093 tree clauses
= NULL_TREE
;
21094 bool capture
= false;
21095 bool compare
= false;
21097 enum omp_memory_order fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
21098 bool no_semicolon
= false;
21099 bool extra_scope
= false;
21101 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21103 if (c_parser_next_token_is (parser
, CPP_COMMA
)
21104 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
21105 c_parser_consume_token (parser
);
21107 if (c_parser_next_token_is (parser
, CPP_NAME
))
21110 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21111 location_t cloc
= c_parser_peek_token (parser
)->location
;
21112 enum tree_code new_code
= ERROR_MARK
;
21113 enum omp_memory_order new_memory_order
21114 = OMP_MEMORY_ORDER_UNSPECIFIED
;
21115 bool new_capture
= false;
21116 bool new_compare
= false;
21117 bool new_weak
= false;
21118 enum omp_memory_order new_fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
21120 if (!strcmp (p
, "read"))
21121 new_code
= OMP_ATOMIC_READ
;
21122 else if (!strcmp (p
, "write"))
21123 new_code
= NOP_EXPR
;
21124 else if (!strcmp (p
, "update"))
21125 new_code
= OMP_ATOMIC
;
21126 else if (openacc
&& !strcmp (p
, "capture"))
21127 new_code
= OMP_ATOMIC_CAPTURE_NEW
;
21131 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
21132 "or %<capture%> clause");
21134 else if (!strcmp (p
, "capture"))
21135 new_capture
= true;
21136 else if (!strcmp (p
, "compare"))
21137 new_compare
= true;
21138 else if (!strcmp (p
, "weak"))
21140 else if (!strcmp (p
, "fail"))
21142 matching_parens parens
;
21144 c_parser_consume_token (parser
);
21145 if (!parens
.require_open (parser
))
21148 if (c_parser_next_token_is (parser
, CPP_NAME
))
21151 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21153 if (!strcmp (q
, "seq_cst"))
21154 new_fail
= OMP_MEMORY_ORDER_SEQ_CST
;
21155 else if (!strcmp (q
, "acquire"))
21156 new_fail
= OMP_MEMORY_ORDER_ACQUIRE
;
21157 else if (!strcmp (q
, "relaxed"))
21158 new_fail
= OMP_MEMORY_ORDER_RELAXED
;
21161 if (new_fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
21163 c_parser_consume_token (parser
);
21164 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
21165 error_at (cloc
, "too many %qs clauses", "fail");
21170 c_parser_error (parser
, "expected %<seq_cst%>, %<acquire%> "
21172 parens
.skip_until_found_close (parser
);
21175 else if (!strcmp (p
, "seq_cst"))
21176 new_memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21177 else if (!strcmp (p
, "acq_rel"))
21178 new_memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
21179 else if (!strcmp (p
, "release"))
21180 new_memory_order
= OMP_MEMORY_ORDER_RELEASE
;
21181 else if (!strcmp (p
, "acquire"))
21182 new_memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
21183 else if (!strcmp (p
, "relaxed"))
21184 new_memory_order
= OMP_MEMORY_ORDER_RELAXED
;
21185 else if (!strcmp (p
, "hint"))
21187 c_parser_consume_token (parser
);
21188 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
21194 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
21195 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
21196 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
21197 "%<relaxed%> or %<hint%> clause");
21201 if (new_code
!= ERROR_MARK
)
21203 /* OpenACC permits 'update capture'. */
21205 && code
== OMP_ATOMIC
21206 && new_code
== OMP_ATOMIC_CAPTURE_NEW
)
21208 else if (code
!= ERROR_MARK
)
21209 error_at (cloc
, "too many atomic clauses");
21213 else if (new_memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
21215 if (memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
21216 error_at (cloc
, "too many memory order clauses");
21218 memory_order
= new_memory_order
;
21220 else if (new_capture
)
21223 error_at (cloc
, "too many %qs clauses", "capture");
21227 else if (new_compare
)
21230 error_at (cloc
, "too many %qs clauses", "compare");
21237 error_at (cloc
, "too many %qs clauses", "weak");
21241 c_parser_consume_token (parser
);
21247 c_parser_skip_to_pragma_eol (parser
);
21249 if (code
== ERROR_MARK
)
21253 if (code
!= OMP_ATOMIC
)
21254 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
21255 "clauses", "capture");
21257 code
= OMP_ATOMIC_CAPTURE_NEW
;
21259 if (compare
&& code
!= OMP_ATOMIC
&& code
!= OMP_ATOMIC_CAPTURE_NEW
)
21261 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
21262 "clauses", "compare");
21265 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
&& !compare
)
21267 error_at (loc
, "%qs clause requires %qs clause", "fail", "compare");
21268 fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
21270 if (weak
&& !compare
)
21272 error_at (loc
, "%qs clause requires %qs clause", "weak", "compare");
21276 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
21277 else if (memory_order
== OMP_MEMORY_ORDER_UNSPECIFIED
)
21280 = (enum omp_requires
) (omp_requires_mask
21281 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
);
21282 switch ((enum omp_memory_order
)
21283 (omp_requires_mask
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
))
21285 case OMP_MEMORY_ORDER_UNSPECIFIED
:
21286 case OMP_MEMORY_ORDER_RELAXED
:
21287 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
21289 case OMP_MEMORY_ORDER_SEQ_CST
:
21290 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21292 case OMP_MEMORY_ORDER_ACQUIRE
:
21293 if (code
== NOP_EXPR
) /* atomic write */
21295 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
21296 "%<acquire%> clause implicitly provided by a "
21297 "%<requires%> directive");
21298 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21301 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
21303 case OMP_MEMORY_ORDER_RELEASE
:
21304 if (code
== OMP_ATOMIC_READ
)
21306 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
21307 "%<release%> clause implicitly provided by a "
21308 "%<requires%> directive");
21309 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21312 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
21314 case OMP_MEMORY_ORDER_ACQ_REL
:
21317 case OMP_ATOMIC_READ
:
21318 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
21320 case NOP_EXPR
: /* atomic write */
21321 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
21324 memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
21329 gcc_unreachable ();
21335 case OMP_ATOMIC_READ
:
21336 if (memory_order
== OMP_MEMORY_ORDER_RELEASE
)
21338 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
21339 "%<release%> clause");
21340 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21342 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
21343 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
21345 case NOP_EXPR
: /* atomic write */
21346 if (memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
21348 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
21349 "%<acquire%> clause");
21350 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21352 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
21353 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
21358 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
21360 = (enum omp_memory_order
) (memory_order
21361 | (fail
<< OMP_FAIL_MEMORY_ORDER_SHIFT
));
21365 case OMP_ATOMIC_READ
:
21366 case NOP_EXPR
: /* atomic write */
21367 v
= c_parser_cast_expression (parser
, NULL
).value
;
21368 non_lvalue_p
= !lvalue_p (v
);
21369 v
= c_fully_fold (v
, false, NULL
, true);
21370 if (v
== error_mark_node
)
21373 v
= non_lvalue (v
);
21374 loc
= c_parser_peek_token (parser
)->location
;
21375 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21377 if (code
== NOP_EXPR
)
21379 lhs
= c_parser_expression (parser
).value
;
21380 lhs
= c_fully_fold (lhs
, false, NULL
);
21381 if (lhs
== error_mark_node
)
21386 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
21387 non_lvalue_p
= !lvalue_p (lhs
);
21388 lhs
= c_fully_fold (lhs
, false, NULL
, true);
21389 if (lhs
== error_mark_node
)
21392 lhs
= non_lvalue (lhs
);
21394 if (code
== NOP_EXPR
)
21396 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
21404 case OMP_ATOMIC_CAPTURE_NEW
:
21405 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
21407 c_parser_consume_token (parser
);
21408 structured_block
= true;
21411 && c_parser_next_token_is_keyword (parser
, RID_IF
))
21415 v
= c_parser_cast_expression (parser
, NULL
).value
;
21416 non_lvalue_p
= !lvalue_p (v
);
21417 v
= c_fully_fold (v
, false, NULL
, true);
21418 if (v
== error_mark_node
)
21421 v
= non_lvalue (v
);
21422 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21424 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
21426 eloc
= c_parser_peek_token (parser
)->location
;
21427 error_at (eloc
, "expected expression");
21436 /* For structured_block case we don't know yet whether
21437 old or new x should be captured. */
21439 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
21441 c_parser_consume_token (parser
);
21443 matching_parens parens
;
21444 if (!parens
.require_open (parser
))
21446 eloc
= c_parser_peek_token (parser
)->location
;
21450 cmp_expr
= c_parser_cast_expression (parser
, NULL
);
21451 cmp_expr
= default_function_array_conversion (eloc
, cmp_expr
);
21454 cmp_expr
= c_parser_binary_expression (parser
, NULL
, void_list_node
);
21455 parens
.skip_until_found_close (parser
);
21456 if (cmp_expr
.value
== error_mark_node
)
21460 if (!c_tree_equal (cmp_expr
.value
, unfolded_lhs
))
21462 cmp_expr
.value
= rhs1
;
21464 gcc_assert (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
);
21466 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
21468 else if (!structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
21470 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
21471 "expected %<==%> comparison in %<if%> condition");
21474 else if (TREE_CODE (cmp_expr
.value
) != GT_EXPR
21475 && TREE_CODE (cmp_expr
.value
) != LT_EXPR
)
21477 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
21478 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
21482 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
21485 extra_scope
= true;
21486 eloc
= c_parser_peek_token (parser
)->location
;
21487 expr
= c_parser_cast_expression (parser
, NULL
);
21489 expr
= default_function_array_conversion (eloc
, expr
);
21490 unfolded_lhs
= expr
.value
;
21491 lhs
= c_fully_fold (lhs
, false, NULL
, true);
21493 if (lhs
== error_mark_node
)
21495 if (!lvalue_p (unfolded_lhs
))
21496 lhs
= non_lvalue (lhs
);
21497 if (!c_parser_next_token_is (parser
, CPP_EQ
))
21499 c_parser_error (parser
, "expected %<=%>");
21502 c_parser_consume_token (parser
);
21503 eloc
= c_parser_peek_token (parser
)->location
;
21504 expr
= c_parser_expr_no_commas (parser
, NULL
);
21507 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
21510 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
21513 extra_scope
= false;
21514 no_semicolon
= true;
21516 if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), unfolded_lhs
))
21518 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
21520 opcode
= COND_EXPR
;
21521 rhs
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
21522 false, NULL
, true);
21523 rhs1
= c_fully_fold (rhs1
, false, NULL
, true);
21525 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), rhs1
))
21527 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
21528 ? MIN_EXPR
: MAX_EXPR
);
21529 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
21530 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 0),
21531 false, NULL
, true);
21536 else if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
21538 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), unfolded_lhs
)
21539 && c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), rhs1
))
21541 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
21542 ? MAX_EXPR
: MIN_EXPR
);
21543 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
21544 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
21545 false, NULL
, true);
21550 c_parser_error (parser
,
21551 "invalid form of %<#pragma omp atomic compare%>");
21555 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
21557 if (code
!= OMP_ATOMIC_CAPTURE_NEW
21558 || (structured_block
&& r
== NULL_TREE
)
21559 || TREE_CODE (cmp_expr
.value
) != EQ_EXPR
)
21561 eloc
= c_parser_peek_token (parser
)->location
;
21562 error_at (eloc
, "unexpected %<else%>");
21566 c_parser_consume_token (parser
);
21568 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
21571 extra_scope
= true;
21572 v
= c_parser_cast_expression (parser
, NULL
).value
;
21573 non_lvalue_p
= !lvalue_p (v
);
21574 v
= c_fully_fold (v
, false, NULL
, true);
21575 if (v
== error_mark_node
)
21578 v
= non_lvalue (v
);
21579 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21582 expr
= c_parser_expr_no_commas (parser
, NULL
);
21584 if (!c_tree_equal (expr
.value
, unfolded_lhs
))
21587 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
21590 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
21593 extra_scope
= false;
21594 code
= OMP_ATOMIC_CAPTURE_OLD
;
21595 if (r
== NULL_TREE
)
21596 /* Signal to c_finish_omp_atomic that in
21597 if (x == e) { x = d; } else { v = x; }
21598 case the store to v should be conditional. */
21599 r
= void_list_node
;
21601 else if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
21603 c_parser_require_keyword (parser
, RID_ELSE
, "expected %<else%>");
21606 else if (code
== OMP_ATOMIC_CAPTURE_NEW
21612 eloc
= c_parser_peek_token (parser
)->location
;
21613 expr
= c_parser_cast_expression (parser
, NULL
);
21615 expr
= default_function_array_conversion (eloc
, expr
);
21616 unfolded_lhs
= expr
.value
;
21617 lhs
= c_fully_fold (lhs
, false, NULL
, true);
21619 switch (TREE_CODE (lhs
))
21622 error_at (eloc
, "invalid form of %<pragma omp atomic compare%>");
21626 c_parser_skip_to_end_of_block_or_statement (parser
);
21627 if (extra_scope
&& c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
21628 c_parser_consume_token (parser
);
21629 if (structured_block
)
21631 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
21632 c_parser_consume_token (parser
);
21633 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
21635 c_parser_skip_to_end_of_block_or_statement (parser
);
21636 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
21637 c_parser_consume_token (parser
);
21642 case POSTINCREMENT_EXPR
:
21643 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
21644 code
= OMP_ATOMIC_CAPTURE_OLD
;
21646 case PREINCREMENT_EXPR
:
21647 lhs
= TREE_OPERAND (lhs
, 0);
21648 unfolded_lhs
= NULL_TREE
;
21649 opcode
= PLUS_EXPR
;
21650 rhs
= integer_one_node
;
21652 goto invalid_compare
;
21655 case POSTDECREMENT_EXPR
:
21656 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
21657 code
= OMP_ATOMIC_CAPTURE_OLD
;
21659 case PREDECREMENT_EXPR
:
21660 lhs
= TREE_OPERAND (lhs
, 0);
21661 unfolded_lhs
= NULL_TREE
;
21662 opcode
= MINUS_EXPR
;
21663 rhs
= integer_one_node
;
21665 goto invalid_compare
;
21668 case COMPOUND_EXPR
:
21669 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
21670 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
21671 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
21672 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
21673 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
21674 (TREE_OPERAND (lhs
, 1), 0), 0))))
21675 /* Undo effects of boolean_increment for post {in,de}crement. */
21676 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
21679 if (TREE_CODE (lhs
) == MODIFY_EXPR
21680 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs
, 0))))
21682 /* Undo effects of boolean_increment. */
21683 if (integer_onep (TREE_OPERAND (lhs
, 1)))
21685 /* This is pre or post increment. */
21686 rhs
= TREE_OPERAND (lhs
, 1);
21687 lhs
= TREE_OPERAND (lhs
, 0);
21688 unfolded_lhs
= NULL_TREE
;
21690 if (code
== OMP_ATOMIC_CAPTURE_NEW
21691 && !structured_block
21692 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
21693 code
= OMP_ATOMIC_CAPTURE_OLD
;
21695 goto invalid_compare
;
21698 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
21699 && TREE_OPERAND (lhs
, 0)
21700 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
21702 /* This is pre or post decrement. */
21703 rhs
= TREE_OPERAND (lhs
, 1);
21704 lhs
= TREE_OPERAND (lhs
, 0);
21705 unfolded_lhs
= NULL_TREE
;
21707 if (code
== OMP_ATOMIC_CAPTURE_NEW
21708 && !structured_block
21709 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
21710 code
= OMP_ATOMIC_CAPTURE_OLD
;
21712 goto invalid_compare
;
21718 if (!lvalue_p (unfolded_lhs
))
21719 lhs
= non_lvalue (lhs
);
21720 if (compare
&& !c_parser_next_token_is (parser
, CPP_EQ
))
21722 c_parser_error (parser
, "expected %<=%>");
21725 switch (c_parser_peek_token (parser
)->type
)
21728 opcode
= MULT_EXPR
;
21731 opcode
= TRUNC_DIV_EXPR
;
21734 opcode
= PLUS_EXPR
;
21737 opcode
= MINUS_EXPR
;
21739 case CPP_LSHIFT_EQ
:
21740 opcode
= LSHIFT_EXPR
;
21742 case CPP_RSHIFT_EQ
:
21743 opcode
= RSHIFT_EXPR
;
21746 opcode
= BIT_AND_EXPR
;
21749 opcode
= BIT_IOR_EXPR
;
21752 opcode
= BIT_XOR_EXPR
;
21755 c_parser_consume_token (parser
);
21756 eloc
= c_parser_peek_token (parser
)->location
;
21757 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
21759 switch (TREE_CODE (rhs1
))
21762 case TRUNC_DIV_EXPR
:
21773 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
21775 opcode
= TREE_CODE (rhs1
);
21776 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21778 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
21782 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
21784 opcode
= TREE_CODE (rhs1
);
21785 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
21787 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21789 swapped
= !commutative_tree_code (opcode
);
21796 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) != GT_EXPR
21797 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != LT_EXPR
21798 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != EQ_EXPR
)
21800 if (!TREE_OPERAND (rhs1
, 1))
21802 if (!c_tree_equal (TREE_OPERAND (rhs1
, 2), unfolded_lhs
))
21804 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
21807 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
21809 opcode
= COND_EXPR
;
21810 rhs
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
21812 false, NULL
, true);
21813 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false,
21817 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
21818 TREE_OPERAND (rhs1
, 1)))
21820 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
21821 ? MIN_EXPR
: MAX_EXPR
);
21822 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21824 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
21826 false, NULL
, true);
21830 else if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
21832 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
21835 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
21836 TREE_OPERAND (rhs1
, 1)))
21838 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
21839 ? MAX_EXPR
: MIN_EXPR
);
21840 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21842 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
21844 false, NULL
, true);
21851 || code
!= OMP_ATOMIC_CAPTURE_NEW
21852 || !structured_block
21856 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
21857 && c_parser_peek_2nd_token (parser
)->keyword
== RID_IF
)
21861 c_parser_consume_token (parser
);
21870 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
21872 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
21874 code
= OMP_ATOMIC_CAPTURE_OLD
;
21877 expr
= default_function_array_read_conversion (eloc
, expr
);
21878 unfolded_lhs1
= expr
.value
;
21879 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
21881 c_parser_consume_token (parser
);
21884 if (structured_block
&& !compare
)
21887 expr
= default_function_array_read_conversion (eloc
, expr
);
21888 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
21893 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
21896 c_parser_error (parser
,
21897 "invalid operator for %<#pragma omp atomic%>");
21901 /* Arrange to pass the location of the assignment operator to
21902 c_finish_omp_atomic. */
21903 loc
= c_parser_peek_token (parser
)->location
;
21904 c_parser_consume_token (parser
);
21905 eloc
= c_parser_peek_token (parser
)->location
;
21906 expr
= c_parser_expression (parser
);
21907 expr
= default_function_array_read_conversion (eloc
, expr
);
21909 rhs
= c_fully_fold (rhs
, false, NULL
, true);
21913 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
&& r
== NULL_TREE
)
21916 && !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
21918 no_semicolon
= false;
21919 v
= c_parser_cast_expression (parser
, NULL
).value
;
21920 non_lvalue_p
= !lvalue_p (v
);
21921 v
= c_fully_fold (v
, false, NULL
, true);
21922 if (v
== error_mark_node
)
21925 v
= non_lvalue (v
);
21926 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21928 eloc
= c_parser_peek_token (parser
)->location
;
21929 expr
= c_parser_cast_expression (parser
, NULL
);
21931 expr
= default_function_array_read_conversion (eloc
, expr
);
21932 unfolded_lhs1
= expr
.value
;
21933 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
21934 if (lhs1
== error_mark_node
)
21936 if (!lvalue_p (unfolded_lhs1
))
21937 lhs1
= non_lvalue (lhs1
);
21939 if (structured_block
)
21942 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
21943 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
21946 if (weak
&& opcode
!= COND_EXPR
)
21948 error_at (loc
, "%<weak%> clause requires atomic equality comparison");
21951 if (unfolded_lhs
&& unfolded_lhs1
21952 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
21954 error ("%<#pragma omp atomic capture%> uses two different "
21955 "expressions for memory");
21956 stmt
= error_mark_node
;
21959 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
, r
,
21960 swapped
, memory_order
, weak
);
21961 if (stmt
!= error_mark_node
)
21964 if (!structured_block
&& !no_semicolon
)
21965 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
21970 # pragma omp barrier new-line
21974 c_parser_omp_barrier (c_parser
*parser
)
21976 location_t loc
= c_parser_peek_token (parser
)->location
;
21977 c_parser_consume_pragma (parser
);
21978 c_parser_skip_to_pragma_eol (parser
);
21980 c_finish_omp_barrier (loc
);
21984 # pragma omp critical [(name)] new-line
21988 # pragma omp critical [(name) [hint(expression)]] new-line
21990 LOC is the location of the #pragma itself. */
21992 #define OMP_CRITICAL_CLAUSE_MASK \
21993 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
21996 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
21998 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
22000 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
22002 c_parser_consume_token (parser
);
22003 if (c_parser_next_token_is (parser
, CPP_NAME
))
22005 name
= c_parser_peek_token (parser
)->value
;
22006 c_parser_consume_token (parser
);
22007 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
22010 c_parser_error (parser
, "expected identifier");
22012 if (c_parser_next_token_is (parser
, CPP_COMMA
)
22013 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
22014 c_parser_consume_token (parser
);
22016 clauses
= c_parser_omp_all_clauses (parser
, OMP_CRITICAL_CLAUSE_MASK
,
22017 "#pragma omp critical");
22018 stmt
= c_parser_omp_structured_block (parser
, if_p
);
22019 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
22023 # pragma omp depobj ( depobj ) depobj-clause new-line
22026 depend (dependence-type : locator)
22028 update (dependence-type)
22030 OpenMP 5.2 additionally:
22040 c_parser_omp_depobj (c_parser
*parser
)
22042 location_t loc
= c_parser_peek_token (parser
)->location
;
22043 c_parser_consume_pragma (parser
);
22044 matching_parens parens
;
22045 if (!parens
.require_open (parser
))
22047 c_parser_skip_to_pragma_eol (parser
);
22051 tree depobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
22052 if (depobj
!= error_mark_node
)
22054 if (!lvalue_p (depobj
))
22056 error_at (EXPR_LOC_OR_LOC (depobj
, loc
),
22057 "%<depobj%> expression is not lvalue expression");
22058 depobj
= error_mark_node
;
22062 tree addr
= build_unary_op (EXPR_LOC_OR_LOC (depobj
, loc
), ADDR_EXPR
,
22064 if (addr
== error_mark_node
)
22065 depobj
= error_mark_node
;
22067 depobj
= build_indirect_ref (EXPR_LOC_OR_LOC (depobj
, loc
),
22068 addr
, RO_UNARY_STAR
);
22072 parens
.skip_until_found_close (parser
);
22073 tree clause
= NULL_TREE
;
22074 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_INVALID
;
22075 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22076 c_parser_consume_token (parser
);
22077 location_t c_loc
= c_parser_peek_token (parser
)->location
;
22078 if (c_parser_next_token_is (parser
, CPP_NAME
))
22080 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22082 c_parser_consume_token (parser
);
22083 if (!strcmp ("depend", p
))
22085 clause
= c_parser_omp_clause_depend (parser
, NULL_TREE
);
22086 clause
= c_finish_omp_clauses (clause
, C_ORT_OMP
);
22088 clause
= error_mark_node
;
22090 else if (!strcmp ("destroy", p
))
22092 matching_parens c_parens
;
22093 kind
= OMP_CLAUSE_DEPEND_LAST
;
22094 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
22095 && c_parens
.require_open (parser
))
22097 tree destobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
22098 if (!lvalue_p (destobj
))
22099 error_at (EXPR_LOC_OR_LOC (destobj
, c_loc
),
22100 "%<destroy%> expression is not lvalue expression");
22101 else if (depobj
!= error_mark_node
22102 && !operand_equal_p (destobj
, depobj
,
22103 OEP_MATCH_SIDE_EFFECTS
22104 | OEP_LEXICOGRAPHIC
))
22105 warning_at (EXPR_LOC_OR_LOC (destobj
, c_loc
), OPT_Wopenmp
,
22106 "the %<destroy%> expression %qE should be the same "
22107 "as the %<depobj%> argument %qE", destobj
, depobj
);
22108 c_parens
.skip_until_found_close (parser
);
22111 else if (!strcmp ("update", p
))
22113 matching_parens c_parens
;
22114 if (c_parens
.require_open (parser
))
22116 location_t c2_loc
= c_parser_peek_token (parser
)->location
;
22117 if (c_parser_next_token_is (parser
, CPP_NAME
))
22120 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22122 c_parser_consume_token (parser
);
22123 if (!strcmp ("in", p2
))
22124 kind
= OMP_CLAUSE_DEPEND_IN
;
22125 else if (!strcmp ("out", p2
))
22126 kind
= OMP_CLAUSE_DEPEND_OUT
;
22127 else if (!strcmp ("inout", p2
))
22128 kind
= OMP_CLAUSE_DEPEND_INOUT
;
22129 else if (!strcmp ("mutexinoutset", p2
))
22130 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
22131 else if (!strcmp ("inoutset", p2
))
22132 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
22134 if (kind
== OMP_CLAUSE_DEPEND_INVALID
)
22136 clause
= error_mark_node
;
22137 error_at (c2_loc
, "expected %<in%>, %<out%>, %<inout%>, "
22138 "%<mutexinoutset%> or %<inoutset%>");
22140 c_parens
.skip_until_found_close (parser
);
22143 clause
= error_mark_node
;
22146 if (!clause
&& kind
== OMP_CLAUSE_DEPEND_INVALID
)
22148 clause
= error_mark_node
;
22149 error_at (c_loc
, "expected %<depend%>, %<destroy%> or %<update%> clause");
22151 c_parser_skip_to_pragma_eol (parser
);
22153 c_finish_omp_depobj (loc
, depobj
, kind
, clause
);
22158 # pragma omp flush flush-vars[opt] new-line
22164 # pragma omp flush memory-order-clause new-line */
22167 c_parser_omp_flush (c_parser
*parser
)
22169 location_t loc
= c_parser_peek_token (parser
)->location
;
22170 c_parser_consume_pragma (parser
);
22171 enum memmodel mo
= MEMMODEL_LAST
;
22172 if (c_parser_next_token_is (parser
, CPP_COMMA
)
22173 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
22174 c_parser_consume_token (parser
);
22175 if (c_parser_next_token_is (parser
, CPP_NAME
))
22178 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22180 if (!strcmp (p
, "seq_cst"))
22181 mo
= MEMMODEL_SEQ_CST
;
22182 else if (!strcmp (p
, "acq_rel"))
22183 mo
= MEMMODEL_ACQ_REL
;
22184 else if (!strcmp (p
, "release"))
22185 mo
= MEMMODEL_RELEASE
;
22186 else if (!strcmp (p
, "acquire"))
22187 mo
= MEMMODEL_ACQUIRE
;
22189 error_at (c_parser_peek_token (parser
)->location
,
22190 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
22192 c_parser_consume_token (parser
);
22194 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
22196 if (mo
!= MEMMODEL_LAST
)
22197 error_at (c_parser_peek_token (parser
)->location
,
22198 "%<flush%> list specified together with memory order "
22200 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
22202 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
22203 c_parser_error (parser
, "expected %<(%> or end of line");
22204 c_parser_skip_to_pragma_eol (parser
);
22206 c_finish_omp_flush (loc
, mo
);
22209 /* Return true if next tokens contain a standard attribute that contains
22210 omp::directive (DIRECTIVE). */
22213 c_parser_omp_section_scan (c_parser
*parser
, const char *directive
,
22216 if (!c_parser_nth_token_starts_std_attributes (parser
, 1))
22218 unsigned int n
= 3;
22219 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
22221 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
22222 if (token
->type
!= CPP_CLOSE_SQUARE
)
22224 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
22225 if (token
->type
!= CPP_CLOSE_SQUARE
)
22229 if (c_parser_peek_nth_token_raw (parser
, 3)->type
== CPP_NAME
22230 && c_parser_peek_nth_token_raw (parser
, 4)->type
== CPP_OPEN_PAREN
22231 && c_parser_peek_nth_token_raw (parser
, 5)->type
== CPP_NAME
)
22233 tree first
= c_parser_peek_nth_token_raw (parser
, 3)->value
;
22234 tree second
= c_parser_peek_nth_token_raw (parser
, 5)->value
;
22235 if (strcmp (IDENTIFIER_POINTER (first
), "directive")
22236 && strcmp (IDENTIFIER_POINTER (first
), "__directive__"))
22238 if (strcmp (IDENTIFIER_POINTER (second
), directive
))
22243 location_t first_loc
= c_parser_peek_token (parser
)->location
;
22244 location_t last_loc
= c_parser_peek_nth_token_raw (parser
, n
+ 1)->location
;
22245 location_t middle_loc
= UNKNOWN_LOCATION
;
22246 tree std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
22249 for (tree attr
= std_attrs
; attr
; attr
= TREE_CHAIN (attr
))
22250 if (is_attribute_namespace_p ("omp", attr
)
22251 && is_attribute_p ("directive", get_attribute_name (attr
)))
22253 for (tree a
= TREE_VALUE (attr
); a
; a
= TREE_CHAIN (a
))
22255 tree d
= TREE_VALUE (a
);
22256 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
22257 c_token
*first
= C_TOKEN_VEC_TOKENS (d
)->address ();
22259 if (first
->type
== CPP_NAME
22260 && strcmp (IDENTIFIER_POINTER (first
->value
),
22264 if (middle_loc
== UNKNOWN_LOCATION
)
22265 middle_loc
= first
->location
;
22271 if (cnt
!= 1 || TREE_CHAIN (std_attrs
))
22273 error_at (make_location (first_loc
, last_loc
, middle_loc
),
22274 "%<[[omp::directive(%s)]]%> must be the only specified "
22275 "attribute on a statement", directive
);
22278 c_parser_handle_statement_omp_attributes (parser
, std_attrs
, NULL
);
22282 /* Parse an OpenMP structured block sequence. KIND is the corresponding
22283 separating directive. */
22286 c_parser_omp_structured_block_sequence (c_parser
*parser
,
22287 enum pragma_kind kind
)
22289 tree stmt
= push_stmt_list ();
22290 c_parser_statement (parser
, NULL
);
22293 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
22295 if (c_parser_next_token_is (parser
, CPP_EOF
))
22298 if (kind
!= PRAGMA_NONE
22299 && c_parser_peek_token (parser
)->pragma_kind
== kind
)
22302 if (kind
!= PRAGMA_NONE
22303 && c_parser_omp_section_scan (parser
,
22304 kind
== PRAGMA_OMP_SCAN
22305 ? "scan" : "section", false))
22308 c_parser_statement (parser
, NULL
);
22311 return pop_stmt_list (stmt
);
22317 { structured-block scan-directive structured-block } */
22320 c_parser_omp_scan_loop_body (c_parser
*parser
, bool open_brace_parsed
)
22324 tree clauses
= NULL_TREE
;
22325 bool found_scan
= false;
22327 loc
= c_parser_peek_token (parser
)->location
;
22328 if (!open_brace_parsed
22329 && !c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
22331 /* Avoid skipping until the end of the block. */
22332 parser
->error
= false;
22336 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SCAN
)
22337 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_OMP_SCAN
);
22340 warning_at (c_parser_peek_token (parser
)->location
, OPT_Wopenmp
,
22341 "%<#pragma omp scan%> with zero preceding executable "
22343 substmt
= build_empty_stmt (loc
);
22345 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, NULL_TREE
);
22346 SET_EXPR_LOCATION (substmt
, loc
);
22347 add_stmt (substmt
);
22349 loc
= c_parser_peek_token (parser
)->location
;
22350 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SCAN
)
22352 enum omp_clause_code clause
= OMP_CLAUSE_ERROR
;
22355 c_parser_consume_pragma (parser
);
22357 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22358 c_parser_consume_token (parser
);
22360 if (c_parser_next_token_is (parser
, CPP_NAME
))
22363 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22364 if (strcmp (p
, "inclusive") == 0)
22365 clause
= OMP_CLAUSE_INCLUSIVE
;
22366 else if (strcmp (p
, "exclusive") == 0)
22367 clause
= OMP_CLAUSE_EXCLUSIVE
;
22369 if (clause
!= OMP_CLAUSE_ERROR
)
22371 c_parser_consume_token (parser
);
22372 clauses
= c_parser_omp_var_list_parens (parser
, clause
, NULL_TREE
);
22375 c_parser_error (parser
, "expected %<inclusive%> or "
22376 "%<exclusive%> clause");
22377 c_parser_skip_to_pragma_eol (parser
);
22380 error ("expected %<#pragma omp scan%>");
22382 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
22383 if (!c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
22384 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_NONE
);
22388 warning_at (loc
, OPT_Wopenmp
,
22389 "%<#pragma omp scan%> with zero succeeding executable "
22391 substmt
= build_empty_stmt (loc
);
22393 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, clauses
);
22394 SET_EXPR_LOCATION (substmt
, loc
);
22395 add_stmt (substmt
);
22397 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
22402 /* Check if the next tokens can start a canonical loop. Return true if yes,
22403 otherwise diagnose an error if ERROR_P is true, and return false. */
22405 c_parser_omp_next_tokens_can_be_canon_loop (c_parser
*parser
,
22406 enum tree_code code
,
22409 if (code
== OACC_LOOP
)
22411 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
22414 c_parser_error (parser
, "for statement expected");
22418 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
22421 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
22422 switch (c_parser_peek_token (parser
)->pragma_kind
)
22424 case PRAGMA_OMP_UNROLL
:
22425 case PRAGMA_OMP_TILE
:
22431 /* Skip standard attributes on next for in case they are
22432 [[omp::directive (unroll partial (4))]] or
22433 [[omp::directive (tile sizes (1, 2, 3))]] etc. */
22434 size_t n
= c_parser_skip_std_attribute_spec_seq (parser
, 1);
22435 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
22436 /* TOKEN is a raw token that hasn't been converted to a keyword yet,
22437 we have to do the lookup explicitly. */
22438 if (token
->type
== CPP_NAME
22439 && C_IS_RESERVED_WORD (token
->value
)
22440 && C_RID_CODE (token
->value
) == RID_FOR
)
22443 c_parser_error (parser
, "loop nest expected");
22449 static tree
c_parser_omp_tile (location_t
, c_parser
*, bool *);
22450 static tree
c_parser_omp_unroll (location_t
, c_parser
*, bool *);
22452 /* This function parses a single level of a loop nest, invoking itself
22453 recursively if necessary.
22455 loop-nest :: for (...) loop-body
22456 loop-body :: loop-nest
22457 | { [intervening-code] loop-body [intervening-code] }
22459 intervening-code :: structured-block-sequence
22460 final-loop-body :: structured-block
22462 For a collapsed loop nest, only a single OMP_FOR is built, pulling out
22463 all the iterator information from the inner loops into the
22464 parser->omp_for_parse_state structure.
22466 The iterator decl, init, cond, and incr are stored in vectors.
22468 Initialization code for iterator variables is collected into
22469 parser->omp_for_parse_state->pre_body and ends up inserted directly
22470 into the OMP_FOR structure. */
22473 c_parser_omp_loop_nest (c_parser
*parser
, bool *if_p
)
22475 tree decl
= NULL_TREE
, cond
= NULL_TREE
, incr
= NULL_TREE
, init
= NULL_TREE
;
22476 tree body
= NULL_TREE
;
22477 matching_parens parens
;
22479 unsigned char save_in_statement
;
22482 struct omp_for_parse_data
*omp_for_parse_state
22483 = parser
->omp_for_parse_state
;
22484 gcc_assert (omp_for_parse_state
);
22485 int depth
= omp_for_parse_state
->depth
;
22487 /* Arrange for C23 standard attribute syntax to be parsed as regular
22489 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
22491 tree std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
22492 c_parser_handle_statement_omp_attributes (parser
, std_attrs
, NULL
);
22494 error_at (c_parser_peek_token (parser
)->location
,
22495 "attributes other than OpenMP directives "
22496 "are not allowed on %<for%> in loop nest");
22499 loc
= c_parser_peek_token (parser
)->location
;
22501 /* Handle loop transformations first. */
22502 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
22504 tree transform
= NULL_TREE
, sizes
, body
= NULL_TREE
;
22506 switch (c_parser_peek_token (parser
)->pragma_kind
)
22508 case PRAGMA_OMP_UNROLL
:
22509 c_parser_consume_pragma (parser
);
22510 body
= push_stmt_list ();
22511 transform
= c_parser_omp_unroll (loc
, parser
, if_p
);
22512 body
= pop_stmt_list (body
);
22513 if (transform
== NULL_TREE
|| transform
== error_mark_node
)
22515 transform
= error_mark_node
;
22518 gcc_assert (TREE_CODE (transform
) == OMP_UNROLL
);
22519 if (omp_find_clause (OMP_FOR_CLAUSES (transform
),
22520 OMP_CLAUSE_PARTIAL
))
22522 if (omp_for_parse_state
->count
- depth
> 1)
22524 error_at (loc
, "%<unroll%> construct with %<partial%> "
22525 "clause generates just one loop with "
22526 "canonical form but %d loops are needed",
22527 omp_for_parse_state
->count
- depth
);
22528 transform
= error_mark_node
;
22535 error_at (loc
, "generated loop of %<unroll%> construct "
22536 "without %<partial%> clause does not have "
22538 transform
= error_mark_node
;
22541 case PRAGMA_OMP_TILE
:
22542 c_parser_consume_pragma (parser
);
22543 body
= push_stmt_list ();
22544 transform
= c_parser_omp_tile (loc
, parser
, if_p
);
22545 body
= pop_stmt_list (body
);
22546 if (transform
== NULL_TREE
|| transform
== error_mark_node
)
22548 transform
= error_mark_node
;
22551 gcc_assert (TREE_CODE (transform
) == OMP_TILE
);
22552 sizes
= omp_find_clause (OMP_FOR_CLAUSES (transform
),
22554 gcc_assert (sizes
);
22555 count
= list_length (OMP_CLAUSE_SIZES_LIST (sizes
));
22556 if (depth
+ count
< omp_for_parse_state
->count
)
22558 error_at (loc
, "%<tile%> construct generates %d loops "
22559 "with canonical form but %d loops are needed",
22560 count
, omp_for_parse_state
->count
- depth
);
22561 transform
= error_mark_node
;
22565 c_parser_pragma (parser
, pragma_stmt
, NULL
);
22568 if (transform
== NULL_TREE
)
22569 error_at (loc
, "expected %<for%> loop or OpenMP loop "
22570 "transformation construct");
22571 if (transform
== NULL_TREE
|| transform
== error_mark_node
)
22573 omp_for_parse_state
->fail
= true;
22576 for (count
= omp_for_parse_state
->count
; depth
< count
; ++depth
)
22578 TREE_VEC_ELT (omp_for_parse_state
->declv
, depth
) = NULL_TREE
;
22579 TREE_VEC_ELT (omp_for_parse_state
->initv
, depth
) = NULL_TREE
;
22580 TREE_VEC_ELT (omp_for_parse_state
->condv
, depth
) = NULL_TREE
;
22581 TREE_VEC_ELT (omp_for_parse_state
->incrv
, depth
) = NULL_TREE
;
22583 omp_for_parse_state
->want_nested_loop
= false;
22587 /* We have already matched the FOR token but not consumed it yet. */
22588 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
22589 c_parser_consume_token (parser
);
22591 /* Forbid break/continue in the loop initializer, condition, and
22592 increment expressions. */
22593 save_in_statement
= in_statement
;
22594 in_statement
= IN_OMP_BLOCK
;
22596 /* We are not in intervening code now. */
22597 omp_for_parse_state
->in_intervening_code
= false;
22599 if (!parens
.require_open (parser
))
22601 omp_for_parse_state
->fail
= true;
22605 /* An implicit scope block surrounds each level of FOR loop, for
22606 declarations of iteration variables at this loop depth. */
22607 loop_scope
= c_begin_compound_stmt (true);
22609 /* Parse the initialization declaration or expression. */
22610 if (c_parser_next_tokens_start_declaration (parser
))
22612 /* This is a declaration, which must be added to the pre_body code. */
22613 tree this_pre_body
= push_stmt_list ();
22614 c_in_omp_for
= true;
22615 c_parser_declaration_or_fndef (parser
, true, true, true, true, true);
22616 c_in_omp_for
= false;
22617 this_pre_body
= pop_stmt_list (this_pre_body
);
22618 append_to_statement_list_force (this_pre_body
,
22619 &(omp_for_parse_state
->pre_body
));
22620 decl
= check_for_loop_decls (omp_for_parse_state
->for_loc
, flag_isoc99
);
22623 if (DECL_INITIAL (decl
) == error_mark_node
)
22624 decl
= error_mark_node
;
22627 else if (c_parser_next_token_is (parser
, CPP_NAME
)
22628 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
22630 struct c_expr decl_exp
;
22631 struct c_expr init_exp
;
22632 location_t init_loc
;
22634 decl_exp
= c_parser_postfix_expression (parser
);
22635 decl
= decl_exp
.value
;
22637 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
22639 init_loc
= c_parser_peek_token (parser
)->location
;
22640 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
22641 init_exp
= default_function_array_read_conversion (init_loc
,
22643 c_in_omp_for
= true;
22644 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
22645 NOP_EXPR
, init_loc
, init_exp
.value
,
22646 init_exp
.original_type
);
22647 c_in_omp_for
= false;
22648 init
= c_process_expr_stmt (init_loc
, init
);
22650 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
22655 c_parser_error (parser
,
22656 "expected iteration declaration or initialization");
22657 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
22659 omp_for_parse_state
->fail
= true;
22663 /* Parse the loop condition. */
22664 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
22666 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
22667 c_in_omp_for
= true;
22668 struct c_expr cond_expr
22669 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
22670 c_in_omp_for
= false;
22672 cond
= cond_expr
.value
;
22673 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
22674 switch (cond_expr
.original_code
)
22682 if (omp_for_parse_state
->code
!= OACC_LOOP
)
22686 /* Can't be cond = error_mark_node, because we want to preserve
22687 the location until c_finish_omp_for. */
22688 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
22691 protected_set_expr_location (cond
, cond_loc
);
22693 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
22695 /* Parse the increment expression. */
22696 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
22698 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
22700 incr
= c_process_expr_stmt (incr_loc
,
22701 c_parser_expression (parser
).value
);
22703 parens
.skip_until_found_close (parser
);
22705 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
22706 omp_for_parse_state
->fail
= true;
22709 TREE_VEC_ELT (omp_for_parse_state
->declv
, depth
) = decl
;
22710 TREE_VEC_ELT (omp_for_parse_state
->initv
, depth
) = init
;
22711 TREE_VEC_ELT (omp_for_parse_state
->condv
, depth
) = cond
;
22712 TREE_VEC_ELT (omp_for_parse_state
->incrv
, depth
) = incr
;
22716 moreloops
= depth
< omp_for_parse_state
->count
- 1;
22717 omp_for_parse_state
->want_nested_loop
= moreloops
;
22719 && c_parser_omp_next_tokens_can_be_canon_loop (parser
,
22720 omp_for_parse_state
->code
,
22723 omp_for_parse_state
->depth
++;
22724 body
= c_parser_omp_loop_nest (parser
, if_p
);
22725 omp_for_parse_state
->depth
--;
22727 else if (moreloops
&& c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
22729 /* This is the open brace in the loop-body grammar production. Rather
22730 than trying to special-case braces, just parse it as a compound
22731 statement and handle the nested loop-body case there. Note that
22732 when we see a further open brace inside the compound statement
22733 loop-body, we don't know whether it is the start of intervening
22734 code that is a compound statement, or a level of braces
22735 surrounding a nested loop-body. Use the WANT_NESTED_LOOP state
22736 bit to ensure we have only one nested loop at each level. */
22737 omp_for_parse_state
->in_intervening_code
= true;
22738 body
= c_parser_compound_statement (parser
, NULL
);
22739 omp_for_parse_state
->in_intervening_code
= false;
22740 if (omp_for_parse_state
->want_nested_loop
)
22742 /* We have already parsed the whole loop body and not found a
22744 error_at (omp_for_parse_state
->for_loc
,
22745 "not enough nested loops");
22746 omp_for_parse_state
->fail
= true;
22752 /* This is the final-loop-body case in the grammar: we have
22753 something that is not a FOR and not an open brace. */
22756 /* If we were expecting a nested loop, give an error and mark
22757 that parsing has failed, and try to recover by parsing the
22758 body as regular code without further collapsing. */
22759 error_at (omp_for_parse_state
->for_loc
,
22760 "not enough nested loops");
22761 omp_for_parse_state
->fail
= true;
22763 in_statement
= IN_OMP_FOR
;
22764 parser
->omp_for_parse_state
= NULL
;
22765 body
= push_stmt_list ();
22766 if (omp_for_parse_state
->inscan
)
22767 c_parser_omp_scan_loop_body (parser
, false);
22769 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
22770 body
= pop_stmt_list (body
);
22771 parser
->omp_for_parse_state
= omp_for_parse_state
;
22773 in_statement
= save_in_statement
;
22774 omp_for_parse_state
->want_nested_loop
= false;
22775 omp_for_parse_state
->in_intervening_code
= true;
22777 /* Pop and return the implicit scope surrounding this level of loop.
22778 If the iteration variable at this depth was bound in the for loop,
22779 pull out and save the binding. Later in c_parser_omp_for_loop,
22780 these bindings will be moved to the scope surrounding the entire
22781 OMP_FOR. That keeps the gimplifier happy later on, and meanwhile
22782 we have already resolved all references to the iteration variable
22783 in its true scope. */
22786 body
= c_end_compound_stmt (loc
, loop_scope
, true);
22787 if (decl
&& TREE_CODE (body
) == BIND_EXPR
)
22789 tree t
= BIND_EXPR_VARS (body
);
22790 tree prev
= NULL_TREE
, next
= NULL_TREE
;
22793 next
= DECL_CHAIN (t
);
22797 DECL_CHAIN (prev
) = next
;
22800 BIND_EXPR_VARS (body
) = next
;
22801 BLOCK_VARS (BIND_EXPR_BLOCK (body
)) = next
;
22803 DECL_CHAIN (t
) = omp_for_parse_state
->bindings
;
22804 omp_for_parse_state
->bindings
= t
;
22813 if (BIND_EXPR_VARS (body
) == NULL_TREE
)
22814 body
= BIND_EXPR_BODY (body
);
22820 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
22821 The real trick here is to determine the loop control variable early
22822 so that we can push a new decl if necessary to make it private.
22823 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
22827 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
22828 tree clauses
, tree
*cclauses
, bool *if_p
)
22830 tree body
, stmt
, cl
;
22831 tree ret
= NULL_TREE
;
22832 tree ordered_cl
= NULL_TREE
;
22833 int i
, collapse
= 1, ordered
= 0, count
;
22834 bool oacc_tiling
= false;
22835 bool inscan
= false;
22836 struct omp_for_parse_data data
;
22837 struct omp_for_parse_data
*save_data
= parser
->omp_for_parse_state
;
22839 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
22840 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
22841 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
22842 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
22844 oacc_tiling
= true;
22845 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
22847 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_SIZES
)
22848 collapse
= list_length (OMP_CLAUSE_SIZES_LIST (cl
));
22849 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
22850 && OMP_CLAUSE_ORDERED_EXPR (cl
))
22853 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
22855 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_REDUCTION
22856 && OMP_CLAUSE_REDUCTION_INSCAN (cl
)
22857 && (code
== OMP_SIMD
|| code
== OMP_FOR
))
22860 if (ordered
&& ordered
< collapse
)
22862 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
22863 "%<ordered%> clause parameter is less than %<collapse%>");
22864 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
22865 = build_int_cst (NULL_TREE
, collapse
);
22866 ordered
= collapse
;
22869 gcc_assert (oacc_tiling
|| (collapse
>= 1 && ordered
>= 0));
22870 count
= ordered
? ordered
: collapse
;
22872 if (!c_parser_omp_next_tokens_can_be_canon_loop (parser
, code
, true))
22875 /* Initialize parse state for recursive descent. */
22876 data
.declv
= make_tree_vec (count
);
22877 data
.initv
= make_tree_vec (count
);
22878 data
.condv
= make_tree_vec (count
);
22879 data
.incrv
= make_tree_vec (count
);
22880 data
.pre_body
= NULL_TREE
;
22881 data
.bindings
= NULL_TREE
;
22882 data
.for_loc
= c_parser_peek_token (parser
)->location
;
22883 data
.count
= count
;
22885 data
.want_nested_loop
= true;
22886 data
.ordered
= ordered
> 0;
22887 data
.in_intervening_code
= false;
22888 data
.perfect_nesting_fail
= false;
22890 data
.inscan
= inscan
;
22891 data
.saw_intervening_code
= false;
22893 parser
->omp_for_parse_state
= &data
;
22895 body
= c_parser_omp_loop_nest (parser
, if_p
);
22897 /* Add saved bindings for iteration variables that were declared in
22898 the nested for loop to the scope surrounding the entire loop. */
22899 for (tree t
= data
.bindings
; t
; )
22901 tree n
= TREE_CHAIN (t
);
22902 TREE_CHAIN (t
) = NULL_TREE
;
22907 /* Only bother calling c_finish_omp_for if we haven't already generated
22908 an error from the initialization parsing. */
22911 c_in_omp_for
= true;
22912 stmt
= c_finish_omp_for (loc
, code
, data
.declv
, NULL
, data
.initv
,
22913 data
.condv
, data
.incrv
,
22914 body
, data
.pre_body
, true);
22915 c_in_omp_for
= false;
22917 /* Check for iterators appearing in lb, b or incr expressions. */
22918 if (stmt
&& !c_omp_check_loop_iv (stmt
, data
.declv
, NULL
))
22921 /* Check for errors involving lb/ub/incr expressions referencing
22922 variables declared in intervening code. */
22923 if (data
.saw_intervening_code
22925 && !c_omp_check_loop_binding_exprs (stmt
, NULL
))
22932 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (stmt
)); i
++)
22934 tree init
= TREE_VEC_ELT (OMP_FOR_INIT (stmt
), i
);
22935 if (init
== NULL_TREE
)
22937 gcc_assert (TREE_CODE (init
) == MODIFY_EXPR
);
22938 tree decl
= TREE_OPERAND (init
, 0);
22939 tree cond
= TREE_VEC_ELT (OMP_FOR_COND (stmt
), i
);
22940 gcc_assert (COMPARISON_CLASS_P (cond
));
22941 gcc_assert (TREE_OPERAND (cond
, 0) == decl
);
22943 tree op0
= TREE_OPERAND (init
, 1);
22944 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
22945 || TREE_CODE (op0
) != TREE_VEC
)
22946 TREE_OPERAND (init
, 1) = c_fully_fold (op0
, false, NULL
);
22949 TREE_VEC_ELT (op0
, 1)
22950 = c_fully_fold (TREE_VEC_ELT (op0
, 1), false, NULL
);
22951 TREE_VEC_ELT (op0
, 2)
22952 = c_fully_fold (TREE_VEC_ELT (op0
, 2), false, NULL
);
22955 tree op1
= TREE_OPERAND (cond
, 1);
22956 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
22957 || TREE_CODE (op1
) != TREE_VEC
)
22958 TREE_OPERAND (cond
, 1) = c_fully_fold (op1
, false, NULL
);
22961 TREE_VEC_ELT (op1
, 1)
22962 = c_fully_fold (TREE_VEC_ELT (op1
, 1), false, NULL
);
22963 TREE_VEC_ELT (op1
, 2)
22964 = c_fully_fold (TREE_VEC_ELT (op1
, 2), false, NULL
);
22968 if (cclauses
!= NULL
22969 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
22972 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
22973 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
22974 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
22975 c
= &OMP_CLAUSE_CHAIN (*c
);
22978 for (i
= 0; i
< count
; i
++)
22979 if (TREE_VEC_ELT (data
.declv
, i
) == OMP_CLAUSE_DECL (*c
))
22982 c
= &OMP_CLAUSE_CHAIN (*c
);
22983 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
22986 "iteration variable %qD should not be firstprivate",
22987 OMP_CLAUSE_DECL (*c
));
22988 *c
= OMP_CLAUSE_CHAIN (*c
);
22992 /* Move lastprivate (decl) clause to
22993 OMP_FOR_CLAUSES. */
22995 *c
= OMP_CLAUSE_CHAIN (*c
);
22996 if (code
== OMP_SIMD
)
22998 OMP_CLAUSE_CHAIN (l
)
22999 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
23000 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
23004 OMP_CLAUSE_CHAIN (l
) = clauses
;
23010 OMP_FOR_CLAUSES (stmt
) = clauses
;
23015 parser
->omp_for_parse_state
= save_data
;
23019 /* Helper function for OpenMP parsing, split clauses and call
23020 finish_omp_clauses on each of the set of clauses afterwards. */
23023 omp_split_clauses (location_t loc
, enum tree_code code
,
23024 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
23027 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
23028 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
23030 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
],
23031 i
== C_OMP_CLAUSE_SPLIT_TARGET
23032 ? C_ORT_OMP_TARGET
: C_ORT_OMP
);
23036 #pragma omp loop loop-clause[optseq] new-line
23039 LOC is the location of the #pragma token.
23042 #define OMP_LOOP_CLAUSE_MASK \
23043 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23044 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23045 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23046 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23047 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
23048 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
23051 c_parser_omp_loop (location_t loc
, c_parser
*parser
,
23052 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23055 tree block
, clauses
, ret
;
23057 strcat (p_name
, " loop");
23058 mask
|= OMP_LOOP_CLAUSE_MASK
;
23060 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23063 omp_split_clauses (loc
, OMP_LOOP
, mask
, clauses
, cclauses
);
23064 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_LOOP
];
23067 block
= c_begin_compound_stmt (true);
23068 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_LOOP
, clauses
, cclauses
, if_p
);
23069 block
= c_end_compound_stmt (loc
, block
, true);
23076 #pragma omp simd simd-clause[optseq] new-line
23079 LOC is the location of the #pragma token.
23082 #define OMP_SIMD_CLAUSE_MASK \
23083 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
23084 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
23085 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
23086 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
23087 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23088 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23089 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23090 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23091 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23092 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
23093 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
23096 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
23097 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23100 tree block
, clauses
, ret
;
23102 strcat (p_name
, " simd");
23103 mask
|= OMP_SIMD_CLAUSE_MASK
;
23105 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23108 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
23109 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
23112 block
= c_begin_compound_stmt (true);
23113 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
23114 block
= c_end_compound_stmt (loc
, block
, true);
23121 #pragma omp for for-clause[optseq] new-line
23125 #pragma omp for simd for-simd-clause[optseq] new-line
23128 LOC is the location of the #pragma token.
23131 #define OMP_FOR_CLAUSE_MASK \
23132 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23133 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23134 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23135 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
23136 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23137 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
23138 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
23139 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23140 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
23141 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23142 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
23145 c_parser_omp_for (location_t loc
, c_parser
*parser
,
23146 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23149 tree block
, clauses
, ret
;
23151 strcat (p_name
, " for");
23152 mask
|= OMP_FOR_CLAUSE_MASK
;
23153 /* parallel for{, simd} disallows nowait clause, but for
23154 target {teams distribute ,}parallel for{, simd} it should be accepted. */
23155 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
23156 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
23157 /* Composite distribute parallel for{, simd} disallows ordered clause. */
23158 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
23159 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
23161 if (c_parser_next_token_is (parser
, CPP_NAME
))
23163 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23165 if (strcmp (p
, "simd") == 0)
23167 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23168 if (cclauses
== NULL
)
23169 cclauses
= cclauses_buf
;
23171 c_parser_consume_token (parser
);
23172 if (!flag_openmp
) /* flag_openmp_simd */
23173 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
23175 block
= c_begin_compound_stmt (true);
23176 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
23177 block
= c_end_compound_stmt (loc
, block
, true);
23178 if (ret
== NULL_TREE
)
23180 ret
= make_node (OMP_FOR
);
23181 TREE_TYPE (ret
) = void_type_node
;
23182 OMP_FOR_BODY (ret
) = block
;
23183 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
23184 SET_EXPR_LOCATION (ret
, loc
);
23189 if (!flag_openmp
) /* flag_openmp_simd */
23191 c_parser_skip_to_pragma_eol (parser
, false);
23195 /* Composite distribute parallel for disallows linear clause. */
23196 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
23197 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
23199 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23202 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
23203 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
23206 block
= c_begin_compound_stmt (true);
23207 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
23208 block
= c_end_compound_stmt (loc
, block
, true);
23214 static tree
c_parser_omp_taskloop (location_t
, c_parser
*, char *,
23215 omp_clause_mask
, tree
*, bool *);
23218 # pragma omp master new-line
23221 LOC is the location of the #pragma token.
23225 c_parser_omp_master (location_t loc
, c_parser
*parser
,
23226 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23229 tree block
, clauses
, ret
;
23231 strcat (p_name
, " master");
23233 if (c_parser_next_token_is (parser
, CPP_NAME
))
23235 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23237 if (strcmp (p
, "taskloop") == 0)
23239 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23240 if (cclauses
== NULL
)
23241 cclauses
= cclauses_buf
;
23243 c_parser_consume_token (parser
);
23244 if (!flag_openmp
) /* flag_openmp_simd */
23245 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
23247 block
= c_begin_compound_stmt (true);
23248 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
23250 block
= c_end_compound_stmt (loc
, block
, true);
23251 if (ret
== NULL_TREE
)
23253 ret
= c_finish_omp_master (loc
, block
);
23254 OMP_MASTER_COMBINED (ret
) = 1;
23258 if (!flag_openmp
) /* flag_openmp_simd */
23260 c_parser_skip_to_pragma_eol (parser
, false);
23266 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, false);
23267 omp_split_clauses (loc
, OMP_MASTER
, mask
, clauses
, cclauses
);
23270 c_parser_skip_to_pragma_eol (parser
);
23272 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
23277 # pragma omp masked masked-clauses new-line
23280 LOC is the location of the #pragma token.
23283 #define OMP_MASKED_CLAUSE_MASK \
23284 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
23287 c_parser_omp_masked (location_t loc
, c_parser
*parser
,
23288 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23291 tree block
, clauses
, ret
;
23293 strcat (p_name
, " masked");
23294 mask
|= OMP_MASKED_CLAUSE_MASK
;
23296 if (c_parser_next_token_is (parser
, CPP_NAME
))
23298 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23300 if (strcmp (p
, "taskloop") == 0)
23302 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23303 if (cclauses
== NULL
)
23304 cclauses
= cclauses_buf
;
23306 c_parser_consume_token (parser
);
23307 if (!flag_openmp
) /* flag_openmp_simd */
23308 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
23310 block
= c_begin_compound_stmt (true);
23311 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
23313 block
= c_end_compound_stmt (loc
, block
, true);
23314 if (ret
== NULL_TREE
)
23316 ret
= c_finish_omp_masked (loc
, block
,
23317 cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
]);
23318 OMP_MASKED_COMBINED (ret
) = 1;
23322 if (!flag_openmp
) /* flag_openmp_simd */
23324 c_parser_skip_to_pragma_eol (parser
, false);
23328 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23331 omp_split_clauses (loc
, OMP_MASKED
, mask
, clauses
, cclauses
);
23332 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
];
23335 return c_finish_omp_masked (loc
, c_parser_omp_structured_block (parser
,
23341 # pragma omp ordered new-line
23345 # pragma omp ordered ordered-clauses new-line
23348 # pragma omp ordered depend-clauses new-line
23351 # pragma omp ordered doacross-clauses new-line */
23353 #define OMP_ORDERED_CLAUSE_MASK \
23354 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
23355 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
23357 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
23358 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23359 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
23362 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
23365 location_t loc
= c_parser_peek_token (parser
)->location
;
23366 c_parser_consume_pragma (parser
);
23368 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
23370 c_parser_error (parser
, "expected declaration specifiers");
23371 c_parser_skip_to_pragma_eol (parser
, false);
23376 if (c_parser_next_token_is (parser
, CPP_COMMA
))
23379 if (c_parser_peek_nth_token (parser
, n
)->type
== CPP_NAME
)
23382 = IDENTIFIER_POINTER (c_parser_peek_nth_token (parser
, n
)->value
);
23384 if (!strcmp ("depend", p
) || !strcmp ("doacross", p
))
23386 if (!flag_openmp
) /* flag_openmp_simd */
23388 c_parser_skip_to_pragma_eol (parser
, false);
23391 if (context
== pragma_stmt
)
23394 "%<#pragma omp ordered%> with %qs clause may "
23395 "only be used in compound statements", p
);
23396 c_parser_skip_to_pragma_eol (parser
, false);
23401 = c_parser_omp_all_clauses (parser
,
23402 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
23403 "#pragma omp ordered");
23404 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
23409 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
23410 "#pragma omp ordered");
23412 if (!flag_openmp
/* flag_openmp_simd */
23413 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
23416 c_finish_omp_ordered (loc
, clauses
,
23417 c_parser_omp_structured_block (parser
, if_p
));
23424 { section-sequence }
23427 section-directive[opt] structured-block
23428 section-sequence section-directive structured-block
23430 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
23432 SECTIONS_LOC is the location of the #pragma omp sections. */
23435 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
23437 tree stmt
, substmt
;
23438 bool error_suppress
= false;
23441 loc
= c_parser_peek_token (parser
)->location
;
23442 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
23444 /* Avoid skipping until the end of the block. */
23445 parser
->error
= false;
23449 stmt
= push_stmt_list ();
23451 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
23452 && !c_parser_omp_section_scan (parser
, "section", true))
23454 substmt
= c_parser_omp_structured_block_sequence (parser
,
23455 PRAGMA_OMP_SECTION
);
23456 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
23457 SET_EXPR_LOCATION (substmt
, loc
);
23458 add_stmt (substmt
);
23463 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
23465 if (c_parser_next_token_is (parser
, CPP_EOF
))
23468 loc
= c_parser_peek_token (parser
)->location
;
23469 c_parser_omp_section_scan (parser
, "section", false);
23470 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
23472 c_parser_consume_pragma (parser
);
23473 c_parser_skip_to_pragma_eol (parser
);
23474 error_suppress
= false;
23476 else if (!error_suppress
)
23478 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
23479 error_suppress
= true;
23482 substmt
= c_parser_omp_structured_block_sequence (parser
,
23483 PRAGMA_OMP_SECTION
);
23484 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
23485 SET_EXPR_LOCATION (substmt
, loc
);
23486 add_stmt (substmt
);
23488 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
23489 "expected %<#pragma omp section%> or %<}%>");
23491 substmt
= pop_stmt_list (stmt
);
23493 stmt
= make_node (OMP_SECTIONS
);
23494 SET_EXPR_LOCATION (stmt
, sections_loc
);
23495 TREE_TYPE (stmt
) = void_type_node
;
23496 OMP_SECTIONS_BODY (stmt
) = substmt
;
23498 return add_stmt (stmt
);
23502 # pragma omp sections sections-clause[optseq] newline
23505 LOC is the location of the #pragma token.
23508 #define OMP_SECTIONS_CLAUSE_MASK \
23509 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23513 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23514 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23517 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
23518 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
23520 tree block
, clauses
, ret
;
23522 strcat (p_name
, " sections");
23523 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
23525 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
23527 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23530 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
23531 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
23534 block
= c_begin_compound_stmt (true);
23535 ret
= c_parser_omp_sections_scope (loc
, parser
);
23537 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
23538 block
= c_end_compound_stmt (loc
, block
, true);
23545 # pragma omp parallel parallel-clause[optseq] new-line
23547 # pragma omp parallel for parallel-for-clause[optseq] new-line
23549 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
23553 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
23556 LOC is the location of the #pragma token.
23559 #define OMP_PARALLEL_CLAUSE_MASK \
23560 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23561 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23562 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23563 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23564 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23565 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
23566 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23567 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
23568 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23569 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
23572 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
23573 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23576 tree stmt
, clauses
, block
;
23578 strcat (p_name
, " parallel");
23579 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
23580 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
23581 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
23582 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
23583 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
23585 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
23587 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23588 if (cclauses
== NULL
)
23589 cclauses
= cclauses_buf
;
23591 c_parser_consume_token (parser
);
23592 if (!flag_openmp
) /* flag_openmp_simd */
23593 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
23594 block
= c_begin_omp_parallel ();
23595 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
23597 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23599 if (ret
== NULL_TREE
)
23601 OMP_PARALLEL_COMBINED (stmt
) = 1;
23604 /* When combined with distribute, parallel has to be followed by for.
23605 #pragma omp target parallel is allowed though. */
23607 && (mask
& (OMP_CLAUSE_MASK_1
23608 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
23610 error_at (loc
, "expected %<for%> after %qs", p_name
);
23611 c_parser_skip_to_pragma_eol (parser
);
23614 else if (c_parser_next_token_is (parser
, CPP_NAME
))
23616 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23617 if (cclauses
== NULL
&& strcmp (p
, "masked") == 0)
23619 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23620 cclauses
= cclauses_buf
;
23622 c_parser_consume_token (parser
);
23623 if (!flag_openmp
) /* flag_openmp_simd */
23624 return c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
23626 block
= c_begin_omp_parallel ();
23627 tree ret
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
23629 stmt
= c_finish_omp_parallel (loc
,
23630 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23634 /* masked does have just filter clause, but during gimplification
23635 isn't represented by a gimplification omp context, so for
23636 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
23638 #pragma omp parallel masked
23639 #pragma omp taskloop simd lastprivate (x)
23640 isn't confused with
23641 #pragma omp parallel masked taskloop simd lastprivate (x) */
23642 if (OMP_MASKED_COMBINED (ret
))
23643 OMP_PARALLEL_COMBINED (stmt
) = 1;
23646 else if (cclauses
== NULL
&& strcmp (p
, "master") == 0)
23648 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23649 cclauses
= cclauses_buf
;
23651 c_parser_consume_token (parser
);
23652 if (!flag_openmp
) /* flag_openmp_simd */
23653 return c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
23655 block
= c_begin_omp_parallel ();
23656 tree ret
= c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
23658 stmt
= c_finish_omp_parallel (loc
,
23659 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23663 /* master doesn't have any clauses and during gimplification
23664 isn't represented by a gimplification omp context, so for
23665 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
23667 #pragma omp parallel master
23668 #pragma omp taskloop simd lastprivate (x)
23669 isn't confused with
23670 #pragma omp parallel master taskloop simd lastprivate (x) */
23671 if (OMP_MASTER_COMBINED (ret
))
23672 OMP_PARALLEL_COMBINED (stmt
) = 1;
23675 else if (strcmp (p
, "loop") == 0)
23677 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23678 if (cclauses
== NULL
)
23679 cclauses
= cclauses_buf
;
23681 c_parser_consume_token (parser
);
23682 if (!flag_openmp
) /* flag_openmp_simd */
23683 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
23685 block
= c_begin_omp_parallel ();
23686 tree ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
23689 = c_finish_omp_parallel (loc
,
23690 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23692 if (ret
== NULL_TREE
)
23694 OMP_PARALLEL_COMBINED (stmt
) = 1;
23697 else if (!flag_openmp
) /* flag_openmp_simd */
23699 c_parser_skip_to_pragma_eol (parser
, false);
23702 else if (cclauses
== NULL
&& strcmp (p
, "sections") == 0)
23704 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23705 cclauses
= cclauses_buf
;
23707 c_parser_consume_token (parser
);
23708 block
= c_begin_omp_parallel ();
23709 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
23710 stmt
= c_finish_omp_parallel (loc
,
23711 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23713 OMP_PARALLEL_COMBINED (stmt
) = 1;
23717 else if (!flag_openmp
) /* flag_openmp_simd */
23719 c_parser_skip_to_pragma_eol (parser
, false);
23723 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23726 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
23727 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
23730 block
= c_begin_omp_parallel ();
23731 parser
->omp_attrs_forbidden_p
= true;
23732 c_parser_statement (parser
, if_p
);
23733 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
23739 # pragma omp single single-clause[optseq] new-line
23742 LOC is the location of the #pragma.
23745 #define OMP_SINGLE_CLAUSE_MASK \
23746 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
23749 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23750 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23753 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
23755 tree stmt
= make_node (OMP_SINGLE
);
23756 SET_EXPR_LOCATION (stmt
, loc
);
23757 TREE_TYPE (stmt
) = void_type_node
;
23759 OMP_SINGLE_CLAUSES (stmt
)
23760 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
23761 "#pragma omp single");
23762 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
23764 return add_stmt (stmt
);
23768 # pragma omp scope scope-clause[optseq] new-line
23771 LOC is the location of the #pragma.
23774 #define OMP_SCOPE_CLAUSE_MASK \
23775 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23776 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23777 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23778 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23779 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23782 c_parser_omp_scope (location_t loc
, c_parser
*parser
, bool *if_p
)
23784 tree stmt
= make_node (OMP_SCOPE
);
23785 SET_EXPR_LOCATION (stmt
, loc
);
23786 TREE_TYPE (stmt
) = void_type_node
;
23788 OMP_SCOPE_CLAUSES (stmt
)
23789 = c_parser_omp_all_clauses (parser
, OMP_SCOPE_CLAUSE_MASK
,
23790 "#pragma omp scope");
23791 OMP_SCOPE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
23793 return add_stmt (stmt
);
23797 # pragma omp task task-clause[optseq] new-line
23799 LOC is the location of the #pragma.
23802 #define OMP_TASK_CLAUSE_MASK \
23803 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
23805 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23806 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23807 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23808 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23809 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
23810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
23811 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23812 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
23813 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
23815 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
23816 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
23819 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
23821 tree clauses
, block
;
23823 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
23824 "#pragma omp task");
23826 block
= c_begin_omp_task ();
23827 parser
->omp_attrs_forbidden_p
= true;
23828 c_parser_statement (parser
, if_p
);
23829 return c_finish_omp_task (loc
, clauses
, block
);
23833 # pragma omp taskwait new-line
23836 # pragma omp taskwait taskwait-clause[optseq] new-line
23839 #define OMP_TASKWAIT_CLAUSE_MASK \
23840 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23841 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23844 c_parser_omp_taskwait (c_parser
*parser
)
23846 location_t loc
= c_parser_peek_token (parser
)->location
;
23847 c_parser_consume_pragma (parser
);
23850 = c_parser_omp_all_clauses (parser
, OMP_TASKWAIT_CLAUSE_MASK
,
23851 "#pragma omp taskwait");
23855 tree stmt
= make_node (OMP_TASK
);
23856 TREE_TYPE (stmt
) = void_node
;
23857 OMP_TASK_CLAUSES (stmt
) = clauses
;
23858 OMP_TASK_BODY (stmt
) = NULL_TREE
;
23859 SET_EXPR_LOCATION (stmt
, loc
);
23863 c_finish_omp_taskwait (loc
);
23867 # pragma omp taskyield new-line
23871 c_parser_omp_taskyield (c_parser
*parser
)
23873 location_t loc
= c_parser_peek_token (parser
)->location
;
23874 c_parser_consume_pragma (parser
);
23875 c_parser_skip_to_pragma_eol (parser
);
23877 c_finish_omp_taskyield (loc
);
23881 # pragma omp taskgroup new-line
23884 # pragma omp taskgroup taskgroup-clause[optseq] new-line
23887 #define OMP_TASKGROUP_CLAUSE_MASK \
23888 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23889 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
23892 c_parser_omp_taskgroup (location_t loc
, c_parser
*parser
, bool *if_p
)
23894 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_TASKGROUP_CLAUSE_MASK
,
23895 "#pragma omp taskgroup");
23897 tree body
= c_parser_omp_structured_block (parser
, if_p
);
23898 return c_finish_omp_taskgroup (loc
, body
, clauses
);
23902 # pragma omp cancel cancel-clause[optseq] new-line
23904 LOC is the location of the #pragma.
23907 #define OMP_CANCEL_CLAUSE_MASK \
23908 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23909 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23910 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
23912 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
23915 c_parser_omp_cancel (c_parser
*parser
)
23917 location_t loc
= c_parser_peek_token (parser
)->location
;
23919 c_parser_consume_pragma (parser
);
23920 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
23921 "#pragma omp cancel");
23923 c_finish_omp_cancel (loc
, clauses
);
23927 # pragma omp cancellation point cancelpt-clause[optseq] new-line
23929 LOC is the location of the #pragma.
23932 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
23933 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23934 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23935 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23936 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
23939 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
23941 location_t loc
= c_parser_peek_token (parser
)->location
;
23943 bool point_seen
= false;
23945 c_parser_consume_pragma (parser
);
23946 if (c_parser_next_token_is (parser
, CPP_NAME
))
23948 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23949 if (strcmp (p
, "point") == 0)
23951 c_parser_consume_token (parser
);
23957 c_parser_error (parser
, "expected %<point%>");
23958 c_parser_skip_to_pragma_eol (parser
);
23962 if (context
!= pragma_compound
)
23964 if (context
== pragma_stmt
)
23966 "%<#pragma %s%> may only be used in compound statements",
23967 "omp cancellation point");
23969 c_parser_error (parser
, "expected declaration specifiers");
23970 c_parser_skip_to_pragma_eol (parser
, false);
23975 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
23976 "#pragma omp cancellation point");
23978 c_finish_omp_cancellation_point (loc
, clauses
);
23983 #pragma omp distribute distribute-clause[optseq] new-line
23986 #define OMP_DISTRIBUTE_CLAUSE_MASK \
23987 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23988 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23989 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23990 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
23991 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23992 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23993 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
23996 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
23997 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
24000 tree clauses
, block
, ret
;
24002 strcat (p_name
, " distribute");
24003 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
24005 if (c_parser_next_token_is (parser
, CPP_NAME
))
24007 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24009 bool parallel
= false;
24011 if (strcmp (p
, "simd") == 0)
24014 parallel
= strcmp (p
, "parallel") == 0;
24015 if (parallel
|| simd
)
24017 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
24018 if (cclauses
== NULL
)
24019 cclauses
= cclauses_buf
;
24020 c_parser_consume_token (parser
);
24021 if (!flag_openmp
) /* flag_openmp_simd */
24024 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
24027 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
24030 block
= c_begin_compound_stmt (true);
24032 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
24035 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
24037 block
= c_end_compound_stmt (loc
, block
, true);
24040 ret
= make_node (OMP_DISTRIBUTE
);
24041 TREE_TYPE (ret
) = void_type_node
;
24042 OMP_FOR_BODY (ret
) = block
;
24043 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
24044 SET_EXPR_LOCATION (ret
, loc
);
24049 if (!flag_openmp
) /* flag_openmp_simd */
24051 c_parser_skip_to_pragma_eol (parser
, false);
24055 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
24058 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
24059 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
24062 block
= c_begin_compound_stmt (true);
24063 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
24065 block
= c_end_compound_stmt (loc
, block
, true);
24072 # pragma omp teams teams-clause[optseq] new-line
24073 structured-block */
24075 #define OMP_TEAMS_CLAUSE_MASK \
24076 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
24077 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
24078 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
24079 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
24080 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
24081 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
24082 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
24083 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
24086 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
24087 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
24090 tree clauses
, block
, ret
;
24092 strcat (p_name
, " teams");
24093 mask
|= OMP_TEAMS_CLAUSE_MASK
;
24095 if (c_parser_next_token_is (parser
, CPP_NAME
))
24097 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24098 if (strcmp (p
, "distribute") == 0)
24100 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
24101 if (cclauses
== NULL
)
24102 cclauses
= cclauses_buf
;
24104 c_parser_consume_token (parser
);
24105 if (!flag_openmp
) /* flag_openmp_simd */
24106 return c_parser_omp_distribute (loc
, parser
, p_name
, mask
,
24108 block
= c_begin_omp_parallel ();
24109 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
24111 block
= c_end_compound_stmt (loc
, block
, true);
24114 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
24115 ret
= make_node (OMP_TEAMS
);
24116 TREE_TYPE (ret
) = void_type_node
;
24117 OMP_TEAMS_CLAUSES (ret
) = clauses
;
24118 OMP_TEAMS_BODY (ret
) = block
;
24119 OMP_TEAMS_COMBINED (ret
) = 1;
24120 SET_EXPR_LOCATION (ret
, loc
);
24121 return add_stmt (ret
);
24123 else if (strcmp (p
, "loop") == 0)
24125 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
24126 if (cclauses
== NULL
)
24127 cclauses
= cclauses_buf
;
24129 c_parser_consume_token (parser
);
24130 if (!flag_openmp
) /* flag_openmp_simd */
24131 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
24133 block
= c_begin_omp_parallel ();
24134 ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
24135 block
= c_end_compound_stmt (loc
, block
, true);
24138 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
24139 ret
= make_node (OMP_TEAMS
);
24140 TREE_TYPE (ret
) = void_type_node
;
24141 OMP_TEAMS_CLAUSES (ret
) = clauses
;
24142 OMP_TEAMS_BODY (ret
) = block
;
24143 OMP_TEAMS_COMBINED (ret
) = 1;
24144 SET_EXPR_LOCATION (ret
, loc
);
24145 return add_stmt (ret
);
24148 if (!flag_openmp
) /* flag_openmp_simd */
24150 c_parser_skip_to_pragma_eol (parser
, false);
24154 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
24157 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
24158 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
24161 tree stmt
= make_node (OMP_TEAMS
);
24162 TREE_TYPE (stmt
) = void_type_node
;
24163 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
24164 block
= c_begin_omp_parallel ();
24165 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
24166 OMP_TEAMS_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
24167 SET_EXPR_LOCATION (stmt
, loc
);
24169 return add_stmt (stmt
);
24173 # pragma omp target data target-data-clause[optseq] new-line
24174 structured-block */
24176 #define OMP_TARGET_DATA_CLAUSE_MASK \
24177 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24178 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24179 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24180 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
24181 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
24184 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
24188 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
24191 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
24192 "#pragma omp target data");
24193 c_omp_adjust_map_clauses (clauses
, false);
24195 for (tree
*pc
= &clauses
; *pc
;)
24197 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
24198 switch (OMP_CLAUSE_MAP_KIND (*pc
))
24201 case GOMP_MAP_ALWAYS_TO
:
24202 case GOMP_MAP_PRESENT_TO
:
24203 case GOMP_MAP_ALWAYS_PRESENT_TO
:
24204 case GOMP_MAP_FROM
:
24205 case GOMP_MAP_ALWAYS_FROM
:
24206 case GOMP_MAP_PRESENT_FROM
:
24207 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
24208 case GOMP_MAP_TOFROM
:
24209 case GOMP_MAP_ALWAYS_TOFROM
:
24210 case GOMP_MAP_PRESENT_TOFROM
:
24211 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
24212 case GOMP_MAP_ALLOC
:
24213 case GOMP_MAP_PRESENT_ALLOC
:
24216 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
24217 case GOMP_MAP_ALWAYS_POINTER
:
24218 case GOMP_MAP_ATTACH_DETACH
:
24219 case GOMP_MAP_ATTACH
:
24223 error_at (OMP_CLAUSE_LOCATION (*pc
),
24224 "%<#pragma omp target data%> with map-type other "
24225 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
24226 "on %<map%> clause");
24227 *pc
= OMP_CLAUSE_CHAIN (*pc
);
24230 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
24231 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
24233 pc
= &OMP_CLAUSE_CHAIN (*pc
);
24240 "%<#pragma omp target data%> must contain at least "
24241 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
24246 tree stmt
= make_node (OMP_TARGET_DATA
);
24247 TREE_TYPE (stmt
) = void_type_node
;
24248 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
24249 keep_next_level ();
24250 tree block
= c_begin_compound_stmt (true);
24251 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
24252 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
24254 SET_EXPR_LOCATION (stmt
, loc
);
24255 return add_stmt (stmt
);
24259 # pragma omp target update target-update-clause[optseq] new-line */
24261 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
24262 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
24263 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
24264 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24265 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24266 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24267 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
24270 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
24271 enum pragma_context context
)
24273 if (context
== pragma_stmt
)
24275 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
24276 "omp target update");
24277 c_parser_skip_to_pragma_eol (parser
, false);
24282 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
24283 "#pragma omp target update");
24284 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
24285 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
24288 "%<#pragma omp target update%> must contain at least one "
24289 "%<from%> or %<to%> clauses");
24295 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
24297 tree stmt
= make_node (OMP_TARGET_UPDATE
);
24298 TREE_TYPE (stmt
) = void_type_node
;
24299 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
24300 SET_EXPR_LOCATION (stmt
, loc
);
24306 # pragma omp target enter data target-data-clause[optseq] new-line */
24308 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
24309 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24310 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24311 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24312 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24313 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
24316 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
24317 enum pragma_context context
)
24319 bool data_seen
= false;
24320 if (c_parser_next_token_is (parser
, CPP_NAME
))
24322 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24323 if (strcmp (p
, "data") == 0)
24325 c_parser_consume_token (parser
);
24331 c_parser_error (parser
, "expected %<data%>");
24332 c_parser_skip_to_pragma_eol (parser
);
24336 if (context
== pragma_stmt
)
24338 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
24339 "omp target enter data");
24340 c_parser_skip_to_pragma_eol (parser
, false);
24346 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
24349 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
24350 "#pragma omp target enter data");
24351 c_omp_adjust_map_clauses (clauses
, false);
24353 for (tree
*pc
= &clauses
; *pc
;)
24355 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
24356 switch (OMP_CLAUSE_MAP_KIND (*pc
))
24359 case GOMP_MAP_ALWAYS_TO
:
24360 case GOMP_MAP_PRESENT_TO
:
24361 case GOMP_MAP_ALWAYS_PRESENT_TO
:
24362 case GOMP_MAP_ALLOC
:
24363 case GOMP_MAP_PRESENT_ALLOC
:
24366 case GOMP_MAP_TOFROM
:
24367 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_TO
);
24370 case GOMP_MAP_ALWAYS_TOFROM
:
24371 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_TO
);
24374 case GOMP_MAP_PRESENT_TOFROM
:
24375 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_PRESENT_TO
);
24378 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
24379 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_PRESENT_TO
);
24382 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
24383 case GOMP_MAP_ALWAYS_POINTER
:
24384 case GOMP_MAP_ATTACH_DETACH
:
24385 case GOMP_MAP_ATTACH
:
24389 error_at (OMP_CLAUSE_LOCATION (*pc
),
24390 "%<#pragma omp target enter data%> with map-type other "
24391 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
24392 *pc
= OMP_CLAUSE_CHAIN (*pc
);
24395 pc
= &OMP_CLAUSE_CHAIN (*pc
);
24402 "%<#pragma omp target enter data%> must contain at least "
24403 "one %<map%> clause");
24407 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
24408 TREE_TYPE (stmt
) = void_type_node
;
24409 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
24410 SET_EXPR_LOCATION (stmt
, loc
);
24416 # pragma omp target exit data target-data-clause[optseq] new-line */
24418 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
24419 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24420 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24421 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24422 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24423 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
24426 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
24427 enum pragma_context context
)
24429 bool data_seen
= false;
24430 if (c_parser_next_token_is (parser
, CPP_NAME
))
24432 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24433 if (strcmp (p
, "data") == 0)
24435 c_parser_consume_token (parser
);
24441 c_parser_error (parser
, "expected %<data%>");
24442 c_parser_skip_to_pragma_eol (parser
);
24446 if (context
== pragma_stmt
)
24448 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
24449 "omp target exit data");
24450 c_parser_skip_to_pragma_eol (parser
, false);
24456 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
24459 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
24460 "#pragma omp target exit data", false);
24461 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP_EXIT_DATA
);
24462 c_omp_adjust_map_clauses (clauses
, false);
24464 for (tree
*pc
= &clauses
; *pc
;)
24466 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
24467 switch (OMP_CLAUSE_MAP_KIND (*pc
))
24469 case GOMP_MAP_FROM
:
24470 case GOMP_MAP_ALWAYS_FROM
:
24471 case GOMP_MAP_PRESENT_FROM
:
24472 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
24473 case GOMP_MAP_RELEASE
:
24474 case GOMP_MAP_DELETE
:
24477 case GOMP_MAP_TOFROM
:
24478 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_FROM
);
24481 case GOMP_MAP_ALWAYS_TOFROM
:
24482 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_FROM
);
24485 case GOMP_MAP_PRESENT_TOFROM
:
24486 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_PRESENT_FROM
);
24489 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
24490 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_PRESENT_FROM
);
24493 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
24494 case GOMP_MAP_ALWAYS_POINTER
:
24495 case GOMP_MAP_ATTACH_DETACH
:
24496 case GOMP_MAP_DETACH
:
24500 error_at (OMP_CLAUSE_LOCATION (*pc
),
24501 "%<#pragma omp target exit data%> with map-type other "
24502 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
24503 "on %<map%> clause");
24504 *pc
= OMP_CLAUSE_CHAIN (*pc
);
24507 pc
= &OMP_CLAUSE_CHAIN (*pc
);
24514 "%<#pragma omp target exit data%> must contain at least one "
24519 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
24520 TREE_TYPE (stmt
) = void_type_node
;
24521 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
24522 SET_EXPR_LOCATION (stmt
, loc
);
24528 # pragma omp target target-clause[optseq] new-line
24529 structured-block */
24531 #define OMP_TARGET_CLAUSE_MASK \
24532 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24533 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24534 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24535 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24536 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
24537 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
24538 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
24539 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
24540 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
24541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
24542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
24543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
24544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
24547 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
24549 location_t loc
= c_parser_peek_token (parser
)->location
;
24550 c_parser_consume_pragma (parser
);
24551 tree
*pc
= NULL
, stmt
, block
;
24553 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
24555 c_parser_error (parser
, "expected declaration specifiers");
24556 c_parser_skip_to_pragma_eol (parser
);
24562 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
24564 if (c_parser_next_token_is (parser
, CPP_NAME
))
24566 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24567 enum tree_code ccode
= ERROR_MARK
;
24569 if (strcmp (p
, "teams") == 0)
24571 else if (strcmp (p
, "parallel") == 0)
24572 ccode
= OMP_PARALLEL
;
24573 else if (strcmp (p
, "simd") == 0)
24575 if (ccode
!= ERROR_MARK
)
24577 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
24578 char p_name
[sizeof ("#pragma omp target teams distribute "
24579 "parallel for simd")];
24581 c_parser_consume_token (parser
);
24582 strcpy (p_name
, "#pragma omp target");
24583 if (!flag_openmp
) /* flag_openmp_simd */
24589 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
24590 OMP_TARGET_CLAUSE_MASK
,
24594 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
24595 OMP_TARGET_CLAUSE_MASK
,
24599 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
24600 OMP_TARGET_CLAUSE_MASK
,
24604 gcc_unreachable ();
24606 return stmt
!= NULL_TREE
;
24608 keep_next_level ();
24609 tree block
= c_begin_compound_stmt (true), ret
;
24613 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
24614 OMP_TARGET_CLAUSE_MASK
, cclauses
,
24618 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
24619 OMP_TARGET_CLAUSE_MASK
, cclauses
,
24623 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
24624 OMP_TARGET_CLAUSE_MASK
, cclauses
,
24628 gcc_unreachable ();
24630 block
= c_end_compound_stmt (loc
, block
, true);
24631 if (ret
== NULL_TREE
)
24633 if (ccode
== OMP_TEAMS
)
24634 /* For combined target teams, ensure the num_teams and
24635 thread_limit clause expressions are evaluated on the host,
24636 before entering the target construct. */
24637 for (tree c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
24638 c
; c
= OMP_CLAUSE_CHAIN (c
))
24639 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
24640 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
24642 i
<= (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
); ++i
)
24643 if (OMP_CLAUSE_OPERAND (c
, i
)
24644 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, i
)) != INTEGER_CST
)
24646 tree expr
= OMP_CLAUSE_OPERAND (c
, i
);
24647 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
24648 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
24649 expr
, NULL_TREE
, NULL_TREE
);
24651 OMP_CLAUSE_OPERAND (c
, i
) = expr
;
24652 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
24653 OMP_CLAUSE_FIRSTPRIVATE
);
24654 OMP_CLAUSE_DECL (tc
) = tmp
;
24655 OMP_CLAUSE_CHAIN (tc
)
24656 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
24657 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
24659 tree stmt
= make_node (OMP_TARGET
);
24660 TREE_TYPE (stmt
) = void_type_node
;
24661 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
24662 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
24663 OMP_TARGET_BODY (stmt
) = block
;
24664 OMP_TARGET_COMBINED (stmt
) = 1;
24665 SET_EXPR_LOCATION (stmt
, loc
);
24667 pc
= &OMP_TARGET_CLAUSES (stmt
);
24668 goto check_clauses
;
24670 else if (!flag_openmp
) /* flag_openmp_simd */
24672 c_parser_skip_to_pragma_eol (parser
, false);
24675 else if (strcmp (p
, "data") == 0)
24677 c_parser_consume_token (parser
);
24678 c_parser_omp_target_data (loc
, parser
, if_p
);
24681 else if (strcmp (p
, "enter") == 0)
24683 c_parser_consume_token (parser
);
24684 return c_parser_omp_target_enter_data (loc
, parser
, context
);
24686 else if (strcmp (p
, "exit") == 0)
24688 c_parser_consume_token (parser
);
24689 return c_parser_omp_target_exit_data (loc
, parser
, context
);
24691 else if (strcmp (p
, "update") == 0)
24693 c_parser_consume_token (parser
);
24694 return c_parser_omp_target_update (loc
, parser
, context
);
24697 if (!flag_openmp
) /* flag_openmp_simd */
24699 c_parser_skip_to_pragma_eol (parser
, false);
24703 stmt
= make_node (OMP_TARGET
);
24704 TREE_TYPE (stmt
) = void_type_node
;
24706 OMP_TARGET_CLAUSES (stmt
)
24707 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
24708 "#pragma omp target", false);
24709 for (tree c
= OMP_TARGET_CLAUSES (stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
24710 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
)
24712 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
24713 OMP_CLAUSE_DECL (nc
) = OMP_CLAUSE_DECL (c
);
24714 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_ALWAYS_TOFROM
);
24715 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
24716 OMP_CLAUSE_CHAIN (c
) = nc
;
24718 OMP_TARGET_CLAUSES (stmt
)
24719 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt
), C_ORT_OMP_TARGET
);
24720 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
24722 pc
= &OMP_TARGET_CLAUSES (stmt
);
24723 keep_next_level ();
24724 block
= c_begin_compound_stmt (true);
24725 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
24726 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
24728 SET_EXPR_LOCATION (stmt
, loc
);
24734 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
24735 switch (OMP_CLAUSE_MAP_KIND (*pc
))
24738 case GOMP_MAP_ALWAYS_TO
:
24739 case GOMP_MAP_PRESENT_TO
:
24740 case GOMP_MAP_ALWAYS_PRESENT_TO
:
24741 case GOMP_MAP_FROM
:
24742 case GOMP_MAP_ALWAYS_FROM
:
24743 case GOMP_MAP_PRESENT_FROM
:
24744 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
24745 case GOMP_MAP_TOFROM
:
24746 case GOMP_MAP_ALWAYS_TOFROM
:
24747 case GOMP_MAP_PRESENT_TOFROM
:
24748 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
24749 case GOMP_MAP_ALLOC
:
24750 case GOMP_MAP_PRESENT_ALLOC
:
24751 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
24752 case GOMP_MAP_ALWAYS_POINTER
:
24753 case GOMP_MAP_POINTER
:
24754 case GOMP_MAP_ATTACH_DETACH
:
24755 case GOMP_MAP_ATTACH
:
24758 error_at (OMP_CLAUSE_LOCATION (*pc
),
24759 "%<#pragma omp target%> with map-type other "
24760 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
24761 "on %<map%> clause");
24762 *pc
= OMP_CLAUSE_CHAIN (*pc
);
24765 pc
= &OMP_CLAUSE_CHAIN (*pc
);
24767 cfun
->has_omp_target
= true;
24772 # pragma omp declare simd declare-simd-clauses[optseq] new-line
24775 # pragma omp declare variant (identifier) match(context-selector) new-line
24778 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
24779 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
24780 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
24781 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
24782 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
24783 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
24784 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
24787 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
24789 c_token
*token
= c_parser_peek_token (parser
);
24790 gcc_assert (token
->type
== CPP_NAME
);
24791 tree kind
= token
->value
;
24792 gcc_assert (strcmp (IDENTIFIER_POINTER (kind
), "simd") == 0
24793 || strcmp (IDENTIFIER_POINTER (kind
), "variant") == 0);
24795 auto_vec
<c_token
> clauses
;
24796 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
24798 c_token
*token
= c_parser_peek_token (parser
);
24799 if (token
->type
== CPP_EOF
)
24801 c_parser_skip_to_pragma_eol (parser
);
24804 clauses
.safe_push (*token
);
24805 c_parser_consume_token (parser
);
24807 clauses
.safe_push (*c_parser_peek_token (parser
));
24808 c_parser_skip_to_pragma_eol (parser
);
24810 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
24812 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_DECLARE
24813 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
24814 || c_parser_peek_2nd_token (parser
)->value
!= kind
)
24816 error ("%<#pragma omp declare %s%> must be followed by "
24817 "function declaration or definition or another "
24818 "%<#pragma omp declare %s%>",
24819 IDENTIFIER_POINTER (kind
), IDENTIFIER_POINTER (kind
));
24822 c_parser_consume_pragma (parser
);
24823 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
24825 c_token
*token
= c_parser_peek_token (parser
);
24826 if (token
->type
== CPP_EOF
)
24828 c_parser_skip_to_pragma_eol (parser
);
24831 clauses
.safe_push (*token
);
24832 c_parser_consume_token (parser
);
24834 clauses
.safe_push (*c_parser_peek_token (parser
));
24835 c_parser_skip_to_pragma_eol (parser
);
24838 /* Make sure nothing tries to read past the end of the tokens. */
24840 memset (&eof_token
, 0, sizeof (eof_token
));
24841 eof_token
.type
= CPP_EOF
;
24842 clauses
.safe_push (eof_token
);
24843 clauses
.safe_push (eof_token
);
24847 case pragma_external
:
24848 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24849 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
24851 int ext
= disable_extension_diagnostics ();
24853 c_parser_consume_token (parser
);
24854 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24855 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
24856 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
24858 restore_extension_diagnostics (ext
);
24861 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
24864 case pragma_struct
:
24867 error ("%<#pragma omp declare %s%> must be followed by "
24868 "function declaration or definition",
24869 IDENTIFIER_POINTER (kind
));
24871 case pragma_compound
:
24872 bool have_std_attrs
;
24874 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
24875 if (have_std_attrs
)
24876 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
24878 std_attrs
= NULL_TREE
;
24879 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24880 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
24882 int ext
= disable_extension_diagnostics ();
24884 c_parser_consume_token (parser
);
24885 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24886 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
24887 if (c_parser_next_tokens_start_declaration (parser
)
24888 || c_parser_nth_token_starts_std_attributes (parser
, 1))
24890 c_parser_declaration_or_fndef (parser
, true, true, true, true,
24891 true, NULL
, &clauses
,
24892 have_std_attrs
, std_attrs
);
24893 restore_extension_diagnostics (ext
);
24896 restore_extension_diagnostics (ext
);
24898 else if (c_parser_next_tokens_start_declaration (parser
))
24900 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
24901 NULL
, &clauses
, have_std_attrs
,
24905 error ("%<#pragma omp declare %s%> must be followed by "
24906 "function declaration or definition",
24907 IDENTIFIER_POINTER (kind
));
24910 gcc_unreachable ();
24917 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
24920 score(score-expression)
24922 Note that this function returns a list of trait selectors for the
24923 trait-selector-set SET. */
24926 c_parser_omp_context_selector (c_parser
*parser
, enum omp_tss_code set
,
24929 tree ret
= NULL_TREE
;
24933 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24934 || c_parser_next_token_is (parser
, CPP_NAME
))
24935 selector
= c_parser_peek_token (parser
)->value
;
24938 c_parser_error (parser
, "expected trait selector name");
24939 return error_mark_node
;
24941 enum omp_ts_code sel
24942 = omp_lookup_ts_code (set
, IDENTIFIER_POINTER (selector
));
24944 if (sel
== OMP_TRAIT_INVALID
)
24946 /* Per the spec, "Implementations can ignore specified selectors
24947 that are not those described in this section"; however, we
24948 must record such selectors because they cause match failures. */
24949 warning_at (c_parser_peek_token (parser
)->location
, OPT_Wopenmp
,
24950 "unknown selector %qs for context selector set %qs",
24951 IDENTIFIER_POINTER (selector
), omp_tss_map
[set
]);
24952 c_parser_consume_token (parser
);
24953 ret
= make_trait_selector (sel
, NULL_TREE
, NULL_TREE
, ret
);
24954 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
24955 c_parser_balanced_token_sequence (parser
);
24956 if (c_parser_next_token_is (parser
, CPP_COMMA
))
24958 c_parser_consume_token (parser
);
24965 c_parser_consume_token (parser
);
24967 tree properties
= NULL_TREE
;
24968 tree scoreval
= NULL_TREE
;
24969 enum omp_tp_type property_kind
= omp_ts_map
[sel
].tp_type
;
24970 bool allow_score
= omp_ts_map
[sel
].allow_score
;
24973 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
24975 if (property_kind
== OMP_TRAIT_PROPERTY_NONE
)
24977 error_at (c_parser_peek_token (parser
)->location
,
24978 "selector %qs does not accept any properties",
24979 IDENTIFIER_POINTER (selector
));
24980 return error_mark_node
;
24983 matching_parens parens
;
24984 parens
.require_open (parser
);
24986 c_token
*token
= c_parser_peek_token (parser
);
24987 if (c_parser_next_token_is (parser
, CPP_NAME
)
24988 && strcmp (IDENTIFIER_POINTER (token
->value
), "score") == 0
24989 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
24991 c_parser_consume_token (parser
);
24993 matching_parens parens2
;
24994 parens2
.require_open (parser
);
24995 tree score
= c_parser_expr_no_commas (parser
, NULL
).value
;
24996 parens2
.skip_until_found_close (parser
);
24997 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
24999 error_at (token
->location
,
25000 "%<score%> cannot be specified in traits "
25001 "in the %qs trait-selector-set",
25003 else if (score
!= error_mark_node
)
25005 mark_exp_read (score
);
25006 score
= c_fully_fold (score
, false, NULL
);
25007 if (!INTEGRAL_TYPE_P (TREE_TYPE (score
))
25008 || TREE_CODE (score
) != INTEGER_CST
)
25009 error_at (token
->location
, "%<score%> argument must "
25010 "be constant integer expression");
25011 else if (tree_int_cst_sgn (score
) < 0)
25012 error_at (token
->location
, "%<score%> argument must "
25013 "be non-negative");
25017 token
= c_parser_peek_token (parser
);
25020 switch (property_kind
)
25022 case OMP_TRAIT_PROPERTY_ID
:
25023 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
25024 || c_parser_next_token_is (parser
, CPP_NAME
))
25026 tree prop
= c_parser_peek_token (parser
)->value
;
25027 c_parser_consume_token (parser
);
25028 properties
= make_trait_property (prop
, NULL_TREE
,
25033 c_parser_error (parser
, "expected identifier");
25034 return error_mark_node
;
25037 case OMP_TRAIT_PROPERTY_NAME_LIST
:
25040 tree prop
= OMP_TP_NAMELIST_NODE
;
25041 tree value
= NULL_TREE
;
25042 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
25043 || c_parser_next_token_is (parser
, CPP_NAME
))
25045 value
= c_parser_peek_token (parser
)->value
;
25046 c_parser_consume_token (parser
);
25048 else if (c_parser_next_token_is (parser
, CPP_STRING
))
25049 value
= c_parser_string_literal (parser
, false,
25053 c_parser_error (parser
, "expected identifier or "
25055 return error_mark_node
;
25058 properties
= make_trait_property (prop
, value
, properties
);
25060 if (c_parser_next_token_is (parser
, CPP_COMMA
))
25061 c_parser_consume_token (parser
);
25067 case OMP_TRAIT_PROPERTY_DEV_NUM_EXPR
:
25068 case OMP_TRAIT_PROPERTY_BOOL_EXPR
:
25069 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
25070 if (t
!= error_mark_node
)
25073 t
= c_fully_fold (t
, false, NULL
);
25074 /* FIXME: this is bogus, both device_num and
25075 condition selectors allow arbitrary expressions. */
25076 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
25077 || !tree_fits_shwi_p (t
))
25078 error_at (token
->location
, "property must be "
25079 "constant integer expression");
25081 properties
= make_trait_property (NULL_TREE
, t
,
25085 return error_mark_node
;
25087 case OMP_TRAIT_PROPERTY_CLAUSE_LIST
:
25088 if (sel
== OMP_TRAIT_CONSTRUCT_SIMD
)
25090 if (parms
== NULL_TREE
)
25092 error_at (token
->location
, "properties for %<simd%> "
25093 "selector may not be specified in "
25094 "%<metadirective%>");
25095 return error_mark_node
;
25098 c
= c_parser_omp_all_clauses (parser
,
25099 OMP_DECLARE_SIMD_CLAUSE_MASK
,
25101 c
= c_omp_declare_simd_clauses_to_numbers (parms
25103 ? NULL_TREE
: parms
,
25107 else if (sel
== OMP_TRAIT_IMPLEMENTATION_REQUIRES
)
25109 /* FIXME: The "requires" selector was added in OpenMP 5.1.
25110 Currently only the now-deprecated syntax
25111 from OpenMP 5.0 is supported. */
25112 sorry_at (token
->location
,
25113 "%<requires%> selector is not supported yet");
25114 return error_mark_node
;
25117 gcc_unreachable ();
25120 gcc_unreachable ();
25123 parens
.skip_until_found_close (parser
);
25124 properties
= nreverse (properties
);
25126 else if (property_kind
!= OMP_TRAIT_PROPERTY_NONE
25127 && property_kind
!= OMP_TRAIT_PROPERTY_CLAUSE_LIST
25128 && property_kind
!= OMP_TRAIT_PROPERTY_EXTENSION
)
25130 c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>");
25131 return error_mark_node
;
25134 ret
= make_trait_selector (sel
, scoreval
, properties
, ret
);
25136 if (c_parser_next_token_is (parser
, CPP_COMMA
))
25137 c_parser_consume_token (parser
);
25143 return nreverse (ret
);
25148 trait-set-selector[,trait-set-selector[,...]]
25150 trait-set-selector:
25151 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
25153 trait-set-selector-name:
25160 c_parser_omp_context_selector_specification (c_parser
*parser
, tree parms
)
25162 tree ret
= NULL_TREE
;
25165 const char *setp
= "";
25166 if (c_parser_next_token_is (parser
, CPP_NAME
))
25167 setp
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25168 enum omp_tss_code set
= omp_lookup_tss_code (setp
);
25170 if (set
== OMP_TRAIT_SET_INVALID
)
25172 c_parser_error (parser
, "expected context selector set name");
25173 return error_mark_node
;
25176 c_parser_consume_token (parser
);
25178 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
25179 return error_mark_node
;
25181 matching_braces braces
;
25182 if (!braces
.require_open (parser
))
25183 return error_mark_node
;
25185 tree selectors
= c_parser_omp_context_selector (parser
, set
, parms
);
25186 if (selectors
== error_mark_node
)
25187 ret
= error_mark_node
;
25188 else if (ret
!= error_mark_node
)
25189 ret
= make_trait_set_selector (set
, selectors
, ret
);
25191 braces
.skip_until_found_close (parser
);
25193 if (c_parser_next_token_is (parser
, CPP_COMMA
))
25194 c_parser_consume_token (parser
);
25200 if (ret
== error_mark_node
)
25202 return nreverse (ret
);
25205 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
25206 that into "omp declare variant base" attribute. */
25209 c_finish_omp_declare_variant (c_parser
*parser
, tree fndecl
, tree parms
)
25211 matching_parens parens
;
25212 if (!parens
.require_open (parser
))
25215 c_parser_skip_to_pragma_eol (parser
, false);
25219 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
25220 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
25222 c_parser_error (parser
, "expected identifier");
25226 c_token
*token
= c_parser_peek_token (parser
);
25227 tree variant
= lookup_name (token
->value
);
25229 if (variant
== NULL_TREE
)
25231 undeclared_variable (token
->location
, token
->value
);
25232 variant
= error_mark_node
;
25235 c_parser_consume_token (parser
);
25237 parens
.require_close (parser
);
25239 if (c_parser_next_token_is (parser
, CPP_COMMA
)
25240 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
25241 c_parser_consume_token (parser
);
25243 const char *clause
= "";
25244 location_t match_loc
= c_parser_peek_token (parser
)->location
;
25245 if (c_parser_next_token_is (parser
, CPP_NAME
))
25246 clause
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25247 if (strcmp (clause
, "match"))
25249 c_parser_error (parser
, "expected %<match%>");
25253 c_parser_consume_token (parser
);
25255 if (!parens
.require_open (parser
))
25258 if (parms
== NULL_TREE
)
25259 parms
= error_mark_node
;
25261 tree ctx
= c_parser_omp_context_selector_specification (parser
, parms
);
25262 if (ctx
== error_mark_node
)
25264 ctx
= omp_check_context_selector (match_loc
, ctx
);
25265 if (ctx
!= error_mark_node
&& variant
!= error_mark_node
)
25267 if (TREE_CODE (variant
) != FUNCTION_DECL
)
25269 error_at (token
->location
, "variant %qD is not a function", variant
);
25270 variant
= error_mark_node
;
25272 else if (!omp_get_context_selector (ctx
, OMP_TRAIT_SET_CONSTRUCT
,
25273 OMP_TRAIT_CONSTRUCT_SIMD
)
25274 && !comptypes (TREE_TYPE (fndecl
), TREE_TYPE (variant
)))
25276 error_at (token
->location
, "variant %qD and base %qD have "
25277 "incompatible types", variant
, fndecl
);
25278 variant
= error_mark_node
;
25280 else if (fndecl_built_in_p (variant
)
25281 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
25282 "__builtin_", strlen ("__builtin_")) == 0
25283 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
25284 "__sync_", strlen ("__sync_")) == 0
25285 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
25286 "__atomic_", strlen ("__atomic_")) == 0))
25288 error_at (token
->location
, "variant %qD is a built-in", variant
);
25289 variant
= error_mark_node
;
25291 if (variant
!= error_mark_node
)
25293 C_DECL_USED (variant
) = 1;
25295 = omp_get_context_selector_list (ctx
, OMP_TRAIT_SET_CONSTRUCT
);
25296 omp_mark_declare_variant (match_loc
, variant
, construct
);
25297 if (omp_context_selector_matches (ctx
))
25300 = tree_cons (get_identifier ("omp declare variant base"),
25301 build_tree_list (variant
, ctx
),
25302 DECL_ATTRIBUTES (fndecl
));
25303 DECL_ATTRIBUTES (fndecl
) = attr
;
25308 parens
.require_close (parser
);
25309 c_parser_skip_to_pragma_eol (parser
);
25312 /* Finalize #pragma omp declare simd or #pragma omp declare variant
25313 clauses after FNDECL has been parsed, and put that into "omp declare simd"
25314 or "omp declare variant base" attribute. */
25317 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
25318 vec
<c_token
> *pclauses
)
25320 vec
<c_token
> &clauses
= *pclauses
;
25322 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
25323 indicates error has been reported and CPP_PRAGMA that
25324 c_finish_omp_declare_simd has already processed the tokens. */
25325 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
25327 const char *kind
= "simd";
25328 if (clauses
.exists ()
25329 && (clauses
[0].type
== CPP_NAME
|| clauses
[0].type
== CPP_PRAGMA
))
25330 kind
= IDENTIFIER_POINTER (clauses
[0].value
);
25331 gcc_assert (strcmp (kind
, "simd") == 0 || strcmp (kind
, "variant") == 0);
25332 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
25334 error ("%<#pragma omp declare %s%> not immediately followed by "
25335 "a function declaration or definition", kind
);
25336 clauses
[0].type
= CPP_EOF
;
25339 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
25341 error_at (DECL_SOURCE_LOCATION (fndecl
),
25342 "%<#pragma omp declare %s%> not immediately followed by "
25343 "a single function declaration or definition", kind
);
25344 clauses
[0].type
= CPP_EOF
;
25348 if (parms
== NULL_TREE
)
25349 parms
= DECL_ARGUMENTS (fndecl
);
25351 unsigned int tokens_avail
= parser
->tokens_avail
;
25352 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
25354 parser
->tokens
= clauses
.address ();
25355 parser
->tokens_avail
= clauses
.length ();
25357 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
25358 while (parser
->tokens_avail
> 3)
25360 c_token
*token
= c_parser_peek_token (parser
);
25361 gcc_assert (token
->type
== CPP_NAME
);
25362 kind
= IDENTIFIER_POINTER (token
->value
);
25363 c_parser_consume_token (parser
);
25364 parser
->in_pragma
= true;
25366 if (strcmp (kind
, "simd") == 0)
25369 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
25370 "#pragma omp declare simd");
25371 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
25372 if (c
!= NULL_TREE
)
25373 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
25374 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
25375 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
25376 DECL_ATTRIBUTES (fndecl
) = c
;
25380 gcc_assert (strcmp (kind
, "variant") == 0);
25381 c_finish_omp_declare_variant (parser
, fndecl
, parms
);
25385 parser
->tokens
= &parser
->tokens_buf
[0];
25386 parser
->tokens_avail
= tokens_avail
;
25387 if (clauses
.exists ())
25388 clauses
[0].type
= CPP_PRAGMA
;
25391 /* D should be C_TOKEN_VEC from omp::decl attribute. If it contains
25392 a threadprivate, groupprivate, allocate or declare target directive,
25393 return true and parse it for DECL. */
25396 c_maybe_parse_omp_decl (tree decl
, tree d
)
25398 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
25399 vec
<c_token
, va_gc
> *toks
= C_TOKEN_VEC_TOKENS (d
);
25400 c_token
*first
= toks
->address ();
25401 c_token
*last
= first
+ toks
->length ();
25402 const char *directive
[3] = {};
25403 for (int j
= 0; j
< 3; j
++)
25405 tree id
= NULL_TREE
;
25406 if (first
+ j
== last
)
25408 if (first
[j
].type
== CPP_NAME
)
25409 id
= first
[j
].value
;
25410 else if (first
[j
].type
== CPP_KEYWORD
)
25411 id
= ridpointers
[(int) first
[j
].keyword
];
25414 directive
[j
] = IDENTIFIER_POINTER (id
);
25416 const c_omp_directive
*dir
= NULL
;
25418 dir
= c_omp_categorize_directive (directive
[0], directive
[1],
25422 error_at (first
->location
,
25423 "unknown OpenMP directive name in "
25424 "%qs attribute argument", "omp::decl");
25427 if (dir
->id
!= PRAGMA_OMP_THREADPRIVATE
25428 /* && dir->id != PRAGMA_OMP_GROUPPRIVATE */
25429 && dir
->id
!= PRAGMA_OMP_ALLOCATE
25430 && (dir
->id
!= PRAGMA_OMP_DECLARE
25431 || strcmp (directive
[1], "target") != 0))
25434 if (!flag_openmp
&& !dir
->simd
)
25437 c_parser
*parser
= the_parser
;
25438 unsigned int tokens_avail
= parser
->tokens_avail
;
25439 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
25441 vec_safe_reserve (toks
, last
- first
+ 2, true);
25443 tok
.type
= CPP_PRAGMA
;
25444 tok
.keyword
= RID_MAX
;
25445 tok
.pragma_kind
= pragma_kind (dir
->id
);
25446 tok
.location
= first
->location
;
25447 toks
->quick_push (tok
);
25448 while (++first
< last
)
25449 toks
->quick_push (*first
);
25451 tok
.type
= CPP_PRAGMA_EOL
;
25452 tok
.keyword
= RID_MAX
;
25453 tok
.location
= last
[-1].location
;
25454 toks
->quick_push (tok
);
25456 tok
.type
= CPP_EOF
;
25457 tok
.keyword
= RID_MAX
;
25458 tok
.location
= last
[-1].location
;
25459 tok
.flags
= tokens_avail
;
25460 toks
->quick_push (tok
);
25461 parser
->in_omp_decl_attribute
= decl
;
25462 parser
->tokens
= toks
->address ();
25463 parser
->tokens_avail
= toks
->length ();
25464 parser
->in_omp_attribute_pragma
= toks
;
25465 c_parser_pragma (parser
, pragma_external
, NULL
);
25466 parser
->in_omp_decl_attribute
= NULL_TREE
;
25471 # pragma omp declare target new-line
25472 declarations and definitions
25473 # pragma omp end declare target new-line
25476 # pragma omp declare target ( extended-list ) new-line
25478 # pragma omp declare target declare-target-clauses[seq] new-line */
25480 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
25481 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
25482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
25483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
25484 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
25485 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
25488 c_parser_omp_declare_target (c_parser
*parser
)
25490 tree clauses
= NULL_TREE
;
25491 int device_type
= 0;
25492 bool indirect
= false;
25493 bool only_device_type_or_indirect
= true;
25494 if (c_parser_next_token_is (parser
, CPP_NAME
)
25495 || (c_parser_next_token_is (parser
, CPP_COMMA
)
25496 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
))
25497 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
25498 "#pragma omp declare target");
25499 else if (parser
->in_omp_decl_attribute
25500 || c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
25502 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
25504 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
25505 c_parser_skip_to_pragma_eol (parser
);
25509 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25510 c_parser_skip_to_pragma_eol (parser
);
25511 c_omp_declare_target_attr attr
= { attr_syntax
, -1, 0 };
25512 vec_safe_push (current_omp_declare_target_attribute
, attr
);
25515 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
25517 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
25518 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
25519 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_INDIRECT
)
25520 indirect
|= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c
));
25522 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
25524 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
25525 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_INDIRECT
)
25527 tree t
= OMP_CLAUSE_DECL (c
), id
;
25528 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
25529 tree at2
= lookup_attribute ("omp declare target link",
25530 DECL_ATTRIBUTES (t
));
25531 only_device_type_or_indirect
= false;
25532 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
25534 id
= get_identifier ("omp declare target link");
25535 std::swap (at1
, at2
);
25538 id
= get_identifier ("omp declare target");
25541 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_ENTER
)
25542 error_at (OMP_CLAUSE_LOCATION (c
),
25543 "%qD specified both in declare target %<link%> and %qs"
25544 " clauses", t
, OMP_CLAUSE_ENTER_TO (c
) ? "to" : "enter");
25546 error_at (OMP_CLAUSE_LOCATION (c
),
25547 "%qD specified both in declare target %<link%> and "
25548 "%<to%> or %<enter%> clauses", t
);
25553 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
25554 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
25557 symtab_node
*node
= symtab_node::get (t
);
25560 node
->offloadable
= 1;
25561 if (ENABLE_OFFLOADING
)
25563 g
->have_offload
= true;
25564 if (is_a
<varpool_node
*> (node
))
25565 vec_safe_push (offload_vars
, t
);
25569 if (TREE_CODE (t
) != FUNCTION_DECL
)
25571 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_HOST
) != 0)
25573 tree at3
= lookup_attribute ("omp declare target host",
25574 DECL_ATTRIBUTES (t
));
25575 if (at3
== NULL_TREE
)
25577 id
= get_identifier ("omp declare target host");
25578 DECL_ATTRIBUTES (t
)
25579 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
25582 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_NOHOST
) != 0)
25584 tree at3
= lookup_attribute ("omp declare target nohost",
25585 DECL_ATTRIBUTES (t
));
25586 if (at3
== NULL_TREE
)
25588 id
= get_identifier ("omp declare target nohost");
25589 DECL_ATTRIBUTES (t
)
25590 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
25595 tree at4
= lookup_attribute ("omp declare target indirect",
25596 DECL_ATTRIBUTES (t
));
25597 if (at4
== NULL_TREE
)
25599 id
= get_identifier ("omp declare target indirect");
25600 DECL_ATTRIBUTES (t
)
25601 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
25605 if ((device_type
|| indirect
) && only_device_type_or_indirect
)
25606 error_at (OMP_CLAUSE_LOCATION (clauses
),
25607 "directive with only %<device_type%> or %<indirect%> clauses");
25608 if (indirect
&& device_type
&& device_type
!= OMP_CLAUSE_DEVICE_TYPE_ANY
)
25609 error_at (OMP_CLAUSE_LOCATION (clauses
),
25610 "%<device_type%> clause must specify 'any' when used with "
25611 "an %<indirect%> clause");
25615 #pragma omp begin assumes clauses[optseq] new-line
25617 #pragma omp begin declare target clauses[optseq] new-line */
25619 #define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \
25620 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
25621 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
25624 c_parser_omp_begin (c_parser
*parser
)
25626 const char *p
= "";
25627 c_parser_consume_pragma (parser
);
25628 if (c_parser_next_token_is (parser
, CPP_NAME
))
25629 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25630 if (strcmp (p
, "declare") == 0)
25632 c_parser_consume_token (parser
);
25634 if (c_parser_next_token_is (parser
, CPP_NAME
))
25635 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25636 if (strcmp (p
, "target") == 0)
25638 c_parser_consume_token (parser
);
25639 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25641 = c_parser_omp_all_clauses (parser
,
25642 OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK
,
25643 "#pragma omp begin declare target");
25644 int device_type
= 0;
25646 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
25648 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
25649 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
25650 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_INDIRECT
)
25651 indirect
|= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c
));
25653 c_omp_declare_target_attr attr
= { attr_syntax
, device_type
,
25655 vec_safe_push (current_omp_declare_target_attribute
, attr
);
25659 c_parser_error (parser
, "expected %<target%>");
25660 c_parser_skip_to_pragma_eol (parser
);
25663 else if (strcmp (p
, "assumes") == 0)
25665 c_parser_consume_token (parser
);
25666 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25667 c_parser_omp_assumption_clauses (parser
, false);
25668 struct c_omp_begin_assumes_data a
= { attr_syntax
};
25669 vec_safe_push (current_omp_begin_assumes
, a
);
25673 c_parser_error (parser
, "expected %<declare target%> or %<assumes%>");
25674 c_parser_skip_to_pragma_eol (parser
);
25679 #pragma omp end declare target
25682 #pragma omp end assumes */
25685 c_parser_omp_end (c_parser
*parser
)
25687 location_t loc
= c_parser_peek_token (parser
)->location
;
25688 const char *p
= "";
25689 c_parser_consume_pragma (parser
);
25690 if (c_parser_next_token_is (parser
, CPP_NAME
))
25691 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25692 if (strcmp (p
, "declare") == 0)
25694 c_parser_consume_token (parser
);
25695 if (c_parser_next_token_is (parser
, CPP_NAME
)
25696 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
25698 c_parser_consume_token (parser
);
25701 c_parser_error (parser
, "expected %<target%>");
25702 c_parser_skip_to_pragma_eol (parser
);
25705 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25706 c_parser_skip_to_pragma_eol (parser
);
25707 if (!vec_safe_length (current_omp_declare_target_attribute
))
25708 error_at (loc
, "%<#pragma omp end declare target%> without "
25709 "corresponding %<#pragma omp declare target%> or "
25710 "%<#pragma omp begin declare target%>");
25713 c_omp_declare_target_attr
25714 a
= current_omp_declare_target_attribute
->pop ();
25715 if (a
.attr_syntax
!= attr_syntax
)
25719 "%qs in attribute syntax terminated "
25720 "with %qs in pragma syntax",
25721 a
.device_type
>= 0 ? "begin declare target"
25722 : "declare target",
25723 "end declare target");
25726 "%qs in pragma syntax terminated "
25727 "with %qs in attribute syntax",
25728 a
.device_type
>= 0 ? "begin declare target"
25729 : "declare target",
25730 "end declare target");
25734 else if (strcmp (p
, "assumes") == 0)
25736 c_parser_consume_token (parser
);
25737 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25738 c_parser_skip_to_pragma_eol (parser
);
25739 if (!vec_safe_length (current_omp_begin_assumes
))
25740 error_at (loc
, "%qs without corresponding %qs",
25741 "#pragma omp end assumes", "#pragma omp begin assumes");
25744 c_omp_begin_assumes_data
25745 a
= current_omp_begin_assumes
->pop ();
25746 if (a
.attr_syntax
!= attr_syntax
)
25750 "%qs in attribute syntax terminated "
25751 "with %qs in pragma syntax",
25752 "begin assumes", "end assumes");
25755 "%qs in pragma syntax terminated "
25756 "with %qs in attribute syntax",
25757 "begin assumes", "end assumes");
25763 c_parser_error (parser
, "expected %<declare%> or %<assumes%>");
25764 c_parser_skip_to_pragma_eol (parser
);
25769 #pragma omp declare reduction (reduction-id : typename-list : expression) \
25770 initializer-clause[opt] new-line
25772 initializer-clause:
25773 initializer (omp_priv = initializer)
25774 initializer (function-name (argument-list)) */
25777 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
25779 unsigned int tokens_avail
= 0, i
;
25780 c_token
*saved_tokens
= NULL
;
25781 vec
<tree
> types
= vNULL
;
25782 vec
<c_token
> clauses
= vNULL
;
25783 enum tree_code reduc_code
= ERROR_MARK
;
25784 tree reduc_id
= NULL_TREE
;
25786 location_t rloc
= c_parser_peek_token (parser
)->location
;
25788 if (context
== pragma_struct
|| context
== pragma_param
)
25790 error ("%<#pragma omp declare reduction%> not at file or block scope");
25794 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
25797 switch (c_parser_peek_token (parser
)->type
)
25800 reduc_code
= PLUS_EXPR
;
25803 reduc_code
= MULT_EXPR
;
25806 reduc_code
= MINUS_EXPR
;
25809 reduc_code
= BIT_AND_EXPR
;
25812 reduc_code
= BIT_XOR_EXPR
;
25815 reduc_code
= BIT_IOR_EXPR
;
25818 reduc_code
= TRUTH_ANDIF_EXPR
;
25821 reduc_code
= TRUTH_ORIF_EXPR
;
25825 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25826 if (strcmp (p
, "min") == 0)
25828 reduc_code
= MIN_EXPR
;
25831 if (strcmp (p
, "max") == 0)
25833 reduc_code
= MAX_EXPR
;
25836 reduc_id
= c_parser_peek_token (parser
)->value
;
25839 c_parser_error (parser
,
25840 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
25841 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
25845 tree orig_reduc_id
, reduc_decl
;
25846 orig_reduc_id
= reduc_id
;
25847 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
25848 reduc_decl
= c_omp_reduction_decl (reduc_id
);
25849 c_parser_consume_token (parser
);
25851 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
25856 location_t loc
= c_parser_peek_token (parser
)->location
;
25857 struct c_type_name
*ctype
= c_parser_type_name (parser
);
25860 type
= groktypename (ctype
, NULL
, NULL
);
25861 if (type
== error_mark_node
)
25863 else if ((INTEGRAL_TYPE_P (type
)
25864 || SCALAR_FLOAT_TYPE_P (type
)
25865 || TREE_CODE (type
) == COMPLEX_TYPE
)
25866 && orig_reduc_id
== NULL_TREE
)
25867 error_at (loc
, "predeclared arithmetic type in "
25868 "%<#pragma omp declare reduction%>");
25869 else if (TREE_CODE (type
) == FUNCTION_TYPE
25870 || TREE_CODE (type
) == ARRAY_TYPE
)
25871 error_at (loc
, "function or array type in "
25872 "%<#pragma omp declare reduction%>");
25873 else if (TYPE_ATOMIC (type
))
25874 error_at (loc
, "%<_Atomic%> qualified type in "
25875 "%<#pragma omp declare reduction%>");
25876 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
25877 error_at (loc
, "const, volatile or restrict qualified type in "
25878 "%<#pragma omp declare reduction%>");
25882 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
25883 if (comptypes (TREE_PURPOSE (t
), type
))
25885 error_at (loc
, "redeclaration of %qs "
25886 "%<#pragma omp declare reduction%> for "
25888 IDENTIFIER_POINTER (reduc_id
)
25889 + sizeof ("omp declare reduction ") - 1,
25892 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
25894 error_at (ploc
, "previous %<#pragma omp declare "
25898 if (t
== NULL_TREE
)
25899 types
.safe_push (type
);
25901 if (c_parser_next_token_is (parser
, CPP_COMMA
))
25902 c_parser_consume_token (parser
);
25910 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
25911 || types
.is_empty ())
25914 clauses
.release ();
25918 c_token
*token
= c_parser_peek_token (parser
);
25919 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
25921 c_parser_consume_token (parser
);
25923 c_parser_skip_to_pragma_eol (parser
);
25927 if (types
.length () > 1)
25929 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
25931 c_token
*token
= c_parser_peek_token (parser
);
25932 if (token
->type
== CPP_EOF
)
25934 clauses
.safe_push (*token
);
25935 c_parser_consume_token (parser
);
25937 clauses
.safe_push (*c_parser_peek_token (parser
));
25938 c_parser_skip_to_pragma_eol (parser
);
25940 /* Make sure nothing tries to read past the end of the tokens. */
25942 memset (&eof_token
, 0, sizeof (eof_token
));
25943 eof_token
.type
= CPP_EOF
;
25944 clauses
.safe_push (eof_token
);
25945 clauses
.safe_push (eof_token
);
25948 int errs
= errorcount
;
25949 FOR_EACH_VEC_ELT (types
, i
, type
)
25951 saved_tokens
= parser
->tokens
;
25952 tokens_avail
= parser
->tokens_avail
;
25953 if (!clauses
.is_empty ())
25955 parser
->tokens
= clauses
.address ();
25956 parser
->tokens_avail
= clauses
.length ();
25957 parser
->in_pragma
= true;
25960 bool nested
= current_function_decl
!= NULL_TREE
;
25962 c_push_function_context ();
25963 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
25964 reduc_id
, default_function_type
);
25965 current_function_decl
= fndecl
;
25966 allocate_struct_function (fndecl
, true);
25968 tree stmt
= push_stmt_list ();
25969 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
25970 warn about these. */
25971 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
25972 get_identifier ("omp_out"), type
);
25973 DECL_ARTIFICIAL (omp_out
) = 1;
25974 DECL_CONTEXT (omp_out
) = fndecl
;
25975 pushdecl (omp_out
);
25976 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
25977 get_identifier ("omp_in"), type
);
25978 DECL_ARTIFICIAL (omp_in
) = 1;
25979 DECL_CONTEXT (omp_in
) = fndecl
;
25981 struct c_expr combiner
= c_parser_expression (parser
);
25982 struct c_expr initializer
;
25983 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
25985 initializer
.set_error ();
25986 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
25988 else if (c_parser_next_token_is (parser
, CPP_COMMA
)
25989 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
25990 c_parser_consume_token (parser
);
25992 && (c_parser_next_token_is (parser
, CPP_NAME
)
25993 && strcmp (IDENTIFIER_POINTER
25994 (c_parser_peek_token (parser
)->value
),
25995 "initializer") == 0))
25997 c_parser_consume_token (parser
);
26000 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
26001 get_identifier ("omp_priv"), type
);
26002 DECL_ARTIFICIAL (omp_priv
) = 1;
26003 DECL_INITIAL (omp_priv
) = error_mark_node
;
26004 DECL_CONTEXT (omp_priv
) = fndecl
;
26005 pushdecl (omp_priv
);
26006 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
26007 get_identifier ("omp_orig"), type
);
26008 DECL_ARTIFICIAL (omp_orig
) = 1;
26009 DECL_CONTEXT (omp_orig
) = fndecl
;
26010 pushdecl (omp_orig
);
26011 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
26013 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
26015 c_parser_error (parser
, "expected %<omp_priv%> or "
26019 else if (strcmp (IDENTIFIER_POINTER
26020 (c_parser_peek_token (parser
)->value
),
26023 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
26024 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
26026 c_parser_error (parser
, "expected function-name %<(%>");
26030 initializer
= c_parser_postfix_expression (parser
);
26031 if (initializer
.value
26032 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
26035 tree c
= initializer
.value
;
26036 for (j
= 0; j
< call_expr_nargs (c
); j
++)
26038 tree a
= CALL_EXPR_ARG (c
, j
);
26040 if (TREE_CODE (a
) == ADDR_EXPR
26041 && TREE_OPERAND (a
, 0) == omp_priv
)
26044 if (j
== call_expr_nargs (c
))
26045 error ("one of the initializer call arguments should be "
26051 c_parser_consume_token (parser
);
26052 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
26056 tree st
= push_stmt_list ();
26057 location_t loc
= c_parser_peek_token (parser
)->location
;
26058 rich_location
richloc (line_table
, loc
);
26059 start_init (omp_priv
, NULL_TREE
, false, false, &richloc
);
26060 struct c_expr init
= c_parser_initializer (parser
, omp_priv
);
26062 finish_decl (omp_priv
, loc
, init
.value
,
26063 init
.original_type
, NULL_TREE
);
26064 pop_stmt_list (st
);
26068 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
26074 c_parser_skip_to_pragma_eol (parser
);
26076 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
26077 DECL_INITIAL (reduc_decl
));
26078 DECL_INITIAL (reduc_decl
) = t
;
26079 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
26080 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
26081 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
26082 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
26083 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
26084 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
26087 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
26088 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
26089 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
26090 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
26091 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
26092 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
26093 walk_tree (&DECL_INITIAL (omp_priv
),
26094 c_check_omp_declare_reduction_r
,
26095 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
26099 pop_stmt_list (stmt
);
26101 if (cfun
->language
!= NULL
)
26103 ggc_free (cfun
->language
);
26104 cfun
->language
= NULL
;
26107 current_function_decl
= NULL_TREE
;
26109 c_pop_function_context ();
26111 if (!clauses
.is_empty ())
26113 parser
->tokens
= saved_tokens
;
26114 parser
->tokens_avail
= tokens_avail
;
26118 if (errs
!= errorcount
)
26122 clauses
.release ();
26128 #pragma omp declare simd declare-simd-clauses[optseq] new-line
26129 #pragma omp declare reduction (reduction-id : typename-list : expression) \
26130 initializer-clause[opt] new-line
26131 #pragma omp declare target new-line
26134 #pragma omp declare variant (identifier) match (context-selector) */
26137 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
26139 c_parser_consume_pragma (parser
);
26140 if (c_parser_next_token_is (parser
, CPP_NAME
))
26142 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
26143 if (strcmp (p
, "simd") == 0)
26145 /* c_parser_consume_token (parser); done in
26146 c_parser_omp_declare_simd. */
26147 c_parser_omp_declare_simd (parser
, context
);
26150 if (strcmp (p
, "reduction") == 0)
26152 c_parser_consume_token (parser
);
26153 c_parser_omp_declare_reduction (parser
, context
);
26156 if (!flag_openmp
) /* flag_openmp_simd */
26158 c_parser_skip_to_pragma_eol (parser
, false);
26161 if (strcmp (p
, "target") == 0)
26163 c_parser_consume_token (parser
);
26164 c_parser_omp_declare_target (parser
);
26167 if (strcmp (p
, "variant") == 0)
26169 /* c_parser_consume_token (parser); done in
26170 c_parser_omp_declare_simd. */
26171 c_parser_omp_declare_simd (parser
, context
);
26176 c_parser_error (parser
, "expected %<simd%>, %<reduction%>, "
26177 "%<target%> or %<variant%>");
26178 c_parser_skip_to_pragma_eol (parser
);
26183 #pragma omp requires clauses[optseq] new-line */
26186 c_parser_omp_requires (c_parser
*parser
)
26188 enum omp_requires new_req
= (enum omp_requires
) 0;
26190 c_parser_consume_pragma (parser
);
26192 location_t loc
= c_parser_peek_token (parser
)->location
;
26193 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
26195 if (c_parser_next_token_is (parser
, CPP_COMMA
)
26196 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
26197 c_parser_consume_token (parser
);
26199 if (c_parser_next_token_is (parser
, CPP_NAME
))
26202 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
26203 location_t cloc
= c_parser_peek_token (parser
)->location
;
26204 enum omp_requires this_req
= (enum omp_requires
) 0;
26206 if (!strcmp (p
, "unified_address"))
26207 this_req
= OMP_REQUIRES_UNIFIED_ADDRESS
;
26208 else if (!strcmp (p
, "unified_shared_memory"))
26209 this_req
= OMP_REQUIRES_UNIFIED_SHARED_MEMORY
;
26210 else if (!strcmp (p
, "dynamic_allocators"))
26211 this_req
= OMP_REQUIRES_DYNAMIC_ALLOCATORS
;
26212 else if (!strcmp (p
, "reverse_offload"))
26213 this_req
= OMP_REQUIRES_REVERSE_OFFLOAD
;
26214 else if (!strcmp (p
, "atomic_default_mem_order"))
26216 c_parser_consume_token (parser
);
26218 matching_parens parens
;
26219 if (parens
.require_open (parser
))
26221 if (c_parser_next_token_is (parser
, CPP_NAME
))
26223 tree v
= c_parser_peek_token (parser
)->value
;
26224 p
= IDENTIFIER_POINTER (v
);
26226 if (!strcmp (p
, "seq_cst"))
26228 = (enum omp_requires
) OMP_MEMORY_ORDER_SEQ_CST
;
26229 else if (!strcmp (p
, "relaxed"))
26231 = (enum omp_requires
) OMP_MEMORY_ORDER_RELAXED
;
26232 else if (!strcmp (p
, "release"))
26234 = (enum omp_requires
) OMP_MEMORY_ORDER_RELEASE
;
26235 else if (!strcmp (p
, "acq_rel"))
26237 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQ_REL
;
26238 else if (!strcmp (p
, "acquire"))
26240 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQUIRE
;
26244 error_at (c_parser_peek_token (parser
)->location
,
26245 "expected %<acq_rel%>, %<acquire%>, "
26246 "%<relaxed%>, %<release%> or %<seq_cst%>");
26247 switch (c_parser_peek_token (parser
)->type
)
26250 case CPP_PRAGMA_EOL
:
26251 case CPP_CLOSE_PAREN
:
26254 if (c_parser_peek_2nd_token (parser
)->type
26255 == CPP_CLOSE_PAREN
)
26256 c_parser_consume_token (parser
);
26261 c_parser_consume_token (parser
);
26263 parens
.skip_until_found_close (parser
);
26266 c_parser_skip_to_pragma_eol (parser
, false);
26274 error_at (cloc
, "expected %<unified_address%>, "
26275 "%<unified_shared_memory%>, "
26276 "%<dynamic_allocators%>, "
26277 "%<reverse_offload%> "
26278 "or %<atomic_default_mem_order%> clause");
26279 c_parser_skip_to_pragma_eol (parser
, false);
26283 c_parser_consume_token (parser
);
26286 if ((this_req
& ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
26288 if ((this_req
& new_req
) != 0)
26289 error_at (cloc
, "too many %qs clauses", p
);
26290 if (this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
26291 && (omp_requires_mask
& OMP_REQUIRES_TARGET_USED
) != 0)
26292 error_at (cloc
, "%qs clause used lexically after first "
26293 "target construct or offloading API", p
);
26295 else if ((new_req
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
26297 error_at (cloc
, "too many %qs clauses",
26298 "atomic_default_mem_order");
26299 this_req
= (enum omp_requires
) 0;
26301 else if ((omp_requires_mask
26302 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
26304 error_at (cloc
, "more than one %<atomic_default_mem_order%>"
26305 " clause in a single compilation unit");
26307 = (enum omp_requires
)
26309 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
);
26311 else if ((omp_requires_mask
26312 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
) != 0)
26313 error_at (cloc
, "%<atomic_default_mem_order%> clause used "
26314 "lexically after first %<atomic%> construct "
26315 "without memory order clause");
26316 new_req
= (enum omp_requires
) (new_req
| this_req
);
26318 = (enum omp_requires
) (omp_requires_mask
| this_req
);
26324 c_parser_skip_to_pragma_eol (parser
);
26327 error_at (loc
, "%<pragma omp requires%> requires at least one clause");
26330 /* Helper function for c_parser_omp_taskloop.
26331 Disallow zero sized or potentially zero sized task reductions. */
26334 c_finish_taskloop_clauses (tree clauses
)
26336 tree
*pc
= &clauses
;
26337 for (tree c
= clauses
; c
; c
= *pc
)
26339 bool remove
= false;
26340 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
26342 tree type
= strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
26343 if (integer_zerop (TYPE_SIZE_UNIT (type
)))
26345 error_at (OMP_CLAUSE_LOCATION (c
),
26346 "zero sized type %qT in %<reduction%> clause", type
);
26349 else if (TREE_CODE (TYPE_SIZE_UNIT (type
)) != INTEGER_CST
)
26351 error_at (OMP_CLAUSE_LOCATION (c
),
26352 "variable sized type %qT in %<reduction%> clause",
26358 *pc
= OMP_CLAUSE_CHAIN (c
);
26360 pc
= &OMP_CLAUSE_CHAIN (c
);
26366 #pragma omp taskloop taskloop-clause[optseq] new-line
26369 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
26372 #define OMP_TASKLOOP_CLAUSE_MASK \
26373 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
26374 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
26375 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
26376 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
26377 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
26378 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
26379 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
26380 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
26381 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
26382 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
26383 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
26384 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
26385 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
26386 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
26387 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
26388 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
26389 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
26392 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
26393 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
26396 tree clauses
, block
, ret
;
26398 strcat (p_name
, " taskloop");
26399 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
26400 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
26402 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
)) != 0)
26403 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_IN_REDUCTION
);
26405 if (c_parser_next_token_is (parser
, CPP_NAME
))
26407 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
26409 if (strcmp (p
, "simd") == 0)
26411 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
26412 if (cclauses
== NULL
)
26413 cclauses
= cclauses_buf
;
26414 c_parser_consume_token (parser
);
26415 if (!flag_openmp
) /* flag_openmp_simd */
26416 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
26418 block
= c_begin_compound_stmt (true);
26419 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
26420 block
= c_end_compound_stmt (loc
, block
, true);
26423 ret
= make_node (OMP_TASKLOOP
);
26424 TREE_TYPE (ret
) = void_type_node
;
26425 OMP_FOR_BODY (ret
) = block
;
26426 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
26427 OMP_FOR_CLAUSES (ret
)
26428 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret
));
26429 SET_EXPR_LOCATION (ret
, loc
);
26434 if (!flag_openmp
) /* flag_openmp_simd */
26436 c_parser_skip_to_pragma_eol (parser
, false);
26440 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
26443 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
26444 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
26447 clauses
= c_finish_taskloop_clauses (clauses
);
26448 block
= c_begin_compound_stmt (true);
26449 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
26450 block
= c_end_compound_stmt (loc
, block
, true);
26456 /* OpenMP 5.1: Parse sizes list for "omp tile sizes"
26457 sizes ( size-expr-list ) */
26459 c_parser_omp_tile_sizes (c_parser
*parser
, location_t loc
)
26461 tree sizes
= NULL_TREE
;
26463 if (c_parser_next_token_is (parser
, CPP_COMMA
))
26464 c_parser_consume_token (parser
);
26466 c_token
*tok
= c_parser_peek_token (parser
);
26467 if (tok
->type
!= CPP_NAME
26468 || strcmp ("sizes", IDENTIFIER_POINTER (tok
->value
)))
26470 c_parser_error (parser
, "expected %<sizes%>");
26471 return error_mark_node
;
26473 c_parser_consume_token (parser
);
26475 matching_parens parens
;
26476 if (!parens
.require_open (parser
))
26477 return error_mark_node
;
26479 vec
<tree
, va_gc
> *sizes_vec
26480 = c_parser_expr_list (parser
, true, true, NULL
, NULL
, NULL
, NULL
);
26481 sizes
= build_tree_list_vec (sizes_vec
);
26482 release_tree_vector (sizes_vec
);
26484 for (tree s
= sizes
; s
; s
= TREE_CHAIN (s
))
26486 tree expr
= TREE_VALUE (s
);
26487 if (expr
== error_mark_node
)
26489 parens
.skip_until_found_close (parser
);
26490 return error_mark_node
;
26494 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
26495 || !tree_fits_shwi_p (expr
)
26496 || (n
= tree_to_shwi (expr
)) <= 0
26499 c_parser_error (parser
, "%<sizes%> argument needs positive"
26500 " integral constant");
26501 TREE_VALUE (s
) = integer_one_node
;
26504 parens
.require_close (parser
);
26506 gcc_assert (sizes
);
26507 tree c
= build_omp_clause (loc
, OMP_CLAUSE_SIZES
);
26508 OMP_CLAUSE_SIZES_LIST (c
) = sizes
;
26514 #pragma omp tile sizes ( size-expr-list ) new-line
26517 LOC is the location of the #pragma token. */
26520 c_parser_omp_tile (location_t loc
, c_parser
*parser
, bool *if_p
)
26522 tree clauses
= c_parser_omp_tile_sizes (parser
, loc
);
26523 c_parser_skip_to_pragma_eol (parser
);
26525 if (!clauses
|| clauses
== error_mark_node
)
26526 return error_mark_node
;
26528 tree block
= c_begin_compound_stmt (true);
26529 tree ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TILE
, clauses
,
26531 block
= c_end_compound_stmt (loc
, block
, true);
26537 #define OMP_UNROLL_CLAUSE_MASK \
26538 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARTIAL) \
26539 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FULL))
26542 #pragma omp unroll unroll-clause[optseq] new-line
26545 LOC is the location of the #pragma token. */
26548 c_parser_omp_unroll (location_t loc
, c_parser
*parser
, bool *if_p
)
26550 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_UNROLL_CLAUSE_MASK
,
26551 "#pragma omp unroll", true);
26553 tree block
= c_begin_compound_stmt (true);
26554 tree ret
= c_parser_omp_for_loop (loc
, parser
, OMP_UNROLL
, clauses
,
26556 block
= c_end_compound_stmt (loc
, block
, true);
26563 #pragma omp nothing new-line */
26566 c_parser_omp_nothing (c_parser
*parser
)
26568 c_parser_consume_pragma (parser
);
26569 c_parser_skip_to_pragma_eol (parser
);
26573 #pragma omp error clauses[optseq] new-line */
26576 c_parser_omp_error (c_parser
*parser
, enum pragma_context context
)
26578 int at_compilation
= -1;
26579 int severity_fatal
= -1;
26580 tree message
= NULL_TREE
;
26582 location_t loc
= c_parser_peek_token (parser
)->location
;
26584 c_parser_consume_pragma (parser
);
26586 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
26588 if (c_parser_next_token_is (parser
, CPP_COMMA
)
26589 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
26590 c_parser_consume_token (parser
);
26592 if (!c_parser_next_token_is (parser
, CPP_NAME
))
26596 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
26597 location_t cloc
= c_parser_peek_token (parser
)->location
;
26598 static const char *args
[] = {
26599 "execution", "compilation", "warning", "fatal"
26602 int idx
= 0, n
= -1;
26603 tree m
= NULL_TREE
;
26605 if (!strcmp (p
, "at"))
26606 v
= &at_compilation
;
26607 else if (!strcmp (p
, "severity"))
26609 v
= &severity_fatal
;
26612 else if (strcmp (p
, "message"))
26615 "expected %<at%>, %<severity%> or %<message%> clause");
26616 c_parser_skip_to_pragma_eol (parser
, false);
26620 c_parser_consume_token (parser
);
26622 matching_parens parens
;
26623 if (parens
.require_open (parser
))
26627 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
26628 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
26629 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
26630 m
= convert (const_string_type_node
, expr
.value
);
26631 m
= c_fully_fold (m
, false, NULL
);
26635 if (c_parser_next_token_is (parser
, CPP_NAME
))
26637 tree val
= c_parser_peek_token (parser
)->value
;
26638 const char *q
= IDENTIFIER_POINTER (val
);
26640 if (!strcmp (q
, args
[idx
]))
26642 else if (!strcmp (q
, args
[idx
+ 1]))
26647 error_at (c_parser_peek_token (parser
)->location
,
26648 "expected %qs or %qs", args
[idx
], args
[idx
+ 1]);
26650 switch (c_parser_peek_token (parser
)->type
)
26653 case CPP_PRAGMA_EOL
:
26654 case CPP_CLOSE_PAREN
:
26657 if (c_parser_peek_2nd_token (parser
)->type
26658 == CPP_CLOSE_PAREN
)
26659 c_parser_consume_token (parser
);
26664 c_parser_consume_token (parser
);
26667 parens
.skip_until_found_close (parser
);
26673 error_at (cloc
, "too many %qs clauses", p
);
26683 error_at (cloc
, "too many %qs clauses", p
);
26693 c_parser_skip_to_pragma_eol (parser
);
26697 if (at_compilation
== -1)
26698 at_compilation
= 1;
26699 if (severity_fatal
== -1)
26700 severity_fatal
= 1;
26701 if (!at_compilation
)
26703 if (context
!= pragma_compound
)
26705 error_at (loc
, "%<#pragma omp error%> with %<at(execution)%> clause "
26706 "may only be used in compound statements");
26710 = builtin_decl_explicit (severity_fatal
? BUILT_IN_GOMP_ERROR
26711 : BUILT_IN_GOMP_WARNING
);
26713 message
= build_zero_cst (const_string_type_node
);
26714 tree stmt
= build_call_expr_loc (loc
, fndecl
, 2, message
,
26715 build_all_ones_cst (size_type_node
));
26719 const char *msg
= NULL
;
26722 msg
= c_getstr (message
);
26724 msg
= _("<message unknown at compile time>");
26727 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
26728 "%<pragma omp error%> encountered: %s", msg
);
26730 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
26731 "%<pragma omp error%> encountered");
26735 /* Assumption clauses:
26737 absent (directive-name-list)
26738 contains (directive-name-list)
26745 c_parser_omp_assumption_clauses (c_parser
*parser
, bool is_assume
)
26747 bool no_openmp
= false;
26748 bool no_openmp_routines
= false;
26749 bool no_parallelism
= false;
26750 bitmap_head absent_head
, contains_head
;
26752 bitmap_obstack_initialize (NULL
);
26753 bitmap_initialize (&absent_head
, &bitmap_default_obstack
);
26754 bitmap_initialize (&contains_head
, &bitmap_default_obstack
);
26756 if (c_parser_next_token_is (parser
, CPP_PRAGMA_EOL
))
26757 error_at (c_parser_peek_token (parser
)->location
,
26758 "expected at least one assumption clause");
26760 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
26762 if (c_parser_next_token_is (parser
, CPP_COMMA
)
26763 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
26764 c_parser_consume_token (parser
);
26766 if (!c_parser_next_token_is (parser
, CPP_NAME
))
26770 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
26771 location_t cloc
= c_parser_peek_token (parser
)->location
;
26773 if (!strcmp (p
, "no_openmp"))
26775 c_parser_consume_token (parser
);
26777 error_at (cloc
, "too many %qs clauses", "no_openmp");
26780 else if (!strcmp (p
, "no_openmp_routines"))
26782 c_parser_consume_token (parser
);
26783 if (no_openmp_routines
)
26784 error_at (cloc
, "too many %qs clauses", "no_openmp_routines");
26785 no_openmp_routines
= true;
26787 else if (!strcmp (p
, "no_parallelism"))
26789 c_parser_consume_token (parser
);
26790 if (no_parallelism
)
26791 error_at (cloc
, "too many %qs clauses", "no_parallelism");
26792 no_parallelism
= true;
26794 else if (!strcmp (p
, "holds"))
26796 c_parser_consume_token (parser
);
26797 matching_parens parens
;
26798 if (parens
.require_open (parser
))
26800 location_t eloc
= c_parser_peek_token (parser
)->location
;
26801 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
26802 tree t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
26803 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
26804 t
= c_fully_fold (t
, false, NULL
);
26805 if (is_assume
&& t
!= error_mark_node
)
26807 tree fn
= build_call_expr_internal_loc (eloc
, IFN_ASSUME
,
26812 parens
.skip_until_found_close (parser
);
26815 else if (!strcmp (p
, "absent") || !strcmp (p
, "contains"))
26817 c_parser_consume_token (parser
);
26818 matching_parens parens
;
26819 if (parens
.require_open (parser
))
26823 const char *directive
[3] = {};
26825 location_t dloc
= c_parser_peek_token (parser
)->location
;
26826 for (i
= 0; i
< 3; i
++)
26829 if (c_parser_peek_nth_token (parser
, i
+ 1)->type
26831 id
= c_parser_peek_nth_token (parser
, i
+ 1)->value
;
26832 else if (c_parser_peek_nth_token (parser
, i
+ 1)->keyword
26836 = c_parser_peek_nth_token (parser
, i
+ 1)->keyword
;
26837 id
= ridpointers
[rid
];
26841 directive
[i
] = IDENTIFIER_POINTER (id
);
26844 error_at (dloc
, "expected directive name");
26847 const struct c_omp_directive
*dir
26848 = c_omp_categorize_directive (directive
[0],
26852 || dir
->kind
== C_OMP_DIR_DECLARATIVE
26853 || dir
->kind
== C_OMP_DIR_INFORMATIONAL
26854 || dir
->id
== PRAGMA_OMP_END
26855 || (!dir
->second
&& directive
[1])
26856 || (!dir
->third
&& directive
[2]))
26857 error_at (dloc
, "unknown OpenMP directive name in "
26858 "%qs clause argument", p
);
26861 int id
= dir
- c_omp_directives
;
26862 if (bitmap_bit_p (p
[0] == 'a' ? &contains_head
26863 : &absent_head
, id
))
26864 error_at (dloc
, "%<%s%s%s%s%s%> directive "
26865 "mentioned in both %<absent%> and "
26866 "%<contains%> clauses",
26868 directive
[1] ? " " : "",
26869 directive
[1] ? directive
[1] : "",
26870 directive
[2] ? " " : "",
26871 directive
[2] ? directive
[2] : "");
26872 else if (!bitmap_set_bit (p
[0] == 'a'
26874 : &contains_head
, id
))
26875 error_at (dloc
, "%<%s%s%s%s%s%> directive "
26876 "mentioned multiple times in %qs "
26879 directive
[1] ? " " : "",
26880 directive
[1] ? directive
[1] : "",
26881 directive
[2] ? " " : "",
26882 directive
[2] ? directive
[2] : "", p
);
26885 c_parser_consume_token (parser
);
26887 if (c_parser_next_token_is (parser
, CPP_COMMA
))
26888 c_parser_consume_token (parser
);
26893 parens
.skip_until_found_close (parser
);
26896 else if (startswith (p
, "ext_"))
26898 warning_at (cloc
, OPT_Wopenmp
, "unknown assumption clause %qs", p
);
26899 c_parser_consume_token (parser
);
26900 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
26902 matching_parens parens
;
26903 parens
.consume_open (parser
);
26904 c_parser_balanced_token_sequence (parser
);
26905 parens
.require_close (parser
);
26910 c_parser_consume_token (parser
);
26911 error_at (cloc
, "expected assumption clause");
26915 c_parser_skip_to_pragma_eol (parser
);
26919 #pragma omp assume clauses[optseq] new-line */
26922 c_parser_omp_assume (c_parser
*parser
, bool *if_p
)
26924 c_parser_omp_assumption_clauses (parser
, true);
26925 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
26929 #pragma omp assumes clauses[optseq] new-line */
26932 c_parser_omp_assumes (c_parser
*parser
)
26934 c_parser_consume_pragma (parser
);
26935 c_parser_omp_assumption_clauses (parser
, false);
26938 /* Main entry point to parsing most OpenMP pragmas. */
26941 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
26943 enum pragma_kind p_kind
;
26946 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
26947 omp_clause_mask
mask (0);
26949 loc
= c_parser_peek_token (parser
)->location
;
26950 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
26951 c_parser_consume_pragma (parser
);
26955 case PRAGMA_OACC_ATOMIC
:
26956 c_parser_omp_atomic (loc
, parser
, true);
26958 case PRAGMA_OACC_CACHE
:
26959 strcpy (p_name
, "#pragma acc");
26960 stmt
= c_parser_oacc_cache (loc
, parser
);
26962 case PRAGMA_OACC_DATA
:
26963 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
26965 case PRAGMA_OACC_HOST_DATA
:
26966 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
26968 case PRAGMA_OACC_KERNELS
:
26969 case PRAGMA_OACC_PARALLEL
:
26970 case PRAGMA_OACC_SERIAL
:
26971 strcpy (p_name
, "#pragma acc");
26972 stmt
= c_parser_oacc_compute (loc
, parser
, p_kind
, p_name
, if_p
);
26974 case PRAGMA_OACC_LOOP
:
26975 strcpy (p_name
, "#pragma acc");
26976 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26978 case PRAGMA_OACC_WAIT
:
26979 strcpy (p_name
, "#pragma wait");
26980 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
26982 case PRAGMA_OMP_ATOMIC
:
26983 c_parser_omp_atomic (loc
, parser
, false);
26985 case PRAGMA_OMP_CRITICAL
:
26986 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
26988 case PRAGMA_OMP_DISTRIBUTE
:
26989 strcpy (p_name
, "#pragma omp");
26990 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26992 case PRAGMA_OMP_FOR
:
26993 strcpy (p_name
, "#pragma omp");
26994 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26996 case PRAGMA_OMP_LOOP
:
26997 strcpy (p_name
, "#pragma omp");
26998 stmt
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
27000 case PRAGMA_OMP_MASKED
:
27001 strcpy (p_name
, "#pragma omp");
27002 stmt
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, NULL
, if_p
);
27004 case PRAGMA_OMP_MASTER
:
27005 strcpy (p_name
, "#pragma omp");
27006 stmt
= c_parser_omp_master (loc
, parser
, p_name
, mask
, NULL
, if_p
);
27008 case PRAGMA_OMP_PARALLEL
:
27009 strcpy (p_name
, "#pragma omp");
27010 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
27012 case PRAGMA_OMP_SCOPE
:
27013 stmt
= c_parser_omp_scope (loc
, parser
, if_p
);
27015 case PRAGMA_OMP_SECTIONS
:
27016 strcpy (p_name
, "#pragma omp");
27017 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
27019 case PRAGMA_OMP_SIMD
:
27020 strcpy (p_name
, "#pragma omp");
27021 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
27023 case PRAGMA_OMP_SINGLE
:
27024 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
27026 case PRAGMA_OMP_TASK
:
27027 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
27029 case PRAGMA_OMP_TASKGROUP
:
27030 stmt
= c_parser_omp_taskgroup (loc
, parser
, if_p
);
27032 case PRAGMA_OMP_TASKLOOP
:
27033 strcpy (p_name
, "#pragma omp");
27034 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
27036 case PRAGMA_OMP_TEAMS
:
27037 strcpy (p_name
, "#pragma omp");
27038 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
27040 case PRAGMA_OMP_ASSUME
:
27041 c_parser_omp_assume (parser
, if_p
);
27043 case PRAGMA_OMP_TILE
:
27044 stmt
= c_parser_omp_tile (loc
, parser
, if_p
);
27046 case PRAGMA_OMP_UNROLL
:
27047 stmt
= c_parser_omp_unroll (loc
, parser
, if_p
);
27050 gcc_unreachable ();
27053 if (stmt
&& stmt
!= error_mark_node
)
27054 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
27059 # pragma omp threadprivate (variable-list) */
27062 c_parser_omp_threadprivate (c_parser
*parser
)
27067 c_parser_consume_pragma (parser
);
27068 loc
= c_parser_peek_token (parser
)->location
;
27069 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
27071 /* Mark every variable in VARS to be assigned thread local storage. */
27072 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
27074 tree v
= TREE_PURPOSE (t
);
27076 /* FIXME diagnostics: Ideally we should keep individual
27077 locations for all the variables in the var list to make the
27078 following errors more precise. Perhaps
27079 c_parser_omp_var_list_parens() should construct a list of
27080 locations to go along with the var list. */
27082 /* If V had already been marked threadprivate, it doesn't matter
27083 whether it had been used prior to this point. */
27085 error_at (loc
, "%qD is not a variable", v
);
27086 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
27087 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
27088 else if (! is_global_var (v
))
27089 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
27090 else if (TREE_TYPE (v
) == error_mark_node
)
27092 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
27093 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
27096 if (! DECL_THREAD_LOCAL_P (v
))
27098 set_decl_tls_model (v
, decl_default_tls_model (v
));
27099 /* If rtl has been already set for this var, call
27100 make_decl_rtl once again, so that encode_section_info
27101 has a chance to look at the new decl flags. */
27102 if (DECL_RTL_SET_P (v
))
27105 C_DECL_THREADPRIVATE_P (v
) = 1;
27109 c_parser_skip_to_pragma_eol (parser
);
27112 /* Parse a transaction attribute (GCC Extension).
27114 transaction-attribute:
27116 attribute-specifier
27120 c_parser_transaction_attributes (c_parser
*parser
)
27122 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
27123 return c_parser_gnu_attributes (parser
);
27125 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
27127 return c_parser_std_attribute_specifier (parser
, true);
27130 /* Parse a __transaction_atomic or __transaction_relaxed statement
27133 transaction-statement:
27134 __transaction_atomic transaction-attribute[opt] compound-statement
27135 __transaction_relaxed compound-statement
27137 Note that the only valid attribute is: "outer".
27141 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
27143 unsigned int old_in
= parser
->in_transaction
;
27144 unsigned int this_in
= 1, new_in
;
27145 location_t loc
= c_parser_peek_token (parser
)->location
;
27148 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
27149 || keyword
== RID_TRANSACTION_RELAXED
)
27150 && c_parser_next_token_is_keyword (parser
, keyword
));
27151 c_parser_consume_token (parser
);
27153 if (keyword
== RID_TRANSACTION_RELAXED
)
27154 this_in
|= TM_STMT_ATTR_RELAXED
;
27157 attrs
= c_parser_transaction_attributes (parser
);
27159 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
27162 /* Keep track if we're in the lexical scope of an outer transaction. */
27163 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
27165 parser
->in_transaction
= new_in
;
27166 stmt
= c_parser_compound_statement (parser
);
27167 parser
->in_transaction
= old_in
;
27170 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
27172 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
27173 "%<__transaction_atomic%> without transactional memory support enabled"
27174 : "%<__transaction_relaxed %> "
27175 "without transactional memory support enabled"));
27180 /* Parse a __transaction_atomic or __transaction_relaxed expression
27183 transaction-expression:
27184 __transaction_atomic ( expression )
27185 __transaction_relaxed ( expression )
27188 static struct c_expr
27189 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
27192 unsigned int old_in
= parser
->in_transaction
;
27193 unsigned int this_in
= 1;
27194 location_t loc
= c_parser_peek_token (parser
)->location
;
27197 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
27198 || keyword
== RID_TRANSACTION_RELAXED
)
27199 && c_parser_next_token_is_keyword (parser
, keyword
));
27200 c_parser_consume_token (parser
);
27202 if (keyword
== RID_TRANSACTION_RELAXED
)
27203 this_in
|= TM_STMT_ATTR_RELAXED
;
27206 attrs
= c_parser_transaction_attributes (parser
);
27208 this_in
|= parse_tm_stmt_attr (attrs
, 0);
27211 parser
->in_transaction
= this_in
;
27212 matching_parens parens
;
27213 if (parens
.require_open (parser
))
27215 tree expr
= c_parser_expression (parser
).value
;
27216 ret
.original_type
= TREE_TYPE (expr
);
27217 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
27218 if (this_in
& TM_STMT_ATTR_RELAXED
)
27219 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
27220 SET_EXPR_LOCATION (ret
.value
, loc
);
27221 ret
.original_code
= TRANSACTION_EXPR
;
27223 if (!parens
.require_close (parser
))
27225 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
27233 ret
.original_code
= ERROR_MARK
;
27234 ret
.original_type
= NULL
;
27236 parser
->in_transaction
= old_in
;
27239 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
27240 "%<__transaction_atomic%> without transactional memory support enabled"
27241 : "%<__transaction_relaxed %> "
27242 "without transactional memory support enabled"));
27244 set_c_expr_source_range (&ret
, loc
, loc
);
27249 /* Parse a __transaction_cancel statement (GCC Extension).
27251 transaction-cancel-statement:
27252 __transaction_cancel transaction-attribute[opt] ;
27254 Note that the only valid attribute is "outer".
27258 c_parser_transaction_cancel (c_parser
*parser
)
27260 location_t loc
= c_parser_peek_token (parser
)->location
;
27262 bool is_outer
= false;
27264 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
27265 c_parser_consume_token (parser
);
27267 attrs
= c_parser_transaction_attributes (parser
);
27269 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
27273 error_at (loc
, "%<__transaction_cancel%> without "
27274 "transactional memory support enabled");
27277 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
27279 error_at (loc
, "%<__transaction_cancel%> within a "
27280 "%<__transaction_relaxed%>");
27285 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
27286 && !is_tm_may_cancel_outer (current_function_decl
))
27288 error_at (loc
, "outer %<__transaction_cancel%> not "
27289 "within outer %<__transaction_atomic%> or "
27290 "a %<transaction_may_cancel_outer%> function");
27294 else if (parser
->in_transaction
== 0)
27296 error_at (loc
, "%<__transaction_cancel%> not within "
27297 "%<__transaction_atomic%>");
27301 return add_stmt (build_tm_abort_call (loc
, is_outer
));
27304 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
27307 /* Parse a single source file. */
27310 c_parse_file (void)
27312 /* Use local storage to begin. If the first token is a pragma, parse it.
27313 If it is #pragma GCC pch_preprocess, then this will load a PCH file
27314 which will cause garbage collection. */
27317 memset (&tparser
, 0, sizeof tparser
);
27318 tparser
.translate_strings_p
= true;
27319 tparser
.tokens
= &tparser
.tokens_buf
[0];
27320 the_parser
= &tparser
;
27322 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
27323 c_parser_pragma_pch_preprocess (&tparser
);
27325 c_common_no_more_pch ();
27327 the_parser
= ggc_alloc
<c_parser
> ();
27328 *the_parser
= tparser
;
27329 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
27330 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
27332 /* Initialize EH, if we've been told to do so. */
27333 if (flag_exceptions
)
27334 using_eh_for_cleanups ();
27336 c_parser_translation_unit (the_parser
);
27341 c_init_preprocess (void)
27343 /* Create a parser for use by pragma_lex during preprocessing. */
27344 the_parser
= ggc_alloc
<c_parser
> ();
27345 memset (the_parser
, 0, sizeof (c_parser
));
27346 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
27349 /* Parse the body of a function declaration marked with "__RTL".
27351 The RTL parser works on the level of characters read from a
27352 FILE *, whereas c_parser works at the level of tokens.
27353 Square this circle by consuming all of the tokens up to and
27354 including the closing brace, recording the start/end of the RTL
27355 fragment, and reopening the file and re-reading the relevant
27356 lines within the RTL parser.
27358 This requires the opening and closing braces of the C function
27359 to be on separate lines from the RTL they wrap.
27361 Take ownership of START_WITH_PASS, if non-NULL. */
27364 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
27366 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
27368 free (start_with_pass
);
27369 return c_parser_peek_token (parser
)->location
;
27372 location_t start_loc
= c_parser_peek_token (parser
)->location
;
27374 /* Consume all tokens, up to the closing brace, handling
27375 matching pairs of braces in the rtl dump. */
27376 int num_open_braces
= 1;
27379 switch (c_parser_peek_token (parser
)->type
)
27381 case CPP_OPEN_BRACE
:
27384 case CPP_CLOSE_BRACE
:
27385 if (--num_open_braces
== 0)
27386 goto found_closing_brace
;
27389 error_at (start_loc
, "no closing brace");
27390 free (start_with_pass
);
27391 return c_parser_peek_token (parser
)->location
;
27395 c_parser_consume_token (parser
);
27398 found_closing_brace
:
27399 /* At the closing brace; record its location. */
27400 location_t end_loc
= c_parser_peek_token (parser
)->location
;
27402 /* Consume the closing brace. */
27403 c_parser_consume_token (parser
);
27405 /* Invoke the RTL parser. */
27406 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
27408 free (start_with_pass
);
27412 /* Run the backend on the cfun created above, transferring ownership of
27413 START_WITH_PASS. */
27414 run_rtl_passes (start_with_pass
);
27418 #include "gt-c-c-parser.h"