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 (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)
1538 cpp_opts
->cpp_pedantic
= pedantic
= 0;
1539 warn_pointer_arith
= 0;
1540 cpp_opts
->cpp_warn_traditional
= warn_traditional
= 0;
1542 cpp_opts
->cpp_warn_long_long
= warn_long_long
= 0;
1543 warn_cxx_compat
= 0;
1544 warn_overlength_strings
= 0;
1545 warn_c90_c99_compat
= 0;
1546 warn_c99_c11_compat
= 0;
1547 warn_c11_c23_compat
= 0;
1551 /* Restore the warning flags which are controlled by __extension__.
1552 FLAGS is the return value from disable_extension_diagnostics. */
1555 restore_extension_diagnostics (int flags
)
1557 cpp_opts
->cpp_pedantic
= pedantic
= flags
& 1;
1558 warn_pointer_arith
= (flags
>> 1) & 1;
1559 cpp_opts
->cpp_warn_traditional
= warn_traditional
= (flags
>> 2) & 1;
1560 flag_iso
= (flags
>> 3) & 1;
1561 cpp_opts
->cpp_warn_long_long
= warn_long_long
= (flags
>> 4) & 1;
1562 warn_cxx_compat
= (flags
>> 5) & 1;
1563 warn_overlength_strings
= (flags
>> 6) & 1;
1564 /* See above for why is this needed. */
1565 warn_c90_c99_compat
= (flags
>> 7) & 1 ? 1 : ((flags
>> 8) & 1 ? -1 : 0);
1566 warn_c99_c11_compat
= (flags
>> 9) & 1 ? 1 : ((flags
>> 10) & 1 ? -1 : 0);
1567 warn_c11_c23_compat
= (flags
>> 11) & 1 ? 1 : ((flags
>> 12) & 1 ? -1 : 0);
1570 /* Helper data structure for parsing #pragma acc routine. */
1571 struct oacc_routine_data
{
1572 bool error_seen
; /* Set if error has been reported. */
1573 bool fndecl_seen
; /* Set if one fn decl/definition has been seen already. */
1578 /* Used for parsing objc foreach statements. */
1579 static tree objc_foreach_break_label
, objc_foreach_continue_label
;
1581 /* Used for parsing OMP for loops.
1583 Some notes on flags used for context:
1584 parser->omp_for_parse_state is non-null anywhere inside the OMP FOR
1585 construct, except for the final-loop-body.
1586 The want_nested_loop flag is true if inside a {} sequence where
1587 a loop-nest (or another {} sequence containing a loop-nest) is expected,
1588 but has not yet been seen. It's false when parsing intervening code
1589 statements or their substatements that cannot contain a loop-nest.
1590 The in_intervening_code flag is true when parsing any intervening code,
1591 including substatements, and whether or not want_nested_loop is true.
1593 And, about error handling:
1594 The saw_intervening_code flag is set if the loop is not perfectly
1595 nested, even in the usual case where this is not an error.
1596 perfect_nesting_fail is set if an error has been diagnosed because an
1597 imperfectly-nested loop was found where a perfectly-nested one is
1598 required (we diagnose this only once).
1599 fail is set if any kind of structural error in the loop nest
1600 has been found and diagnosed.
1602 struct omp_for_parse_data
{
1603 enum tree_code code
;
1604 tree declv
, condv
, incrv
, initv
;
1607 int count
; /* Expected nesting depth. */
1608 int depth
; /* Current nesting depth. */
1612 bool want_nested_loop
: 1;
1613 bool in_intervening_code
: 1;
1614 bool saw_intervening_code
: 1;
1615 bool perfect_nesting_fail
: 1;
1619 static bool c_parser_nth_token_starts_std_attributes (c_parser
*,
1621 static tree
c_parser_std_attribute_specifier_sequence (c_parser
*);
1622 static void c_parser_external_declaration (c_parser
*);
1623 static void c_parser_asm_definition (c_parser
*);
1624 static void c_parser_declaration_or_fndef (c_parser
*, bool, bool, bool,
1625 bool, bool, tree
* = NULL
,
1626 vec
<c_token
> * = NULL
,
1627 bool have_attrs
= false,
1629 struct oacc_routine_data
* = NULL
,
1631 static bool c_parser_handle_statement_omp_attributes (c_parser
*, tree
&,
1633 static void c_parser_static_assert_declaration_no_semi (c_parser
*);
1634 static void c_parser_static_assert_declaration (c_parser
*);
1635 static struct c_typespec
c_parser_enum_specifier (c_parser
*);
1636 static struct c_typespec
c_parser_struct_or_union_specifier (c_parser
*);
1637 static tree
c_parser_struct_declaration (c_parser
*, tree
*);
1638 static struct c_typespec
c_parser_typeof_specifier (c_parser
*);
1639 static tree
c_parser_alignas_specifier (c_parser
*);
1640 static struct c_declarator
*c_parser_direct_declarator (c_parser
*, bool,
1642 static struct c_declarator
*c_parser_direct_declarator_inner (c_parser
*,
1644 struct c_declarator
*);
1645 static struct c_arg_info
*c_parser_parms_declarator (c_parser
*, bool, tree
,
1647 static struct c_arg_info
*c_parser_parms_list_declarator (c_parser
*, tree
,
1649 static struct c_parm
*c_parser_parameter_declaration (c_parser
*, tree
, bool);
1650 static tree
c_parser_simple_asm_expr (c_parser
*);
1651 static tree
c_parser_gnu_attributes (c_parser
*);
1652 static struct c_expr
c_parser_initializer (c_parser
*, tree
);
1653 static struct c_expr
c_parser_braced_init (c_parser
*, tree
, bool,
1654 struct obstack
*, tree
);
1655 static void c_parser_initelt (c_parser
*, struct obstack
*);
1656 static void c_parser_initval (c_parser
*, struct c_expr
*,
1658 static tree
c_parser_compound_statement (c_parser
*, location_t
* = NULL
);
1659 static location_t
c_parser_compound_statement_nostart (c_parser
*);
1660 static void c_parser_label (c_parser
*, tree
);
1661 static void c_parser_statement (c_parser
*, bool *, location_t
* = NULL
);
1662 static void c_parser_statement_after_labels (c_parser
*, bool *,
1663 vec
<tree
> * = NULL
);
1664 static tree
c_parser_c99_block_statement (c_parser
*, bool *,
1665 location_t
* = NULL
);
1666 static void c_parser_if_statement (c_parser
*, bool *, vec
<tree
> *);
1667 static void c_parser_switch_statement (c_parser
*, bool *);
1668 static void c_parser_while_statement (c_parser
*, bool, unsigned short, bool,
1670 static void c_parser_do_statement (c_parser
*, bool, unsigned short, bool);
1671 static void c_parser_for_statement (c_parser
*, bool, unsigned short, bool,
1673 static tree
c_parser_asm_statement (c_parser
*);
1674 static tree
c_parser_asm_operands (c_parser
*);
1675 static tree
c_parser_asm_goto_operands (c_parser
*);
1676 static tree
c_parser_asm_clobbers (c_parser
*);
1677 static struct c_expr
c_parser_expr_no_commas (c_parser
*, struct c_expr
*,
1679 static struct c_expr
c_parser_conditional_expression (c_parser
*,
1680 struct c_expr
*, tree
);
1681 static struct c_expr
c_parser_binary_expression (c_parser
*, struct c_expr
*,
1683 static struct c_expr
c_parser_cast_expression (c_parser
*, struct c_expr
*);
1684 static struct c_expr
c_parser_unary_expression (c_parser
*);
1685 static struct c_expr
c_parser_sizeof_expression (c_parser
*);
1686 static struct c_expr
c_parser_alignof_expression (c_parser
*);
1687 static struct c_expr
c_parser_postfix_expression (c_parser
*);
1688 static struct c_expr
c_parser_postfix_expression_after_paren_type (c_parser
*,
1689 struct c_declspecs
*,
1690 struct c_type_name
*,
1692 static struct c_expr
c_parser_postfix_expression_after_primary (c_parser
*,
1695 static tree
c_parser_transaction (c_parser
*, enum rid
);
1696 static struct c_expr
c_parser_transaction_expression (c_parser
*, enum rid
);
1697 static tree
c_parser_transaction_cancel (c_parser
*);
1698 static struct c_expr
c_parser_expression (c_parser
*);
1699 static struct c_expr
c_parser_expression_conv (c_parser
*);
1700 static vec
<tree
, va_gc
> *c_parser_expr_list (c_parser
*, bool, bool,
1701 vec
<tree
, va_gc
> **, location_t
*,
1702 tree
*, vec
<location_t
> *,
1703 unsigned int * = NULL
);
1704 static struct c_expr
c_parser_has_attribute_expression (c_parser
*);
1706 static void c_parser_oacc_declare (c_parser
*);
1707 static void c_parser_oacc_enter_exit_data (c_parser
*, bool);
1708 static void c_parser_oacc_update (c_parser
*);
1709 static void c_parser_omp_construct (c_parser
*, bool *);
1710 static void c_parser_omp_threadprivate (c_parser
*);
1711 static void c_parser_omp_barrier (c_parser
*);
1712 static void c_parser_omp_depobj (c_parser
*);
1713 static void c_parser_omp_flush (c_parser
*);
1714 static tree
c_parser_omp_loop_nest (c_parser
*, bool *);
1715 static tree
c_parser_omp_for_loop (location_t
, c_parser
*, enum tree_code
,
1716 tree
, tree
*, bool *);
1717 static void c_parser_omp_taskwait (c_parser
*);
1718 static void c_parser_omp_taskyield (c_parser
*);
1719 static void c_parser_omp_cancel (c_parser
*);
1720 static void c_parser_omp_nothing (c_parser
*);
1722 enum pragma_context
{ pragma_external
, pragma_struct
, pragma_param
,
1723 pragma_stmt
, pragma_compound
};
1724 static bool c_parser_pragma (c_parser
*, enum pragma_context
, bool *);
1725 static bool c_parser_omp_cancellation_point (c_parser
*, enum pragma_context
);
1726 static bool c_parser_omp_target (c_parser
*, enum pragma_context
, bool *);
1727 static void c_parser_omp_begin (c_parser
*);
1728 static void c_parser_omp_end (c_parser
*);
1729 static bool c_parser_omp_declare (c_parser
*, enum pragma_context
);
1730 static void c_parser_omp_requires (c_parser
*);
1731 static bool c_parser_omp_error (c_parser
*, enum pragma_context
);
1732 static void c_parser_omp_assumption_clauses (c_parser
*, bool);
1733 static void c_parser_omp_allocate (c_parser
*);
1734 static void c_parser_omp_assumes (c_parser
*);
1735 static bool c_parser_omp_ordered (c_parser
*, enum pragma_context
, bool *);
1736 static void c_parser_oacc_routine (c_parser
*, enum pragma_context
);
1738 /* These Objective-C parser functions are only ever called when
1739 compiling Objective-C. */
1740 static void c_parser_objc_class_definition (c_parser
*, tree
);
1741 static void c_parser_objc_class_instance_variables (c_parser
*);
1742 static void c_parser_objc_class_declaration (c_parser
*);
1743 static void c_parser_objc_alias_declaration (c_parser
*);
1744 static void c_parser_objc_protocol_definition (c_parser
*, tree
);
1745 static bool c_parser_objc_method_type (c_parser
*);
1746 static void c_parser_objc_method_definition (c_parser
*);
1747 static void c_parser_objc_methodprotolist (c_parser
*);
1748 static void c_parser_objc_methodproto (c_parser
*);
1749 static tree
c_parser_objc_method_decl (c_parser
*, bool, tree
*, tree
*);
1750 static tree
c_parser_objc_type_name (c_parser
*);
1751 static tree
c_parser_objc_protocol_refs (c_parser
*);
1752 static void c_parser_objc_try_catch_finally_statement (c_parser
*);
1753 static void c_parser_objc_synchronized_statement (c_parser
*);
1754 static tree
c_parser_objc_selector (c_parser
*);
1755 static tree
c_parser_objc_selector_arg (c_parser
*);
1756 static tree
c_parser_objc_receiver (c_parser
*);
1757 static tree
c_parser_objc_message_args (c_parser
*);
1758 static tree
c_parser_objc_keywordexpr (c_parser
*);
1759 static void c_parser_objc_at_property_declaration (c_parser
*);
1760 static void c_parser_objc_at_synthesize_declaration (c_parser
*);
1761 static void c_parser_objc_at_dynamic_declaration (c_parser
*);
1762 static bool c_parser_objc_diagnose_bad_element_prefix
1763 (c_parser
*, struct c_declspecs
*);
1764 static location_t
c_parser_parse_rtl_body (c_parser
*, char *);
1770 /* Concrete implementation of ana::translation_unit for the C frontend. */
1772 class c_translation_unit
: public translation_unit
1775 /* Implementation of translation_unit::lookup_constant_by_id for use by the
1776 analyzer to look up named constants in the user's source code. */
1777 tree
lookup_constant_by_id (tree id
) const final override
1779 /* Consider decls. */
1780 if (tree decl
= lookup_name (id
))
1781 if (TREE_CODE (decl
) == CONST_DECL
)
1782 if (tree value
= DECL_INITIAL (decl
))
1783 if (TREE_CODE (value
) == INTEGER_CST
)
1786 /* Consider macros. */
1787 cpp_hashnode
*hashnode
= C_CPP_HASHNODE (id
);
1788 if (cpp_macro_p (hashnode
))
1789 if (tree value
= consider_macro (hashnode
->value
.macro
))
1796 lookup_type_by_id (tree id
) const final override
1798 if (tree type_decl
= lookup_name (id
))
1799 if (TREE_CODE (type_decl
) == TYPE_DECL
)
1801 tree record_type
= TREE_TYPE (type_decl
);
1802 if (TREE_CODE (record_type
) == RECORD_TYPE
)
1810 lookup_global_var_by_id (tree id
) const final override
1812 if (tree var_decl
= lookup_name (id
))
1813 if (TREE_CODE (var_decl
) == VAR_DECL
)
1820 /* Attempt to get an INTEGER_CST from MACRO.
1821 Only handle the simplest cases: where MACRO's definition is a single
1822 token containing a number, by lexing the number again.
1823 This will handle e.g.
1825 and other bases but not negative numbers, parentheses or e.g.
1827 as doing so would require a parser. */
1828 tree
consider_macro (cpp_macro
*macro
) const
1830 if (macro
->paramc
> 0)
1832 if (macro
->kind
!= cmk_macro
)
1834 if (macro
->count
!= 1)
1836 const cpp_token
&tok
= macro
->exp
.tokens
[0];
1837 if (tok
.type
!= CPP_NUMBER
)
1840 cpp_reader
*old_parse_in
= parse_in
;
1841 parse_in
= cpp_create_reader (CLK_GNUC89
, NULL
, line_table
);
1844 pp_string (&pp
, (const char *) tok
.val
.str
.text
);
1846 cpp_push_buffer (parse_in
,
1847 (const unsigned char *) pp_formatted_text (&pp
),
1848 strlen (pp_formatted_text (&pp
)),
1853 unsigned char cpp_flags
;
1854 c_lex_with_flags (&value
, &loc
, &cpp_flags
, 0);
1856 cpp_destroy (parse_in
);
1857 parse_in
= old_parse_in
;
1859 if (value
&& TREE_CODE (value
) == INTEGER_CST
)
1868 #endif /* #if ENABLE_ANALYZER */
1870 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1873 external-declarations
1875 external-declarations:
1876 external-declaration
1877 external-declarations external-declaration
1886 c_parser_translation_unit (c_parser
*parser
)
1888 if (c_parser_next_token_is (parser
, CPP_EOF
))
1890 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1891 "ISO C forbids an empty translation unit");
1895 void *obstack_position
= obstack_alloc (&parser_obstack
, 0);
1896 mark_valid_location_for_stdc_pragma (false);
1900 c_parser_external_declaration (parser
);
1901 obstack_free (&parser_obstack
, obstack_position
);
1903 while (c_parser_next_token_is_not (parser
, CPP_EOF
));
1908 FOR_EACH_VEC_ELT (incomplete_record_decls
, i
, decl
)
1909 if (DECL_SIZE (decl
) == NULL_TREE
&& TREE_TYPE (decl
) != error_mark_node
)
1910 error ("storage size of %q+D isn%'t known", decl
);
1912 if (vec_safe_length (current_omp_declare_target_attribute
))
1914 c_omp_declare_target_attr
1915 a
= current_omp_declare_target_attribute
->pop ();
1917 error ("%qs without corresponding %qs",
1918 a
.device_type
>= 0 ? "#pragma omp begin declare target"
1919 : "#pragma omp declare target",
1920 "#pragma omp end declare target");
1921 vec_safe_truncate (current_omp_declare_target_attribute
, 0);
1923 if (vec_safe_length (current_omp_begin_assumes
))
1926 error ("%qs without corresponding %qs",
1927 "#pragma omp begin assumes", "#pragma omp end assumes");
1928 vec_safe_truncate (current_omp_begin_assumes
, 0);
1934 ana::c_translation_unit tu
;
1935 ana::on_finish_translation_unit (tu
);
1940 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1942 external-declaration:
1948 external-declaration:
1951 __extension__ external-declaration
1955 external-declaration:
1956 objc-class-definition
1957 objc-class-declaration
1958 objc-alias-declaration
1959 objc-protocol-definition
1960 objc-method-definition
1965 c_parser_external_declaration (c_parser
*parser
)
1968 switch (c_parser_peek_token (parser
)->type
)
1971 switch (c_parser_peek_token (parser
)->keyword
)
1974 ext
= disable_extension_diagnostics ();
1975 c_parser_consume_token (parser
);
1976 c_parser_external_declaration (parser
);
1977 restore_extension_diagnostics (ext
);
1980 c_parser_asm_definition (parser
);
1982 case RID_AT_INTERFACE
:
1983 case RID_AT_IMPLEMENTATION
:
1984 gcc_assert (c_dialect_objc ());
1985 c_parser_objc_class_definition (parser
, NULL_TREE
);
1988 gcc_assert (c_dialect_objc ());
1989 c_parser_objc_class_declaration (parser
);
1992 gcc_assert (c_dialect_objc ());
1993 c_parser_objc_alias_declaration (parser
);
1995 case RID_AT_PROTOCOL
:
1996 gcc_assert (c_dialect_objc ());
1997 c_parser_objc_protocol_definition (parser
, NULL_TREE
);
1999 case RID_AT_PROPERTY
:
2000 gcc_assert (c_dialect_objc ());
2001 c_parser_objc_at_property_declaration (parser
);
2003 case RID_AT_SYNTHESIZE
:
2004 gcc_assert (c_dialect_objc ());
2005 c_parser_objc_at_synthesize_declaration (parser
);
2007 case RID_AT_DYNAMIC
:
2008 gcc_assert (c_dialect_objc ());
2009 c_parser_objc_at_dynamic_declaration (parser
);
2012 gcc_assert (c_dialect_objc ());
2013 c_parser_consume_token (parser
);
2014 objc_finish_implementation ();
2021 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
2022 "ISO C does not allow extra %<;%> outside of a function");
2023 c_parser_consume_token (parser
);
2026 mark_valid_location_for_stdc_pragma (true);
2027 c_parser_pragma (parser
, pragma_external
, NULL
);
2028 mark_valid_location_for_stdc_pragma (false);
2032 if (c_dialect_objc ())
2034 c_parser_objc_method_definition (parser
);
2037 /* Else fall through, and yield a syntax error trying to parse
2038 as a declaration or function definition. */
2042 /* A declaration or a function definition (or, in Objective-C,
2043 an @interface or @protocol with prefix attributes). We can
2044 only tell which after parsing the declaration specifiers, if
2045 any, and the first declarator. */
2046 c_parser_declaration_or_fndef (parser
, true, true, true, false, true);
2051 static void c_parser_handle_directive_omp_attributes (tree
&, vec
<c_token
> *&,
2053 static void c_finish_omp_declare_simd (c_parser
*, tree
, tree
, vec
<c_token
> *);
2054 static void c_finish_oacc_routine (struct oacc_routine_data
*, tree
, bool);
2056 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
2059 add_debug_begin_stmt (location_t loc
)
2061 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
2062 if (!MAY_HAVE_DEBUG_MARKER_STMTS
|| !building_stmt_list_p ())
2065 tree stmt
= build0 (DEBUG_BEGIN_STMT
, void_type_node
);
2066 SET_EXPR_LOCATION (stmt
, loc
);
2070 /* Helper function for c_parser_declaration_or_fndef and
2071 Handle assume attribute(s). */
2074 handle_assume_attribute (location_t here
, tree attrs
, bool nested
)
2077 for (tree attr
= lookup_attribute ("gnu", "assume", attrs
); attr
;
2078 attr
= lookup_attribute ("gnu", "assume", TREE_CHAIN (attr
)))
2080 tree args
= TREE_VALUE (attr
);
2081 int nargs
= list_length (args
);
2084 error_at (here
, "wrong number of arguments specified "
2085 "for %qE attribute",
2086 get_attribute_name (attr
));
2087 inform (here
, "expected %i, found %i", 1, nargs
);
2091 tree arg
= TREE_VALUE (args
);
2092 arg
= c_objc_common_truthvalue_conversion (here
, arg
);
2093 arg
= c_fully_fold (arg
, false, NULL
);
2094 if (arg
!= error_mark_node
)
2096 tree fn
= build_call_expr_internal_loc (here
, IFN_ASSUME
,
2104 pedwarn (here
, OPT_Wattributes
,
2105 "%<assume%> attribute at top level");
2107 return remove_attribute ("gnu", "assume", attrs
);
2110 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
2111 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
2112 is accepted; otherwise (old-style parameter declarations) only other
2113 declarations are accepted. If STATIC_ASSERT_OK is true, a static
2114 assertion is accepted; otherwise (old-style parameter declarations)
2115 it is not. If NESTED is true, we are inside a function or parsing
2116 old-style parameter declarations; any functions encountered are
2117 nested functions and declaration specifiers are required; otherwise
2118 we are at top level and functions are normal functions and
2119 declaration specifiers may be optional. If EMPTY_OK is true, empty
2120 declarations are OK (subject to all other constraints); otherwise
2121 (old-style parameter declarations) they are diagnosed. If
2122 START_ATTR_OK is true, the declaration specifiers may start with
2123 attributes (GNU or standard); otherwise they may not.
2124 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
2125 declaration when parsing an Objective-C foreach statement.
2126 FALLTHRU_ATTR_P is used to signal whether this function parsed
2127 "__attribute__((fallthrough));". ATTRS are any standard attributes
2128 parsed in the caller (in contexts where such attributes had to be
2129 parsed to determine whether what follows is a declaration or a
2130 statement); HAVE_ATTRS says whether there were any such attributes
2134 declaration-specifiers init-declarator-list[opt] ;
2135 static_assert-declaration
2137 function-definition:
2138 declaration-specifiers[opt] declarator declaration-list[opt]
2143 declaration-list declaration
2145 init-declarator-list:
2147 init-declarator-list , init-declarator
2150 declarator simple-asm-expr[opt] gnu-attributes[opt]
2151 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
2155 nested-function-definition:
2156 declaration-specifiers declarator declaration-list[opt]
2162 gnu-attributes objc-class-definition
2163 gnu-attributes objc-category-definition
2164 gnu-attributes objc-protocol-definition
2166 The simple-asm-expr and gnu-attributes are GNU extensions.
2168 This function does not handle __extension__; that is handled in its
2169 callers. ??? Following the old parser, __extension__ may start
2170 external declarations, declarations in functions and declarations
2171 at the start of "for" loops, but not old-style parameter
2174 C99 requires declaration specifiers in a function definition; the
2175 absence is diagnosed through the diagnosis of implicit int. In GNU
2176 C we also allow but diagnose declarations without declaration
2177 specifiers, but only at top level (elsewhere they conflict with
2180 In Objective-C, declarations of the looping variable in a foreach
2181 statement are exceptionally terminated by 'in' (for example, 'for
2182 (NSObject *object in array) { ... }').
2187 threadprivate-directive
2191 gimple-function-definition:
2192 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
2193 declaration-list[opt] compound-statement
2195 rtl-function-definition:
2196 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
2197 declaration-list[opt] compound-statement */
2200 c_parser_declaration_or_fndef (c_parser
*parser
, bool fndef_ok
,
2201 bool static_assert_ok
, bool empty_ok
,
2202 bool nested
, bool start_attr_ok
,
2203 tree
*objc_foreach_object_declaration
2205 vec
<c_token
> *omp_declare_simd_clauses
2207 bool have_attrs
/* = false */,
2208 tree attrs
/* = NULL_TREE */,
2209 struct oacc_routine_data
*oacc_routine_data
2211 bool *fallthru_attr_p
/* = NULL */)
2213 struct c_declspecs
*specs
;
2215 tree all_prefix_attrs
;
2216 bool diagnosed_no_specs
= false;
2217 location_t here
= c_parser_peek_token (parser
)->location
;
2219 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
2221 if (static_assert_ok
2222 && c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
2224 c_parser_static_assert_declaration (parser
);
2227 specs
= build_null_declspecs ();
2229 /* Handle any standard attributes parsed in the caller. */
2232 declspecs_add_attrs (here
, specs
, attrs
);
2233 specs
->non_std_attrs_seen_p
= false;
2236 /* Try to detect an unknown type name when we have "A B" or "A *B". */
2237 if (c_parser_peek_token (parser
)->type
== CPP_NAME
2238 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
2239 && (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
2240 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
2241 && (!nested
|| !lookup_name (c_parser_peek_token (parser
)->value
)))
2243 tree name
= c_parser_peek_token (parser
)->value
;
2245 /* Issue a warning about NAME being an unknown type name, perhaps
2246 with some kind of hint.
2247 If the user forgot a "struct" etc, suggest inserting
2248 it. Otherwise, attempt to look for misspellings. */
2249 gcc_rich_location
richloc (here
);
2250 if (tag_exists_p (RECORD_TYPE
, name
))
2252 /* This is not C++ with its implicit typedef. */
2253 richloc
.add_fixit_insert_before ("struct ");
2255 "unknown type name %qE;"
2256 " use %<struct%> keyword to refer to the type",
2259 else if (tag_exists_p (UNION_TYPE
, name
))
2261 richloc
.add_fixit_insert_before ("union ");
2263 "unknown type name %qE;"
2264 " use %<union%> keyword to refer to the type",
2267 else if (tag_exists_p (ENUMERAL_TYPE
, name
))
2269 richloc
.add_fixit_insert_before ("enum ");
2271 "unknown type name %qE;"
2272 " use %<enum%> keyword to refer to the type",
2277 auto_diagnostic_group d
;
2278 name_hint hint
= lookup_name_fuzzy (name
, FUZZY_LOOKUP_TYPENAME
,
2280 if (const char *suggestion
= hint
.suggestion ())
2282 richloc
.add_fixit_replace (suggestion
);
2284 "unknown type name %qE; did you mean %qs?",
2288 error_at (here
, "unknown type name %qE", name
);
2291 /* Parse declspecs normally to get a correct pointer type, but avoid
2292 a further "fails to be a type name" error. Refuse nested functions
2293 since it is not how the user likely wants us to recover. */
2294 c_parser_peek_token (parser
)->type
= CPP_KEYWORD
;
2295 c_parser_peek_token (parser
)->keyword
= RID_VOID
;
2296 c_parser_peek_token (parser
)->value
= error_mark_node
;
2300 /* When there are standard attributes at the start of the
2301 declaration (to apply to the entity being declared), an
2302 init-declarator-list or function definition must be present. */
2303 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
2306 c_parser_declspecs (parser
, specs
, true, true, start_attr_ok
,
2307 true, true, start_attr_ok
, true, cla_nonabstract_decl
);
2310 c_parser_skip_to_end_of_block_or_statement (parser
);
2313 if (nested
&& !specs
->declspecs_seen_p
)
2315 c_parser_error (parser
, "expected declaration specifiers");
2316 c_parser_skip_to_end_of_block_or_statement (parser
);
2320 finish_declspecs (specs
);
2321 bool gnu_auto_type_p
= specs
->typespec_word
== cts_auto_type
;
2322 bool std_auto_type_p
= specs
->c23_auto_p
;
2323 bool any_auto_type_p
= gnu_auto_type_p
|| std_auto_type_p
;
2324 gcc_assert (!(gnu_auto_type_p
&& std_auto_type_p
));
2325 const char *auto_type_keyword
= gnu_auto_type_p
? "__auto_type" : "auto";
2326 if (specs
->constexpr_p
)
2328 /* An underspecified declaration may not declare tags or members
2329 or structures or unions; it is undefined behavior to declare
2330 the members of an enumeration. Where the structure, union or
2331 enumeration type is declared within an initializer, this is
2332 diagnosed elsewhere. Diagnose here the case of declaring
2333 such a type in the type specifiers of a constexpr
2335 switch (specs
->typespec_kind
)
2337 case ctsk_tagfirstref
:
2338 case ctsk_tagfirstref_attrs
:
2339 error_at (here
, "%qT declared in underspecified object declaration",
2344 error_at (here
, "%qT defined in underspecified object declaration",
2352 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2354 bool handled_assume
= false;
2357 && specs
->typespec_kind
== ctsk_none
2358 && c_parser_handle_statement_omp_attributes (parser
, specs
->attrs
,
2362 c_warn_unused_attributes (specs
->attrs
);
2363 while (parser
->in_omp_attribute_pragma
)
2365 gcc_assert (c_parser_next_token_is (parser
, CPP_PRAGMA
));
2366 c_parser_pragma (parser
, pragma_external
, NULL
);
2368 c_parser_consume_token (parser
);
2371 if (specs
->typespec_kind
== ctsk_none
2372 && lookup_attribute ("gnu", "assume", specs
->attrs
))
2374 handled_assume
= true;
2376 = handle_assume_attribute (here
, specs
->attrs
, nested
);
2378 if (any_auto_type_p
)
2379 error_at (here
, "%qs in empty declaration", auto_type_keyword
);
2380 else if (specs
->typespec_kind
== ctsk_none
2381 && attribute_fallthrough_p (specs
->attrs
))
2383 if (fallthru_attr_p
!= NULL
)
2384 *fallthru_attr_p
= true;
2387 tree fn
= build_call_expr_internal_loc (here
, IFN_FALLTHROUGH
,
2392 pedwarn (here
, OPT_Wattributes
,
2393 "%<fallthrough%> attribute at top level");
2396 && !(have_attrs
&& specs
->non_std_attrs_seen_p
)
2401 shadow_tag_warned (specs
, 1);
2402 if (!handled_assume
)
2403 pedwarn (here
, 0, "empty declaration");
2405 /* We still have to evaluate size expressions. */
2407 add_stmt (fold_convert (void_type_node
, specs
->expr
));
2408 c_parser_consume_token (parser
);
2409 if (oacc_routine_data
)
2410 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2414 /* Provide better error recovery. Note that a type name here is usually
2415 better diagnosed as a redeclaration. */
2417 && specs
->typespec_kind
== ctsk_tagdef
2418 && c_parser_next_token_starts_declspecs (parser
)
2419 && !c_parser_next_token_is (parser
, CPP_NAME
))
2421 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
2422 parser
->error
= false;
2423 shadow_tag_warned (specs
, 1);
2426 else if (c_dialect_objc () && !any_auto_type_p
)
2428 /* Prefix attributes are an error on method decls. */
2429 switch (c_parser_peek_token (parser
)->type
)
2433 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2437 warning_at (c_parser_peek_token (parser
)->location
,
2439 "prefix attributes are ignored for methods");
2440 specs
->attrs
= NULL_TREE
;
2443 c_parser_objc_method_definition (parser
);
2445 c_parser_objc_methodproto (parser
);
2451 /* This is where we parse 'attributes @interface ...',
2452 'attributes @implementation ...', 'attributes @protocol ...'
2453 (where attributes could be, for example, __attribute__
2456 switch (c_parser_peek_token (parser
)->keyword
)
2458 case RID_AT_INTERFACE
:
2460 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2462 c_parser_objc_class_definition (parser
, specs
->attrs
);
2466 case RID_AT_IMPLEMENTATION
:
2468 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2472 warning_at (c_parser_peek_token (parser
)->location
,
2474 "prefix attributes are ignored for implementations");
2475 specs
->attrs
= NULL_TREE
;
2477 c_parser_objc_class_definition (parser
, NULL_TREE
);
2481 case RID_AT_PROTOCOL
:
2483 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2485 c_parser_objc_protocol_definition (parser
, specs
->attrs
);
2492 case RID_AT_PROPERTY
:
2495 c_parser_error (parser
, "unexpected attribute");
2496 specs
->attrs
= NULL
;
2503 else if (attribute_fallthrough_p (specs
->attrs
))
2504 warning_at (here
, OPT_Wattributes
,
2505 "%<fallthrough%> attribute not followed by %<;%>");
2506 else if (lookup_attribute ("gnu", "assume", specs
->attrs
))
2507 warning_at (here
, OPT_Wattributes
,
2508 "%<assume%> attribute not followed by %<;%>");
2510 auto_vec
<c_token
> omp_declare_simd_attr_clauses
;
2511 c_parser_handle_directive_omp_attributes (specs
->attrs
,
2512 omp_declare_simd_clauses
,
2513 &omp_declare_simd_attr_clauses
);
2514 pending_xref_error ();
2515 prefix_attrs
= specs
->attrs
;
2516 all_prefix_attrs
= prefix_attrs
;
2517 specs
->attrs
= NULL_TREE
;
2520 struct c_declarator
*declarator
;
2523 tree fnbody
= NULL_TREE
;
2524 tree underspec_name
= NULL_TREE
;
2525 auto_vec
<c_token
> omp_dsimd_idattr_clauses
;
2526 /* Declaring either one or more declarators (in which case we
2527 should diagnose if there were no declaration specifiers) or a
2528 function definition (in which case the diagnostic for
2529 implicit int suffices). */
2530 declarator
= c_parser_declarator (parser
,
2531 specs
->typespec_kind
!= ctsk_none
,
2532 C_DTR_NORMAL
, &dummy
);
2533 if (declarator
== NULL
)
2535 if (omp_declare_simd_clauses
)
2536 c_finish_omp_declare_simd (parser
, NULL_TREE
, NULL_TREE
,
2537 omp_declare_simd_clauses
);
2538 if (oacc_routine_data
)
2539 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2540 c_parser_skip_to_end_of_block_or_statement (parser
);
2543 if (flag_openmp
|| flag_openmp_simd
)
2545 struct c_declarator
*d
= declarator
;
2546 while (d
->kind
!= cdk_id
)
2548 vec
<c_token
> *dummy
= NULL
;
2549 c_parser_handle_directive_omp_attributes (d
->u
.id
.attrs
, dummy
,
2550 &omp_dsimd_idattr_clauses
);
2552 if (gnu_auto_type_p
&& declarator
->kind
!= cdk_id
)
2555 "%<__auto_type%> requires a plain identifier"
2557 c_parser_skip_to_end_of_block_or_statement (parser
);
2560 if (std_auto_type_p
)
2562 struct c_declarator
*d
= declarator
;
2563 while (d
->kind
== cdk_attrs
)
2565 if (d
->kind
!= cdk_id
)
2568 "%<auto%> requires a plain identifier, possibly with"
2569 " attributes, as declarator");
2570 c_parser_skip_to_end_of_block_or_statement (parser
);
2573 underspec_name
= d
->u
.id
.id
;
2575 else if (specs
->constexpr_p
)
2577 struct c_declarator
*d
= declarator
;
2578 while (d
->kind
!= cdk_id
)
2580 underspec_name
= d
->u
.id
.id
;
2582 if (c_parser_next_token_is (parser
, CPP_EQ
)
2583 || c_parser_next_token_is (parser
, CPP_COMMA
)
2584 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
2585 || c_parser_next_token_is_keyword (parser
, RID_ASM
)
2586 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
)
2587 || c_parser_next_token_is_keyword (parser
, RID_IN
))
2589 tree asm_name
= NULL_TREE
;
2590 tree postfix_attrs
= NULL_TREE
;
2591 if (!diagnosed_no_specs
&& !specs
->declspecs_seen_p
)
2593 diagnosed_no_specs
= true;
2594 pedwarn (here
, 0, "data definition has no type or storage class");
2596 /* Having seen a data definition, there cannot now be a
2597 function definition. */
2599 if (c_parser_next_token_is_keyword (parser
, RID_ASM
))
2600 asm_name
= c_parser_simple_asm_expr (parser
);
2601 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2603 postfix_attrs
= c_parser_gnu_attributes (parser
);
2604 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2606 /* This means there is an attribute specifier after
2607 the declarator in a function definition. Provide
2608 some more information for the user. */
2609 error_at (here
, "attributes should be specified before the "
2610 "declarator in a function definition");
2611 c_parser_skip_to_end_of_block_or_statement (parser
);
2615 if (c_parser_next_token_is (parser
, CPP_EQ
))
2619 location_t init_loc
;
2620 c_parser_consume_token (parser
);
2621 if (any_auto_type_p
)
2623 init_loc
= c_parser_peek_token (parser
)->location
;
2624 rich_location
richloc (line_table
, init_loc
);
2625 unsigned int underspec_state
= 0;
2626 if (std_auto_type_p
)
2628 start_underspecified_init (init_loc
, underspec_name
);
2629 start_init (NULL_TREE
, asm_name
,
2630 (global_bindings_p ()
2631 || specs
->storage_class
== csc_static
2632 || specs
->constexpr_p
),
2633 specs
->constexpr_p
, &richloc
);
2634 /* A parameter is initialized, which is invalid. Don't
2635 attempt to instrument the initializer. */
2636 int flag_sanitize_save
= flag_sanitize
;
2637 if (nested
&& !empty_ok
)
2639 init
= c_parser_expr_no_commas (parser
, NULL
);
2640 if (std_auto_type_p
)
2641 finish_underspecified_init (underspec_name
,
2643 flag_sanitize
= flag_sanitize_save
;
2645 && TREE_CODE (init
.value
) == COMPONENT_REF
2646 && DECL_C_BIT_FIELD (TREE_OPERAND (init
.value
, 1)))
2648 "%<__auto_type%> used with a bit-field"
2650 init
= convert_lvalue_to_rvalue (init_loc
, init
, true, true,
2652 tree init_type
= TREE_TYPE (init
.value
);
2653 bool vm_type
= c_type_variably_modified_p (init_type
);
2655 init
.value
= save_expr (init
.value
);
2657 specs
->typespec_kind
= ctsk_typeof
;
2658 specs
->locations
[cdw_typedef
] = init_loc
;
2659 specs
->typedef_p
= true;
2660 specs
->type
= init_type
;
2661 if (specs
->postfix_attrs
)
2663 /* Postfix [[]] attributes are valid with C23
2664 auto, although not with __auto_type, and
2665 modify the type given by the initializer. */
2666 specs
->postfix_attrs
=
2667 c_warn_type_attributes (specs
->postfix_attrs
);
2668 decl_attributes (&specs
->type
, specs
->postfix_attrs
, 0);
2669 specs
->postfix_attrs
= NULL_TREE
;
2673 bool maybe_const
= true;
2674 tree type_expr
= c_fully_fold (init
.value
, false,
2676 specs
->expr_const_operands
&= maybe_const
;
2678 specs
->expr
= build2 (COMPOUND_EXPR
,
2679 TREE_TYPE (type_expr
),
2680 specs
->expr
, type_expr
);
2682 specs
->expr
= type_expr
;
2684 d
= start_decl (declarator
, specs
, true,
2685 chainon (postfix_attrs
, all_prefix_attrs
));
2687 d
= error_mark_node
;
2688 if (omp_declare_simd_clauses
)
2689 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2690 omp_declare_simd_clauses
);
2691 if (!omp_dsimd_idattr_clauses
.is_empty ())
2692 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2693 &omp_dsimd_idattr_clauses
);
2697 /* The declaration of the variable is in effect while
2698 its initializer is parsed, except for a constexpr
2700 init_loc
= c_parser_peek_token (parser
)->location
;
2701 rich_location
richloc (line_table
, init_loc
);
2702 unsigned int underspec_state
= 0;
2703 if (specs
->constexpr_p
)
2705 start_underspecified_init (init_loc
, underspec_name
);
2706 d
= start_decl (declarator
, specs
, true,
2707 chainon (postfix_attrs
,
2709 !specs
->constexpr_p
);
2711 d
= error_mark_node
;
2712 if (!specs
->constexpr_p
&& omp_declare_simd_clauses
)
2713 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2714 omp_declare_simd_clauses
);
2715 if (!specs
->constexpr_p
2716 && !omp_dsimd_idattr_clauses
.is_empty ())
2717 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2718 &omp_dsimd_idattr_clauses
);
2719 start_init (d
, asm_name
,
2720 TREE_STATIC (d
) || specs
->constexpr_p
,
2721 specs
->constexpr_p
, &richloc
);
2722 /* A parameter is initialized, which is invalid. Don't
2723 attempt to instrument the initializer. */
2724 int flag_sanitize_save
= flag_sanitize
;
2725 if (TREE_CODE (d
) == PARM_DECL
)
2727 init
= c_parser_initializer (parser
, d
);
2728 flag_sanitize
= flag_sanitize_save
;
2729 if (specs
->constexpr_p
)
2731 finish_underspecified_init (underspec_name
,
2734 if (omp_declare_simd_clauses
)
2735 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2736 omp_declare_simd_clauses
);
2737 if (!specs
->constexpr_p
2738 && !omp_dsimd_idattr_clauses
.is_empty ())
2739 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2740 &omp_dsimd_idattr_clauses
);
2744 if (oacc_routine_data
)
2745 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2746 if (d
!= error_mark_node
)
2748 maybe_warn_string_init (init_loc
, TREE_TYPE (d
), init
);
2749 finish_decl (d
, init_loc
, init
.value
,
2750 init
.original_type
, asm_name
);
2755 if (any_auto_type_p
|| specs
->constexpr_p
)
2758 "%qs requires an initialized data declaration",
2759 any_auto_type_p
? auto_type_keyword
: "constexpr");
2760 c_parser_skip_to_end_of_block_or_statement (parser
);
2764 location_t lastloc
= UNKNOWN_LOCATION
;
2765 tree attrs
= chainon (postfix_attrs
, all_prefix_attrs
);
2766 tree d
= start_decl (declarator
, specs
, false, attrs
, true,
2768 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2770 /* Find the innermost declarator that is neither cdk_id
2772 const struct c_declarator
*decl
= declarator
;
2773 const struct c_declarator
*last_non_id_attrs
= NULL
;
2781 last_non_id_attrs
= decl
;
2782 decl
= decl
->declarator
;
2786 decl
= decl
->declarator
;
2797 /* If it exists and is cdk_function declaration whose
2798 arguments have not been set yet, use its arguments. */
2799 if (last_non_id_attrs
2800 && last_non_id_attrs
->kind
== cdk_function
)
2802 tree parms
= last_non_id_attrs
->u
.arg_info
->parms
;
2803 if (DECL_ARGUMENTS (d
) == NULL_TREE
2804 && DECL_INITIAL (d
) == NULL_TREE
)
2805 DECL_ARGUMENTS (d
) = parms
;
2807 warn_parm_array_mismatch (lastloc
, d
, parms
);
2810 if (omp_declare_simd_clauses
2811 || !omp_dsimd_idattr_clauses
.is_empty ())
2813 tree parms
= NULL_TREE
;
2814 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2816 struct c_declarator
*ce
= declarator
;
2818 if (ce
->kind
== cdk_function
)
2820 parms
= ce
->u
.arg_info
->parms
;
2824 ce
= ce
->declarator
;
2827 temp_store_parm_decls (d
, parms
);
2828 if (omp_declare_simd_clauses
)
2829 c_finish_omp_declare_simd (parser
, d
, parms
,
2830 omp_declare_simd_clauses
);
2831 if (!specs
->constexpr_p
2832 && !omp_dsimd_idattr_clauses
.is_empty ())
2833 c_finish_omp_declare_simd (parser
, d
, parms
,
2834 &omp_dsimd_idattr_clauses
);
2836 temp_pop_parm_decls ();
2838 if (oacc_routine_data
)
2839 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2841 finish_decl (d
, UNKNOWN_LOCATION
, NULL_TREE
,
2842 NULL_TREE
, asm_name
);
2844 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2847 *objc_foreach_object_declaration
= d
;
2849 *objc_foreach_object_declaration
= error_mark_node
;
2852 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2854 if (any_auto_type_p
|| specs
->constexpr_p
)
2857 "%qs may only be used with a single declarator",
2858 any_auto_type_p
? auto_type_keyword
: "constexpr");
2859 c_parser_skip_to_end_of_block_or_statement (parser
);
2862 c_parser_consume_token (parser
);
2863 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2864 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
2867 all_prefix_attrs
= prefix_attrs
;
2870 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2872 c_parser_consume_token (parser
);
2875 else if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2877 /* This can only happen in Objective-C: we found the
2878 'in' that terminates the declaration inside an
2879 Objective-C foreach statement. Do not consume the
2880 token, so that the caller can use it to determine
2881 that this indeed is a foreach context. */
2886 c_parser_error (parser
, "expected %<,%> or %<;%>");
2887 c_parser_skip_to_end_of_block_or_statement (parser
);
2891 else if (any_auto_type_p
|| specs
->constexpr_p
)
2894 "%qs requires an initialized data declaration",
2895 any_auto_type_p
? auto_type_keyword
: "constexpr");
2896 c_parser_skip_to_end_of_block_or_statement (parser
);
2901 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, "
2902 "%<asm%> or %<__attribute__%>");
2903 c_parser_skip_to_end_of_block_or_statement (parser
);
2906 /* Function definition (nested or otherwise). */
2909 pedwarn (here
, OPT_Wpedantic
, "ISO C forbids nested functions");
2910 c_push_function_context ();
2912 if (!start_function (specs
, declarator
, all_prefix_attrs
))
2914 /* At this point we've consumed:
2915 declaration-specifiers declarator
2916 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2917 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2919 declaration-specifiers declarator
2920 aren't grokkable as a function definition, so we have
2922 gcc_assert (!c_parser_next_token_is (parser
, CPP_SEMICOLON
));
2923 if (c_parser_next_token_starts_declspecs (parser
))
2926 declaration-specifiers declarator decl-specs
2927 then assume we have a missing semicolon, which would
2929 declaration-specifiers declarator decl-specs
2932 <~~~~~~~~~ declaration ~~~~~~~~~~>
2933 Use c_parser_require to get an error with a fix-it hint. */
2934 c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>");
2935 parser
->error
= false;
2939 /* This can appear in many cases looking nothing like a
2940 function definition, so we don't give a more specific
2941 error suggesting there was one. */
2942 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2943 "or %<__attribute__%>");
2946 c_pop_function_context ();
2950 if (DECL_DECLARED_INLINE_P (current_function_decl
))
2951 tv
= TV_PARSE_INLINE
;
2954 auto_timevar
at (g_timer
, tv
);
2956 /* Parse old-style parameter declarations. ??? Attributes are
2957 not allowed to start declaration specifiers here because of a
2958 syntax conflict between a function declaration with attribute
2959 suffix and a function definition with an attribute prefix on
2960 first old-style parameter declaration. Following the old
2961 parser, they are not accepted on subsequent old-style
2962 parameter declarations either. However, there is no
2963 ambiguity after the first declaration, nor indeed on the
2964 first as long as we don't allow postfix attributes after a
2965 declarator with a nonempty identifier list in a definition;
2966 and postfix attributes have never been accepted here in
2967 function definitions either. */
2968 int save_debug_nonbind_markers_p
= debug_nonbind_markers_p
;
2969 debug_nonbind_markers_p
= 0;
2970 while (c_parser_next_token_is_not (parser
, CPP_EOF
)
2971 && c_parser_next_token_is_not (parser
, CPP_OPEN_BRACE
))
2972 c_parser_declaration_or_fndef (parser
, false, false, false,
2974 debug_nonbind_markers_p
= save_debug_nonbind_markers_p
;
2975 store_parm_decls ();
2976 if (omp_declare_simd_clauses
)
2977 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2978 omp_declare_simd_clauses
);
2979 if (!omp_dsimd_idattr_clauses
.is_empty ())
2980 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2981 &omp_dsimd_idattr_clauses
);
2982 if (oacc_routine_data
)
2983 c_finish_oacc_routine (oacc_routine_data
, current_function_decl
, true);
2984 location_t startloc
= c_parser_peek_token (parser
)->location
;
2985 DECL_STRUCT_FUNCTION (current_function_decl
)->function_start_locus
2987 location_t endloc
= startloc
;
2989 /* If the definition was marked with __RTL, use the RTL parser now,
2990 consuming the function body. */
2991 if (specs
->declspec_il
== cdil_rtl
)
2993 endloc
= c_parser_parse_rtl_body (parser
, specs
->gimple_or_rtl_pass
);
2995 /* Normally, store_parm_decls sets next_is_function_body,
2996 anticipating a function body. We need a push_scope/pop_scope
2997 pair to flush out this state, or subsequent function parsing
3002 finish_function (endloc
);
3005 /* If the definition was marked with __GIMPLE then parse the
3006 function body as GIMPLE. */
3007 else if (specs
->declspec_il
!= cdil_none
)
3009 bool saved
= in_late_binary_op
;
3010 in_late_binary_op
= true;
3011 c_parser_parse_gimple_body (parser
, specs
->gimple_or_rtl_pass
,
3013 specs
->entry_bb_count
);
3014 in_late_binary_op
= saved
;
3017 fnbody
= c_parser_compound_statement (parser
, &endloc
);
3018 tree fndecl
= current_function_decl
;
3021 tree decl
= current_function_decl
;
3022 /* Mark nested functions as needing static-chain initially.
3023 lower_nested_functions will recompute it but the
3024 DECL_STATIC_CHAIN flag is also used before that happens,
3025 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
3026 DECL_STATIC_CHAIN (decl
) = 1;
3028 finish_function (endloc
);
3029 c_pop_function_context ();
3030 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl
), DECL_EXPR
, decl
));
3036 finish_function (endloc
);
3038 /* Get rid of the empty stmt list for GIMPLE/RTL. */
3039 if (specs
->declspec_il
!= cdil_none
)
3040 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
3046 /* Parse an asm-definition (asm() outside a function body). This is a
3054 c_parser_asm_definition (c_parser
*parser
)
3056 tree asm_str
= c_parser_simple_asm_expr (parser
);
3058 symtab
->finalize_toplevel_asm (asm_str
);
3059 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
3062 /* Parse a static assertion (C11 6.7.10).
3064 static_assert-declaration:
3065 static_assert-declaration-no-semi ;
3069 c_parser_static_assert_declaration (c_parser
*parser
)
3071 c_parser_static_assert_declaration_no_semi (parser
);
3073 || !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
3074 c_parser_skip_to_end_of_block_or_statement (parser
);
3077 /* Parse a static assertion (C11 6.7.10), without the trailing
3080 static_assert-declaration-no-semi:
3081 _Static_assert ( constant-expression , string-literal )
3084 static_assert-declaration-no-semi:
3085 _Static_assert ( constant-expression )
3089 c_parser_static_assert_declaration_no_semi (c_parser
*parser
)
3091 location_t assert_loc
, value_loc
;
3093 tree string
= NULL_TREE
;
3095 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
));
3096 tree spelling
= c_parser_peek_token (parser
)->value
;
3097 assert_loc
= c_parser_peek_token (parser
)->location
;
3099 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
3100 "ISO C99 does not support %qE", spelling
);
3102 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
3103 "ISO C90 does not support %qE", spelling
);
3104 c_parser_consume_token (parser
);
3105 matching_parens parens
;
3106 if (!parens
.require_open (parser
))
3108 location_t value_tok_loc
= c_parser_peek_token (parser
)->location
;
3109 value
= convert_lvalue_to_rvalue (value_tok_loc
,
3110 c_parser_expr_no_commas (parser
, NULL
),
3112 value_loc
= EXPR_LOC_OR_LOC (value
, value_tok_loc
);
3113 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3115 c_parser_consume_token (parser
);
3116 switch (c_parser_peek_token (parser
)->type
)
3122 case CPP_UTF8STRING
:
3123 string
= c_parser_string_literal (parser
, false, true).value
;
3126 c_parser_error (parser
, "expected string literal");
3130 else if (flag_isoc11
)
3131 /* If pedantic for pre-C11, the use of _Static_assert itself will
3132 have been diagnosed, so do not also diagnose the use of this
3133 new C23 feature of _Static_assert. */
3134 pedwarn_c11 (assert_loc
, OPT_Wpedantic
,
3135 "ISO C11 does not support omitting the string in "
3137 parens
.require_close (parser
);
3139 if (!INTEGRAL_TYPE_P (TREE_TYPE (value
)))
3141 error_at (value_loc
, "expression in static assertion is not an integer");
3144 if (TREE_CODE (value
) != INTEGER_CST
)
3146 value
= c_fully_fold (value
, false, NULL
);
3147 /* Strip no-op conversions. */
3148 STRIP_TYPE_NOPS (value
);
3149 if (TREE_CODE (value
) == INTEGER_CST
)
3150 pedwarn (value_loc
, OPT_Wpedantic
, "expression in static assertion "
3151 "is not an integer constant expression");
3153 if (TREE_CODE (value
) != INTEGER_CST
)
3155 error_at (value_loc
, "expression in static assertion is not constant");
3158 constant_expression_warning (value
);
3159 if (integer_zerop (value
))
3162 error_at (assert_loc
, "static assertion failed: %E", string
);
3164 error_at (assert_loc
, "static assertion failed");
3168 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
3169 6.7, C11 6.7), adding them to SPECS (which may already include some).
3170 Storage class specifiers are accepted iff SCSPEC_OK; type
3171 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
3172 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
3173 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
3174 addition to the syntax shown, standard attributes are accepted at
3175 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
3176 unlike gnu-attributes, they are not accepted in the middle of the
3177 list. (This combines various different syntax productions in the C
3178 standard, and in some cases gnu-attributes and standard attributes
3179 at the start may already have been parsed before this function is
3182 declaration-specifiers:
3183 storage-class-specifier declaration-specifiers[opt]
3184 type-specifier declaration-specifiers[opt]
3185 type-qualifier declaration-specifiers[opt]
3186 function-specifier declaration-specifiers[opt]
3187 alignment-specifier declaration-specifiers[opt]
3189 Function specifiers (inline) are from C99, and are currently
3190 handled as storage class specifiers, as is __thread. Alignment
3191 specifiers are from C11.
3193 C90 6.5.1, C99 6.7.1, C11 6.7.1:
3194 storage-class-specifier:
3202 (_Thread_local is new in C11.)
3204 C99 6.7.4, C11 6.7.4:
3209 (_Noreturn is new in C11.)
3211 C90 6.5.2, C99 6.7.2, C11 6.7.2:
3224 [_Imaginary removed in C99 TC2]
3225 _BitInt ( constant-expression )
3226 struct-or-union-specifier
3229 atomic-type-specifier
3231 (_Bool and _Complex are new in C99.)
3232 (atomic-type-specifier is new in C11.)
3233 (_BitInt is new in C23.)
3235 C90 6.5.3, C99 6.7.3, C11 6.7.3:
3241 address-space-qualifier
3244 (restrict is new in C99.)
3245 (_Atomic is new in C11.)
3249 declaration-specifiers:
3250 gnu-attributes declaration-specifiers[opt]
3256 identifier recognized by the target
3258 storage-class-specifier:
3272 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
3273 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
3275 atomic-type-specifier
3276 _Atomic ( type-name )
3281 class-name objc-protocol-refs[opt]
3282 typedef-name objc-protocol-refs
3287 c_parser_declspecs (c_parser
*parser
, struct c_declspecs
*specs
,
3288 bool scspec_ok
, bool typespec_ok
, bool start_attr_ok
,
3289 bool alignspec_ok
, bool auto_type_ok
,
3290 bool start_std_attr_ok
, bool end_std_attr_ok
,
3291 enum c_lookahead_kind la
)
3293 bool attrs_ok
= start_attr_ok
;
3294 bool seen_type
= specs
->typespec_kind
!= ctsk_none
;
3297 gcc_assert (la
== cla_prefer_id
);
3299 if (start_std_attr_ok
3300 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3302 gcc_assert (!specs
->non_std_attrs_seen_p
);
3303 location_t loc
= c_parser_peek_token (parser
)->location
;
3304 tree attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3305 declspecs_add_attrs (loc
, specs
, attrs
);
3306 specs
->non_std_attrs_seen_p
= false;
3309 while (c_parser_next_token_is (parser
, CPP_NAME
)
3310 || c_parser_next_token_is (parser
, CPP_KEYWORD
)
3311 || (c_dialect_objc () && c_parser_next_token_is (parser
, CPP_LESS
)))
3313 struct c_typespec t
;
3316 location_t loc
= c_parser_peek_token (parser
)->location
;
3318 /* If we cannot accept a type, exit if the next token must start
3319 one. Also, if we already have seen a tagged definition,
3320 a typename would be an error anyway and likely the user
3321 has simply forgotten a semicolon, so we exit. */
3322 if ((!typespec_ok
|| specs
->typespec_kind
== ctsk_tagdef
)
3323 && c_parser_next_tokens_start_typename (parser
, la
)
3324 && !c_parser_next_token_is_qualifier (parser
)
3325 && !c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
))
3328 if (c_parser_next_token_is (parser
, CPP_NAME
))
3330 c_token
*name_token
= c_parser_peek_token (parser
);
3331 tree value
= name_token
->value
;
3332 c_id_kind kind
= name_token
->id_kind
;
3334 if (kind
== C_ID_ADDRSPACE
)
3337 = name_token
->keyword
- RID_FIRST_ADDR_SPACE
;
3338 declspecs_add_addrspace (name_token
->location
, specs
, as
);
3339 c_parser_consume_token (parser
);
3344 gcc_assert (!c_parser_next_token_is_qualifier (parser
));
3346 /* If we cannot accept a type, and the next token must start one,
3347 exit. Do the same if we already have seen a tagged definition,
3348 since it would be an error anyway and likely the user has simply
3349 forgotten a semicolon. */
3350 if (seen_type
|| !c_parser_next_tokens_start_typename (parser
, la
))
3353 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
3354 a C_ID_CLASSNAME. */
3355 c_parser_consume_token (parser
);
3358 if (kind
== C_ID_ID
)
3360 auto_diagnostic_group d
;
3361 name_hint hint
= lookup_name_fuzzy (value
, FUZZY_LOOKUP_TYPENAME
,
3363 if (const char *suggestion
= hint
.suggestion ())
3365 gcc_rich_location
richloc (loc
);
3366 richloc
.add_fixit_replace (suggestion
);
3368 "unknown type name %qE; did you mean %qs?",
3372 error_at (loc
, "unknown type name %qE", value
);
3373 t
.kind
= ctsk_typedef
;
3374 t
.spec
= error_mark_node
;
3376 else if (kind
== C_ID_TYPENAME
3377 && (!c_dialect_objc ()
3378 || c_parser_next_token_is_not (parser
, CPP_LESS
)))
3380 t
.kind
= ctsk_typedef
;
3381 /* For a typedef name, record the meaning, not the name.
3382 In case of 'foo foo, bar;'. */
3383 t
.spec
= lookup_name (value
);
3387 tree proto
= NULL_TREE
;
3388 gcc_assert (c_dialect_objc ());
3390 if (c_parser_next_token_is (parser
, CPP_LESS
))
3391 proto
= c_parser_objc_protocol_refs (parser
);
3392 t
.spec
= objc_get_protocol_qualified_type (value
, proto
);
3395 t
.expr_const_operands
= true;
3396 t
.has_enum_type_specifier
= false;
3397 declspecs_add_type (name_token
->location
, specs
, t
);
3400 if (c_parser_next_token_is (parser
, CPP_LESS
))
3402 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
3403 nisse@lysator.liu.se. */
3405 gcc_assert (c_dialect_objc ());
3406 if (!typespec_ok
|| seen_type
)
3408 proto
= c_parser_objc_protocol_refs (parser
);
3410 t
.spec
= objc_get_protocol_qualified_type (NULL_TREE
, proto
);
3412 t
.expr_const_operands
= true;
3413 t
.has_enum_type_specifier
= false;
3414 declspecs_add_type (loc
, specs
, t
);
3417 gcc_assert (c_parser_next_token_is (parser
, CPP_KEYWORD
));
3418 switch (c_parser_peek_token (parser
)->keyword
)
3432 /* TODO: Distinguish between function specifiers (inline, noreturn)
3433 and storage class specifiers, either here or in
3434 declspecs_add_scspec. */
3435 declspecs_add_scspec (loc
, specs
,
3436 c_parser_peek_token (parser
)->value
);
3437 c_parser_consume_token (parser
);
3469 if (c_dialect_objc ())
3470 parser
->objc_need_raw_identifier
= true;
3471 t
.kind
= ctsk_resword
;
3472 t
.spec
= c_parser_peek_token (parser
)->value
;
3474 t
.expr_const_operands
= true;
3475 t
.has_enum_type_specifier
= false;
3476 declspecs_add_type (loc
, specs
, t
);
3477 c_parser_consume_token (parser
);
3484 t
= c_parser_enum_specifier (parser
);
3485 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
3486 declspecs_add_type (loc
, specs
, t
);
3494 t
= c_parser_struct_or_union_specifier (parser
);
3495 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
3496 declspecs_add_type (loc
, specs
, t
);
3499 case RID_TYPEOF_UNQUAL
:
3500 /* ??? The old parser rejected typeof after other type
3501 specifiers, but is a syntax error the best way of
3503 if (!typespec_ok
|| seen_type
)
3507 t
= c_parser_typeof_specifier (parser
);
3508 declspecs_add_type (loc
, specs
, t
);
3517 t
.kind
= ctsk_resword
;
3518 t
.spec
= c_parser_peek_token (parser
)->value
;
3519 t
.expr
= error_mark_node
;
3520 t
.expr_const_operands
= true;
3521 t
.has_enum_type_specifier
= false;
3522 c_parser_consume_token (parser
);
3523 matching_parens parens
;
3524 if (parens
.require_open (parser
))
3526 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
3527 t
.expr
= convert_lvalue_to_rvalue (loc
, expr
, true,
3529 parens
.skip_until_found_close (parser
);
3531 declspecs_add_type (loc
, specs
, t
);
3535 /* C parser handling of Objective-C constructs needs
3536 checking for correct lvalue-to-rvalue conversions, and
3537 the code in build_modify_expr handling various
3538 Objective-C cases, and that in build_unary_op handling
3539 Objective-C cases for increment / decrement, also needs
3540 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3541 and objc_types_are_equivalent may also need updates. */
3542 if (c_dialect_objc ())
3543 sorry ("%<_Atomic%> in Objective-C");
3545 pedwarn_c99 (loc
, OPT_Wpedantic
,
3546 "ISO C99 does not support the %<_Atomic%> qualifier");
3548 pedwarn_c99 (loc
, OPT_Wpedantic
,
3549 "ISO C90 does not support the %<_Atomic%> qualifier");
3552 value
= c_parser_peek_token (parser
)->value
;
3553 c_parser_consume_token (parser
);
3554 if (typespec_ok
&& c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3556 /* _Atomic ( type-name ). */
3558 c_parser_consume_token (parser
);
3559 struct c_type_name
*type
= c_parser_type_name (parser
);
3560 t
.kind
= ctsk_typeof
;
3561 t
.spec
= error_mark_node
;
3563 t
.expr_const_operands
= true;
3564 t
.has_enum_type_specifier
= false;
3566 t
.spec
= groktypename (type
, &t
.expr
,
3567 &t
.expr_const_operands
);
3568 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3570 if (t
.spec
!= error_mark_node
)
3572 if (TREE_CODE (t
.spec
) == ARRAY_TYPE
)
3573 error_at (loc
, "%<_Atomic%>-qualified array type");
3574 else if (TREE_CODE (t
.spec
) == FUNCTION_TYPE
)
3575 error_at (loc
, "%<_Atomic%>-qualified function type");
3576 else if (TYPE_QUALS (t
.spec
) != TYPE_UNQUALIFIED
)
3577 error_at (loc
, "%<_Atomic%> applied to a qualified type");
3579 t
.spec
= c_build_qualified_type (t
.spec
, TYPE_QUAL_ATOMIC
);
3581 declspecs_add_type (loc
, specs
, t
);
3584 declspecs_add_qual (loc
, specs
, value
);
3590 declspecs_add_qual (loc
, specs
, c_parser_peek_token (parser
)->value
);
3591 c_parser_consume_token (parser
);
3596 attrs
= c_parser_gnu_attributes (parser
);
3597 declspecs_add_attrs (loc
, specs
, attrs
);
3602 align
= c_parser_alignas_specifier (parser
);
3603 declspecs_add_alignas (loc
, specs
, align
);
3607 error_at (loc
, "%<__GIMPLE%> only valid with %<-fgimple%>");
3608 c_parser_consume_token (parser
);
3609 specs
->declspec_il
= cdil_gimple
;
3610 specs
->locations
[cdw_gimple
] = loc
;
3611 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3614 c_parser_consume_token (parser
);
3615 specs
->declspec_il
= cdil_rtl
;
3616 specs
->locations
[cdw_rtl
] = loc
;
3617 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3625 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3626 specs
->postfix_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3629 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3632 enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3633 { enumerator-list } gnu-attributes[opt]
3634 enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3635 { enumerator-list , } gnu-attributes[opt] enum-type-specifier[opt]
3636 enum gnu-attributes[opt] identifier
3638 The form with trailing comma is new in C99; enum-type-specifiers
3639 are new in C23. The forms with gnu-attributes are GNU extensions.
3640 In GNU C, we accept any expression without commas in the syntax
3641 (assignment expressions, not just conditional expressions);
3642 assignment expressions will be diagnosed as non-constant.
3644 enum-type-specifier:
3645 : specifier-qualifier-list
3649 enumerator-list , enumerator
3652 enumeration-constant attribute-specifier-sequence[opt]
3653 enumeration-constant attribute-specifier-sequence[opt]
3654 = constant-expression
3659 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3660 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3661 = constant-expression
3665 static struct c_typespec
3666 c_parser_enum_specifier (c_parser
*parser
)
3668 struct c_typespec ret
;
3669 bool have_std_attrs
;
3670 bool potential_nesting_p
= false;
3671 tree std_attrs
= NULL_TREE
;
3673 tree ident
= NULL_TREE
;
3674 tree fixed_underlying_type
= NULL_TREE
;
3675 location_t enum_loc
;
3676 location_t ident_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3677 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ENUM
));
3678 c_parser_consume_token (parser
);
3679 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3681 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3682 attrs
= c_parser_gnu_attributes (parser
);
3683 enum_loc
= c_parser_peek_token (parser
)->location
;
3684 /* Set the location in case we create a decl now. */
3685 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3686 if (c_parser_next_token_is (parser
, CPP_NAME
))
3688 ident
= c_parser_peek_token (parser
)->value
;
3689 ident_loc
= c_parser_peek_token (parser
)->location
;
3690 enum_loc
= ident_loc
;
3691 c_parser_consume_token (parser
);
3693 if (c_parser_next_token_is (parser
, CPP_COLON
)
3694 /* Distinguish an enum-type-specifier from a bit-field
3695 declaration of the form "enum e : constant-expression;". */
3696 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
3698 pedwarn_c11 (enum_loc
, OPT_Wpedantic
,
3699 "ISO C does not support specifying %<enum%> underlying "
3700 "types before C23");
3703 /* The tag is in scope during the enum-type-specifier (which
3704 may refer to the tag inside typeof). */
3705 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
,
3706 have_std_attrs
, std_attrs
, true);
3707 if (!ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
))
3708 error_at (enum_loc
, "%<enum%> declared both with and without "
3709 "fixed underlying type");
3710 potential_nesting_p
= NULL_TREE
== TYPE_VALUES (ret
.spec
);
3714 /* There must be an enum definition, so this initialization
3715 (to avoid possible warnings about uninitialized data)
3716 will be replaced later (either with the results of that
3717 definition, or with the results of error handling for the
3718 case of no tag and no definition). */
3719 ret
.spec
= NULL_TREE
;
3720 ret
.kind
= ctsk_tagdef
;
3721 ret
.expr
= NULL_TREE
;
3722 ret
.expr_const_operands
= true;
3723 ret
.has_enum_type_specifier
= true;
3725 c_parser_consume_token (parser
);
3726 struct c_declspecs
*specs
= build_null_declspecs ();
3727 c_parser_declspecs (parser
, specs
, false, true, false, false, false,
3728 false, true, cla_prefer_id
);
3729 finish_declspecs (specs
);
3730 if (specs
->default_int_p
)
3731 error_at (enum_loc
, "no %<enum%> underlying type specified");
3732 else if (TREE_CODE (specs
->type
) != INTEGER_TYPE
3733 && TREE_CODE (specs
->type
) != BOOLEAN_TYPE
)
3735 error_at (enum_loc
, "invalid %<enum%> underlying type");
3736 specs
->type
= integer_type_node
;
3738 else if (specs
->restrict_p
)
3739 error_at (enum_loc
, "invalid use of %<restrict%>");
3740 fixed_underlying_type
= TYPE_MAIN_VARIANT (specs
->type
);
3743 /* The type specified must be consistent with any previously
3744 specified underlying type. If this is a newly declared
3745 type, it is now a complete type. */
3746 if (ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
)
3747 && ENUM_UNDERLYING_TYPE (ret
.spec
) == NULL_TREE
)
3749 TYPE_MIN_VALUE (ret
.spec
) =
3750 TYPE_MIN_VALUE (fixed_underlying_type
);
3751 TYPE_MAX_VALUE (ret
.spec
) =
3752 TYPE_MAX_VALUE (fixed_underlying_type
);
3753 TYPE_UNSIGNED (ret
.spec
) = TYPE_UNSIGNED (fixed_underlying_type
);
3754 SET_TYPE_ALIGN (ret
.spec
, TYPE_ALIGN (fixed_underlying_type
));
3755 TYPE_SIZE (ret
.spec
) = NULL_TREE
;
3756 TYPE_PRECISION (ret
.spec
) =
3757 TYPE_PRECISION (fixed_underlying_type
);
3758 ENUM_UNDERLYING_TYPE (ret
.spec
) = fixed_underlying_type
;
3759 layout_type (ret
.spec
);
3761 else if (ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
)
3762 && !comptypes (fixed_underlying_type
,
3763 ENUM_UNDERLYING_TYPE (ret
.spec
)))
3765 error_at (enum_loc
, "%<enum%> underlying type incompatible with "
3766 "previous declaration");
3767 fixed_underlying_type
= ENUM_UNDERLYING_TYPE (ret
.spec
);
3771 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3773 /* Parse an enum definition. */
3774 struct c_enum_contents the_enum
;
3777 /* We chain the enumerators in reverse order, then put them in
3778 forward order at the end. */
3780 timevar_push (TV_PARSE_ENUM
);
3781 type
= start_enum (enum_loc
, &the_enum
, ident
, fixed_underlying_type
,
3782 potential_nesting_p
);
3784 c_parser_consume_token (parser
);
3792 location_t comma_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3793 location_t decl_loc
, value_loc
;
3794 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
3796 /* Give a nicer error for "enum {}". */
3797 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3800 error_at (c_parser_peek_token (parser
)->location
,
3801 "empty enum is invalid");
3802 parser
->error
= true;
3805 c_parser_error (parser
, "expected identifier");
3806 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3807 values
= error_mark_node
;
3810 token
= c_parser_peek_token (parser
);
3811 enum_id
= token
->value
;
3812 /* Set the location in case we create a decl now. */
3813 c_parser_set_source_position_from_token (token
);
3814 decl_loc
= value_loc
= token
->location
;
3815 c_parser_consume_token (parser
);
3816 /* Parse any specified attributes. */
3817 tree std_attrs
= NULL_TREE
;
3818 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3819 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3820 tree enum_attrs
= chainon (std_attrs
,
3821 c_parser_gnu_attributes (parser
));
3822 if (c_parser_next_token_is (parser
, CPP_EQ
))
3824 c_parser_consume_token (parser
);
3825 value_loc
= c_parser_peek_token (parser
)->location
;
3826 enum_value
= convert_lvalue_to_rvalue (value_loc
,
3827 (c_parser_expr_no_commas
3832 enum_value
= NULL_TREE
;
3833 enum_decl
= build_enumerator (decl_loc
, value_loc
,
3834 &the_enum
, enum_id
, enum_value
);
3836 decl_attributes (&TREE_PURPOSE (enum_decl
), enum_attrs
, 0);
3837 TREE_CHAIN (enum_decl
) = values
;
3840 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3842 comma_loc
= c_parser_peek_token (parser
)->location
;
3844 c_parser_consume_token (parser
);
3846 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3849 pedwarn_c90 (comma_loc
, OPT_Wpedantic
,
3850 "comma at end of enumerator list");
3851 c_parser_consume_token (parser
);
3856 c_parser_error (parser
, "expected %<,%> or %<}%>");
3857 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3858 values
= error_mark_node
;
3862 postfix_attrs
= c_parser_gnu_attributes (parser
);
3863 ret
.spec
= finish_enum (type
, nreverse (values
),
3865 chainon (attrs
, postfix_attrs
)));
3866 ret
.kind
= ctsk_tagdef
;
3867 ret
.expr
= NULL_TREE
;
3868 ret
.expr_const_operands
= true;
3869 ret
.has_enum_type_specifier
= fixed_underlying_type
!= NULL_TREE
;
3870 timevar_pop (TV_PARSE_ENUM
);
3875 c_parser_error (parser
, "expected %<{%>");
3876 ret
.spec
= error_mark_node
;
3877 ret
.kind
= ctsk_tagref
;
3878 ret
.expr
= NULL_TREE
;
3879 ret
.expr_const_operands
= true;
3880 ret
.has_enum_type_specifier
= false;
3883 /* Attributes may only appear when the members are defined or in
3884 certain forward declarations (treat enum forward declarations in
3885 GNU C analogously to struct and union forward declarations in
3887 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3888 c_parser_error (parser
, "expected %<;%>");
3889 if (fixed_underlying_type
== NULL_TREE
)
3891 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
, have_std_attrs
,
3893 /* In ISO C, enumerated types without a fixed underlying type
3894 can be referred to only if already defined. */
3895 if (pedantic
&& !COMPLETE_TYPE_P (ret
.spec
))
3898 pedwarn (enum_loc
, OPT_Wpedantic
,
3899 "ISO C forbids forward references to %<enum%> types");
3905 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3907 struct-or-union-specifier:
3908 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3909 identifier[opt] { struct-contents } gnu-attributes[opt]
3910 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3914 struct-declaration-list
3916 struct-declaration-list:
3917 struct-declaration ;
3918 struct-declaration-list struct-declaration ;
3925 struct-declaration-list struct-declaration
3927 struct-declaration-list:
3928 struct-declaration-list ;
3931 (Note that in the syntax here, unlike that in ISO C, the semicolons
3932 are included here rather than in struct-declaration, in order to
3933 describe the syntax with extra semicolons and missing semicolon at
3938 struct-declaration-list:
3939 @defs ( class-name )
3941 (Note this does not include a trailing semicolon, but can be
3942 followed by further declarations, and gets a pedwarn-if-pedantic
3943 when followed by a semicolon.) */
3945 static struct c_typespec
3946 c_parser_struct_or_union_specifier (c_parser
*parser
)
3948 struct c_typespec ret
;
3949 bool have_std_attrs
;
3950 tree std_attrs
= NULL_TREE
;
3952 tree ident
= NULL_TREE
;
3953 location_t struct_loc
;
3954 location_t ident_loc
= UNKNOWN_LOCATION
;
3955 enum tree_code code
;
3956 switch (c_parser_peek_token (parser
)->keyword
)
3967 struct_loc
= c_parser_peek_token (parser
)->location
;
3968 c_parser_consume_token (parser
);
3969 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3971 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3972 attrs
= c_parser_gnu_attributes (parser
);
3974 /* Set the location in case we create a decl now. */
3975 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3977 if (c_parser_next_token_is (parser
, CPP_NAME
))
3979 ident
= c_parser_peek_token (parser
)->value
;
3980 ident_loc
= c_parser_peek_token (parser
)->location
;
3981 struct_loc
= ident_loc
;
3982 c_parser_consume_token (parser
);
3984 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3986 /* Parse a struct or union definition. Start the scope of the
3987 tag before parsing components. */
3988 class c_struct_parse_info
*struct_info
;
3989 tree type
= start_struct (struct_loc
, code
, ident
, &struct_info
);
3991 /* We chain the components in reverse order, then put them in
3992 forward order at the end. Each struct-declaration may
3993 declare multiple components (comma-separated), so we must use
3994 chainon to join them, although when parsing each
3995 struct-declaration we can use TREE_CHAIN directly.
3997 The theory behind all this is that there will be more
3998 semicolon separated fields than comma separated fields, and
3999 so we'll be minimizing the number of node traversals required
4003 timevar_push (TV_PARSE_STRUCT
);
4004 contents
= NULL_TREE
;
4005 c_parser_consume_token (parser
);
4006 /* Handle the Objective-C @defs construct,
4007 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
4008 if (c_parser_next_token_is_keyword (parser
, RID_AT_DEFS
))
4011 gcc_assert (c_dialect_objc ());
4012 c_parser_consume_token (parser
);
4013 matching_parens parens
;
4014 if (!parens
.require_open (parser
))
4016 if (c_parser_next_token_is (parser
, CPP_NAME
)
4017 && c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
)
4019 name
= c_parser_peek_token (parser
)->value
;
4020 c_parser_consume_token (parser
);
4024 c_parser_error (parser
, "expected class name");
4025 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4028 parens
.skip_until_found_close (parser
);
4029 contents
= nreverse (objc_get_class_ivars (name
));
4032 /* Parse the struct-declarations and semicolons. Problems with
4033 semicolons are diagnosed here; empty structures are diagnosed
4038 /* Parse any stray semicolon. */
4039 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4041 location_t semicolon_loc
4042 = c_parser_peek_token (parser
)->location
;
4043 gcc_rich_location
richloc (semicolon_loc
);
4044 richloc
.add_fixit_remove ();
4045 pedwarn (&richloc
, OPT_Wpedantic
,
4046 "extra semicolon in struct or union specified");
4047 c_parser_consume_token (parser
);
4050 /* Stop if at the end of the struct or union contents. */
4051 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4053 c_parser_consume_token (parser
);
4056 /* Accept #pragmas at struct scope. */
4057 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
4059 c_parser_pragma (parser
, pragma_struct
, NULL
);
4062 /* Parse some comma-separated declarations, but not the
4063 trailing semicolon if any. */
4064 decls
= c_parser_struct_declaration (parser
, &expr
);
4065 contents
= chainon (decls
, contents
);
4066 /* If no semicolon follows, either we have a parse error or
4067 are at the end of the struct or union and should
4069 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4070 c_parser_consume_token (parser
);
4073 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4074 pedwarn (c_parser_peek_token (parser
)->location
, 0,
4075 "no semicolon at end of struct or union");
4076 else if (parser
->error
4077 || !c_parser_next_token_starts_declspecs (parser
))
4079 c_parser_error (parser
, "expected %<;%>");
4080 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
4084 /* If we come here, we have already emitted an error
4085 for an expected `;', identifier or `(', and we also
4086 recovered already. Go on with the next field. */
4089 postfix_attrs
= c_parser_gnu_attributes (parser
);
4090 ret
.spec
= finish_struct (struct_loc
, type
, nreverse (contents
),
4092 chainon (attrs
, postfix_attrs
)),
4093 struct_info
, &expr
);
4094 ret
.kind
= ctsk_tagdef
;
4096 ret
.expr_const_operands
= true;
4097 ret
.has_enum_type_specifier
= false;
4098 timevar_pop (TV_PARSE_STRUCT
);
4103 c_parser_error (parser
, "expected %<{%>");
4104 ret
.spec
= error_mark_node
;
4105 ret
.kind
= ctsk_tagref
;
4106 ret
.expr
= NULL_TREE
;
4107 ret
.expr_const_operands
= true;
4108 ret
.has_enum_type_specifier
= false;
4111 /* Attributes may only appear when the members are defined or in
4112 certain forward declarations. */
4113 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
4114 c_parser_error (parser
, "expected %<;%>");
4115 /* ??? Existing practice is that GNU attributes are ignored after
4116 the struct or union keyword when not defining the members. */
4117 ret
= parser_xref_tag (ident_loc
, code
, ident
, have_std_attrs
, std_attrs
,
4122 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
4123 *without* the trailing semicolon.
4126 attribute-specifier-sequence[opt] specifier-qualifier-list
4127 attribute-specifier-sequence[opt] struct-declarator-list
4128 static_assert-declaration-no-semi
4130 specifier-qualifier-list:
4131 type-specifier specifier-qualifier-list[opt]
4132 type-qualifier specifier-qualifier-list[opt]
4133 alignment-specifier specifier-qualifier-list[opt]
4134 gnu-attributes specifier-qualifier-list[opt]
4136 struct-declarator-list:
4138 struct-declarator-list , gnu-attributes[opt] struct-declarator
4141 declarator gnu-attributes[opt]
4142 declarator[opt] : constant-expression gnu-attributes[opt]
4147 __extension__ struct-declaration
4148 specifier-qualifier-list
4150 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
4151 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
4152 any expression without commas in the syntax (assignment
4153 expressions, not just conditional expressions); assignment
4154 expressions will be diagnosed as non-constant. */
4157 c_parser_struct_declaration (c_parser
*parser
, tree
*expr
)
4159 struct c_declspecs
*specs
;
4161 tree all_prefix_attrs
;
4163 location_t decl_loc
;
4164 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
4168 ext
= disable_extension_diagnostics ();
4169 c_parser_consume_token (parser
);
4170 decl
= c_parser_struct_declaration (parser
, expr
);
4171 restore_extension_diagnostics (ext
);
4174 if (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
4176 c_parser_static_assert_declaration_no_semi (parser
);
4179 specs
= build_null_declspecs ();
4180 decl_loc
= c_parser_peek_token (parser
)->location
;
4181 /* Strictly by the standard, we shouldn't allow _Alignas here,
4182 but it appears to have been intended to allow it there, so
4183 we're keeping it as it is until WG14 reaches a conclusion
4185 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
4186 c_parser_declspecs (parser
, specs
, false, true, true,
4187 true, false, true, true, cla_nonabstract_decl
);
4190 if (!specs
->declspecs_seen_p
)
4192 c_parser_error (parser
, "expected specifier-qualifier-list");
4195 finish_declspecs (specs
);
4196 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
4197 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4200 if (specs
->typespec_kind
== ctsk_none
)
4202 pedwarn (decl_loc
, OPT_Wpedantic
,
4203 "ISO C forbids member declarations with no members");
4204 shadow_tag_warned (specs
, pedantic
);
4209 /* Support for unnamed structs or unions as members of
4210 structs or unions (which is [a] useful and [b] supports
4214 ret
= grokfield (c_parser_peek_token (parser
)->location
,
4215 build_id_declarator (NULL_TREE
), specs
,
4216 NULL_TREE
, &attrs
, expr
);
4218 decl_attributes (&ret
, attrs
, 0);
4223 /* Provide better error recovery. Note that a type name here is valid,
4224 and will be treated as a field name. */
4225 if (specs
->typespec_kind
== ctsk_tagdef
4226 && TREE_CODE (specs
->type
) != ENUMERAL_TYPE
4227 && c_parser_next_token_starts_declspecs (parser
)
4228 && !c_parser_next_token_is (parser
, CPP_NAME
))
4230 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
4231 parser
->error
= false;
4235 pending_xref_error ();
4236 prefix_attrs
= specs
->attrs
;
4237 all_prefix_attrs
= prefix_attrs
;
4238 specs
->attrs
= NULL_TREE
;
4242 /* Declaring one or more declarators or un-named bit-fields. */
4243 struct c_declarator
*declarator
;
4245 if (c_parser_next_token_is (parser
, CPP_COLON
))
4246 declarator
= build_id_declarator (NULL_TREE
);
4248 declarator
= c_parser_declarator (parser
,
4249 specs
->typespec_kind
!= ctsk_none
,
4250 C_DTR_NORMAL
, &dummy
);
4251 if (declarator
== NULL
)
4253 c_parser_skip_to_end_of_block_or_statement (parser
);
4256 if (c_parser_next_token_is (parser
, CPP_COLON
)
4257 || c_parser_next_token_is (parser
, CPP_COMMA
)
4258 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
4259 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
4260 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4262 tree postfix_attrs
= NULL_TREE
;
4263 tree width
= NULL_TREE
;
4265 if (c_parser_next_token_is (parser
, CPP_COLON
))
4267 c_parser_consume_token (parser
);
4268 location_t loc
= c_parser_peek_token (parser
)->location
;
4269 width
= convert_lvalue_to_rvalue (loc
,
4270 (c_parser_expr_no_commas
4274 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4275 postfix_attrs
= c_parser_gnu_attributes (parser
);
4276 d
= grokfield (c_parser_peek_token (parser
)->location
,
4277 declarator
, specs
, width
, &all_prefix_attrs
, expr
);
4278 decl_attributes (&d
, chainon (postfix_attrs
,
4279 all_prefix_attrs
), 0);
4280 DECL_CHAIN (d
) = decls
;
4282 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4283 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
4286 all_prefix_attrs
= prefix_attrs
;
4287 if (c_parser_next_token_is (parser
, CPP_COMMA
))
4288 c_parser_consume_token (parser
);
4289 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
4290 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4292 /* Semicolon consumed in caller. */
4297 c_parser_error (parser
, "expected %<,%>, %<;%> or %<}%>");
4303 c_parser_error (parser
,
4304 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
4305 "%<__attribute__%>");
4312 /* Parse a typeof specifier (a GNU extension adopted in C23).
4315 typeof ( expression )
4316 typeof ( type-name )
4317 typeof_unqual ( expression )
4318 typeof_unqual ( type-name )
4321 static struct c_typespec
4322 c_parser_typeof_specifier (c_parser
*parser
)
4326 struct c_typespec ret
;
4327 ret
.kind
= ctsk_typeof
;
4328 ret
.spec
= error_mark_node
;
4329 ret
.expr
= NULL_TREE
;
4330 ret
.expr_const_operands
= true;
4331 ret
.has_enum_type_specifier
= false;
4332 if (c_parser_next_token_is_keyword (parser
, RID_TYPEOF
))
4335 tree spelling
= c_parser_peek_token (parser
)->value
;
4336 is_std
= (flag_isoc23
4337 && strcmp (IDENTIFIER_POINTER (spelling
), "typeof") == 0);
4341 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TYPEOF_UNQUAL
));
4343 tree spelling
= c_parser_peek_token (parser
)->value
;
4344 is_std
= strcmp (IDENTIFIER_POINTER (spelling
), "typeof_unqual") == 0;
4346 c_parser_consume_token (parser
);
4347 c_inhibit_evaluation_warnings
++;
4349 matching_parens parens
;
4350 if (!parens
.require_open (parser
))
4352 c_inhibit_evaluation_warnings
--;
4356 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
4358 struct c_type_name
*type
= c_parser_type_name (parser
);
4359 c_inhibit_evaluation_warnings
--;
4363 ret
.spec
= groktypename (type
, &ret
.expr
, &ret
.expr_const_operands
);
4364 pop_maybe_used (c_type_variably_modified_p (ret
.spec
));
4370 location_t here
= c_parser_peek_token (parser
)->location
;
4371 struct c_expr expr
= c_parser_expression (parser
);
4372 c_inhibit_evaluation_warnings
--;
4374 if (TREE_CODE (expr
.value
) == COMPONENT_REF
4375 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
4376 error_at (here
, "%<typeof%> applied to a bit-field");
4377 mark_exp_read (expr
.value
);
4378 ret
.spec
= TREE_TYPE (expr
.value
);
4379 was_vm
= c_type_variably_modified_p (ret
.spec
);
4380 /* This is returned with the type so that when the type is
4381 evaluated, this can be evaluated. */
4383 ret
.expr
= c_fully_fold (expr
.value
, false, &ret
.expr_const_operands
);
4384 pop_maybe_used (was_vm
);
4386 parens
.skip_until_found_close (parser
);
4387 if (ret
.spec
!= error_mark_node
)
4389 if (is_unqual
&& TYPE_QUALS (ret
.spec
) != TYPE_UNQUALIFIED
)
4390 ret
.spec
= TYPE_MAIN_VARIANT (ret
.spec
);
4393 /* In ISO C terms, _Noreturn is not part of the type of
4394 expressions such as &abort, but in GCC it is represented
4395 internally as a type qualifier. */
4396 if (TREE_CODE (ret
.spec
) == FUNCTION_TYPE
4397 && TYPE_QUALS (ret
.spec
) != TYPE_UNQUALIFIED
)
4398 ret
.spec
= TYPE_MAIN_VARIANT (ret
.spec
);
4399 else if (FUNCTION_POINTER_TYPE_P (ret
.spec
)
4400 && TYPE_QUALS (TREE_TYPE (ret
.spec
)) != TYPE_UNQUALIFIED
)
4402 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (ret
.spec
)));
4408 /* Parse an alignment-specifier.
4412 alignment-specifier:
4413 _Alignas ( type-name )
4414 _Alignas ( constant-expression )
4418 c_parser_alignas_specifier (c_parser
* parser
)
4420 tree ret
= error_mark_node
;
4421 location_t loc
= c_parser_peek_token (parser
)->location
;
4422 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
));
4423 tree spelling
= c_parser_peek_token (parser
)->value
;
4424 c_parser_consume_token (parser
);
4426 pedwarn_c99 (loc
, OPT_Wpedantic
,
4427 "ISO C99 does not support %qE", spelling
);
4429 pedwarn_c99 (loc
, OPT_Wpedantic
,
4430 "ISO C90 does not support %qE", spelling
);
4431 matching_parens parens
;
4432 if (!parens
.require_open (parser
))
4434 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
4436 struct c_type_name
*type
= c_parser_type_name (parser
);
4438 ret
= c_sizeof_or_alignof_type (loc
, groktypename (type
, NULL
, NULL
),
4442 ret
= convert_lvalue_to_rvalue (loc
,
4443 c_parser_expr_no_commas (parser
, NULL
),
4445 parens
.skip_until_found_close (parser
);
4449 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
4450 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
4451 a typedef name may be redeclared; otherwise it may not. KIND
4452 indicates which kind of declarator is wanted. Returns a valid
4453 declarator except in the case of a syntax error in which case NULL is
4454 returned. *SEEN_ID is set to true if an identifier being declared is
4455 seen; this is used to diagnose bad forms of abstract array declarators
4456 and to determine whether an identifier list is syntactically permitted.
4459 pointer[opt] direct-declarator
4463 ( gnu-attributes[opt] declarator )
4464 direct-declarator array-declarator
4465 direct-declarator ( parameter-type-list )
4466 direct-declarator ( identifier-list[opt] )
4469 * type-qualifier-list[opt]
4470 * type-qualifier-list[opt] pointer
4472 type-qualifier-list:
4475 type-qualifier-list type-qualifier
4476 type-qualifier-list gnu-attributes
4479 [ type-qualifier-list[opt] assignment-expression[opt] ]
4480 [ static type-qualifier-list[opt] assignment-expression ]
4481 [ type-qualifier-list static assignment-expression ]
4482 [ type-qualifier-list[opt] * ]
4484 parameter-type-list:
4486 parameter-list , ...
4489 parameter-declaration
4490 parameter-list , parameter-declaration
4492 parameter-declaration:
4493 declaration-specifiers declarator gnu-attributes[opt]
4494 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
4498 identifier-list , identifier
4500 abstract-declarator:
4502 pointer[opt] direct-abstract-declarator
4504 direct-abstract-declarator:
4505 ( gnu-attributes[opt] abstract-declarator )
4506 direct-abstract-declarator[opt] array-declarator
4507 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
4512 direct-declarator ( parameter-forward-declarations
4513 parameter-type-list[opt] )
4515 direct-abstract-declarator:
4516 direct-abstract-declarator[opt] ( parameter-forward-declarations
4517 parameter-type-list[opt] )
4519 parameter-forward-declarations:
4521 parameter-forward-declarations parameter-list ;
4523 The uses of gnu-attributes shown above are GNU extensions.
4525 Some forms of array declarator are not included in C99 in the
4526 syntax for abstract declarators; these are disallowed elsewhere.
4527 This may be a defect (DR#289).
4529 This function also accepts an omitted abstract declarator as being
4530 an abstract declarator, although not part of the formal syntax. */
4532 struct c_declarator
*
4533 c_parser_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
4536 /* Parse any initial pointer part. */
4537 if (c_parser_next_token_is (parser
, CPP_MULT
))
4539 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4540 struct c_declarator
*inner
;
4541 c_parser_consume_token (parser
);
4542 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4543 false, false, true, false, cla_prefer_id
);
4544 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4548 return make_pointer_declarator (quals_attrs
, inner
);
4550 /* Now we have a direct declarator, direct abstract declarator or
4551 nothing (which counts as a direct abstract declarator here). */
4552 return c_parser_direct_declarator (parser
, type_seen_p
, kind
, seen_id
);
4555 /* Parse a direct declarator or direct abstract declarator; arguments
4556 as c_parser_declarator. */
4558 static struct c_declarator
*
4559 c_parser_direct_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
4562 /* The direct declarator must start with an identifier (possibly
4563 omitted) or a parenthesized declarator (possibly abstract). In
4564 an ordinary declarator, initial parentheses must start a
4565 parenthesized declarator. In an abstract declarator or parameter
4566 declarator, they could start a parenthesized declarator or a
4567 parameter list. To tell which, the open parenthesis and any
4568 following gnu-attributes must be read. If a declaration
4569 specifier or standard attributes follow, then it is a parameter
4570 list; if the specifier is a typedef name, there might be an
4571 ambiguity about redeclaring it, which is resolved in the
4572 direction of treating it as a typedef name. If a close
4573 parenthesis follows, it is also an empty parameter list, as the
4574 syntax does not permit empty abstract declarators. Otherwise, it
4575 is a parenthesized declarator (in which case the analysis may be
4576 repeated inside it, recursively).
4578 ??? There is an ambiguity in a parameter declaration "int
4579 (__attribute__((foo)) x)", where x is not a typedef name: it
4580 could be an abstract declarator for a function, or declare x with
4581 parentheses. The proper resolution of this ambiguity needs
4582 documenting. At present we follow an accident of the old
4583 parser's implementation, whereby the first parameter must have
4584 some declaration specifiers other than just gnu-attributes. Thus as
4585 a parameter declaration it is treated as a parenthesized
4586 parameter named x, and as an abstract declarator it is
4589 ??? Also following the old parser, gnu-attributes inside an empty
4590 parameter list are ignored, making it a list not yielding a
4591 prototype, rather than giving an error or making it have one
4592 parameter with implicit type int.
4594 ??? Also following the old parser, typedef names may be
4595 redeclared in declarators, but not Objective-C class names. */
4597 if (kind
!= C_DTR_ABSTRACT
4598 && c_parser_next_token_is (parser
, CPP_NAME
)
4600 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
4601 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
4602 || c_parser_peek_token (parser
)->id_kind
== C_ID_ID
))
4604 struct c_declarator
*inner
4605 = build_id_declarator (c_parser_peek_token (parser
)->value
);
4607 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
4608 c_parser_consume_token (parser
);
4609 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4610 inner
->u
.id
.attrs
= c_parser_std_attribute_specifier_sequence (parser
);
4611 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4614 if (kind
!= C_DTR_NORMAL
4615 && c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4616 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4618 struct c_declarator
*inner
= build_id_declarator (NULL_TREE
);
4619 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
4620 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4623 /* Either we are at the end of an abstract declarator, or we have
4626 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4629 struct c_declarator
*inner
;
4630 c_parser_consume_token (parser
);
4631 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4633 attrs
= c_parser_gnu_attributes (parser
);
4634 if (kind
!= C_DTR_NORMAL
4635 && (c_parser_next_token_starts_declspecs (parser
)
4637 && (c_parser_nth_token_starts_std_attributes (parser
, 1)
4638 || c_parser_next_token_is (parser
, CPP_ELLIPSIS
)))
4639 || c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
)))
4641 struct c_arg_info
*args
4642 = c_parser_parms_declarator (parser
, kind
== C_DTR_NORMAL
,
4643 attrs
, have_gnu_attrs
);
4648 inner
= build_id_declarator (NULL_TREE
);
4650 && args
->types
!= error_mark_node
4651 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4652 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4655 = c_parser_std_attribute_specifier_sequence (parser
);
4657 inner
= build_attrs_declarator (std_attrs
, inner
);
4659 inner
= build_function_declarator (args
, inner
);
4660 return c_parser_direct_declarator_inner (parser
, *seen_id
,
4664 /* A parenthesized declarator. */
4665 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4666 if (inner
!= NULL
&& attrs
!= NULL
)
4667 inner
= build_attrs_declarator (attrs
, inner
);
4668 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4670 c_parser_consume_token (parser
);
4674 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4678 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4685 if (kind
== C_DTR_NORMAL
)
4687 c_parser_error (parser
, "expected identifier or %<(%>");
4691 return build_id_declarator (NULL_TREE
);
4695 /* Parse part of a direct declarator or direct abstract declarator,
4696 given that some (in INNER) has already been parsed; ID_PRESENT is
4697 true if an identifier is present, false for an abstract
4700 static struct c_declarator
*
4701 c_parser_direct_declarator_inner (c_parser
*parser
, bool id_present
,
4702 struct c_declarator
*inner
)
4704 /* Parse a sequence of array declarators and parameter lists. */
4705 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4706 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4708 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
4709 struct c_declarator
*declarator
;
4710 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4713 struct c_expr dimen
;
4714 dimen
.value
= NULL_TREE
;
4715 dimen
.original_code
= ERROR_MARK
;
4716 dimen
.original_type
= NULL_TREE
;
4717 c_parser_consume_token (parser
);
4718 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4719 false, false, false, false, cla_prefer_id
);
4720 static_seen
= c_parser_next_token_is_keyword (parser
, RID_STATIC
);
4722 c_parser_consume_token (parser
);
4723 if (static_seen
&& !quals_attrs
->declspecs_seen_p
)
4724 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4725 false, false, false, false, cla_prefer_id
);
4726 if (!quals_attrs
->declspecs_seen_p
)
4728 /* If "static" is present, there must be an array dimension.
4729 Otherwise, there may be a dimension, "*", or no
4734 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4738 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4740 dimen
.value
= NULL_TREE
;
4743 else if (c_parser_next_token_is (parser
, CPP_MULT
))
4745 if (c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_SQUARE
)
4747 dimen
.value
= NULL_TREE
;
4749 c_parser_consume_token (parser
);
4754 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4760 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4763 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4764 c_parser_consume_token (parser
);
4767 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4772 dimen
= convert_lvalue_to_rvalue (brace_loc
, dimen
, true, true);
4773 declarator
= build_array_declarator (brace_loc
, dimen
.value
, quals_attrs
,
4774 static_seen
, star_seen
);
4775 if (declarator
== NULL
)
4777 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4780 = c_parser_std_attribute_specifier_sequence (parser
);
4782 inner
= build_attrs_declarator (std_attrs
, inner
);
4784 inner
= set_array_declarator_inner (declarator
, inner
);
4785 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4787 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4790 struct c_arg_info
*args
;
4791 c_parser_consume_token (parser
);
4792 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4794 attrs
= c_parser_gnu_attributes (parser
);
4795 args
= c_parser_parms_declarator (parser
, id_present
, attrs
,
4802 && args
->types
!= error_mark_node
4803 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4804 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4807 = c_parser_std_attribute_specifier_sequence (parser
);
4809 inner
= build_attrs_declarator (std_attrs
, inner
);
4811 inner
= build_function_declarator (args
, inner
);
4812 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4818 /* Parse a parameter list or identifier list, including the closing
4819 parenthesis but not the opening one. ATTRS are the gnu-attributes
4820 at the start of the list. ID_LIST_OK is true if an identifier list
4821 is acceptable; such a list must not have attributes at the start.
4822 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4823 attributes) were present (in which case standard attributes cannot
4826 static struct c_arg_info
*
4827 c_parser_parms_declarator (c_parser
*parser
, bool id_list_ok
, tree attrs
,
4828 bool have_gnu_attrs
)
4831 declare_parm_level ();
4832 /* If the list starts with an identifier, it is an identifier list.
4833 Otherwise, it is either a prototype list or an empty list. */
4836 && c_parser_next_token_is (parser
, CPP_NAME
)
4837 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4839 /* Look ahead to detect typos in type names. */
4840 && c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
4841 && c_parser_peek_2nd_token (parser
)->type
!= CPP_MULT
4842 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
4843 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_SQUARE
4844 && c_parser_peek_2nd_token (parser
)->type
!= CPP_KEYWORD
)
4846 tree list
= NULL_TREE
, *nextp
= &list
;
4847 while (c_parser_next_token_is (parser
, CPP_NAME
)
4848 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
4850 *nextp
= build_tree_list (NULL_TREE
,
4851 c_parser_peek_token (parser
)->value
);
4852 nextp
= & TREE_CHAIN (*nextp
);
4853 c_parser_consume_token (parser
);
4854 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
4856 c_parser_consume_token (parser
);
4857 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4859 c_parser_error (parser
, "expected identifier");
4863 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4865 struct c_arg_info
*ret
= build_arg_info ();
4867 c_parser_consume_token (parser
);
4873 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4881 struct c_arg_info
*ret
4882 = c_parser_parms_list_declarator (parser
, attrs
, NULL
, have_gnu_attrs
);
4888 /* Parse a parameter list (possibly empty), including the closing
4889 parenthesis but not the opening one. ATTRS are the gnu-attributes
4890 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4891 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4892 which means standard attributes cannot start the list. EXPR is
4893 NULL or an expression that needs to be evaluated for the side
4894 effects of array size expressions in the parameters. */
4896 static struct c_arg_info
*
4897 c_parser_parms_list_declarator (c_parser
*parser
, tree attrs
, tree expr
,
4898 bool have_gnu_attrs
)
4900 bool bad_parm
= false;
4902 /* ??? Following the old parser, forward parameter declarations may
4903 use abstract declarators, and if no real parameter declarations
4904 follow the forward declarations then this is not diagnosed. Also
4905 note as above that gnu-attributes are ignored as the only contents of
4906 the parentheses, or as the only contents after forward
4908 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4910 struct c_arg_info
*ret
= build_arg_info ();
4911 c_parser_consume_token (parser
);
4914 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
) && !have_gnu_attrs
)
4916 struct c_arg_info
*ret
= build_arg_info ();
4918 ret
->types
= NULL_TREE
;
4919 pedwarn_c11 (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
4920 "ISO C requires a named argument before %<...%> "
4922 c_parser_consume_token (parser
);
4923 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4925 ret
->no_named_args_stdarg_p
= true;
4926 c_parser_consume_token (parser
);
4931 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4936 /* Nonempty list of parameters, either terminated with semicolon
4937 (forward declarations; recurse) or with close parenthesis (normal
4938 function) or with ", ... )" (variadic function). */
4941 /* Parse a parameter. */
4942 struct c_parm
*parm
= c_parser_parameter_declaration (parser
, attrs
,
4945 have_gnu_attrs
= false;
4949 push_parm_decl (parm
, &expr
);
4950 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4953 c_parser_consume_token (parser
);
4954 mark_forward_parm_decls ();
4955 bool new_have_gnu_attrs
4956 = c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
);
4957 new_attrs
= c_parser_gnu_attributes (parser
);
4958 return c_parser_parms_list_declarator (parser
, new_attrs
, expr
,
4959 new_have_gnu_attrs
);
4961 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4963 c_parser_consume_token (parser
);
4967 return get_parm_info (false, expr
);
4969 if (!c_parser_require (parser
, CPP_COMMA
,
4970 "expected %<;%>, %<,%> or %<)%>",
4971 UNKNOWN_LOCATION
, false))
4973 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4976 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4978 c_parser_consume_token (parser
);
4979 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4981 c_parser_consume_token (parser
);
4985 return get_parm_info (true, expr
);
4989 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4997 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4998 start of the declaration if it is the first parameter;
4999 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
5002 static struct c_parm
*
5003 c_parser_parameter_declaration (c_parser
*parser
, tree attrs
,
5004 bool have_gnu_attrs
)
5006 struct c_declspecs
*specs
;
5007 struct c_declarator
*declarator
;
5009 tree postfix_attrs
= NULL_TREE
;
5012 /* Accept #pragmas between parameter declarations. */
5013 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
5014 c_parser_pragma (parser
, pragma_param
, NULL
);
5016 if (!c_parser_next_token_starts_declspecs (parser
)
5017 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
5019 c_token
*token
= c_parser_peek_token (parser
);
5022 c_parser_set_source_position_from_token (token
);
5023 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
5025 auto_diagnostic_group d
;
5026 name_hint hint
= lookup_name_fuzzy (token
->value
,
5027 FUZZY_LOOKUP_TYPENAME
,
5029 if (const char *suggestion
= hint
.suggestion ())
5031 gcc_rich_location
richloc (token
->location
);
5032 richloc
.add_fixit_replace (suggestion
);
5034 "unknown type name %qE; did you mean %qs?",
5035 token
->value
, suggestion
);
5038 error_at (token
->location
, "unknown type name %qE", token
->value
);
5039 parser
->error
= true;
5041 /* ??? In some Objective-C cases '...' isn't applicable so there
5042 should be a different message. */
5044 c_parser_error (parser
,
5045 "expected declaration specifiers or %<...%>");
5046 c_parser_skip_to_end_of_parameter (parser
);
5050 location_t start_loc
= c_parser_peek_token (parser
)->location
;
5052 specs
= build_null_declspecs ();
5055 declspecs_add_attrs (input_location
, specs
, attrs
);
5058 c_parser_declspecs (parser
, specs
, true, true, true, true, false,
5059 !have_gnu_attrs
, true, cla_nonabstract_decl
);
5060 finish_declspecs (specs
);
5061 pending_xref_error ();
5062 prefix_attrs
= specs
->attrs
;
5063 specs
->attrs
= NULL_TREE
;
5064 declarator
= c_parser_declarator (parser
,
5065 specs
->typespec_kind
!= ctsk_none
,
5066 C_DTR_PARM
, &dummy
);
5067 if (declarator
== NULL
)
5069 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5072 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
5073 postfix_attrs
= c_parser_gnu_attributes (parser
);
5075 /* Generate a location for the parameter, ranging from the start of the
5076 initial token to the end of the final token.
5078 If we have a identifier, then use it for the caret location, e.g.
5080 extern int callee (int one, int (*two)(int, int), float three);
5081 ~~~~~~^~~~~~~~~~~~~~
5083 otherwise, reuse the start location for the caret location e.g.:
5085 extern int callee (int one, int (*)(int, int), float three);
5088 location_t end_loc
= parser
->last_token_location
;
5090 /* Find any cdk_id declarator; determine if we have an identifier. */
5091 c_declarator
*id_declarator
= declarator
;
5092 while (id_declarator
&& id_declarator
->kind
!= cdk_id
)
5093 id_declarator
= id_declarator
->declarator
;
5094 location_t caret_loc
= (id_declarator
->u
.id
.id
5095 ? id_declarator
->id_loc
5097 location_t param_loc
= make_location (caret_loc
, start_loc
, end_loc
);
5099 return build_c_parm (specs
, chainon (postfix_attrs
, prefix_attrs
),
5100 declarator
, param_loc
);
5103 /* Parse a string literal in an asm expression. It should not be
5104 translated, and wide string literals are an error although
5105 permitted by the syntax. This is a GNU extension.
5112 c_parser_asm_string_literal (c_parser
*parser
)
5115 int save_flag
= warn_overlength_strings
;
5116 warn_overlength_strings
= 0;
5117 str
= c_parser_string_literal (parser
, false, false).value
;
5118 warn_overlength_strings
= save_flag
;
5122 /* Parse a simple asm expression. This is used in restricted
5123 contexts, where a full expression with inputs and outputs does not
5124 make sense. This is a GNU extension.
5127 asm ( asm-string-literal )
5131 c_parser_simple_asm_expr (c_parser
*parser
)
5134 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
5135 c_parser_consume_token (parser
);
5136 matching_parens parens
;
5137 if (!parens
.require_open (parser
))
5139 str
= c_parser_asm_string_literal (parser
);
5140 if (!parens
.require_close (parser
))
5142 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
5149 c_parser_gnu_attribute_any_word (c_parser
*parser
)
5151 tree attr_name
= NULL_TREE
;
5153 if (c_parser_next_token_is (parser
, CPP_KEYWORD
))
5155 /* ??? See comment above about what keywords are accepted here. */
5157 switch (c_parser_peek_token (parser
)->keyword
)
5189 case RID_TRANSACTION_ATOMIC
:
5190 case RID_TRANSACTION_CANCEL
:
5207 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
5208 attr_name
= ridpointers
[(int) c_parser_peek_token (parser
)->keyword
];
5210 else if (c_parser_next_token_is (parser
, CPP_NAME
))
5211 attr_name
= c_parser_peek_token (parser
)->value
;
5216 /* Parse attribute arguments. This is a common form of syntax
5217 covering all currently valid GNU and standard attributes.
5219 gnu-attribute-arguments:
5221 identifier , nonempty-expr-list
5224 where the "identifier" must not be declared as a type. ??? Why not
5225 allow identifiers declared as types to start the arguments? */
5228 c_parser_attribute_arguments (c_parser
*parser
, bool takes_identifier
,
5229 bool require_string
, bool assume_attr
,
5230 bool allow_empty_args
)
5232 vec
<tree
, va_gc
> *expr_list
;
5234 /* Parse the attribute contents. If they start with an
5235 identifier which is followed by a comma or close
5236 parenthesis, then the arguments start with that
5237 identifier; otherwise they are an expression list.
5238 In objective-c the identifier may be a classname. */
5239 if (c_parser_next_token_is (parser
, CPP_NAME
)
5240 && (c_parser_peek_token (parser
)->id_kind
== C_ID_ID
5241 || (c_dialect_objc ()
5242 && c_parser_peek_token (parser
)->id_kind
5244 && ((c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
5245 || (c_parser_peek_2nd_token (parser
)->type
5246 == CPP_CLOSE_PAREN
))
5247 && (takes_identifier
5248 || (c_dialect_objc ()
5250 && c_parser_peek_token (parser
)->id_kind
5251 == C_ID_CLASSNAME
)))
5253 tree arg1
= c_parser_peek_token (parser
)->value
;
5254 c_parser_consume_token (parser
);
5255 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5256 attr_args
= build_tree_list (NULL_TREE
, arg1
);
5260 c_parser_consume_token (parser
);
5261 expr_list
= c_parser_expr_list (parser
, false, true,
5262 NULL
, NULL
, NULL
, NULL
);
5263 tree_list
= build_tree_list_vec (expr_list
);
5264 attr_args
= tree_cons (NULL_TREE
, arg1
, tree_list
);
5265 release_tree_vector (expr_list
);
5270 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5272 if (!allow_empty_args
)
5273 error_at (c_parser_peek_token (parser
)->location
,
5274 "parentheses must be omitted if "
5275 "attribute argument list is empty");
5276 attr_args
= NULL_TREE
;
5278 else if (require_string
)
5280 /* The only valid argument for this attribute is a string
5281 literal. Handle this specially here to avoid accepting
5282 string literals with excess parentheses. */
5283 tree string
= c_parser_string_literal (parser
, false, true).value
;
5284 attr_args
= build_tree_list (NULL_TREE
, string
);
5286 else if (assume_attr
)
5289 = c_parser_conditional_expression (parser
, NULL
, NULL_TREE
).value
;
5290 if (!c_parser_next_token_is (parser
, CPP_COMMA
))
5291 attr_args
= build_tree_list (NULL_TREE
, cond
);
5295 c_parser_consume_token (parser
);
5296 expr_list
= c_parser_expr_list (parser
, false, true,
5297 NULL
, NULL
, NULL
, NULL
);
5298 tree_list
= build_tree_list_vec (expr_list
);
5299 attr_args
= tree_cons (NULL_TREE
, cond
, tree_list
);
5300 release_tree_vector (expr_list
);
5305 expr_list
= c_parser_expr_list (parser
, false, true,
5306 NULL
, NULL
, NULL
, NULL
);
5307 attr_args
= build_tree_list_vec (expr_list
);
5308 release_tree_vector (expr_list
);
5314 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
5318 gnu-attributes gnu-attribute
5321 __attribute__ ( ( gnu-attribute-list ) )
5325 gnu-attribute_list , gnu-attrib
5330 any-word ( gnu-attribute-arguments )
5332 where "any-word" may be any identifier (including one declared as a
5333 type), a reserved word storage class specifier, type specifier or
5334 type qualifier. ??? This still leaves out most reserved keywords
5335 (following the old parser), shouldn't we include them?
5336 When EXPECT_COMMA is true, expect the attribute to be preceded
5337 by a comma and fail if it isn't.
5338 When EMPTY_OK is true, allow and consume any number of consecutive
5339 commas with no attributes in between. */
5342 c_parser_gnu_attribute (c_parser
*parser
, tree attrs
,
5343 bool expect_comma
= false, bool empty_ok
= true)
5345 bool comma_first
= c_parser_next_token_is (parser
, CPP_COMMA
);
5347 && !c_parser_next_token_is (parser
, CPP_NAME
)
5348 && !c_parser_next_token_is (parser
, CPP_KEYWORD
))
5351 while (c_parser_next_token_is (parser
, CPP_COMMA
))
5353 c_parser_consume_token (parser
);
5358 tree attr_name
= c_parser_gnu_attribute_any_word (parser
);
5359 if (attr_name
== NULL_TREE
)
5362 attr_name
= canonicalize_attr_name (attr_name
);
5363 c_parser_consume_token (parser
);
5366 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
5368 if (expect_comma
&& !comma_first
)
5370 /* A comma is missing between the last attribute on the chain
5372 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5374 return error_mark_node
;
5376 attr
= build_tree_list (attr_name
, NULL_TREE
);
5377 /* Add this attribute to the list. */
5378 attrs
= chainon (attrs
, attr
);
5381 c_parser_consume_token (parser
);
5384 = c_parser_attribute_arguments (parser
,
5385 attribute_takes_identifier_p (attr_name
),
5387 is_attribute_p ("assume", attr_name
),
5390 attr
= build_tree_list (attr_name
, attr_args
);
5391 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5392 c_parser_consume_token (parser
);
5395 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5397 return error_mark_node
;
5400 if (expect_comma
&& !comma_first
)
5402 /* A comma is missing between the last attribute on the chain
5404 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5406 return error_mark_node
;
5409 /* Add this attribute to the list. */
5410 attrs
= chainon (attrs
, attr
);
5415 c_parser_gnu_attributes (c_parser
*parser
)
5417 tree attrs
= NULL_TREE
;
5418 while (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
5420 bool save_translate_strings_p
= parser
->translate_strings_p
;
5421 parser
->translate_strings_p
= false;
5422 /* Consume the `__attribute__' keyword. */
5423 c_parser_consume_token (parser
);
5424 /* Look for the two `(' tokens. */
5425 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
5427 parser
->translate_strings_p
= save_translate_strings_p
;
5430 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
5432 parser
->translate_strings_p
= save_translate_strings_p
;
5433 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
5436 /* Parse the attribute list. Require a comma between successive
5437 (possibly empty) attributes. */
5438 for (bool expect_comma
= false; ; expect_comma
= true)
5440 /* Parse a single attribute. */
5441 tree attr
= c_parser_gnu_attribute (parser
, attrs
, expect_comma
);
5442 if (attr
== error_mark_node
)
5449 /* Look for the two `)' tokens. */
5450 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5451 c_parser_consume_token (parser
);
5454 parser
->translate_strings_p
= save_translate_strings_p
;
5455 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5459 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5460 c_parser_consume_token (parser
);
5463 parser
->translate_strings_p
= save_translate_strings_p
;
5464 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5468 parser
->translate_strings_p
= save_translate_strings_p
;
5474 /* Parse an optional balanced token sequence.
5476 balanced-token-sequence:
5478 balanced-token-sequence balanced-token
5481 ( balanced-token-sequence[opt] )
5482 [ balanced-token-sequence[opt] ]
5483 { balanced-token-sequence[opt] }
5484 any token other than ()[]{}
5488 c_parser_balanced_token_sequence (c_parser
*parser
)
5492 c_token
*token
= c_parser_peek_token (parser
);
5493 switch (token
->type
)
5495 case CPP_OPEN_BRACE
:
5497 matching_braces braces
;
5498 braces
.consume_open (parser
);
5499 c_parser_balanced_token_sequence (parser
);
5500 braces
.require_close (parser
);
5504 case CPP_OPEN_PAREN
:
5506 matching_parens parens
;
5507 parens
.consume_open (parser
);
5508 c_parser_balanced_token_sequence (parser
);
5509 parens
.require_close (parser
);
5513 case CPP_OPEN_SQUARE
:
5514 c_parser_consume_token (parser
);
5515 c_parser_balanced_token_sequence (parser
);
5516 c_parser_require (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5519 case CPP_CLOSE_BRACE
:
5520 case CPP_CLOSE_PAREN
:
5521 case CPP_CLOSE_SQUARE
:
5526 c_parser_consume_pragma (parser
);
5527 c_parser_skip_to_pragma_eol (parser
, false);
5531 c_parser_consume_token (parser
);
5537 static bool c_parser_check_balanced_raw_token_sequence (c_parser
*,
5540 /* Parse arguments of omp::directive or omp::decl attribute.
5542 directive-name ,[opt] clause-list[opt]
5544 For directive just remember the tokens in a vector for subsequent
5548 c_parser_omp_directive_args (c_parser
*parser
, tree attribute
, bool decl_p
)
5551 c_token
*first
= c_parser_peek_token (parser
);
5552 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
)
5553 || (c_parser_peek_nth_token_raw (parser
, n
)->type
5554 != CPP_CLOSE_PAREN
))
5556 c_parser_balanced_token_sequence (parser
);
5557 TREE_VALUE (attribute
) = NULL_TREE
;
5562 error_at (first
->location
, "expected OpenMP directive name");
5563 TREE_VALUE (attribute
) = NULL_TREE
;
5566 vec
<c_token
, va_gc
> *v
;
5567 vec_alloc (v
, n
- 1);
5570 c_token
*tok
= c_parser_peek_token (parser
);
5571 v
->quick_push (*tok
);
5572 c_parser_consume_token (parser
);
5574 tree arg
= make_node (C_TOKEN_VEC
);
5575 C_TOKEN_VEC_TOKENS (arg
) = v
;
5577 TREE_PUBLIC (arg
) = 1;
5578 TREE_VALUE (attribute
) = tree_cons (NULL_TREE
, arg
, TREE_VALUE (attribute
));
5581 /* Parse arguments of omp::sequence attribute.
5583 omp::[opt] directive-attr [ , omp::[opt] directive-attr ]... */
5586 c_parser_omp_sequence_args (c_parser
*parser
, tree attribute
)
5590 c_token
*token
= c_parser_peek_token (parser
);
5591 if (token
->type
== CPP_NAME
5592 && strcmp (IDENTIFIER_POINTER (token
->value
), "omp") == 0
5593 && c_parser_peek_2nd_token (parser
)->type
== CPP_SCOPE
)
5595 c_parser_consume_token (parser
);
5596 c_parser_consume_token (parser
);
5597 token
= c_parser_peek_token (parser
);
5599 bool directive
= false;
5601 if (token
->type
!= CPP_NAME
)
5604 p
= IDENTIFIER_POINTER (token
->value
);
5605 if (strcmp (p
, "directive") == 0)
5607 else if (strcmp (p
, "sequence") != 0)
5609 error_at (token
->location
, "expected %<directive%> or %<sequence%>");
5610 unsigned nesting_depth
= 0;
5614 /* Peek at the next token. */
5615 token
= c_parser_peek_token (parser
);
5616 /* If we've reached the token we want, consume it and stop. */
5617 if ((token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_COMMA
)
5620 /* If we've run out of tokens, stop. */
5621 if (token
->type
== CPP_EOF
)
5623 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
5625 if (token
->type
== CPP_OPEN_BRACE
5626 || token
->type
== CPP_OPEN_PAREN
5627 || token
->type
== CPP_OPEN_SQUARE
)
5629 else if (token
->type
== CPP_CLOSE_BRACE
5630 || token
->type
== CPP_CLOSE_PAREN
5631 || token
->type
== CPP_CLOSE_SQUARE
)
5633 if (nesting_depth
-- == 0)
5636 /* Consume this token. */
5637 c_parser_consume_token (parser
);
5639 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5641 c_parser_consume_token (parser
);
5644 c_parser_consume_token (parser
);
5645 matching_parens parens
;
5646 if (parens
.require_open (parser
))
5649 c_parser_omp_directive_args (parser
, attribute
, false);
5651 c_parser_omp_sequence_args (parser
, attribute
);
5652 parens
.skip_until_found_close (parser
);
5653 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5655 c_parser_consume_token (parser
);
5657 else if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5660 c_parser_consume_token (parser
);
5665 /* Parse standard (C23) attributes (including GNU attributes in the
5668 attribute-specifier-sequence:
5669 attribute-specifier-sequence[opt] attribute-specifier
5671 attribute-specifier:
5672 [ [ attribute-list ] ]
5676 attribute-list, attribute[opt]
5679 attribute-token attribute-argument-clause[opt]
5683 attribute-prefixed-token
5688 attribute-prefixed-token:
5689 attribute-prefix :: identifier
5694 attribute-argument-clause:
5695 ( balanced-token-sequence[opt] )
5697 Keywords are accepted as identifiers for this purpose.
5699 As an extension, we permit an attribute-specifier to be:
5701 [ [ __extension__ attribute-list ] ]
5703 Two colons are then accepted as a synonym for ::. No attempt is made
5704 to check whether the colons are immediately adjacent. LOOSE_SCOPE_P
5705 indicates whether this relaxation is in effect. */
5708 c_parser_std_attribute (c_parser
*parser
, bool for_tm
)
5710 c_token
*token
= c_parser_peek_token (parser
);
5711 tree ns
, name
, attribute
;
5713 /* Parse the attribute-token. */
5714 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
5716 c_parser_error (parser
, "expected identifier");
5717 return error_mark_node
;
5719 name
= canonicalize_attr_name (token
->value
);
5720 c_parser_consume_token (parser
);
5721 if (c_parser_next_token_is (parser
, CPP_SCOPE
)
5722 || (c_parser_next_token_is (parser
, CPP_COLON
)
5723 && (c_parser_peek_token (parser
)->flags
& COLON_SCOPE
) != 0
5724 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5727 if (c_parser_next_token_is (parser
, CPP_COLON
))
5728 c_parser_consume_token (parser
);
5729 c_parser_consume_token (parser
);
5730 token
= c_parser_peek_token (parser
);
5731 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
5733 c_parser_error (parser
, "expected identifier");
5734 return error_mark_node
;
5736 name
= canonicalize_attr_name (token
->value
);
5737 c_parser_consume_token (parser
);
5741 attribute
= build_tree_list (build_tree_list (ns
, name
), NULL_TREE
);
5743 /* Parse the arguments, if any. */
5744 const attribute_spec
*as
= lookup_attribute_spec (TREE_PURPOSE (attribute
));
5745 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
5747 if ((flag_openmp
|| flag_openmp_simd
)
5749 && is_attribute_p ("omp", ns
)
5750 && (is_attribute_p ("directive", name
)
5751 || is_attribute_p ("sequence", name
)
5752 || is_attribute_p ("decl", name
)))
5754 error ("%<omp::%E%> attribute requires argument", name
);
5755 return error_mark_node
;
5760 location_t open_loc
= c_parser_peek_token (parser
)->location
;
5761 matching_parens parens
;
5762 parens
.consume_open (parser
);
5763 if ((as
&& as
->max_length
== 0)
5764 /* Special-case the transactional-memory attribute "outer",
5765 which is specially handled but not registered as an
5766 attribute, to avoid allowing arbitrary balanced token
5767 sequences as arguments. */
5768 || is_attribute_p ("outer", name
))
5770 error_at (open_loc
, "%qE attribute does not take any arguments", name
);
5771 parens
.skip_until_found_close (parser
);
5772 return error_mark_node
;
5774 /* If this is a fake attribute created to handle -Wno-attributes,
5775 we must skip parsing the arguments. */
5776 if (as
&& !attribute_ignored_p (as
))
5778 bool takes_identifier
5780 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
5781 && attribute_takes_identifier_p (name
));
5784 && (strcmp (IDENTIFIER_POINTER (name
), "deprecated") == 0
5785 || strcmp (IDENTIFIER_POINTER (name
), "nodiscard") == 0));
5788 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
5789 && strcmp (IDENTIFIER_POINTER (name
), "assume") == 0);
5790 TREE_VALUE (attribute
)
5791 = c_parser_attribute_arguments (parser
, takes_identifier
,
5792 require_string
, assume_attr
, false);
5796 if ((flag_openmp
|| flag_openmp_simd
)
5798 && is_attribute_p ("omp", ns
))
5800 if (is_attribute_p ("directive", name
))
5802 c_parser_omp_directive_args (parser
, attribute
, false);
5803 parens
.skip_until_found_close (parser
);
5806 else if (is_attribute_p ("decl", name
))
5808 TREE_VALUE (TREE_PURPOSE (attribute
))
5809 = get_identifier ("directive");
5810 c_parser_omp_directive_args (parser
, attribute
, true);
5811 parens
.skip_until_found_close (parser
);
5814 else if (is_attribute_p ("sequence", name
))
5816 TREE_VALUE (TREE_PURPOSE (attribute
))
5817 = get_identifier ("directive");
5818 c_parser_omp_sequence_args (parser
, attribute
);
5819 parens
.skip_until_found_close (parser
);
5820 TREE_VALUE (attribute
) = nreverse (TREE_VALUE (attribute
));
5824 c_parser_balanced_token_sequence (parser
);
5826 parens
.require_close (parser
);
5829 if (ns
== NULL_TREE
&& !for_tm
&& !as
)
5831 /* An attribute with standard syntax and no namespace specified
5832 is a constraint violation if it is not one of the known
5833 standard attributes. Diagnose it here with a pedwarn and
5834 then discard it to prevent a duplicate warning later. */
5835 pedwarn (input_location
, OPT_Wattributes
, "%qE attribute ignored",
5837 return error_mark_node
;
5843 c_parser_std_attribute_list (c_parser
*parser
, bool for_tm
)
5845 tree attributes
= NULL_TREE
;
5848 c_token
*token
= c_parser_peek_token (parser
);
5849 if (token
->type
== CPP_CLOSE_SQUARE
)
5851 if (token
->type
== CPP_COMMA
)
5853 c_parser_consume_token (parser
);
5856 tree attribute
= c_parser_std_attribute (parser
, for_tm
);
5857 if (attribute
!= error_mark_node
)
5859 TREE_CHAIN (attribute
) = attributes
;
5860 attributes
= attribute
;
5862 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5869 c_parser_std_attribute_specifier (c_parser
*parser
, bool for_tm
)
5871 location_t loc
= c_parser_peek_token (parser
)->location
;
5872 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
5874 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
5876 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5880 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
5882 auto ext
= disable_extension_diagnostics ();
5883 c_parser_consume_token (parser
);
5884 attributes
= c_parser_std_attribute_list (parser
, for_tm
);
5885 restore_extension_diagnostics (ext
);
5890 pedwarn_c11 (loc
, OPT_Wpedantic
,
5891 "ISO C does not support %<[[]]%> attributes before C23");
5892 attributes
= c_parser_std_attribute_list (parser
, for_tm
);
5894 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5895 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5896 return nreverse (attributes
);
5899 /* Look past an optional balanced token sequence of raw look-ahead
5900 tokens starting with the *Nth token. *N is updated to point to the
5901 following token. Return true if such a sequence was found, false
5902 if the tokens parsed were not balanced. */
5905 c_parser_check_balanced_raw_token_sequence (c_parser
*parser
, unsigned int *n
)
5909 c_token
*token
= c_parser_peek_nth_token_raw (parser
, *n
);
5910 switch (token
->type
)
5912 case CPP_OPEN_BRACE
:
5915 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5917 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5918 if (token
->type
== CPP_CLOSE_BRACE
)
5928 case CPP_OPEN_PAREN
:
5931 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5933 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5934 if (token
->type
== CPP_CLOSE_PAREN
)
5944 case CPP_OPEN_SQUARE
:
5947 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5949 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5950 if (token
->type
== CPP_CLOSE_SQUARE
)
5960 case CPP_CLOSE_BRACE
:
5961 case CPP_CLOSE_PAREN
:
5962 case CPP_CLOSE_SQUARE
:
5973 /* Return whether standard attributes start with the Nth token. */
5976 c_parser_nth_token_starts_std_attributes (c_parser
*parser
, unsigned int n
)
5978 if (!(c_parser_peek_nth_token (parser
, n
)->type
== CPP_OPEN_SQUARE
5979 && c_parser_peek_nth_token (parser
, n
+ 1)->type
== CPP_OPEN_SQUARE
))
5981 /* In C, '[[' must start attributes. In Objective-C, we need to
5982 check whether '[[' is matched by ']]'. */
5983 if (!c_dialect_objc ())
5986 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
5988 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
5989 if (token
->type
!= CPP_CLOSE_SQUARE
)
5991 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
5992 return token
->type
== CPP_CLOSE_SQUARE
;
5996 c_parser_std_attribute_specifier_sequence (c_parser
*parser
)
5998 tree attributes
= NULL_TREE
;
6001 tree attrs
= c_parser_std_attribute_specifier (parser
, false);
6002 attributes
= chainon (attributes
, attrs
);
6004 while (c_parser_nth_token_starts_std_attributes (parser
, 1));
6008 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
6009 says whether alignment specifiers are OK (only in cases that might
6010 be the type name of a compound literal).
6013 specifier-qualifier-list abstract-declarator[opt]
6016 struct c_type_name
*
6017 c_parser_type_name (c_parser
*parser
, bool alignas_ok
)
6019 struct c_declspecs
*specs
= build_null_declspecs ();
6020 struct c_declarator
*declarator
;
6021 struct c_type_name
*ret
;
6023 c_parser_declspecs (parser
, specs
, false, true, true, alignas_ok
, false,
6024 false, true, cla_prefer_type
);
6025 if (!specs
->declspecs_seen_p
)
6027 c_parser_error (parser
, "expected specifier-qualifier-list");
6030 if (specs
->type
!= error_mark_node
)
6032 pending_xref_error ();
6033 finish_declspecs (specs
);
6035 declarator
= c_parser_declarator (parser
,
6036 specs
->typespec_kind
!= ctsk_none
,
6037 C_DTR_ABSTRACT
, &dummy
);
6038 if (declarator
== NULL
)
6040 ret
= XOBNEW (&parser_obstack
, struct c_type_name
);
6042 ret
->declarator
= declarator
;
6046 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
6049 assignment-expression
6050 { initializer-list }
6051 { initializer-list , }
6054 designation[opt] initializer
6055 initializer-list , designation[opt] initializer
6062 designator-list designator
6069 [ constant-expression ]
6081 [ constant-expression ... constant-expression ]
6083 Any expression without commas is accepted in the syntax for the
6084 constant-expressions, with non-constant expressions rejected later.
6086 DECL is the declaration we're parsing this initializer for.
6088 This function is only used for top-level initializers; for nested
6089 ones, see c_parser_initval. */
6091 static struct c_expr
6092 c_parser_initializer (c_parser
*parser
, tree decl
)
6094 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6095 return c_parser_braced_init (parser
, NULL_TREE
, false, NULL
, decl
);
6099 location_t loc
= c_parser_peek_token (parser
)->location
;
6100 ret
= c_parser_expr_no_commas (parser
, NULL
);
6101 if (decl
!= error_mark_node
&& C_DECL_VARIABLE_SIZE (decl
))
6104 "variable-sized object may not be initialized except "
6105 "with an empty initializer");
6108 /* This is handled mostly by gimplify.cc, but we have to deal with
6109 not warning about int x = x; as it is a GCC extension to turn off
6110 this warning but only if warn_init_self is zero. */
6112 && !DECL_EXTERNAL (decl
)
6113 && !TREE_STATIC (decl
)
6114 && ret
.value
== decl
6115 && !warning_enabled_at (DECL_SOURCE_LOCATION (decl
), OPT_Winit_self
))
6116 suppress_warning (decl
, OPT_Winit_self
);
6117 if (TREE_CODE (ret
.value
) != STRING_CST
6118 && (TREE_CODE (ret
.value
) != COMPOUND_LITERAL_EXPR
6119 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6121 ret
= convert_lvalue_to_rvalue (loc
, ret
, true, true, true);
6126 /* The location of the last comma within the current initializer list,
6127 or UNKNOWN_LOCATION if not within one. */
6129 location_t last_init_list_comma
;
6131 /* Parse a braced initializer list. TYPE is the type specified for a
6132 compound literal, and NULL_TREE for other initializers and for
6133 nested braced lists. NESTED_P is true for nested braced lists,
6134 false for the list of a compound literal or the list that is the
6135 top-level initializer in a declaration. DECL is the declaration for
6136 the top-level initializer for a declaration, otherwise NULL_TREE. */
6138 static struct c_expr
6139 c_parser_braced_init (c_parser
*parser
, tree type
, bool nested_p
,
6140 struct obstack
*outer_obstack
, tree decl
)
6143 struct obstack braced_init_obstack
;
6144 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
6145 gcc_obstack_init (&braced_init_obstack
);
6146 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
6147 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
6148 c_omp_array_section_p
= false;
6149 matching_braces braces
;
6150 braces
.consume_open (parser
);
6153 finish_implicit_inits (brace_loc
, outer_obstack
);
6154 push_init_level (brace_loc
, 0, &braced_init_obstack
);
6157 really_start_incremental_init (type
);
6158 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
6160 pedwarn_c11 (brace_loc
, OPT_Wpedantic
,
6161 "ISO C forbids empty initializer braces before C23");
6165 if (decl
&& decl
!= error_mark_node
&& C_DECL_VARIABLE_SIZE (decl
))
6166 error_at (brace_loc
,
6167 "variable-sized object may not be initialized except "
6168 "with an empty initializer");
6169 /* Parse a non-empty initializer list, possibly with a trailing
6173 c_parser_initelt (parser
, &braced_init_obstack
);
6176 if (c_parser_next_token_is (parser
, CPP_COMMA
))
6178 last_init_list_comma
= c_parser_peek_token (parser
)->location
;
6179 c_parser_consume_token (parser
);
6183 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
6187 c_omp_array_section_p
= save_c_omp_array_section_p
;
6188 c_token
*next_tok
= c_parser_peek_token (parser
);
6189 if (next_tok
->type
!= CPP_CLOSE_BRACE
)
6192 ret
.original_code
= ERROR_MARK
;
6193 ret
.original_type
= NULL
;
6194 braces
.skip_until_found_close (parser
);
6195 pop_init_level (brace_loc
, 0, &braced_init_obstack
, last_init_list_comma
);
6196 obstack_free (&braced_init_obstack
, NULL
);
6199 location_t close_loc
= next_tok
->location
;
6200 c_parser_consume_token (parser
);
6201 ret
= pop_init_level (brace_loc
, 0, &braced_init_obstack
, close_loc
);
6202 obstack_free (&braced_init_obstack
, NULL
);
6203 set_c_expr_source_range (&ret
, brace_loc
, close_loc
);
6207 /* Parse a nested initializer, including designators. */
6210 c_parser_initelt (c_parser
*parser
, struct obstack
* braced_init_obstack
)
6212 /* Parse any designator or designator list. A single array
6213 designator may have the subsequent "=" omitted in GNU C, but a
6214 longer list or a structure member designator may not. */
6215 if (c_parser_next_token_is (parser
, CPP_NAME
)
6216 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
6218 /* Old-style structure member designator. */
6219 set_init_label (c_parser_peek_token (parser
)->location
,
6220 c_parser_peek_token (parser
)->value
,
6221 c_parser_peek_token (parser
)->location
,
6222 braced_init_obstack
);
6223 /* Use the colon as the error location. */
6224 pedwarn (c_parser_peek_2nd_token (parser
)->location
, OPT_Wpedantic
,
6225 "obsolete use of designated initializer with %<:%>");
6226 c_parser_consume_token (parser
);
6227 c_parser_consume_token (parser
);
6231 /* des_seen is 0 if there have been no designators, 1 if there
6232 has been a single array designator and 2 otherwise. */
6234 /* Location of a designator. */
6235 location_t des_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
6236 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
6237 || c_parser_next_token_is (parser
, CPP_DOT
))
6239 int des_prev
= des_seen
;
6241 des_loc
= c_parser_peek_token (parser
)->location
;
6244 if (c_parser_next_token_is (parser
, CPP_DOT
))
6247 c_parser_consume_token (parser
);
6248 if (c_parser_next_token_is (parser
, CPP_NAME
))
6250 set_init_label (des_loc
, c_parser_peek_token (parser
)->value
,
6251 c_parser_peek_token (parser
)->location
,
6252 braced_init_obstack
);
6253 c_parser_consume_token (parser
);
6259 init
.original_code
= ERROR_MARK
;
6260 init
.original_type
= NULL
;
6261 c_parser_error (parser
, "expected identifier");
6262 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
6263 process_init_element (input_location
, init
, false,
6264 braced_init_obstack
);
6270 struct c_expr first_expr
;
6272 location_t ellipsis_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
6273 location_t array_index_loc
= UNKNOWN_LOCATION
;
6274 /* ??? Following the old parser, [ objc-receiver
6275 objc-message-args ] is accepted as an initializer,
6276 being distinguished from a designator by what follows
6277 the first assignment expression inside the square
6278 brackets, but after a first array designator a
6279 subsequent square bracket is for Objective-C taken to
6280 start an expression, using the obsolete form of
6281 designated initializer without '=', rather than
6282 possibly being a second level of designation: in LALR
6283 terms, the '[' is shifted rather than reducing
6284 designator to designator-list. */
6285 if (des_prev
== 1 && c_dialect_objc ())
6287 des_seen
= des_prev
;
6290 if (des_prev
== 0 && c_dialect_objc ())
6292 /* This might be an array designator or an
6293 Objective-C message expression. If the former,
6294 continue parsing here; if the latter, parse the
6295 remainder of the initializer given the starting
6296 primary-expression. ??? It might make sense to
6297 distinguish when des_prev == 1 as well; see
6298 previous comment. */
6300 struct c_expr mexpr
;
6301 c_parser_consume_token (parser
);
6302 if (c_parser_peek_token (parser
)->type
== CPP_NAME
6303 && ((c_parser_peek_token (parser
)->id_kind
6305 || (c_parser_peek_token (parser
)->id_kind
6306 == C_ID_CLASSNAME
)))
6308 /* Type name receiver. */
6309 tree id
= c_parser_peek_token (parser
)->value
;
6310 c_parser_consume_token (parser
);
6311 rec
= objc_get_class_reference (id
);
6312 goto parse_message_args
;
6314 array_index_loc
= c_parser_peek_token (parser
)->location
;
6315 first_expr
= c_parser_expr_no_commas (parser
, NULL
);
6316 mark_exp_read (first_expr
.value
);
6317 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
)
6318 || c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
6319 goto array_desig_after_first
;
6320 first
= first_expr
.value
;
6321 /* Expression receiver. So far only one part
6322 without commas has been parsed; there might be
6323 more of the expression. */
6325 while (c_parser_next_token_is (parser
, CPP_COMMA
))
6328 location_t comma_loc
, exp_loc
;
6329 comma_loc
= c_parser_peek_token (parser
)->location
;
6330 c_parser_consume_token (parser
);
6331 exp_loc
= c_parser_peek_token (parser
)->location
;
6332 next
= c_parser_expr_no_commas (parser
, NULL
);
6333 next
= convert_lvalue_to_rvalue (exp_loc
, next
,
6335 rec
= build_compound_expr (comma_loc
, rec
, next
.value
);
6338 /* Now parse the objc-message-args. */
6339 args
= c_parser_objc_message_args (parser
);
6340 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
6343 = objc_build_message_expr (rec
, args
);
6344 mexpr
.original_code
= ERROR_MARK
;
6345 mexpr
.original_type
= NULL
;
6346 mexpr
.m_decimal
= 0;
6347 /* Now parse and process the remainder of the
6348 initializer, starting with this message
6349 expression as a primary-expression. */
6350 c_parser_initval (parser
, &mexpr
, braced_init_obstack
);
6353 c_parser_consume_token (parser
);
6354 array_index_loc
= c_parser_peek_token (parser
)->location
;
6355 first_expr
= c_parser_expr_no_commas (parser
, NULL
);
6356 mark_exp_read (first_expr
.value
);
6357 array_desig_after_first
:
6358 first_expr
= convert_lvalue_to_rvalue (array_index_loc
,
6361 first
= first_expr
.value
;
6362 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
6364 ellipsis_loc
= c_parser_peek_token (parser
)->location
;
6365 c_parser_consume_token (parser
);
6366 second
= convert_lvalue_to_rvalue (ellipsis_loc
,
6367 (c_parser_expr_no_commas
6370 mark_exp_read (second
);
6374 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
6376 c_parser_consume_token (parser
);
6377 set_init_index (array_index_loc
, first
, second
,
6378 braced_init_obstack
);
6380 pedwarn (ellipsis_loc
, OPT_Wpedantic
,
6381 "ISO C forbids specifying range of elements to initialize");
6384 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
6390 if (c_parser_next_token_is (parser
, CPP_EQ
))
6392 pedwarn_c90 (des_loc
, OPT_Wpedantic
,
6393 "ISO C90 forbids specifying subobject "
6395 c_parser_consume_token (parser
);
6400 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
6401 "obsolete use of designated initializer without %<=%>");
6406 init
.original_code
= ERROR_MARK
;
6407 init
.original_type
= NULL
;
6408 c_parser_error (parser
, "expected %<=%>");
6409 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
6410 process_init_element (input_location
, init
, false,
6411 braced_init_obstack
);
6417 c_parser_initval (parser
, NULL
, braced_init_obstack
);
6420 /* Parse a nested initializer; as c_parser_initializer but parses
6421 initializers within braced lists, after any designators have been
6422 applied. If AFTER is not NULL then it is an Objective-C message
6423 expression which is the primary-expression starting the
6427 c_parser_initval (c_parser
*parser
, struct c_expr
*after
,
6428 struct obstack
* braced_init_obstack
)
6431 gcc_assert (!after
|| c_dialect_objc ());
6432 location_t loc
= c_parser_peek_token (parser
)->location
;
6434 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
) && !after
)
6435 init
= c_parser_braced_init (parser
, NULL_TREE
, true,
6436 braced_init_obstack
, NULL_TREE
);
6439 init
= c_parser_expr_no_commas (parser
, after
);
6440 if (init
.value
!= NULL_TREE
6441 && TREE_CODE (init
.value
) != STRING_CST
6442 && (TREE_CODE (init
.value
) != COMPOUND_LITERAL_EXPR
6443 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6445 init
= convert_lvalue_to_rvalue (loc
, init
, true, true, true);
6447 process_init_element (loc
, init
, false, braced_init_obstack
);
6450 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
6451 C99 6.8.2, C11 6.8.2, C23 6.8.2).
6454 { block-item-list[opt] }
6455 { label-declarations block-item-list }
6459 block-item-list block-item
6472 { label-declarations block-item-list }
6475 __extension__ nested-declaration
6476 nested-function-definition
6480 label-declarations label-declaration
6483 __label__ identifier-list ;
6485 Allowing the mixing of declarations and code is new in C99. The
6486 GNU syntax also permits (not shown above) labels at the end of
6487 compound statements, which yield an error. We don't allow labels
6488 on declarations; this might seem like a natural extension, but
6489 there would be a conflict between gnu-attributes on the label and
6490 prefix gnu-attributes on the declaration. ??? The syntax follows the
6491 old parser in requiring something after label declarations.
6492 Although they are erroneous if the labels declared aren't defined,
6493 is it useful for the syntax to be this way?
6514 cancellation-point-directive */
6517 c_parser_compound_statement (c_parser
*parser
, location_t
*endlocp
)
6520 location_t brace_loc
;
6521 brace_loc
= c_parser_peek_token (parser
)->location
;
6522 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
6524 /* Ensure a scope is entered and left anyway to avoid confusion
6525 if we have just prepared to enter a function body. */
6526 stmt
= c_begin_compound_stmt (true);
6527 c_end_compound_stmt (brace_loc
, stmt
, true);
6528 return error_mark_node
;
6530 stmt
= c_begin_compound_stmt (true);
6531 location_t end_loc
= c_parser_compound_statement_nostart (parser
);
6535 return c_end_compound_stmt (brace_loc
, stmt
, true);
6538 /* Diagnose errors related to imperfectly nested loops in an OMP
6539 loop construct. This function is called when such code is seen.
6540 Only issue one such diagnostic no matter how much invalid
6541 intervening code there is in the loop.
6542 FIXME: maybe the location associated with the diagnostic should
6543 be the current parser token instead of the location of the outer loop
6547 check_omp_intervening_code (c_parser
*parser
)
6549 struct omp_for_parse_data
*omp_for_parse_state
= parser
->omp_for_parse_state
;
6550 gcc_assert (omp_for_parse_state
);
6552 if (!omp_for_parse_state
->in_intervening_code
)
6554 omp_for_parse_state
->saw_intervening_code
= true;
6556 /* Only diagnose errors related to perfect nesting once. */
6557 if (!omp_for_parse_state
->perfect_nesting_fail
)
6560 /* OpenACC does not (yet) permit intervening code, in
6561 addition to situations forbidden by the OpenMP spec. */
6562 if (omp_for_parse_state
->code
== OACC_LOOP
)
6564 error_at (omp_for_parse_state
->for_loc
,
6565 "inner loops must be perfectly nested in "
6566 "%<#pragma acc loop%>");
6567 omp_for_parse_state
->perfect_nesting_fail
= true;
6569 else if (omp_for_parse_state
->ordered
)
6571 error_at (omp_for_parse_state
->for_loc
,
6572 "inner loops must be perfectly nested with "
6573 "%<ordered%> clause");
6574 omp_for_parse_state
->perfect_nesting_fail
= true;
6576 else if (omp_for_parse_state
->inscan
)
6578 error_at (omp_for_parse_state
->for_loc
,
6579 "inner loops must be perfectly nested with "
6580 "%<reduction%> %<inscan%> clause");
6581 omp_for_parse_state
->perfect_nesting_fail
= true;
6583 /* TODO: Also reject loops with TILE directive. */
6584 if (omp_for_parse_state
->perfect_nesting_fail
)
6585 omp_for_parse_state
->fail
= true;
6589 /* Helper function for below: wrap an OMP_STRUCTURED_BLOCK around SL
6590 and add the statement to the current list. If SL is an empty statement
6591 list, do nothing. */
6593 add_structured_block_stmt (tree sl
)
6595 if (TREE_CODE (sl
) != STATEMENT_LIST
6596 || !tsi_end_p (tsi_start (sl
)))
6597 add_stmt (build1 (OMP_STRUCTURED_BLOCK
, void_type_node
, sl
));
6600 struct c_omp_attribute_data
6602 vec
<c_token
, va_gc
> *tokens
;
6603 const c_omp_directive
*dir
;
6604 c_omp_directive_kind kind
;
6607 /* Handle omp::directive and omp::sequence attributes in ATTRS
6608 (if any) at the start of a statement or in attribute-declaration. */
6611 c_parser_handle_statement_omp_attributes (c_parser
*parser
, tree
&attrs
,
6612 bool *have_std_attrs
)
6614 if (!flag_openmp
&& !flag_openmp_simd
)
6617 auto_vec
<c_omp_attribute_data
, 16> vd
;
6621 for (tree
*pa
= &attrs
; *pa
; )
6622 if (is_attribute_namespace_p ("omp", *pa
)
6623 && is_attribute_p ("directive", get_attribute_name (*pa
)))
6626 for (tree a
= TREE_VALUE (*pa
); a
; a
= TREE_CHAIN (a
))
6628 tree d
= TREE_VALUE (a
);
6629 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
6630 vec
<c_token
, va_gc
> *toks
= C_TOKEN_VEC_TOKENS (d
);
6631 c_token
*first
= toks
->address ();
6632 c_token
*last
= first
+ toks
->length ();
6633 if (parser
->omp_attrs_forbidden_p
)
6635 error_at (first
->location
,
6636 "mixing OpenMP directives with attribute and pragma "
6637 "syntax on the same statement");
6638 parser
->omp_attrs_forbidden_p
= false;
6641 else if (TREE_PUBLIC (d
))
6643 error_at (first
->location
,
6644 "OpenMP %<omp::decl%> attribute on a statement");
6647 const char *directive
[3] = {};
6648 for (int i
= 0; i
< 3; i
++)
6650 tree id
= NULL_TREE
;
6651 if (first
+ i
== last
)
6653 if (first
[i
].type
== CPP_NAME
)
6654 id
= first
[i
].value
;
6655 else if (first
[i
].type
== CPP_KEYWORD
)
6656 id
= ridpointers
[(int) first
[i
].keyword
];
6659 directive
[i
] = IDENTIFIER_POINTER (id
);
6661 const c_omp_directive
*dir
= NULL
;
6663 dir
= c_omp_categorize_directive (directive
[0], directive
[1],
6667 error_at (first
->location
,
6668 "unknown OpenMP directive name in %qs attribute "
6670 TREE_PUBLIC (d
) ? "omp::decl" : "omp::directive");
6673 c_omp_directive_kind kind
= dir
->kind
;
6674 if (dir
->id
== PRAGMA_OMP_ORDERED
)
6676 /* ordered is C_OMP_DIR_CONSTRUCT only if it doesn't contain
6677 depend/doacross clause. */
6679 && (strcmp (directive
[1], "depend") == 0
6680 || strcmp (directive
[1], "doacross") == 0))
6681 kind
= C_OMP_DIR_STANDALONE
;
6682 else if (first
+ 2 < last
6683 && first
[1].type
== CPP_COMMA
6684 && first
[2].type
== CPP_NAME
6685 && (strcmp (IDENTIFIER_POINTER (first
[2].value
),
6687 || strcmp (IDENTIFIER_POINTER (first
[2].value
),
6689 kind
= C_OMP_DIR_STANDALONE
;
6691 else if (dir
->id
== PRAGMA_OMP_ERROR
)
6693 /* error with at(execution) clause is C_OMP_DIR_STANDALONE. */
6694 int paren_depth
= 0;
6695 for (int i
= 1; first
+ i
< last
; i
++)
6696 if (first
[i
].type
== CPP_OPEN_PAREN
)
6698 else if (first
[i
].type
== CPP_CLOSE_PAREN
)
6700 else if (paren_depth
== 0
6701 && first
+ i
+ 2 < last
6702 && first
[i
].type
== CPP_NAME
6703 && first
[i
+ 1].type
== CPP_OPEN_PAREN
6704 && first
[i
+ 2].type
== CPP_NAME
6705 && !strcmp (IDENTIFIER_POINTER (first
[i
].value
),
6707 && !strcmp (IDENTIFIER_POINTER (first
[i
6711 kind
= C_OMP_DIR_STANDALONE
;
6715 c_omp_attribute_data v
= { toks
, dir
, kind
};
6717 if (flag_openmp
|| dir
->simd
)
6718 tokens
+= (last
- first
) + 1;
6720 c_omp_attribute_data v
= {};
6722 *pa
= TREE_CHAIN (*pa
);
6725 pa
= &TREE_CHAIN (*pa
);
6730 if (have_std_attrs
&& attrs
== NULL
)
6731 *have_std_attrs
= false;
6736 c_omp_attribute_data
*v
;
6737 c_omp_attribute_data
*construct_seen
= nullptr;
6738 c_omp_attribute_data
*standalone_seen
= nullptr;
6739 c_omp_attribute_data
*prev_standalone_seen
= nullptr;
6740 FOR_EACH_VEC_ELT (vd
, i
, v
)
6743 if (v
->kind
== C_OMP_DIR_CONSTRUCT
&& !construct_seen
)
6745 else if (v
->kind
== C_OMP_DIR_STANDALONE
&& !standalone_seen
)
6746 standalone_seen
= v
;
6750 if (standalone_seen
&& !prev_standalone_seen
)
6752 prev_standalone_seen
= standalone_seen
;
6753 standalone_seen
= nullptr;
6757 if (cnt
> 1 && construct_seen
)
6759 error_at ((*construct_seen
->tokens
)[0].location
,
6760 "OpenMP construct among %<omp::directive%> attributes"
6761 " requires all %<omp::directive%> attributes on the"
6762 " same statement to be in the same %<omp::sequence%>");
6765 if (cnt
> 1 && standalone_seen
&& prev_standalone_seen
)
6767 error_at ((*standalone_seen
->tokens
)[0].location
,
6768 "multiple OpenMP standalone directives among"
6769 " %<omp::directive%> attributes must be all within the"
6770 " same %<omp::sequence%>");
6774 if (prev_standalone_seen
)
6775 standalone_seen
= prev_standalone_seen
;
6777 && !c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6779 error_at (standalone_seen
->tokens
->address ()->location
,
6780 "standalone OpenMP directives in %<omp::directive%> attribute"
6781 " can only appear on an empty statement");
6784 if (cnt
&& c_parser_next_token_is (parser
, CPP_PRAGMA
))
6786 c_token
*token
= c_parser_peek_token (parser
);
6787 enum pragma_kind kind
= token
->pragma_kind
;
6788 if (kind
>= PRAGMA_OMP__START_
&& kind
<= PRAGMA_OMP__LAST_
)
6790 error_at (token
->location
,
6791 "mixing OpenMP directives with attribute and pragma "
6792 "syntax on the same statement");
6800 unsigned int tokens_avail
= parser
->tokens_avail
;
6801 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
6804 vec
<c_token
, va_gc
> *toks
= NULL
;
6805 vec_safe_reserve (toks
, tokens
, true);
6806 FOR_EACH_VEC_ELT (vd
, i
, v
)
6810 if (!flag_openmp
&& !v
->dir
->simd
)
6812 c_token
*first
= v
->tokens
->address ();
6813 c_token
*last
= first
+ v
->tokens
->length ();
6815 tok
.type
= CPP_PRAGMA
;
6816 tok
.keyword
= RID_MAX
;
6817 tok
.pragma_kind
= pragma_kind (v
->dir
->id
);
6818 tok
.location
= first
->location
;
6819 toks
->quick_push (tok
);
6820 while (++first
< last
)
6821 toks
->quick_push (*first
);
6823 tok
.type
= CPP_PRAGMA_EOL
;
6824 tok
.keyword
= RID_MAX
;
6825 tok
.location
= last
[-1].location
;
6826 toks
->quick_push (tok
);
6831 tok
.keyword
= RID_MAX
;
6832 tok
.location
= toks
->last ().location
;
6833 tok
.flags
= tokens_avail
;
6834 toks
->quick_push (tok
);
6836 parser
->tokens
= toks
->address ();
6837 parser
->tokens_avail
= tokens
;
6838 parser
->in_omp_attribute_pragma
= toks
;
6842 /* Handle omp::directive and omp::sequence attributes in ATTRS
6843 (if any) at the start or after declaration-id of a declaration. */
6846 c_parser_handle_directive_omp_attributes (tree
&attrs
,
6847 vec
<c_token
> *&pragma_clauses
,
6848 vec
<c_token
> *attr_clauses
)
6850 if (!flag_openmp
&& !flag_openmp_simd
)
6853 for (tree
*pa
= &attrs
; *pa
; )
6854 if (is_attribute_namespace_p ("omp", *pa
)
6855 && is_attribute_p ("directive", get_attribute_name (*pa
)))
6858 for (tree
*pa2
= &TREE_VALUE (*pa
); *pa2
; )
6861 tree d
= TREE_VALUE (a
);
6862 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
6863 vec
<c_token
, va_gc
> *toks
= C_TOKEN_VEC_TOKENS (d
);
6864 c_token
*first
= toks
->address ();
6865 c_token
*last
= first
+ toks
->length ();
6866 const char *directive
[3] = {};
6867 for (int i
= 0; i
< 3; i
++)
6869 tree id
= NULL_TREE
;
6870 if (first
+ i
== last
)
6872 if (first
[i
].type
== CPP_NAME
)
6873 id
= first
[i
].value
;
6874 else if (first
[i
].type
== CPP_KEYWORD
)
6875 id
= ridpointers
[(int) first
[i
].keyword
];
6878 directive
[i
] = IDENTIFIER_POINTER (id
);
6880 const c_omp_directive
*dir
= NULL
;
6882 dir
= c_omp_categorize_directive (directive
[0], directive
[1],
6886 error_at (first
->location
,
6887 "unknown OpenMP directive name in "
6888 "%qs attribute argument",
6889 TREE_PUBLIC (d
) ? "omp::decl" : "omp::directive");
6890 *pa2
= TREE_CHAIN (a
);
6892 else if (dir
->id
== PRAGMA_OMP_DECLARE
6893 && (strcmp (directive
[1], "simd") == 0
6894 || strcmp (directive
[1], "variant") == 0))
6898 error_at (first
->location
,
6899 "mixing OpenMP directives with attribute and "
6900 "pragma syntax on the same declaration");
6901 for (pa
= &attrs
; *pa
; )
6902 if (is_attribute_namespace_p ("omp", *pa
)
6903 && is_attribute_p ("directive",
6904 get_attribute_name (*pa
)))
6905 *pa
= TREE_CHAIN (*pa
);
6907 pa
= &TREE_CHAIN (*pa
);
6911 attr_clauses
->reserve (attr_clauses
->length ()
6912 + toks
->length () + 2);
6913 for (++first
; first
< last
; ++first
)
6914 attr_clauses
->quick_push (*first
);
6916 tok
.type
= CPP_PRAGMA_EOL
;
6917 tok
.keyword
= RID_MAX
;
6918 tok
.location
= last
[-1].location
;
6919 attr_clauses
->quick_push (tok
);
6920 *pa2
= TREE_CHAIN (a
);
6923 pa2
= &TREE_CHAIN (a
);
6925 if (cnt
&& TREE_VALUE (*pa
) == NULL_TREE
)
6926 *pa
= TREE_CHAIN (*pa
);
6928 pa
= &TREE_CHAIN (*pa
);
6931 pa
= &TREE_CHAIN (*pa
);
6932 if (attr_clauses
->length ())
6936 tok
.keyword
= RID_MAX
;
6937 tok
.location
= attr_clauses
->last ().location
;
6938 attr_clauses
->quick_push (tok
);
6939 attr_clauses
->quick_push (tok
);
6940 pragma_clauses
= attr_clauses
;
6944 /* Parse a compound statement except for the opening brace. This is
6945 used for parsing both compound statements and statement expressions
6946 (which follow different paths to handling the opening). */
6949 c_parser_compound_statement_nostart (c_parser
*parser
)
6951 bool last_stmt
= false;
6952 bool last_label
= false;
6953 bool save_valid_for_pragma
= valid_location_for_stdc_pragma_p ();
6954 location_t label_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
6955 struct omp_for_parse_data
*omp_for_parse_state
6956 = parser
->omp_for_parse_state
;
6957 bool in_omp_loop_block
6958 = omp_for_parse_state
? omp_for_parse_state
->want_nested_loop
: false;
6959 tree sl
= NULL_TREE
;
6961 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
6963 location_t endloc
= c_parser_peek_token (parser
)->location
;
6964 add_debug_begin_stmt (endloc
);
6965 c_parser_consume_token (parser
);
6969 /* If we're parsing a {} sequence in an OMP_FOR body, start a
6970 statement list for intervening code. */
6971 if (in_omp_loop_block
)
6972 sl
= push_stmt_list ();
6974 mark_valid_location_for_stdc_pragma (true);
6975 if (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
6977 /* Read zero or more forward-declarations for labels that nested
6978 functions can jump to. */
6979 mark_valid_location_for_stdc_pragma (false);
6980 if (in_omp_loop_block
)
6981 check_omp_intervening_code (parser
);
6982 while (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
6984 label_loc
= c_parser_peek_token (parser
)->location
;
6985 c_parser_consume_token (parser
);
6986 /* Any identifiers, including those declared as type names,
6991 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
6993 c_parser_error (parser
, "expected identifier");
6997 = declare_label (c_parser_peek_token (parser
)->value
);
6998 C_DECLARED_LABEL_FLAG (label
) = 1;
6999 add_stmt (build_stmt (label_loc
, DECL_EXPR
, label
));
7000 c_parser_consume_token (parser
);
7001 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7002 c_parser_consume_token (parser
);
7006 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
7008 pedwarn (label_loc
, OPT_Wpedantic
, "ISO C forbids label declarations");
7010 /* We must now have at least one statement, label or declaration. */
7011 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
7013 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7014 c_parser_error (parser
, "expected declaration or statement");
7015 location_t endloc
= c_parser_peek_token (parser
)->location
;
7016 c_parser_consume_token (parser
);
7019 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_BRACE
))
7021 location_t loc
= c_parser_peek_token (parser
)->location
;
7022 loc
= expansion_point_location_if_in_system_header (loc
);
7024 bool want_nested_loop
= (omp_for_parse_state
7025 ? omp_for_parse_state
->want_nested_loop
7028 /* First take care of special cases for OpenMP "canonical loop
7029 nest form", that do not allow standard attributes, labels, or
7030 __extension__ before the nested statement. */
7031 if (in_omp_loop_block
&& !last_label
)
7033 if (want_nested_loop
7034 && c_parser_next_token_is_keyword (parser
, RID_FOR
))
7036 /* Found the next nested loop. If there were intervening
7037 code statements collected before now, wrap them in an
7038 OMP_STRUCTURED_BLOCK node, and start a new structured
7039 block to hold statements that may come after the FOR. */
7041 add_structured_block_stmt (pop_stmt_list (sl
));
7042 omp_for_parse_state
->depth
++;
7043 add_stmt (c_parser_omp_loop_nest (parser
, NULL
));
7044 omp_for_parse_state
->depth
--;
7045 sl
= push_stmt_list ();
7046 parser
->error
= false;
7049 else if (want_nested_loop
7050 && c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7052 /* If this nested compound statement contains the nested loop,
7053 we need to separate the other statements in the current
7054 statement into separate blocks of intervening code. If
7055 there's no nested loop, it's all part of the same
7056 chunk of intervening code. */
7057 tree pre_sl
= pop_stmt_list (sl
);
7058 tree nested_sl
= push_stmt_list ();
7059 mark_valid_location_for_stdc_pragma (false);
7060 c_parser_statement_after_labels (parser
, NULL
);
7061 nested_sl
= pop_stmt_list (nested_sl
);
7062 if (omp_for_parse_state
->want_nested_loop
)
7064 /* This block didn't contain a loop-nest, so it's
7065 all part of the same chunk of intervening code. */
7066 check_omp_intervening_code (parser
);
7067 sl
= push_stmt_list ();
7069 add_stmt (nested_sl
);
7073 /* It contains the nested loop. */
7074 add_structured_block_stmt (pre_sl
);
7075 add_stmt (nested_sl
);
7076 sl
= push_stmt_list ();
7078 parser
->error
= false;
7081 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7083 /* Prior to implementing the OpenMP 5.1 syntax for canonical
7084 loop form, GCC used to accept an empty statements that
7085 would now be flagged as intervening code. Continue to
7086 do that, as an extension. */
7087 /* FIXME: Maybe issue a warning or something here? */
7088 c_parser_consume_token (parser
);
7093 /* Standard attributes may start a label, statement or declaration. */
7095 = c_parser_nth_token_starts_std_attributes (parser
, 1);
7096 tree std_attrs
= NULL_TREE
;
7098 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
7099 if (c_parser_next_token_is_keyword (parser
, RID_CASE
)
7100 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
7101 || (c_parser_next_token_is (parser
, CPP_NAME
)
7102 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
7104 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
7105 label_loc
= c_parser_peek_2nd_token (parser
)->location
;
7107 label_loc
= c_parser_peek_token (parser
)->location
;
7110 mark_valid_location_for_stdc_pragma (false);
7111 if (in_omp_loop_block
)
7112 check_omp_intervening_code (parser
);
7113 c_parser_label (parser
, std_attrs
);
7115 else if (c_parser_next_tokens_start_declaration (parser
)
7117 && !c_parser_handle_statement_omp_attributes
7118 (parser
, std_attrs
, &have_std_attrs
)
7119 && c_parser_next_token_is (parser
, CPP_SEMICOLON
)
7120 && (have_std_attrs
= true)))
7123 pedwarn_c11 (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
7124 "a label can only be part of a statement and "
7125 "a declaration is not a statement");
7126 /* It's unlikely we'll see a nested loop in a declaration in
7127 intervening code in an OMP loop, but disallow it anyway. */
7128 if (in_omp_loop_block
)
7130 check_omp_intervening_code (parser
);
7131 omp_for_parse_state
->want_nested_loop
= false;
7133 mark_valid_location_for_stdc_pragma (false);
7134 bool fallthru_attr_p
= false;
7135 c_parser_declaration_or_fndef (parser
, true, !have_std_attrs
,
7136 true, true, true, NULL
,
7137 NULL
, have_std_attrs
, std_attrs
,
7138 NULL
, &fallthru_attr_p
);
7140 if (in_omp_loop_block
)
7141 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7142 if (last_stmt
&& !fallthru_attr_p
)
7143 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
7144 "ISO C90 forbids mixed declarations and code");
7145 last_stmt
= fallthru_attr_p
;
7148 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
7150 /* __extension__ can start a declaration, but is also an
7151 unary operator that can start an expression. Consume all
7152 but the last of a possible series of __extension__ to
7153 determine which. If standard attributes have already
7154 been seen, it must start a statement, not a declaration,
7155 but standard attributes starting a declaration may appear
7156 after __extension__. */
7157 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
7158 && (c_parser_peek_2nd_token (parser
)->keyword
7160 c_parser_consume_token (parser
);
7162 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
7163 || c_parser_nth_token_starts_std_attributes (parser
, 2)))
7166 ext
= disable_extension_diagnostics ();
7167 c_parser_consume_token (parser
);
7169 /* It's unlikely we'll see a nested loop in a declaration in
7170 intervening code in an OMP loop, but disallow it anyway. */
7171 if (in_omp_loop_block
)
7173 check_omp_intervening_code (parser
);
7174 omp_for_parse_state
->want_nested_loop
= false;
7176 mark_valid_location_for_stdc_pragma (false);
7177 c_parser_declaration_or_fndef (parser
, true, true, true, true,
7179 if (in_omp_loop_block
)
7180 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7181 /* Following the old parser, __extension__ does not
7182 disable this diagnostic. */
7183 restore_extension_diagnostics (ext
);
7185 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
7186 "ISO C90 forbids mixed declarations and code");
7192 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
7194 if (have_std_attrs
&& !parser
->in_omp_attribute_pragma
)
7195 c_parser_error (parser
, "expected declaration or statement");
7197 c_warn_unused_attributes (std_attrs
);
7198 /* External pragmas, and some omp pragmas, are not associated
7199 with regular c code, and so are not to be considered statements
7200 syntactically. This ensures that the user doesn't put them
7201 places that would turn into syntax errors if the directive
7203 if (omp_for_parse_state
)
7204 omp_for_parse_state
->want_nested_loop
= false;
7205 if (c_parser_pragma (parser
,
7206 last_label
? pragma_stmt
: pragma_compound
,
7211 if (omp_for_parse_state
)
7212 check_omp_intervening_code (parser
);
7214 if (omp_for_parse_state
)
7215 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7217 else if (c_parser_next_token_is (parser
, CPP_EOF
))
7219 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7220 c_parser_error (parser
, "expected declaration or statement");
7221 return c_parser_peek_token (parser
)->location
;
7223 else if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
7225 if (parser
->in_if_block
)
7227 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7228 error_at (loc
, "expected %<}%> before %<else%>");
7229 return c_parser_peek_token (parser
)->location
;
7233 error_at (loc
, "%<else%> without a previous %<if%>");
7234 c_parser_consume_token (parser
);
7241 c_warn_unused_attributes (std_attrs
);
7244 mark_valid_location_for_stdc_pragma (false);
7245 if (!omp_for_parse_state
)
7246 c_parser_statement_after_labels (parser
, NULL
);
7249 /* In canonical loop nest form, nested loops can only appear
7250 directly, or in a directly nested compound statement. We
7251 already took care of those cases above, so now we have
7252 something else. This statement and everything inside
7253 it must be intervening code. */
7254 omp_for_parse_state
->want_nested_loop
= false;
7255 check_omp_intervening_code (parser
);
7256 c_parser_statement_after_labels (parser
, NULL
);
7257 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7261 parser
->error
= false;
7264 pedwarn_c11 (label_loc
, OPT_Wpedantic
, "label at end of compound statement");
7265 location_t endloc
= c_parser_peek_token (parser
)->location
;
7266 c_parser_consume_token (parser
);
7268 /* Restore the value we started with. */
7269 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7271 /* Package leftover intervening code, or the whole contents of the
7272 compound statement if we were looking for a nested loop in an OMP_FOR
7273 construct and didn't find one. */
7276 sl
= pop_stmt_list (sl
);
7277 if (omp_for_parse_state
->want_nested_loop
)
7280 add_structured_block_stmt (sl
);
7285 /* Parse all consecutive labels, possibly preceded by standard
7286 attributes. In this context, a statement is required, not a
7287 declaration, so attributes must be followed by a statement that is
7288 not just a semicolon. */
7291 c_parser_all_labels (c_parser
*parser
)
7293 bool have_std_attrs
;
7294 tree std_attrs
= NULL
;
7295 if ((have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1)))
7296 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
7297 while (c_parser_next_token_is_keyword (parser
, RID_CASE
)
7298 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
7299 || (c_parser_next_token_is (parser
, CPP_NAME
)
7300 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
7302 c_parser_label (parser
, std_attrs
);
7304 if ((have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
,
7306 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
7309 && (!c_parser_handle_statement_omp_attributes (parser
, std_attrs
, &have_std_attrs
)
7312 if (have_std_attrs
&& c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7313 c_parser_error (parser
, "expected statement");
7314 c_warn_unused_attributes (std_attrs
);
7316 else if (have_std_attrs
&& c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7317 c_parser_error (parser
, "expected statement");
7320 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
7323 identifier : gnu-attributes[opt]
7324 case constant-expression :
7330 case constant-expression ... constant-expression :
7332 The use of gnu-attributes on labels is a GNU extension. The syntax in
7333 GNU C accepts any expressions without commas, non-constant
7334 expressions being rejected later. Any standard
7335 attribute-specifier-sequence before the first label has been parsed
7336 in the caller, to distinguish statements from declarations. Any
7337 attribute-specifier-sequence after the label is parsed in this
7340 c_parser_label (c_parser
*parser
, tree std_attrs
)
7342 location_t loc1
= c_parser_peek_token (parser
)->location
;
7343 tree label
= NULL_TREE
;
7345 /* Remember whether this case or a user-defined label is allowed to fall
7347 bool fallthrough_p
= c_parser_peek_token (parser
)->flags
& PREV_FALLTHROUGH
;
7349 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
7352 c_parser_consume_token (parser
);
7353 exp1
= convert_lvalue_to_rvalue (loc1
,
7354 c_parser_expr_no_commas (parser
, NULL
),
7356 if (c_parser_next_token_is (parser
, CPP_COLON
))
7358 c_parser_consume_token (parser
);
7359 label
= do_case (loc1
, exp1
, NULL_TREE
, std_attrs
);
7361 else if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
7363 c_parser_consume_token (parser
);
7364 exp2
= convert_lvalue_to_rvalue (loc1
,
7365 c_parser_expr_no_commas (parser
,
7368 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7369 label
= do_case (loc1
, exp1
, exp2
, std_attrs
);
7372 c_parser_error (parser
, "expected %<:%> or %<...%>");
7374 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
7376 c_parser_consume_token (parser
);
7377 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7378 label
= do_case (loc1
, NULL_TREE
, NULL_TREE
, std_attrs
);
7382 tree name
= c_parser_peek_token (parser
)->value
;
7385 location_t loc2
= c_parser_peek_token (parser
)->location
;
7386 gcc_assert (c_parser_next_token_is (parser
, CPP_NAME
));
7387 c_parser_consume_token (parser
);
7388 gcc_assert (c_parser_next_token_is (parser
, CPP_COLON
));
7389 c_parser_consume_token (parser
);
7390 attrs
= c_parser_gnu_attributes (parser
);
7391 tlab
= define_label (loc2
, name
);
7394 decl_attributes (&tlab
, attrs
, 0);
7395 decl_attributes (&tlab
, std_attrs
, 0);
7396 label
= add_stmt (build_stmt (loc1
, LABEL_EXPR
, tlab
));
7399 && c_parser_next_tokens_start_declaration (parser
))
7400 warning_at (loc2
, OPT_Wattributes
, "GNU-style attribute between"
7401 " label and declaration appertains to the label");
7405 if (TREE_CODE (label
) == LABEL_EXPR
)
7406 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label
)) = fallthrough_p
;
7408 FALLTHROUGH_LABEL_P (CASE_LABEL (label
)) = fallthrough_p
;
7412 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
7416 attribute-specifier-sequence[opt] compound-statement
7417 expression-statement
7418 attribute-specifier-sequence[opt] selection-statement
7419 attribute-specifier-sequence[opt] iteration-statement
7420 attribute-specifier-sequence[opt] jump-statement
7423 attribute-specifier-sequence[opt] label statement
7425 expression-statement:
7427 attribute-specifier-sequence expression ;
7429 selection-statement:
7433 iteration-statement:
7442 return expression[opt] ;
7447 attribute-specifier-sequence[opt] asm-statement
7452 expression-statement:
7458 attribute-specifier-sequence[opt] objc-throw-statement
7459 attribute-specifier-sequence[opt] objc-try-catch-statement
7460 attribute-specifier-sequence[opt] objc-synchronized-statement
7462 objc-throw-statement:
7469 attribute-specifier-sequence[opt] openacc-construct
7478 parallel-directive structured-block
7481 kernels-directive structured-block
7484 data-directive structured-block
7487 loop-directive structured-block
7492 attribute-specifier-sequence[opt] openmp-construct
7501 parallel-for-construct
7502 parallel-for-simd-construct
7503 parallel-sections-construct
7510 parallel-directive structured-block
7513 for-directive iteration-statement
7516 simd-directive iteration-statements
7519 for-simd-directive iteration-statements
7522 sections-directive section-scope
7525 single-directive structured-block
7527 parallel-for-construct:
7528 parallel-for-directive iteration-statement
7530 parallel-for-simd-construct:
7531 parallel-for-simd-directive iteration-statement
7533 parallel-sections-construct:
7534 parallel-sections-directive section-scope
7537 master-directive structured-block
7540 critical-directive structured-block
7543 atomic-directive expression-statement
7546 ordered-directive structured-block
7548 Transactional Memory:
7551 attribute-specifier-sequence[opt] transaction-statement
7552 attribute-specifier-sequence[opt] transaction-cancel-statement
7554 IF_P is used to track whether there's a (possibly labeled) if statement
7555 which is not enclosed in braces and has an else clause. This is used to
7556 implement -Wparentheses. */
7559 c_parser_statement (c_parser
*parser
, bool *if_p
, location_t
*loc_after_labels
)
7561 c_parser_all_labels (parser
);
7562 if (loc_after_labels
)
7563 *loc_after_labels
= c_parser_peek_token (parser
)->location
;
7564 parser
->omp_attrs_forbidden_p
= false;
7565 c_parser_statement_after_labels (parser
, if_p
, NULL
);
7568 /* Parse a statement, other than a labeled statement. CHAIN is a vector
7569 of if-else-if conditions. All labels and standard attributes have
7570 been parsed in the caller.
7572 IF_P is used to track whether there's a (possibly labeled) if statement
7573 which is not enclosed in braces and has an else clause. This is used to
7574 implement -Wparentheses. */
7577 c_parser_statement_after_labels (c_parser
*parser
, bool *if_p
,
7580 location_t loc
= c_parser_peek_token (parser
)->location
;
7581 tree stmt
= NULL_TREE
;
7582 bool in_if_block
= parser
->in_if_block
;
7583 parser
->in_if_block
= false;
7587 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_BRACE
)
7588 add_debug_begin_stmt (loc
);
7591 switch (c_parser_peek_token (parser
)->type
)
7593 case CPP_OPEN_BRACE
:
7594 add_stmt (c_parser_compound_statement (parser
));
7597 switch (c_parser_peek_token (parser
)->keyword
)
7600 c_parser_if_statement (parser
, if_p
, chain
);
7603 c_parser_switch_statement (parser
, if_p
);
7606 c_parser_while_statement (parser
, false, 0, false, if_p
);
7609 c_parser_do_statement (parser
, false, 0, false);
7612 c_parser_for_statement (parser
, false, 0, false, if_p
);
7615 c_parser_consume_token (parser
);
7616 if (c_parser_next_token_is (parser
, CPP_NAME
))
7618 stmt
= c_finish_goto_label (loc
,
7619 c_parser_peek_token (parser
)->value
);
7620 c_parser_consume_token (parser
);
7622 else if (c_parser_next_token_is (parser
, CPP_MULT
))
7626 c_parser_consume_token (parser
);
7627 val
= c_parser_expression (parser
);
7628 val
= convert_lvalue_to_rvalue (loc
, val
, false, true);
7629 stmt
= c_finish_goto_ptr (loc
, val
);
7632 c_parser_error (parser
, "expected identifier or %<*%>");
7633 goto expect_semicolon
;
7635 c_parser_consume_token (parser
);
7636 stmt
= c_finish_bc_stmt (loc
, objc_foreach_continue_label
, false);
7637 goto expect_semicolon
;
7639 c_parser_consume_token (parser
);
7640 stmt
= c_finish_bc_stmt (loc
, objc_foreach_break_label
, true);
7641 goto expect_semicolon
;
7643 c_parser_consume_token (parser
);
7644 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7646 stmt
= c_finish_return (loc
, NULL_TREE
, NULL_TREE
);
7647 c_parser_consume_token (parser
);
7651 location_t xloc
= c_parser_peek_token (parser
)->location
;
7652 struct c_expr expr
= c_parser_expression_conv (parser
);
7653 mark_exp_read (expr
.value
);
7654 stmt
= c_finish_return (EXPR_LOC_OR_LOC (expr
.value
, xloc
),
7655 expr
.value
, expr
.original_type
);
7656 goto expect_semicolon
;
7660 stmt
= c_parser_asm_statement (parser
);
7662 case RID_TRANSACTION_ATOMIC
:
7663 case RID_TRANSACTION_RELAXED
:
7664 stmt
= c_parser_transaction (parser
,
7665 c_parser_peek_token (parser
)->keyword
);
7667 case RID_TRANSACTION_CANCEL
:
7668 stmt
= c_parser_transaction_cancel (parser
);
7669 goto expect_semicolon
;
7671 gcc_assert (c_dialect_objc ());
7672 c_parser_consume_token (parser
);
7673 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7675 stmt
= objc_build_throw_stmt (loc
, NULL_TREE
);
7676 c_parser_consume_token (parser
);
7680 struct c_expr expr
= c_parser_expression (parser
);
7681 expr
= convert_lvalue_to_rvalue (loc
, expr
, false, false);
7682 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
7683 stmt
= objc_build_throw_stmt (loc
, expr
.value
);
7684 goto expect_semicolon
;
7688 gcc_assert (c_dialect_objc ());
7689 c_parser_objc_try_catch_finally_statement (parser
);
7691 case RID_AT_SYNCHRONIZED
:
7692 gcc_assert (c_dialect_objc ());
7693 c_parser_objc_synchronized_statement (parser
);
7697 /* Allow '__attribute__((fallthrough));' or
7698 '__attribute__((assume(cond)));'. */
7699 tree attrs
= c_parser_gnu_attributes (parser
);
7700 bool has_assume
= lookup_attribute ("assume", attrs
);
7703 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7704 attrs
= handle_assume_attribute (loc
, attrs
, true);
7707 warning_at (loc
, OPT_Wattributes
,
7708 "%<assume%> attribute not followed by %<;%>");
7712 if (attribute_fallthrough_p (attrs
))
7714 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7716 tree fn
= build_call_expr_internal_loc (loc
,
7721 c_parser_consume_token (parser
);
7724 warning_at (loc
, OPT_Wattributes
,
7725 "%<fallthrough%> attribute not followed "
7728 else if (has_assume
)
7730 c_parser_consume_token (parser
);
7731 else if (attrs
!= NULL_TREE
)
7732 warning_at (loc
, OPT_Wattributes
,
7733 "only attribute %<fallthrough%> or %<assume%> can "
7734 "be applied to a null statement");
7742 c_parser_consume_token (parser
);
7744 case CPP_CLOSE_PAREN
:
7745 case CPP_CLOSE_SQUARE
:
7746 /* Avoid infinite loop in error recovery:
7747 c_parser_skip_until_found stops at a closing nesting
7748 delimiter without consuming it, but here we need to consume
7749 it to proceed further. */
7750 c_parser_error (parser
, "expected statement");
7751 c_parser_consume_token (parser
);
7754 if (!c_parser_pragma (parser
, pragma_stmt
, if_p
))
7759 stmt
= c_finish_expr_stmt (loc
, c_parser_expression_conv (parser
).value
);
7761 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
7764 /* Two cases cannot and do not have line numbers associated: If stmt
7765 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
7766 cannot hold line numbers. But that's OK because the statement
7767 will either be changed to a MODIFY_EXPR during gimplification of
7768 the statement expr, or discarded. If stmt was compound, but
7769 without new variables, we will have skipped the creation of a
7770 BIND and will have a bare STATEMENT_LIST. But that's OK because
7771 (recursively) all of the component statements should already have
7772 line numbers assigned. ??? Can we discard no-op statements
7774 if (EXPR_LOCATION (stmt
) == UNKNOWN_LOCATION
)
7775 protected_set_expr_location (stmt
, loc
);
7777 parser
->in_if_block
= in_if_block
;
7780 /* Parse the condition from an if, do, while or for statements. */
7783 c_parser_condition (c_parser
*parser
)
7785 location_t loc
= c_parser_peek_token (parser
)->location
;
7787 cond
= c_parser_expression_conv (parser
).value
;
7788 cond
= c_objc_common_truthvalue_conversion (loc
, cond
);
7789 cond
= c_fully_fold (cond
, false, NULL
);
7790 if (warn_sequence_point
)
7791 verify_sequence_points (cond
);
7795 /* Parse a parenthesized condition from an if, do or while statement.
7801 c_parser_paren_condition (c_parser
*parser
)
7804 matching_parens parens
;
7805 if (!parens
.require_open (parser
))
7806 return error_mark_node
;
7807 cond
= c_parser_condition (parser
);
7808 parens
.skip_until_found_close (parser
);
7812 /* Parse a statement which is a block in C99.
7814 IF_P is used to track whether there's a (possibly labeled) if statement
7815 which is not enclosed in braces and has an else clause. This is used to
7816 implement -Wparentheses. */
7819 c_parser_c99_block_statement (c_parser
*parser
, bool *if_p
,
7820 location_t
*loc_after_labels
)
7822 tree block
= c_begin_compound_stmt (flag_isoc99
);
7823 location_t loc
= c_parser_peek_token (parser
)->location
;
7824 c_parser_statement (parser
, if_p
, loc_after_labels
);
7825 return c_end_compound_stmt (loc
, block
, flag_isoc99
);
7828 /* Parse the body of an if statement. This is just parsing a
7829 statement but (a) it is a block in C99, (b) we track whether the
7830 body is an if statement for the sake of -Wparentheses warnings, (c)
7831 we handle an empty body specially for the sake of -Wempty-body
7832 warnings, and (d) we call parser_compound_statement directly
7833 because c_parser_statement_after_labels resets
7834 parser->in_if_block.
7836 IF_P is used to track whether there's a (possibly labeled) if statement
7837 which is not enclosed in braces and has an else clause. This is used to
7838 implement -Wparentheses. */
7841 c_parser_if_body (c_parser
*parser
, bool *if_p
,
7842 const token_indent_info
&if_tinfo
)
7844 tree block
= c_begin_compound_stmt (flag_isoc99
);
7845 location_t body_loc
= c_parser_peek_token (parser
)->location
;
7846 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
7847 token_indent_info body_tinfo
7848 = get_token_indent_info (c_parser_peek_token (parser
));
7850 c_parser_all_labels (parser
);
7851 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7853 location_t loc
= c_parser_peek_token (parser
)->location
;
7854 add_stmt (build_empty_stmt (loc
));
7855 c_parser_consume_token (parser
);
7856 if (!c_parser_next_token_is_keyword (parser
, RID_ELSE
))
7857 warning_at (loc
, OPT_Wempty_body
,
7858 "suggest braces around empty body in an %<if%> statement");
7860 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7861 add_stmt (c_parser_compound_statement (parser
));
7864 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
7865 c_parser_statement_after_labels (parser
, if_p
);
7868 token_indent_info next_tinfo
7869 = get_token_indent_info (c_parser_peek_token (parser
));
7870 warn_for_misleading_indentation (if_tinfo
, body_tinfo
, next_tinfo
);
7871 if (body_loc_after_labels
!= UNKNOWN_LOCATION
7872 && next_tinfo
.type
!= CPP_SEMICOLON
)
7873 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
7874 if_tinfo
.location
, RID_IF
);
7876 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
7879 /* Parse the else body of an if statement. This is just parsing a
7880 statement but (a) it is a block in C99, (b) we handle an empty body
7881 specially for the sake of -Wempty-body warnings. CHAIN is a vector
7882 of if-else-if conditions. */
7885 c_parser_else_body (c_parser
*parser
, const token_indent_info
&else_tinfo
,
7888 location_t body_loc
= c_parser_peek_token (parser
)->location
;
7889 tree block
= c_begin_compound_stmt (flag_isoc99
);
7890 token_indent_info body_tinfo
7891 = get_token_indent_info (c_parser_peek_token (parser
));
7892 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
7894 c_parser_all_labels (parser
);
7895 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7897 location_t loc
= c_parser_peek_token (parser
)->location
;
7900 "suggest braces around empty body in an %<else%> statement");
7901 add_stmt (build_empty_stmt (loc
));
7902 c_parser_consume_token (parser
);
7906 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7907 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
7908 c_parser_statement_after_labels (parser
, NULL
, chain
);
7911 token_indent_info next_tinfo
7912 = get_token_indent_info (c_parser_peek_token (parser
));
7913 warn_for_misleading_indentation (else_tinfo
, body_tinfo
, next_tinfo
);
7914 if (body_loc_after_labels
!= UNKNOWN_LOCATION
7915 && next_tinfo
.type
!= CPP_SEMICOLON
)
7916 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
7917 else_tinfo
.location
, RID_ELSE
);
7919 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
7922 /* We might need to reclassify any previously-lexed identifier, e.g.
7923 when we've left a for loop with an if-statement without else in the
7924 body - we might have used a wrong scope for the token. See PR67784. */
7927 c_parser_maybe_reclassify_token (c_parser
*parser
)
7929 if (c_parser_next_token_is (parser
, CPP_NAME
))
7931 c_token
*token
= c_parser_peek_token (parser
);
7933 if (token
->id_kind
!= C_ID_CLASSNAME
)
7935 tree decl
= lookup_name (token
->value
);
7937 token
->id_kind
= C_ID_ID
;
7940 if (TREE_CODE (decl
) == TYPE_DECL
)
7941 token
->id_kind
= C_ID_TYPENAME
;
7943 else if (c_dialect_objc ())
7945 tree objc_interface_decl
= objc_is_class_name (token
->value
);
7946 /* Objective-C class names are in the same namespace as
7947 variables and typedefs, and hence are shadowed by local
7949 if (objc_interface_decl
)
7951 token
->value
= objc_interface_decl
;
7952 token
->id_kind
= C_ID_CLASSNAME
;
7959 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
7962 if ( expression ) statement
7963 if ( expression ) statement else statement
7965 CHAIN is a vector of if-else-if conditions.
7966 IF_P is used to track whether there's a (possibly labeled) if statement
7967 which is not enclosed in braces and has an else clause. This is used to
7968 implement -Wparentheses. */
7971 c_parser_if_statement (c_parser
*parser
, bool *if_p
, vec
<tree
> *chain
)
7976 bool nested_if
= false;
7977 tree first_body
, second_body
;
7980 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_IF
));
7981 token_indent_info if_tinfo
7982 = get_token_indent_info (c_parser_peek_token (parser
));
7983 c_parser_consume_token (parser
);
7984 block
= c_begin_compound_stmt (flag_isoc99
);
7985 loc
= c_parser_peek_token (parser
)->location
;
7986 cond
= c_parser_paren_condition (parser
);
7987 in_if_block
= parser
->in_if_block
;
7988 parser
->in_if_block
= true;
7989 first_body
= c_parser_if_body (parser
, &nested_if
, if_tinfo
);
7990 parser
->in_if_block
= in_if_block
;
7992 if (warn_duplicated_cond
)
7993 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond
), cond
, &chain
);
7995 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
7997 token_indent_info else_tinfo
7998 = get_token_indent_info (c_parser_peek_token (parser
));
7999 c_parser_consume_token (parser
);
8000 if (warn_duplicated_cond
)
8002 if (c_parser_next_token_is_keyword (parser
, RID_IF
)
8005 /* We've got "if (COND) else if (COND2)". Start the
8006 condition chain and add COND as the first element. */
8007 chain
= new vec
<tree
> ();
8008 if (!CONSTANT_CLASS_P (cond
) && !TREE_SIDE_EFFECTS (cond
))
8009 chain
->safe_push (cond
);
8011 else if (!c_parser_next_token_is_keyword (parser
, RID_IF
))
8012 /* This is if-else without subsequent if. Zap the condition
8013 chain; we would have already warned at this point. */
8016 second_body
= c_parser_else_body (parser
, else_tinfo
, chain
);
8017 /* Set IF_P to true to indicate that this if statement has an
8018 else clause. This may trigger the Wparentheses warning
8019 below when we get back up to the parent if statement. */
8025 second_body
= NULL_TREE
;
8027 /* Diagnose an ambiguous else if if-then-else is nested inside
8030 warning_at (loc
, OPT_Wdangling_else
,
8031 "suggest explicit braces to avoid ambiguous %<else%>");
8033 if (warn_duplicated_cond
)
8034 /* This if statement does not have an else clause. We don't
8035 need the condition chain anymore. */
8038 c_finish_if_stmt (loc
, cond
, first_body
, second_body
);
8039 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
8041 c_parser_maybe_reclassify_token (parser
);
8044 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
8047 switch (expression) statement
8051 c_parser_switch_statement (c_parser
*parser
, bool *if_p
)
8054 tree block
, expr
, body
;
8055 unsigned char save_in_statement
;
8056 location_t switch_loc
= c_parser_peek_token (parser
)->location
;
8057 location_t switch_cond_loc
;
8058 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SWITCH
));
8059 c_parser_consume_token (parser
);
8060 block
= c_begin_compound_stmt (flag_isoc99
);
8061 bool explicit_cast_p
= false;
8062 matching_parens parens
;
8063 if (parens
.require_open (parser
))
8065 switch_cond_loc
= c_parser_peek_token (parser
)->location
;
8066 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8067 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8068 explicit_cast_p
= true;
8069 ce
= c_parser_expression (parser
);
8070 ce
= convert_lvalue_to_rvalue (switch_cond_loc
, ce
, true, true);
8072 /* ??? expr has no valid location? */
8073 parens
.skip_until_found_close (parser
);
8077 switch_cond_loc
= UNKNOWN_LOCATION
;
8078 expr
= error_mark_node
;
8079 ce
.original_type
= error_mark_node
;
8081 c_start_switch (switch_loc
, switch_cond_loc
, expr
, explicit_cast_p
);
8082 save_in_statement
= in_statement
;
8083 in_statement
|= IN_SWITCH_STMT
;
8084 location_t loc_after_labels
;
8085 bool open_brace_p
= c_parser_peek_token (parser
)->type
== CPP_OPEN_BRACE
;
8086 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
8087 location_t next_loc
= c_parser_peek_token (parser
)->location
;
8088 if (!open_brace_p
&& c_parser_peek_token (parser
)->type
!= CPP_SEMICOLON
)
8089 warn_for_multistatement_macros (loc_after_labels
, next_loc
, switch_loc
,
8091 c_finish_switch (body
, ce
.original_type
);
8092 in_statement
= save_in_statement
;
8093 add_stmt (c_end_compound_stmt (switch_loc
, block
, flag_isoc99
));
8094 c_parser_maybe_reclassify_token (parser
);
8097 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8100 while (expression) statement
8102 IF_P is used to track whether there's a (possibly labeled) if statement
8103 which is not enclosed in braces and has an else clause. This is used to
8104 implement -Wparentheses. */
8107 c_parser_while_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
8108 bool novector
, bool *if_p
)
8110 tree block
, cond
, body
;
8111 unsigned char save_in_statement
;
8113 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_WHILE
));
8114 token_indent_info while_tinfo
8115 = get_token_indent_info (c_parser_peek_token (parser
));
8117 if (parser
->omp_for_parse_state
)
8119 error_at (c_parser_peek_token (parser
)->location
,
8120 "loop not permitted in intervening code in OpenMP loop body");
8121 parser
->omp_for_parse_state
->fail
= true;
8124 c_parser_consume_token (parser
);
8125 block
= c_begin_compound_stmt (flag_isoc99
);
8126 loc
= c_parser_peek_token (parser
)->location
;
8127 cond
= c_parser_paren_condition (parser
);
8128 if (ivdep
&& cond
!= error_mark_node
)
8129 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8130 build_int_cst (integer_type_node
,
8131 annot_expr_ivdep_kind
),
8133 if (unroll
&& cond
!= error_mark_node
)
8134 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8135 build_int_cst (integer_type_node
,
8136 annot_expr_unroll_kind
),
8137 build_int_cst (integer_type_node
, unroll
));
8138 if (novector
&& cond
!= error_mark_node
)
8139 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8140 build_int_cst (integer_type_node
,
8141 annot_expr_no_vector_kind
),
8143 save_in_statement
= in_statement
;
8144 in_statement
= IN_ITERATION_STMT
;
8146 token_indent_info body_tinfo
8147 = get_token_indent_info (c_parser_peek_token (parser
));
8149 location_t loc_after_labels
;
8150 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
8151 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
8152 add_stmt (build_stmt (loc
, WHILE_STMT
, cond
, body
));
8153 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
8154 c_parser_maybe_reclassify_token (parser
);
8156 token_indent_info next_tinfo
8157 = get_token_indent_info (c_parser_peek_token (parser
));
8158 warn_for_misleading_indentation (while_tinfo
, body_tinfo
, next_tinfo
);
8160 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
8161 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
8162 while_tinfo
.location
, RID_WHILE
);
8164 in_statement
= save_in_statement
;
8167 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8170 do statement while ( expression ) ;
8174 c_parser_do_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
8177 tree block
, cond
, body
;
8178 unsigned char save_in_statement
;
8180 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_DO
));
8182 if (parser
->omp_for_parse_state
)
8184 error_at (c_parser_peek_token (parser
)->location
,
8185 "loop not permitted in intervening code in OpenMP loop body");
8186 parser
->omp_for_parse_state
->fail
= true;
8189 c_parser_consume_token (parser
);
8190 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
8191 warning_at (c_parser_peek_token (parser
)->location
,
8193 "suggest braces around empty body in %<do%> statement");
8194 block
= c_begin_compound_stmt (flag_isoc99
);
8195 loc
= c_parser_peek_token (parser
)->location
;
8196 save_in_statement
= in_statement
;
8197 in_statement
= IN_ITERATION_STMT
;
8198 body
= c_parser_c99_block_statement (parser
, NULL
);
8199 c_parser_require_keyword (parser
, RID_WHILE
, "expected %<while%>");
8200 in_statement
= save_in_statement
;
8201 cond
= c_parser_paren_condition (parser
);
8202 if (ivdep
&& cond
!= error_mark_node
)
8203 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8204 build_int_cst (integer_type_node
,
8205 annot_expr_ivdep_kind
),
8207 if (unroll
&& cond
!= error_mark_node
)
8208 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8209 build_int_cst (integer_type_node
,
8210 annot_expr_unroll_kind
),
8211 build_int_cst (integer_type_node
, unroll
));
8212 if (novector
&& cond
!= error_mark_node
)
8213 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8214 build_int_cst (integer_type_node
,
8215 annot_expr_no_vector_kind
),
8217 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
8218 c_parser_skip_to_end_of_block_or_statement (parser
);
8220 add_stmt (build_stmt (loc
, DO_STMT
, cond
, body
));
8221 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
8224 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8227 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
8228 for ( nested-declaration expression[opt] ; expression[opt] ) statement
8230 The form with a declaration is new in C99.
8232 ??? In accordance with the old parser, the declaration may be a
8233 nested function, which is then rejected in check_for_loop_decls,
8234 but does it make any sense for this to be included in the grammar?
8235 Note in particular that the nested function does not include a
8236 trailing ';', whereas the "declaration" production includes one.
8237 Also, can we reject bad declarations earlier and cheaper than
8238 check_for_loop_decls?
8240 In Objective-C, there are two additional variants:
8243 for ( expression in expresssion ) statement
8244 for ( declaration in expression ) statement
8246 This is inconsistent with C, because the second variant is allowed
8247 even if c99 is not enabled.
8249 The rest of the comment documents these Objective-C foreach-statement.
8251 Here is the canonical example of the first variant:
8252 for (object in array) { do something with object }
8253 we call the first expression ("object") the "object_expression" and
8254 the second expression ("array") the "collection_expression".
8255 object_expression must be an lvalue of type "id" (a generic Objective-C
8256 object) because the loop works by assigning to object_expression the
8257 various objects from the collection_expression. collection_expression
8258 must evaluate to something of type "id" which responds to the method
8259 countByEnumeratingWithState:objects:count:.
8261 The canonical example of the second variant is:
8262 for (id object in array) { do something with object }
8263 which is completely equivalent to
8266 for (object in array) { do something with object }
8268 Note that initizializing 'object' in some way (eg, "for ((object =
8269 xxx) in array) { do something with object }") is possibly
8270 technically valid, but completely pointless as 'object' will be
8271 assigned to something else as soon as the loop starts. We should
8272 most likely reject it (TODO).
8274 The beginning of the Objective-C foreach-statement looks exactly
8275 like the beginning of the for-statement, and we can tell it is a
8276 foreach-statement only because the initial declaration or
8277 expression is terminated by 'in' instead of ';'.
8279 IF_P is used to track whether there's a (possibly labeled) if statement
8280 which is not enclosed in braces and has an else clause. This is used to
8281 implement -Wparentheses. */
8284 c_parser_for_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
8285 bool novector
, bool *if_p
)
8287 tree block
, cond
, incr
, body
;
8288 unsigned char save_in_statement
;
8289 tree save_objc_foreach_break_label
, save_objc_foreach_continue_label
;
8290 /* The following are only used when parsing an ObjC foreach statement. */
8291 tree object_expression
;
8292 /* Silence the bogus uninitialized warning. */
8293 tree collection_expression
= NULL
;
8294 location_t loc
= c_parser_peek_token (parser
)->location
;
8295 location_t for_loc
= loc
;
8296 bool is_foreach_statement
= false;
8297 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
8298 token_indent_info for_tinfo
8299 = get_token_indent_info (c_parser_peek_token (parser
));
8301 if (parser
->omp_for_parse_state
)
8304 "loop not permitted in intervening code in OpenMP loop body");
8305 parser
->omp_for_parse_state
->fail
= true;
8308 c_parser_consume_token (parser
);
8309 /* Open a compound statement in Objective-C as well, just in case this is
8310 as foreach expression. */
8311 block
= c_begin_compound_stmt (flag_isoc99
|| c_dialect_objc ());
8312 cond
= error_mark_node
;
8313 incr
= error_mark_node
;
8314 matching_parens parens
;
8315 if (parens
.require_open (parser
))
8317 /* Parse the initialization declaration or expression. */
8318 object_expression
= error_mark_node
;
8319 parser
->objc_could_be_foreach_context
= c_dialect_objc ();
8320 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
8322 parser
->objc_could_be_foreach_context
= false;
8323 c_parser_consume_token (parser
);
8324 c_finish_expr_stmt (loc
, NULL_TREE
);
8326 else if (c_parser_next_tokens_start_declaration (parser
)
8327 || c_parser_nth_token_starts_std_attributes (parser
, 1))
8329 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
8330 &object_expression
);
8331 parser
->objc_could_be_foreach_context
= false;
8333 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
8335 c_parser_consume_token (parser
);
8336 is_foreach_statement
= true;
8337 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
8338 c_parser_error (parser
, "multiple iterating variables in "
8339 "fast enumeration");
8342 check_for_loop_decls (for_loc
, flag_isoc99
);
8344 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
8346 /* __extension__ can start a declaration, but is also an
8347 unary operator that can start an expression. Consume all
8348 but the last of a possible series of __extension__ to
8350 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
8351 && (c_parser_peek_2nd_token (parser
)->keyword
8353 c_parser_consume_token (parser
);
8354 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
8355 || c_parser_nth_token_starts_std_attributes (parser
, 2))
8358 ext
= disable_extension_diagnostics ();
8359 c_parser_consume_token (parser
);
8360 c_parser_declaration_or_fndef (parser
, true, true, true, true,
8361 true, &object_expression
);
8362 parser
->objc_could_be_foreach_context
= false;
8364 restore_extension_diagnostics (ext
);
8365 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
8367 c_parser_consume_token (parser
);
8368 is_foreach_statement
= true;
8369 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
8370 c_parser_error (parser
, "multiple iterating variables in "
8371 "fast enumeration");
8374 check_for_loop_decls (for_loc
, flag_isoc99
);
8384 tree init_expression
;
8385 ce
= c_parser_expression (parser
);
8386 init_expression
= ce
.value
;
8387 parser
->objc_could_be_foreach_context
= false;
8388 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
8390 c_parser_consume_token (parser
);
8391 is_foreach_statement
= true;
8392 if (! lvalue_p (init_expression
))
8393 c_parser_error (parser
, "invalid iterating variable in "
8394 "fast enumeration");
8396 = c_fully_fold (init_expression
, false, NULL
);
8400 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
8401 init_expression
= ce
.value
;
8402 c_finish_expr_stmt (loc
, init_expression
);
8403 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
8408 /* Parse the loop condition. In the case of a foreach
8409 statement, there is no loop condition. */
8410 gcc_assert (!parser
->objc_could_be_foreach_context
);
8411 if (!is_foreach_statement
)
8413 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
8417 c_parser_error (parser
, "missing loop condition in loop "
8418 "with %<GCC ivdep%> pragma");
8419 cond
= error_mark_node
;
8423 c_parser_error (parser
, "missing loop condition in loop "
8424 "with %<GCC unroll%> pragma");
8425 cond
= error_mark_node
;
8429 c_parser_consume_token (parser
);
8435 cond
= c_parser_condition (parser
);
8436 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
8439 if (ivdep
&& cond
!= error_mark_node
)
8440 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8441 build_int_cst (integer_type_node
,
8442 annot_expr_ivdep_kind
),
8444 if (unroll
&& cond
!= error_mark_node
)
8445 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8446 build_int_cst (integer_type_node
,
8447 annot_expr_unroll_kind
),
8448 build_int_cst (integer_type_node
, unroll
));
8449 if (novector
&& cond
&& cond
!= error_mark_node
)
8450 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8451 build_int_cst (integer_type_node
,
8452 annot_expr_no_vector_kind
),
8455 /* Parse the increment expression (the third expression in a
8456 for-statement). In the case of a foreach-statement, this is
8457 the expression that follows the 'in'. */
8458 loc
= c_parser_peek_token (parser
)->location
;
8459 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8461 if (is_foreach_statement
)
8463 c_parser_error (parser
,
8464 "missing collection in fast enumeration");
8465 collection_expression
= error_mark_node
;
8468 incr
= c_process_expr_stmt (loc
, NULL_TREE
);
8472 if (is_foreach_statement
)
8473 collection_expression
8474 = c_fully_fold (c_parser_expression (parser
).value
, false, NULL
);
8477 struct c_expr ce
= c_parser_expression (parser
);
8478 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
8479 incr
= c_process_expr_stmt (loc
, ce
.value
);
8482 parens
.skip_until_found_close (parser
);
8484 save_in_statement
= in_statement
;
8485 if (is_foreach_statement
)
8487 in_statement
= IN_OBJC_FOREACH
;
8488 save_objc_foreach_break_label
= objc_foreach_break_label
;
8489 save_objc_foreach_continue_label
= objc_foreach_continue_label
;
8490 objc_foreach_break_label
= create_artificial_label (loc
);
8491 objc_foreach_continue_label
= create_artificial_label (loc
);
8494 in_statement
= IN_ITERATION_STMT
;
8496 token_indent_info body_tinfo
8497 = get_token_indent_info (c_parser_peek_token (parser
));
8499 location_t loc_after_labels
;
8500 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
8501 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
8503 if (is_foreach_statement
)
8504 objc_finish_foreach_loop (for_loc
, object_expression
,
8505 collection_expression
, body
,
8506 objc_foreach_break_label
,
8507 objc_foreach_continue_label
);
8509 add_stmt (build_stmt (for_loc
, FOR_STMT
, NULL_TREE
, cond
, incr
,
8511 add_stmt (c_end_compound_stmt (for_loc
, block
,
8512 flag_isoc99
|| c_dialect_objc ()));
8513 c_parser_maybe_reclassify_token (parser
);
8515 token_indent_info next_tinfo
8516 = get_token_indent_info (c_parser_peek_token (parser
));
8517 warn_for_misleading_indentation (for_tinfo
, body_tinfo
, next_tinfo
);
8519 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
8520 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
8521 for_tinfo
.location
, RID_FOR
);
8523 in_statement
= save_in_statement
;
8524 if (is_foreach_statement
)
8526 objc_foreach_break_label
= save_objc_foreach_break_label
;
8527 objc_foreach_continue_label
= save_objc_foreach_continue_label
;
8531 /* Parse an asm statement, a GNU extension. This is a full-blown asm
8532 statement with inputs, outputs, clobbers, and volatile, inline, and goto
8541 asm-qualifier-list asm-qualifier
8545 asm asm-qualifier-list[opt] ( asm-argument ) ;
8549 asm-string-literal : asm-operands[opt]
8550 asm-string-literal : asm-operands[opt] : asm-operands[opt]
8551 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
8553 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
8556 The form with asm-goto-operands is valid if and only if the
8557 asm-qualifier-list contains goto, and is the only allowed form in that case.
8558 Duplicate asm-qualifiers are not allowed.
8560 The :: token is considered equivalent to two consecutive : tokens. */
8563 c_parser_asm_statement (c_parser
*parser
)
8565 tree str
, outputs
, inputs
, clobbers
, labels
, ret
;
8567 location_t asm_loc
= c_parser_peek_token (parser
)->location
;
8568 int section
, nsections
;
8570 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
8571 c_parser_consume_token (parser
);
8573 /* Handle the asm-qualifier-list. */
8574 location_t volatile_loc
= UNKNOWN_LOCATION
;
8575 location_t inline_loc
= UNKNOWN_LOCATION
;
8576 location_t goto_loc
= UNKNOWN_LOCATION
;
8579 c_token
*token
= c_parser_peek_token (parser
);
8580 location_t loc
= token
->location
;
8581 switch (token
->keyword
)
8586 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
8587 inform (volatile_loc
, "first seen here");
8591 c_parser_consume_token (parser
);
8597 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
8598 inform (inline_loc
, "first seen here");
8602 c_parser_consume_token (parser
);
8608 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
8609 inform (goto_loc
, "first seen here");
8613 c_parser_consume_token (parser
);
8618 error_at (loc
, "%qE is not a valid %<asm%> qualifier", token
->value
);
8619 c_parser_consume_token (parser
);
8628 bool is_volatile
= (volatile_loc
!= UNKNOWN_LOCATION
);
8629 bool is_inline
= (inline_loc
!= UNKNOWN_LOCATION
);
8630 bool is_goto
= (goto_loc
!= UNKNOWN_LOCATION
);
8634 matching_parens parens
;
8635 if (!parens
.require_open (parser
))
8638 str
= c_parser_asm_string_literal (parser
);
8639 if (str
== NULL_TREE
)
8640 goto error_close_paren
;
8643 outputs
= NULL_TREE
;
8645 clobbers
= NULL_TREE
;
8648 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
8651 /* Parse each colon-delimited section of operands. */
8652 nsections
= 3 + is_goto
;
8653 for (section
= 0; section
< nsections
; ++section
)
8655 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
8658 if (section
== nsections
)
8660 c_parser_error (parser
, "expected %<)%>");
8661 goto error_close_paren
;
8663 c_parser_consume_token (parser
);
8665 else if (!c_parser_require (parser
, CPP_COLON
,
8667 ? G_("expected %<:%>")
8668 : G_("expected %<:%> or %<)%>"),
8669 UNKNOWN_LOCATION
, is_goto
))
8670 goto error_close_paren
;
8672 /* Once past any colon, we're no longer a simple asm. */
8675 if ((!c_parser_next_token_is (parser
, CPP_COLON
)
8676 && !c_parser_next_token_is (parser
, CPP_SCOPE
)
8677 && !c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8682 outputs
= c_parser_asm_operands (parser
);
8685 inputs
= c_parser_asm_operands (parser
);
8688 clobbers
= c_parser_asm_clobbers (parser
);
8691 labels
= c_parser_asm_goto_operands (parser
);
8697 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
8702 if (!parens
.require_close (parser
))
8704 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8708 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
8709 c_parser_skip_to_end_of_block_or_statement (parser
);
8711 ret
= build_asm_stmt (is_volatile
,
8712 build_asm_expr (asm_loc
, str
, outputs
, inputs
,
8713 clobbers
, labels
, simple
, is_inline
));
8719 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8723 /* Parse asm operands, a GNU extension.
8727 asm-operands , asm-operand
8730 asm-string-literal ( expression )
8731 [ identifier ] asm-string-literal ( expression )
8735 c_parser_asm_operands (c_parser
*parser
)
8737 tree list
= NULL_TREE
;
8742 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
8744 c_parser_consume_token (parser
);
8745 if (c_parser_next_token_is (parser
, CPP_NAME
))
8747 tree id
= c_parser_peek_token (parser
)->value
;
8748 c_parser_consume_token (parser
);
8749 name
= build_string (IDENTIFIER_LENGTH (id
),
8750 IDENTIFIER_POINTER (id
));
8754 c_parser_error (parser
, "expected identifier");
8755 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
8758 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
8763 str
= c_parser_asm_string_literal (parser
);
8764 if (str
== NULL_TREE
)
8766 matching_parens parens
;
8767 if (!parens
.require_open (parser
))
8769 expr
= c_parser_expression (parser
);
8770 mark_exp_read (expr
.value
);
8771 if (!parens
.require_close (parser
))
8773 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8776 list
= chainon (list
, build_tree_list (build_tree_list (name
, str
),
8778 if (c_parser_next_token_is (parser
, CPP_COMMA
))
8779 c_parser_consume_token (parser
);
8786 /* Parse asm clobbers, a GNU extension.
8790 asm-clobbers , asm-string-literal
8794 c_parser_asm_clobbers (c_parser
*parser
)
8796 tree list
= NULL_TREE
;
8799 tree str
= c_parser_asm_string_literal (parser
);
8801 list
= tree_cons (NULL_TREE
, str
, list
);
8804 if (c_parser_next_token_is (parser
, CPP_COMMA
))
8805 c_parser_consume_token (parser
);
8812 /* Parse asm goto labels, a GNU extension.
8816 asm-goto-operands , identifier
8820 c_parser_asm_goto_operands (c_parser
*parser
)
8822 tree list
= NULL_TREE
;
8827 if (c_parser_next_token_is (parser
, CPP_NAME
))
8829 c_token
*tok
= c_parser_peek_token (parser
);
8831 label
= lookup_label_for_goto (tok
->location
, name
);
8832 c_parser_consume_token (parser
);
8833 TREE_USED (label
) = 1;
8837 c_parser_error (parser
, "expected identifier");
8841 name
= build_string (IDENTIFIER_LENGTH (name
),
8842 IDENTIFIER_POINTER (name
));
8843 list
= tree_cons (name
, label
, list
);
8844 if (c_parser_next_token_is (parser
, CPP_COMMA
))
8845 c_parser_consume_token (parser
);
8847 return nreverse (list
);
8851 /* Parse a possibly concatenated sequence of string literals.
8852 TRANSLATE says whether to translate them to the execution character
8853 set; WIDE_OK says whether any kind of prefixed string literal is
8854 permitted in this context. This code is based on that in
8858 c_parser_string_literal (c_parser
*parser
, bool translate
, bool wide_ok
)
8862 struct obstack str_ob
;
8863 struct obstack loc_ob
;
8864 cpp_string str
, istr
, *strs
;
8866 location_t loc
, last_tok_loc
;
8867 enum cpp_ttype type
;
8868 tree value
, string_tree
;
8870 tok
= c_parser_peek_token (parser
);
8871 loc
= tok
->location
;
8872 last_tok_loc
= linemap_resolve_location (line_table
, loc
,
8873 LRK_MACRO_DEFINITION_LOCATION
,
8882 case CPP_UTF8STRING
:
8883 string_tree
= tok
->value
;
8887 c_parser_error (parser
, "expected string literal");
8889 ret
.value
= NULL_TREE
;
8890 ret
.original_code
= ERROR_MARK
;
8891 ret
.original_type
= NULL_TREE
;
8895 /* Try to avoid the overhead of creating and destroying an obstack
8896 for the common case of just one string. */
8897 switch (c_parser_peek_2nd_token (parser
)->type
)
8900 c_parser_consume_token (parser
);
8901 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
8902 str
.len
= TREE_STRING_LENGTH (string_tree
);
8911 case CPP_UTF8STRING
:
8912 gcc_obstack_init (&str_ob
);
8913 gcc_obstack_init (&loc_ob
);
8917 c_parser_consume_token (parser
);
8919 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
8920 str
.len
= TREE_STRING_LENGTH (string_tree
);
8921 if (type
!= tok
->type
)
8923 if (type
== CPP_STRING
)
8925 else if (tok
->type
!= CPP_STRING
)
8926 error ("unsupported non-standard concatenation "
8927 "of string literals");
8929 obstack_grow (&str_ob
, &str
, sizeof (cpp_string
));
8930 obstack_grow (&loc_ob
, &last_tok_loc
, sizeof (location_t
));
8931 tok
= c_parser_peek_token (parser
);
8932 string_tree
= tok
->value
;
8934 = linemap_resolve_location (line_table
, tok
->location
,
8935 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
8937 while (tok
->type
== CPP_STRING
8938 || tok
->type
== CPP_WSTRING
8939 || tok
->type
== CPP_STRING16
8940 || tok
->type
== CPP_STRING32
8941 || tok
->type
== CPP_UTF8STRING
);
8942 strs
= (cpp_string
*) obstack_finish (&str_ob
);
8945 if (count
> 1 && !in_system_header_at (input_location
))
8946 warning (OPT_Wtraditional
,
8947 "traditional C rejects string constant concatenation");
8949 if ((type
== CPP_STRING
|| wide_ok
)
8951 ? cpp_interpret_string
: cpp_interpret_string_notranslate
)
8952 (parse_in
, strs
, count
, &istr
, type
)))
8954 value
= build_string (istr
.len
, (const char *) istr
.text
);
8955 free (CONST_CAST (unsigned char *, istr
.text
));
8958 location_t
*locs
= (location_t
*) obstack_finish (&loc_ob
);
8959 gcc_assert (g_string_concat_db
);
8960 g_string_concat_db
->record_string_concatenation (count
, locs
);
8965 if (type
!= CPP_STRING
&& !wide_ok
)
8967 error_at (loc
, "a wide string is invalid in this context");
8970 /* Callers cannot generally handle error_mark_node in this
8971 context, so return the empty string instead. An error has
8972 been issued, either above or from cpp_interpret_string. */
8977 case CPP_UTF8STRING
:
8978 if (type
== CPP_UTF8STRING
&& flag_char8_t
)
8980 value
= build_string (TYPE_PRECISION (char8_type_node
)
8981 / TYPE_PRECISION (char_type_node
),
8982 ""); /* char8_t is 8 bits */
8985 value
= build_string (1, "");
8988 value
= build_string (TYPE_PRECISION (char16_type_node
)
8989 / TYPE_PRECISION (char_type_node
),
8990 "\0"); /* char16_t is 16 bits */
8993 value
= build_string (TYPE_PRECISION (char32_type_node
)
8994 / TYPE_PRECISION (char_type_node
),
8995 "\0\0\0"); /* char32_t is 32 bits */
8998 value
= build_string (TYPE_PRECISION (wchar_type_node
)
8999 / TYPE_PRECISION (char_type_node
),
9000 "\0\0\0"); /* widest supported wchar_t
9010 TREE_TYPE (value
) = char_array_type_node
;
9012 case CPP_UTF8STRING
:
9014 TREE_TYPE (value
) = char8_array_type_node
;
9016 TREE_TYPE (value
) = char_array_type_node
;
9019 TREE_TYPE (value
) = char16_array_type_node
;
9022 TREE_TYPE (value
) = char32_array_type_node
;
9025 TREE_TYPE (value
) = wchar_array_type_node
;
9027 value
= fix_string_type (value
);
9031 obstack_free (&str_ob
, 0);
9032 obstack_free (&loc_ob
, 0);
9036 ret
.original_code
= STRING_CST
;
9037 ret
.original_type
= NULL_TREE
;
9038 set_c_expr_source_range (&ret
, get_range_from_loc (line_table
, loc
));
9040 parser
->seen_string_literal
= true;
9044 /* Parse an expression other than a compound expression; that is, an
9045 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
9046 AFTER is not NULL then it is an Objective-C message expression which
9047 is the primary-expression starting the expression as an initializer.
9049 assignment-expression:
9050 conditional-expression
9051 unary-expression assignment-operator assignment-expression
9053 assignment-operator: one of
9054 = *= /= %= += -= <<= >>= &= ^= |=
9056 In GNU C we accept any conditional expression on the LHS and
9057 diagnose the invalid lvalue rather than producing a syntax
9060 static struct c_expr
9061 c_parser_expr_no_commas (c_parser
*parser
, struct c_expr
*after
,
9062 tree omp_atomic_lhs
)
9064 struct c_expr lhs
, rhs
, ret
;
9065 enum tree_code code
;
9066 location_t op_location
, exp_location
;
9067 bool save_in_omp_for
= c_in_omp_for
;
9068 c_in_omp_for
= false;
9069 gcc_assert (!after
|| c_dialect_objc ());
9070 lhs
= c_parser_conditional_expression (parser
, after
, omp_atomic_lhs
);
9071 op_location
= c_parser_peek_token (parser
)->location
;
9072 switch (c_parser_peek_token (parser
)->type
)
9081 code
= TRUNC_DIV_EXPR
;
9084 code
= TRUNC_MOD_EXPR
;
9099 code
= BIT_AND_EXPR
;
9102 code
= BIT_XOR_EXPR
;
9105 code
= BIT_IOR_EXPR
;
9108 c_in_omp_for
= save_in_omp_for
;
9111 c_parser_consume_token (parser
);
9112 exp_location
= c_parser_peek_token (parser
)->location
;
9113 rhs
= c_parser_expr_no_commas (parser
, NULL
);
9114 rhs
= convert_lvalue_to_rvalue (exp_location
, rhs
, true, true);
9116 ret
.value
= build_modify_expr (op_location
, lhs
.value
, lhs
.original_type
,
9117 code
, exp_location
, rhs
.value
,
9120 set_c_expr_source_range (&ret
, lhs
.get_start (), rhs
.get_finish ());
9121 if (code
== NOP_EXPR
)
9122 ret
.original_code
= MODIFY_EXPR
;
9125 suppress_warning (ret
.value
, OPT_Wparentheses
);
9126 ret
.original_code
= ERROR_MARK
;
9128 ret
.original_type
= NULL
;
9129 c_in_omp_for
= save_in_omp_for
;
9133 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
9134 AFTER is not NULL then it is an Objective-C message expression which is
9135 the primary-expression starting the expression as an initializer.
9137 conditional-expression:
9138 logical-OR-expression
9139 logical-OR-expression ? expression : conditional-expression
9143 conditional-expression:
9144 logical-OR-expression ? : conditional-expression
9147 static struct c_expr
9148 c_parser_conditional_expression (c_parser
*parser
, struct c_expr
*after
,
9149 tree omp_atomic_lhs
)
9151 struct c_expr cond
, exp1
, exp2
, ret
;
9152 location_t start
, cond_loc
, colon_loc
;
9153 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
9155 gcc_assert (!after
|| c_dialect_objc ());
9157 cond
= c_parser_binary_expression (parser
, after
, omp_atomic_lhs
);
9159 if (c_parser_next_token_is_not (parser
, CPP_QUERY
))
9161 c_omp_array_section_p
= false;
9162 if (cond
.value
!= error_mark_node
)
9163 start
= cond
.get_start ();
9165 start
= UNKNOWN_LOCATION
;
9166 cond_loc
= c_parser_peek_token (parser
)->location
;
9167 cond
= convert_lvalue_to_rvalue (cond_loc
, cond
, true, true);
9168 c_parser_consume_token (parser
);
9169 if (c_parser_next_token_is (parser
, CPP_COLON
))
9171 tree eptype
= NULL_TREE
;
9173 location_t middle_loc
= c_parser_peek_token (parser
)->location
;
9174 pedwarn (middle_loc
, OPT_Wpedantic
,
9175 "ISO C forbids omitting the middle term of a %<?:%> expression");
9176 if (TREE_CODE (cond
.value
) == EXCESS_PRECISION_EXPR
)
9178 eptype
= TREE_TYPE (cond
.value
);
9179 cond
.value
= TREE_OPERAND (cond
.value
, 0);
9181 tree e
= cond
.value
;
9182 while (TREE_CODE (e
) == COMPOUND_EXPR
)
9183 e
= TREE_OPERAND (e
, 1);
9184 warn_for_omitted_condop (middle_loc
, e
);
9185 /* Make sure first operand is calculated only once. */
9186 exp1
.value
= save_expr (default_conversion (cond
.value
));
9188 exp1
.value
= build1 (EXCESS_PRECISION_EXPR
, eptype
, exp1
.value
);
9189 exp1
.original_type
= NULL
;
9190 exp1
.src_range
= cond
.src_range
;
9191 cond
.value
= c_objc_common_truthvalue_conversion (cond_loc
, exp1
.value
);
9192 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_true_node
;
9197 = c_objc_common_truthvalue_conversion
9198 (cond_loc
, default_conversion (cond
.value
));
9199 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_false_node
;
9200 exp1
= c_parser_expression_conv (parser
);
9201 mark_exp_read (exp1
.value
);
9202 c_inhibit_evaluation_warnings
+=
9203 ((cond
.value
== truthvalue_true_node
)
9204 - (cond
.value
== truthvalue_false_node
));
9207 colon_loc
= c_parser_peek_token (parser
)->location
;
9208 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
9210 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
9212 ret
.original_code
= ERROR_MARK
;
9213 ret
.original_type
= NULL
;
9214 c_omp_array_section_p
= save_c_omp_array_section_p
;
9218 location_t exp2_loc
= c_parser_peek_token (parser
)->location
;
9219 exp2
= c_parser_conditional_expression (parser
, NULL
, NULL_TREE
);
9220 exp2
= convert_lvalue_to_rvalue (exp2_loc
, exp2
, true, true);
9222 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
9223 location_t loc1
= make_location (exp1
.get_start (), exp1
.src_range
);
9224 location_t loc2
= make_location (exp2
.get_start (), exp2
.src_range
);
9225 if (UNLIKELY (omp_atomic_lhs
!= NULL
)
9226 && (TREE_CODE (cond
.value
) == GT_EXPR
9227 || TREE_CODE (cond
.value
) == LT_EXPR
9228 || TREE_CODE (cond
.value
) == EQ_EXPR
)
9229 && c_tree_equal (exp2
.value
, omp_atomic_lhs
)
9230 && (c_tree_equal (TREE_OPERAND (cond
.value
, 0), omp_atomic_lhs
)
9231 || c_tree_equal (TREE_OPERAND (cond
.value
, 1), omp_atomic_lhs
)))
9232 ret
.value
= build3_loc (colon_loc
, COND_EXPR
, TREE_TYPE (omp_atomic_lhs
),
9233 cond
.value
, exp1
.value
, exp2
.value
);
9236 = build_conditional_expr (colon_loc
, cond
.value
,
9237 cond
.original_code
== C_MAYBE_CONST_EXPR
,
9238 exp1
.value
, exp1
.original_type
, loc1
,
9239 exp2
.value
, exp2
.original_type
, loc2
);
9240 ret
.original_code
= ERROR_MARK
;
9241 if (exp1
.value
== error_mark_node
|| exp2
.value
== error_mark_node
)
9242 ret
.original_type
= NULL
;
9247 /* If both sides are enum type, the default conversion will have
9248 made the type of the result be an integer type. We want to
9249 remember the enum types we started with. */
9250 t1
= exp1
.original_type
? exp1
.original_type
: TREE_TYPE (exp1
.value
);
9251 t2
= exp2
.original_type
? exp2
.original_type
: TREE_TYPE (exp2
.value
);
9252 ret
.original_type
= ((t1
!= error_mark_node
9253 && t2
!= error_mark_node
9254 && (TYPE_MAIN_VARIANT (t1
)
9255 == TYPE_MAIN_VARIANT (t2
)))
9259 set_c_expr_source_range (&ret
, start
, exp2
.get_finish ());
9261 c_omp_array_section_p
= save_c_omp_array_section_p
;
9265 /* Parse a binary expression; that is, a logical-OR-expression (C90
9266 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
9267 NULL then it is an Objective-C message expression which is the
9268 primary-expression starting the expression as an initializer.
9270 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
9271 when it should be the unfolded lhs. In a valid OpenMP source,
9272 one of the operands of the toplevel binary expression must be equal
9273 to it. In that case, just return a build2 created binary operation
9274 rather than result of parser_build_binary_op.
9276 multiplicative-expression:
9278 multiplicative-expression * cast-expression
9279 multiplicative-expression / cast-expression
9280 multiplicative-expression % cast-expression
9282 additive-expression:
9283 multiplicative-expression
9284 additive-expression + multiplicative-expression
9285 additive-expression - multiplicative-expression
9289 shift-expression << additive-expression
9290 shift-expression >> additive-expression
9292 relational-expression:
9294 relational-expression < shift-expression
9295 relational-expression > shift-expression
9296 relational-expression <= shift-expression
9297 relational-expression >= shift-expression
9299 equality-expression:
9300 relational-expression
9301 equality-expression == relational-expression
9302 equality-expression != relational-expression
9306 AND-expression & equality-expression
9308 exclusive-OR-expression:
9310 exclusive-OR-expression ^ AND-expression
9312 inclusive-OR-expression:
9313 exclusive-OR-expression
9314 inclusive-OR-expression | exclusive-OR-expression
9316 logical-AND-expression:
9317 inclusive-OR-expression
9318 logical-AND-expression && inclusive-OR-expression
9320 logical-OR-expression:
9321 logical-AND-expression
9322 logical-OR-expression || logical-AND-expression
9325 static struct c_expr
9326 c_parser_binary_expression (c_parser
*parser
, struct c_expr
*after
,
9327 tree omp_atomic_lhs
)
9329 /* A binary expression is parsed using operator-precedence parsing,
9330 with the operands being cast expressions. All the binary
9331 operators are left-associative. Thus a binary expression is of
9334 E0 op1 E1 op2 E2 ...
9336 which we represent on a stack. On the stack, the precedence
9337 levels are strictly increasing. When a new operator is
9338 encountered of higher precedence than that at the top of the
9339 stack, it is pushed; its LHS is the top expression, and its RHS
9340 is everything parsed until it is popped. When a new operator is
9341 encountered with precedence less than or equal to that at the top
9342 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
9343 by the result of the operation until the operator at the top of
9344 the stack has lower precedence than the new operator or there is
9345 only one element on the stack; then the top expression is the LHS
9346 of the new operator. In the case of logical AND and OR
9347 expressions, we also need to adjust c_inhibit_evaluation_warnings
9348 as appropriate when the operators are pushed and popped. */
9351 /* The expression at this stack level. */
9353 /* The precedence of the operator on its left, PREC_NONE at the
9354 bottom of the stack. */
9355 enum c_parser_prec prec
;
9356 /* The operation on its left. */
9358 /* The source location of this operation. */
9360 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
9364 /* Location of the binary operator. */
9365 location_t binary_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
9368 switch (stack[sp].op) \
9370 case TRUTH_ANDIF_EXPR: \
9371 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9372 == truthvalue_false_node); \
9374 case TRUTH_ORIF_EXPR: \
9375 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9376 == truthvalue_true_node); \
9378 case TRUNC_DIV_EXPR: \
9379 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
9380 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
9381 && (stack[sp].expr.original_code == SIZEOF_EXPR \
9382 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
9384 tree type0 = stack[sp - 1].sizeof_arg; \
9385 tree type1 = stack[sp].sizeof_arg; \
9386 tree first_arg = type0; \
9387 if (!TYPE_P (type0)) \
9388 type0 = TREE_TYPE (type0); \
9389 if (!TYPE_P (type1)) \
9390 type1 = TREE_TYPE (type1); \
9391 if (POINTER_TYPE_P (type0) \
9392 && comptypes (TREE_TYPE (type0), type1) \
9393 && !(TREE_CODE (first_arg) == PARM_DECL \
9394 && C_ARRAY_PARAMETER (first_arg) \
9395 && warn_sizeof_array_argument)) \
9397 auto_diagnostic_group d; \
9398 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
9399 "division %<sizeof (%T) / sizeof (%T)%> " \
9400 "does not compute the number of array " \
9403 if (DECL_P (first_arg)) \
9404 inform (DECL_SOURCE_LOCATION (first_arg), \
9405 "first %<sizeof%> operand was declared here"); \
9407 else if (TREE_CODE (type0) == ARRAY_TYPE \
9408 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
9409 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
9410 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
9411 stack[sp].sizeof_arg, type1); \
9417 stack[sp - 1].expr \
9418 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
9419 stack[sp - 1].expr, true, true); \
9421 = convert_lvalue_to_rvalue (stack[sp].loc, \
9422 stack[sp].expr, true, true); \
9423 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
9424 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
9425 && ((1 << stack[sp].prec) \
9426 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
9427 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
9428 | (1 << PREC_ADD) | (1 << PREC_MULT) \
9429 | (1 << PREC_EQ)))) \
9430 || ((c_parser_next_token_is (parser, CPP_QUERY) \
9431 || (omp_atomic_lhs == void_list_node \
9432 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
9433 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
9434 && stack[sp].op != TRUNC_MOD_EXPR \
9435 && stack[sp].op != GE_EXPR \
9436 && stack[sp].op != LE_EXPR \
9437 && stack[sp].op != NE_EXPR \
9438 && stack[0].expr.value != error_mark_node \
9439 && stack[1].expr.value != error_mark_node \
9440 && (omp_atomic_lhs == void_list_node \
9441 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
9442 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
9443 || (stack[sp].op == EQ_EXPR \
9444 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
9446 tree t = make_node (stack[1].op); \
9447 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
9448 TREE_OPERAND (t, 0) = stack[0].expr.value; \
9449 TREE_OPERAND (t, 1) = stack[1].expr.value; \
9450 stack[0].expr.value = t; \
9451 stack[0].expr.m_decimal = 0; \
9454 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
9456 stack[sp - 1].expr, \
9460 gcc_assert (!after
|| c_dialect_objc ());
9461 stack
[0].loc
= c_parser_peek_token (parser
)->location
;
9462 stack
[0].expr
= c_parser_cast_expression (parser
, after
);
9463 stack
[0].prec
= PREC_NONE
;
9464 stack
[0].sizeof_arg
= c_last_sizeof_arg
;
9468 enum c_parser_prec oprec
;
9469 enum tree_code ocode
;
9470 source_range src_range
;
9473 switch (c_parser_peek_token (parser
)->type
)
9481 ocode
= TRUNC_DIV_EXPR
;
9485 ocode
= TRUNC_MOD_EXPR
;
9497 ocode
= LSHIFT_EXPR
;
9501 ocode
= RSHIFT_EXPR
;
9515 case CPP_GREATER_EQ
:
9528 oprec
= PREC_BITAND
;
9529 ocode
= BIT_AND_EXPR
;
9532 oprec
= PREC_BITXOR
;
9533 ocode
= BIT_XOR_EXPR
;
9537 ocode
= BIT_IOR_EXPR
;
9540 oprec
= PREC_LOGAND
;
9541 ocode
= TRUTH_ANDIF_EXPR
;
9545 ocode
= TRUTH_ORIF_EXPR
;
9548 /* Not a binary operator, so end of the binary
9552 binary_loc
= c_parser_peek_token (parser
)->location
;
9553 while (oprec
<= stack
[sp
].prec
)
9555 c_parser_consume_token (parser
);
9558 case TRUTH_ANDIF_EXPR
:
9559 src_range
= stack
[sp
].expr
.src_range
;
9561 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
9562 stack
[sp
].expr
, true, true);
9563 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
9564 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
9565 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
9566 == truthvalue_false_node
);
9567 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
9569 case TRUTH_ORIF_EXPR
:
9570 src_range
= stack
[sp
].expr
.src_range
;
9572 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
9573 stack
[sp
].expr
, true, true);
9574 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
9575 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
9576 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
9577 == truthvalue_true_node
);
9578 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
9584 stack
[sp
].loc
= binary_loc
;
9585 stack
[sp
].expr
= c_parser_cast_expression (parser
, NULL
);
9586 stack
[sp
].prec
= oprec
;
9587 stack
[sp
].op
= ocode
;
9588 stack
[sp
].sizeof_arg
= c_last_sizeof_arg
;
9593 return stack
[0].expr
;
9597 /* Parse any storage class specifiers after an open parenthesis in a
9598 context where a compound literal is permitted. */
9600 static struct c_declspecs
*
9601 c_parser_compound_literal_scspecs (c_parser
*parser
)
9603 bool seen_scspec
= false;
9604 struct c_declspecs
*specs
= build_null_declspecs ();
9605 while (c_parser_next_token_is (parser
, CPP_KEYWORD
))
9607 switch (c_parser_peek_token (parser
)->keyword
)
9614 declspecs_add_scspec (c_parser_peek_token (parser
)->location
,
9615 specs
, c_parser_peek_token (parser
)->value
);
9616 c_parser_consume_token (parser
);
9623 return seen_scspec
? specs
: NULL
;
9626 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
9627 is not NULL then it is an Objective-C message expression which is the
9628 primary-expression starting the expression as an initializer.
9632 ( type-name ) unary-expression
9635 static struct c_expr
9636 c_parser_cast_expression (c_parser
*parser
, struct c_expr
*after
)
9638 location_t cast_loc
= c_parser_peek_token (parser
)->location
;
9639 gcc_assert (!after
|| c_dialect_objc ());
9641 return c_parser_postfix_expression_after_primary (parser
,
9643 /* If the expression begins with a parenthesized type name, it may
9644 be either a cast or a compound literal; we need to see whether
9645 the next character is '{' to tell the difference. If not, it is
9646 an unary expression. Full detection of unknown typenames here
9647 would require a 3-token lookahead. */
9648 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
9649 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
9651 struct c_declspecs
*scspecs
;
9652 struct c_type_name
*type_name
;
9655 matching_parens parens
;
9656 parens
.consume_open (parser
);
9657 scspecs
= c_parser_compound_literal_scspecs (parser
);
9658 type_name
= c_parser_type_name (parser
, true);
9659 parens
.skip_until_found_close (parser
);
9660 if (type_name
== NULL
)
9663 ret
.original_code
= ERROR_MARK
;
9664 ret
.original_type
= NULL
;
9668 /* Save casted types in the function's used types hash table. */
9669 used_types_insert (type_name
->specs
->type
);
9671 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
9672 return c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
9676 error_at (cast_loc
, "storage class specifier in cast");
9677 if (type_name
->specs
->alignas_p
)
9678 error_at (type_name
->specs
->locations
[cdw_alignas
],
9679 "alignment specified for type name in cast");
9681 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
9682 expr
= c_parser_cast_expression (parser
, NULL
);
9683 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
9685 ret
.value
= c_cast_expr (cast_loc
, type_name
, expr
.value
);
9686 if (ret
.value
&& expr
.value
)
9687 set_c_expr_source_range (&ret
, cast_loc
, expr
.get_finish ());
9688 ret
.original_code
= ERROR_MARK
;
9689 ret
.original_type
= NULL
;
9694 return c_parser_unary_expression (parser
);
9697 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
9703 unary-operator cast-expression
9704 sizeof unary-expression
9705 sizeof ( type-name )
9707 unary-operator: one of
9713 __alignof__ unary-expression
9714 __alignof__ ( type-name )
9717 (C11 permits _Alignof with type names only.)
9719 unary-operator: one of
9720 __extension__ __real__ __imag__
9722 Transactional Memory:
9725 transaction-expression
9727 In addition, the GNU syntax treats ++ and -- as unary operators, so
9728 they may be applied to cast expressions with errors for non-lvalues
9731 static struct c_expr
9732 c_parser_unary_expression (c_parser
*parser
)
9735 struct c_expr ret
, op
;
9736 location_t op_loc
= c_parser_peek_token (parser
)->location
;
9739 ret
.original_code
= ERROR_MARK
;
9740 ret
.original_type
= NULL
;
9741 switch (c_parser_peek_token (parser
)->type
)
9744 c_parser_consume_token (parser
);
9745 exp_loc
= c_parser_peek_token (parser
)->location
;
9746 op
= c_parser_cast_expression (parser
, NULL
);
9748 op
= default_function_array_read_conversion (exp_loc
, op
);
9749 return parser_build_unary_op (op_loc
, PREINCREMENT_EXPR
, op
);
9750 case CPP_MINUS_MINUS
:
9751 c_parser_consume_token (parser
);
9752 exp_loc
= c_parser_peek_token (parser
)->location
;
9753 op
= c_parser_cast_expression (parser
, NULL
);
9755 op
= default_function_array_read_conversion (exp_loc
, op
);
9756 return parser_build_unary_op (op_loc
, PREDECREMENT_EXPR
, op
);
9758 c_parser_consume_token (parser
);
9759 op
= c_parser_cast_expression (parser
, NULL
);
9760 mark_exp_read (op
.value
);
9761 return parser_build_unary_op (op_loc
, ADDR_EXPR
, op
);
9764 c_parser_consume_token (parser
);
9765 exp_loc
= c_parser_peek_token (parser
)->location
;
9766 op
= c_parser_cast_expression (parser
, NULL
);
9767 finish
= op
.get_finish ();
9768 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9769 location_t combined_loc
= make_location (op_loc
, op_loc
, finish
);
9770 ret
.value
= build_indirect_ref (combined_loc
, op
.value
, RO_UNARY_STAR
);
9771 ret
.src_range
.m_start
= op_loc
;
9772 ret
.src_range
.m_finish
= finish
;
9777 if (!c_dialect_objc () && !in_system_header_at (input_location
))
9780 "traditional C rejects the unary plus operator");
9781 c_parser_consume_token (parser
);
9782 exp_loc
= c_parser_peek_token (parser
)->location
;
9783 op
= c_parser_cast_expression (parser
, NULL
);
9784 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9785 return parser_build_unary_op (op_loc
, CONVERT_EXPR
, op
);
9787 c_parser_consume_token (parser
);
9788 exp_loc
= c_parser_peek_token (parser
)->location
;
9789 op
= c_parser_cast_expression (parser
, NULL
);
9790 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9791 return parser_build_unary_op (op_loc
, NEGATE_EXPR
, op
);
9793 c_parser_consume_token (parser
);
9794 exp_loc
= c_parser_peek_token (parser
)->location
;
9795 op
= c_parser_cast_expression (parser
, NULL
);
9796 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9797 return parser_build_unary_op (op_loc
, BIT_NOT_EXPR
, op
);
9799 c_parser_consume_token (parser
);
9800 exp_loc
= c_parser_peek_token (parser
)->location
;
9801 op
= c_parser_cast_expression (parser
, NULL
);
9802 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9803 return parser_build_unary_op (op_loc
, TRUTH_NOT_EXPR
, op
);
9805 /* Refer to the address of a label as a pointer. */
9806 c_parser_consume_token (parser
);
9807 if (c_parser_next_token_is (parser
, CPP_NAME
))
9809 ret
.value
= finish_label_address_expr
9810 (c_parser_peek_token (parser
)->value
, op_loc
);
9811 set_c_expr_source_range (&ret
, op_loc
,
9812 c_parser_peek_token (parser
)->get_finish ());
9813 c_parser_consume_token (parser
);
9817 c_parser_error (parser
, "expected identifier");
9822 switch (c_parser_peek_token (parser
)->keyword
)
9825 return c_parser_sizeof_expression (parser
);
9827 return c_parser_alignof_expression (parser
);
9828 case RID_BUILTIN_HAS_ATTRIBUTE
:
9829 return c_parser_has_attribute_expression (parser
);
9831 c_parser_consume_token (parser
);
9832 ext
= disable_extension_diagnostics ();
9833 ret
= c_parser_cast_expression (parser
, NULL
);
9834 restore_extension_diagnostics (ext
);
9837 c_parser_consume_token (parser
);
9838 exp_loc
= c_parser_peek_token (parser
)->location
;
9839 op
= c_parser_cast_expression (parser
, NULL
);
9840 op
= default_function_array_conversion (exp_loc
, op
);
9841 return parser_build_unary_op (op_loc
, REALPART_EXPR
, op
);
9843 c_parser_consume_token (parser
);
9844 exp_loc
= c_parser_peek_token (parser
)->location
;
9845 op
= c_parser_cast_expression (parser
, NULL
);
9846 op
= default_function_array_conversion (exp_loc
, op
);
9847 return parser_build_unary_op (op_loc
, IMAGPART_EXPR
, op
);
9848 case RID_TRANSACTION_ATOMIC
:
9849 case RID_TRANSACTION_RELAXED
:
9850 return c_parser_transaction_expression (parser
,
9851 c_parser_peek_token (parser
)->keyword
);
9853 return c_parser_postfix_expression (parser
);
9856 return c_parser_postfix_expression (parser
);
9860 /* Parse a sizeof expression. */
9862 static struct c_expr
9863 c_parser_sizeof_expression (c_parser
*parser
)
9866 struct c_expr result
;
9867 location_t expr_loc
;
9868 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SIZEOF
));
9871 location_t finish
= UNKNOWN_LOCATION
;
9873 start
= c_parser_peek_token (parser
)->location
;
9875 c_parser_consume_token (parser
);
9876 c_inhibit_evaluation_warnings
++;
9878 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
9879 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
9881 /* Either sizeof ( type-name ) or sizeof unary-expression
9882 starting with a compound literal. */
9883 struct c_declspecs
*scspecs
;
9884 struct c_type_name
*type_name
;
9885 matching_parens parens
;
9886 parens
.consume_open (parser
);
9887 expr_loc
= c_parser_peek_token (parser
)->location
;
9888 scspecs
= c_parser_compound_literal_scspecs (parser
);
9889 type_name
= c_parser_type_name (parser
, true);
9890 parens
.skip_until_found_close (parser
);
9891 finish
= parser
->tokens_buf
[0].location
;
9892 if (type_name
== NULL
)
9895 c_inhibit_evaluation_warnings
--;
9898 ret
.original_code
= ERROR_MARK
;
9899 ret
.original_type
= NULL
;
9902 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
9904 expr
= c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
9907 finish
= expr
.get_finish ();
9910 /* sizeof ( type-name ). */
9912 error_at (expr_loc
, "storage class specifier in %<sizeof%>");
9913 if (type_name
->specs
->alignas_p
)
9914 error_at (type_name
->specs
->locations
[cdw_alignas
],
9915 "alignment specified for type name in %<sizeof%>");
9916 c_inhibit_evaluation_warnings
--;
9918 result
= c_expr_sizeof_type (expr_loc
, type_name
);
9922 expr_loc
= c_parser_peek_token (parser
)->location
;
9923 expr
= c_parser_unary_expression (parser
);
9924 finish
= expr
.get_finish ();
9926 c_inhibit_evaluation_warnings
--;
9928 mark_exp_read (expr
.value
);
9929 if (TREE_CODE (expr
.value
) == COMPONENT_REF
9930 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
9931 error_at (expr_loc
, "%<sizeof%> applied to a bit-field");
9932 result
= c_expr_sizeof_expr (expr_loc
, expr
);
9934 if (finish
== UNKNOWN_LOCATION
)
9936 set_c_expr_source_range (&result
, start
, finish
);
9940 /* Parse an alignof expression. */
9942 static struct c_expr
9943 c_parser_alignof_expression (c_parser
*parser
)
9946 location_t start_loc
= c_parser_peek_token (parser
)->location
;
9948 tree alignof_spelling
= c_parser_peek_token (parser
)->value
;
9949 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNOF
));
9950 bool is_c11_alignof
= (strcmp (IDENTIFIER_POINTER (alignof_spelling
),
9952 || strcmp (IDENTIFIER_POINTER (alignof_spelling
),
9954 /* A diagnostic is not required for the use of this identifier in
9955 the implementation namespace; only diagnose it for the C11 or C23
9956 spelling because of existing code using the other spellings. */
9960 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C99 does not support %qE",
9963 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C90 does not support %qE",
9966 c_parser_consume_token (parser
);
9967 c_inhibit_evaluation_warnings
++;
9969 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
9970 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
9972 /* Either __alignof__ ( type-name ) or __alignof__
9973 unary-expression starting with a compound literal. */
9975 struct c_declspecs
*scspecs
;
9976 struct c_type_name
*type_name
;
9978 matching_parens parens
;
9979 parens
.consume_open (parser
);
9980 loc
= c_parser_peek_token (parser
)->location
;
9981 scspecs
= c_parser_compound_literal_scspecs (parser
);
9982 type_name
= c_parser_type_name (parser
, true);
9983 end_loc
= c_parser_peek_token (parser
)->location
;
9984 parens
.skip_until_found_close (parser
);
9985 if (type_name
== NULL
)
9988 c_inhibit_evaluation_warnings
--;
9991 ret
.original_code
= ERROR_MARK
;
9992 ret
.original_type
= NULL
;
9995 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
9997 expr
= c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
10002 /* alignof ( type-name ). */
10004 error_at (loc
, "storage class specifier in %qE", alignof_spelling
);
10005 if (type_name
->specs
->alignas_p
)
10006 error_at (type_name
->specs
->locations
[cdw_alignas
],
10007 "alignment specified for type name in %qE",
10009 c_inhibit_evaluation_warnings
--;
10011 ret
.value
= c_sizeof_or_alignof_type (loc
, groktypename (type_name
,
10013 false, is_c11_alignof
, 1);
10014 ret
.original_code
= ERROR_MARK
;
10015 ret
.original_type
= NULL
;
10016 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
10023 expr
= c_parser_unary_expression (parser
);
10024 end_loc
= expr
.src_range
.m_finish
;
10026 mark_exp_read (expr
.value
);
10027 c_inhibit_evaluation_warnings
--;
10029 if (is_c11_alignof
)
10030 pedwarn (start_loc
,
10031 OPT_Wpedantic
, "ISO C does not allow %<%E (expression)%>",
10033 ret
.value
= c_alignof_expr (start_loc
, expr
.value
);
10034 ret
.original_code
= ERROR_MARK
;
10035 ret
.original_type
= NULL
;
10036 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
10042 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
10045 static struct c_expr
10046 c_parser_has_attribute_expression (c_parser
*parser
)
10048 gcc_assert (c_parser_next_token_is_keyword (parser
,
10049 RID_BUILTIN_HAS_ATTRIBUTE
));
10050 location_t start
= c_parser_peek_token (parser
)->location
;
10051 c_parser_consume_token (parser
);
10053 c_inhibit_evaluation_warnings
++;
10055 matching_parens parens
;
10056 if (!parens
.require_open (parser
))
10058 c_inhibit_evaluation_warnings
--;
10061 struct c_expr result
;
10062 result
.set_error ();
10063 result
.original_code
= ERROR_MARK
;
10064 result
.original_type
= NULL
;
10068 /* Treat the type argument the same way as in typeof for the purposes
10069 of warnings. FIXME: Generalize this so the warning refers to
10070 __builtin_has_attribute rather than typeof. */
10073 /* The first operand: one of DECL, EXPR, or TYPE. */
10074 tree oper
= NULL_TREE
;
10075 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
10077 struct c_type_name
*tname
= c_parser_type_name (parser
);
10081 oper
= groktypename (tname
, NULL
, NULL
);
10082 pop_maybe_used (c_type_variably_modified_p (oper
));
10087 struct c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
10088 c_inhibit_evaluation_warnings
--;
10090 if (cexpr
.value
!= error_mark_node
)
10092 mark_exp_read (cexpr
.value
);
10093 oper
= cexpr
.value
;
10094 tree etype
= TREE_TYPE (oper
);
10095 bool was_vm
= c_type_variably_modified_p (etype
);
10096 /* This is returned with the type so that when the type is
10097 evaluated, this can be evaluated. */
10099 oper
= c_fully_fold (oper
, false, NULL
);
10100 pop_maybe_used (was_vm
);
10104 struct c_expr result
;
10105 result
.original_code
= ERROR_MARK
;
10106 result
.original_type
= NULL
;
10108 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10110 /* Consume the closing parenthesis if that's the next token
10111 in the likely case the built-in was invoked with fewer
10112 than two arguments. */
10113 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10114 c_parser_consume_token (parser
);
10115 c_inhibit_evaluation_warnings
--;
10116 result
.set_error ();
10120 bool save_translate_strings_p
= parser
->translate_strings_p
;
10122 location_t atloc
= c_parser_peek_token (parser
)->location
;
10123 /* Parse a single attribute. Require no leading comma and do not
10124 allow empty attributes. */
10125 tree attr
= c_parser_gnu_attribute (parser
, NULL_TREE
, false, false);
10127 parser
->translate_strings_p
= save_translate_strings_p
;
10129 location_t finish
= c_parser_peek_token (parser
)->location
;
10130 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10131 c_parser_consume_token (parser
);
10134 c_parser_error (parser
, "expected identifier");
10135 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10137 result
.set_error ();
10143 error_at (atloc
, "expected identifier");
10144 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10146 result
.set_error ();
10150 result
.original_code
= INTEGER_CST
;
10151 result
.original_type
= boolean_type_node
;
10153 if (has_attribute (atloc
, oper
, attr
, default_conversion
))
10154 result
.value
= boolean_true_node
;
10156 result
.value
= boolean_false_node
;
10158 set_c_expr_source_range (&result
, start
, finish
);
10159 result
.m_decimal
= 0;
10163 /* Helper function to read arguments of builtins which are interfaces
10164 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
10165 others. The name of the builtin is passed using BNAME parameter.
10166 Function returns true if there were no errors while parsing and
10167 stores the arguments in CEXPR_LIST. If it returns true,
10168 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
10171 c_parser_get_builtin_args (c_parser
*parser
, const char *bname
,
10172 vec
<c_expr_t
, va_gc
> **ret_cexpr_list
,
10173 bool choose_expr_p
,
10174 location_t
*out_close_paren_loc
)
10176 location_t loc
= c_parser_peek_token (parser
)->location
;
10177 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10179 bool saved_force_folding_builtin_constant_p
;
10181 *ret_cexpr_list
= NULL
;
10182 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
10184 error_at (loc
, "cannot take address of %qs", bname
);
10188 c_parser_consume_token (parser
);
10190 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10192 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
10193 c_parser_consume_token (parser
);
10197 saved_force_folding_builtin_constant_p
10198 = force_folding_builtin_constant_p
;
10199 force_folding_builtin_constant_p
|= choose_expr_p
;
10200 expr
= c_parser_expr_no_commas (parser
, NULL
);
10201 force_folding_builtin_constant_p
10202 = saved_force_folding_builtin_constant_p
;
10203 vec_alloc (cexpr_list
, 1);
10204 vec_safe_push (cexpr_list
, expr
);
10205 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10207 c_parser_consume_token (parser
);
10208 expr
= c_parser_expr_no_commas (parser
, NULL
);
10209 vec_safe_push (cexpr_list
, expr
);
10212 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
10213 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
10216 *ret_cexpr_list
= cexpr_list
;
10220 /* This represents a single generic-association. */
10222 struct c_generic_association
10224 /* The location of the starting token of the type. */
10225 location_t type_location
;
10226 /* The association's type, or NULL_TREE for 'default'. */
10228 /* The association's expression. */
10229 struct c_expr expression
;
10232 /* Parse a generic-selection. (C11 6.5.1.1).
10235 _Generic ( assignment-expression , generic-assoc-list )
10237 generic-assoc-list:
10238 generic-association
10239 generic-assoc-list , generic-association
10241 generic-association:
10242 type-name : assignment-expression
10243 default : assignment-expression
10246 static struct c_expr
10247 c_parser_generic_selection (c_parser
*parser
)
10249 struct c_expr selector
, error_expr
;
10250 tree selector_type
;
10251 struct c_generic_association matched_assoc
;
10252 int match_found
= -1;
10253 location_t generic_loc
, selector_loc
;
10255 error_expr
.original_code
= ERROR_MARK
;
10256 error_expr
.original_type
= NULL
;
10257 error_expr
.set_error ();
10258 matched_assoc
.type_location
= UNKNOWN_LOCATION
;
10259 matched_assoc
.type
= NULL_TREE
;
10260 matched_assoc
.expression
= error_expr
;
10262 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_GENERIC
));
10263 generic_loc
= c_parser_peek_token (parser
)->location
;
10264 c_parser_consume_token (parser
);
10266 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
10267 "ISO C99 does not support %<_Generic%>");
10269 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
10270 "ISO C90 does not support %<_Generic%>");
10272 matching_parens parens
;
10273 if (!parens
.require_open (parser
))
10276 c_inhibit_evaluation_warnings
++;
10277 selector_loc
= c_parser_peek_token (parser
)->location
;
10278 selector
= c_parser_expr_no_commas (parser
, NULL
);
10279 selector
= default_function_array_conversion (selector_loc
, selector
);
10280 c_inhibit_evaluation_warnings
--;
10282 if (selector
.value
== error_mark_node
)
10284 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10287 mark_exp_read (selector
.value
);
10288 selector_type
= TREE_TYPE (selector
.value
);
10289 /* In ISO C terms, rvalues (including the controlling expression of
10290 _Generic) do not have qualified types. */
10291 if (TREE_CODE (selector_type
) != ARRAY_TYPE
)
10292 selector_type
= TYPE_MAIN_VARIANT (selector_type
);
10293 /* In ISO C terms, _Noreturn is not part of the type of expressions
10294 such as &abort, but in GCC it is represented internally as a type
10296 if (FUNCTION_POINTER_TYPE_P (selector_type
)
10297 && TYPE_QUALS (TREE_TYPE (selector_type
)) != TYPE_UNQUALIFIED
)
10299 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type
)));
10301 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10303 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10307 auto_vec
<c_generic_association
> associations
;
10310 struct c_generic_association assoc
, *iter
;
10312 c_token
*token
= c_parser_peek_token (parser
);
10314 assoc
.type_location
= token
->location
;
10315 if (token
->type
== CPP_KEYWORD
&& token
->keyword
== RID_DEFAULT
)
10317 c_parser_consume_token (parser
);
10318 assoc
.type
= NULL_TREE
;
10322 struct c_type_name
*type_name
;
10324 type_name
= c_parser_type_name (parser
);
10325 if (type_name
== NULL
)
10327 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10330 assoc
.type
= groktypename (type_name
, NULL
, NULL
);
10331 if (assoc
.type
== error_mark_node
)
10333 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10337 if (TREE_CODE (assoc
.type
) == FUNCTION_TYPE
)
10338 error_at (assoc
.type_location
,
10339 "%<_Generic%> association has function type");
10340 else if (!COMPLETE_TYPE_P (assoc
.type
))
10341 error_at (assoc
.type_location
,
10342 "%<_Generic%> association has incomplete type");
10344 if (c_type_variably_modified_p (assoc
.type
))
10345 error_at (assoc
.type_location
,
10346 "%<_Generic%> association has "
10347 "variable length type");
10350 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
10352 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10356 bool match
= assoc
.type
== NULL_TREE
10357 || comptypes (assoc
.type
, selector_type
);
10360 c_inhibit_evaluation_warnings
++;
10362 assoc
.expression
= c_parser_expr_no_commas (parser
, NULL
);
10365 c_inhibit_evaluation_warnings
--;
10367 if (assoc
.expression
.value
== error_mark_node
)
10369 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10373 for (ix
= 0; associations
.iterate (ix
, &iter
); ++ix
)
10375 if (assoc
.type
== NULL_TREE
)
10377 if (iter
->type
== NULL_TREE
)
10379 error_at (assoc
.type_location
,
10380 "duplicate %<default%> case in %<_Generic%>");
10381 inform (iter
->type_location
, "original %<default%> is here");
10384 else if (iter
->type
!= NULL_TREE
)
10386 if (comptypes (assoc
.type
, iter
->type
))
10388 error_at (assoc
.type_location
,
10389 "%<_Generic%> specifies two compatible types");
10390 inform (iter
->type_location
, "compatible type is here");
10395 if (assoc
.type
== NULL_TREE
)
10397 if (match_found
< 0)
10399 matched_assoc
= assoc
;
10400 match_found
= associations
.length ();
10405 if (match_found
< 0 || matched_assoc
.type
== NULL_TREE
)
10407 matched_assoc
= assoc
;
10408 match_found
= associations
.length ();
10412 error_at (assoc
.type_location
,
10413 "%<_Generic%> selector matches multiple associations");
10414 inform (matched_assoc
.type_location
,
10415 "other match is here");
10419 associations
.safe_push (assoc
);
10421 if (c_parser_peek_token (parser
)->type
!= CPP_COMMA
)
10423 c_parser_consume_token (parser
);
10427 struct c_generic_association
*iter
;
10428 FOR_EACH_VEC_ELT (associations
, ix
, iter
)
10429 if (ix
!= (unsigned) match_found
)
10430 mark_exp_read (iter
->expression
.value
);
10432 if (!parens
.require_close (parser
))
10434 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10438 if (match_found
< 0)
10440 error_at (selector_loc
, "%<_Generic%> selector of type %qT is not "
10441 "compatible with any association",
10446 return matched_assoc
.expression
;
10449 /* Check the validity of a function pointer argument *EXPR (argument
10450 position POS) to __builtin_tgmath. Return the number of function
10451 arguments if possibly valid; return 0 having reported an error if
10454 static unsigned int
10455 check_tgmath_function (c_expr
*expr
, unsigned int pos
)
10457 tree type
= TREE_TYPE (expr
->value
);
10458 if (!FUNCTION_POINTER_TYPE_P (type
))
10460 error_at (expr
->get_location (),
10461 "argument %u of %<__builtin_tgmath%> is not a function pointer",
10465 type
= TREE_TYPE (type
);
10466 if (!prototype_p (type
))
10468 error_at (expr
->get_location (),
10469 "argument %u of %<__builtin_tgmath%> is unprototyped", pos
);
10472 if (stdarg_p (type
))
10474 error_at (expr
->get_location (),
10475 "argument %u of %<__builtin_tgmath%> has variable arguments",
10479 unsigned int nargs
= 0;
10480 function_args_iterator iter
;
10482 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
10484 if (t
== void_type_node
)
10490 error_at (expr
->get_location (),
10491 "argument %u of %<__builtin_tgmath%> has no arguments", pos
);
10497 /* Ways in which a parameter or return value of a type-generic macro
10498 may vary between the different functions the macro may call. */
10499 enum tgmath_parm_kind
10501 tgmath_fixed
, tgmath_real
, tgmath_complex
10504 /* Helper function for c_parser_postfix_expression. Parse predefined
10507 static struct c_expr
10508 c_parser_predefined_identifier (c_parser
*parser
)
10510 location_t loc
= c_parser_peek_token (parser
)->location
;
10511 switch (c_parser_peek_token (parser
)->keyword
)
10513 case RID_FUNCTION_NAME
:
10514 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
10515 "identifier", "__FUNCTION__");
10517 case RID_PRETTY_FUNCTION_NAME
:
10518 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
10519 "identifier", "__PRETTY_FUNCTION__");
10521 case RID_C99_FUNCTION_NAME
:
10522 pedwarn_c90 (loc
, OPT_Wpedantic
, "ISO C90 does not support "
10523 "%<__func__%> predefined identifier");
10526 gcc_unreachable ();
10529 struct c_expr expr
;
10530 expr
.original_code
= ERROR_MARK
;
10531 expr
.original_type
= NULL
;
10532 expr
.value
= fname_decl (loc
, c_parser_peek_token (parser
)->keyword
,
10533 c_parser_peek_token (parser
)->value
);
10534 set_c_expr_source_range (&expr
, loc
, loc
);
10535 expr
.m_decimal
= 0;
10536 c_parser_consume_token (parser
);
10540 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
10541 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
10542 call c_parser_postfix_expression_after_paren_type on encountering them.
10544 postfix-expression:
10546 postfix-expression [ expression ]
10547 postfix-expression ( argument-expression-list[opt] )
10548 postfix-expression . identifier
10549 postfix-expression -> identifier
10550 postfix-expression ++
10551 postfix-expression --
10552 ( storage-class-specifiers[opt] type-name ) { initializer-list[opt] }
10553 ( storage-class-specifiers[opt] type-name ) { initializer-list , }
10555 argument-expression-list:
10556 argument-expression
10557 argument-expression-list , argument-expression
10559 primary-expression:
10568 primary-expression:
10570 (treated as a keyword in GNU C)
10572 __PRETTY_FUNCTION__
10573 ( compound-statement )
10574 __builtin_va_arg ( assignment-expression , type-name )
10575 __builtin_offsetof ( type-name , offsetof-member-designator )
10576 __builtin_choose_expr ( assignment-expression ,
10577 assignment-expression ,
10578 assignment-expression )
10579 __builtin_types_compatible_p ( type-name , type-name )
10580 __builtin_tgmath ( expr-list )
10581 __builtin_complex ( assignment-expression , assignment-expression )
10582 __builtin_shuffle ( assignment-expression , assignment-expression )
10583 __builtin_shuffle ( assignment-expression ,
10584 assignment-expression ,
10585 assignment-expression, )
10586 __builtin_convertvector ( assignment-expression , type-name )
10587 __builtin_assoc_barrier ( assignment-expression )
10589 offsetof-member-designator:
10591 offsetof-member-designator . identifier
10592 offsetof-member-designator [ expression ]
10596 primary-expression:
10597 [ objc-receiver objc-message-args ]
10598 @selector ( objc-selector-arg )
10599 @protocol ( identifier )
10600 @encode ( type-name )
10601 objc-string-literal
10602 Classname . identifier
10605 static struct c_expr
10606 c_parser_postfix_expression (c_parser
*parser
)
10608 struct c_expr expr
, e1
;
10609 struct c_type_name
*t1
, *t2
;
10610 location_t loc
= c_parser_peek_token (parser
)->location
;
10611 source_range tok_range
= c_parser_peek_token (parser
)->get_range ();
10612 expr
.original_code
= ERROR_MARK
;
10613 expr
.original_type
= NULL
;
10614 expr
.m_decimal
= 0;
10615 switch (c_parser_peek_token (parser
)->type
)
10618 expr
.value
= c_parser_peek_token (parser
)->value
;
10619 set_c_expr_source_range (&expr
, tok_range
);
10620 loc
= c_parser_peek_token (parser
)->location
;
10621 expr
.m_decimal
= c_parser_peek_token (parser
)->flags
& DECIMAL_INT
;
10622 c_parser_consume_token (parser
);
10623 if (TREE_CODE (expr
.value
) == FIXED_CST
10624 && !targetm
.fixed_point_supported_p ())
10626 error_at (loc
, "fixed-point types not supported for this target");
10635 expr
.value
= c_parser_peek_token (parser
)->value
;
10636 /* For the purpose of warning when a pointer is compared with
10637 a zero character constant. */
10638 expr
.original_type
= char_type_node
;
10639 set_c_expr_source_range (&expr
, tok_range
);
10640 c_parser_consume_token (parser
);
10646 case CPP_UTF8STRING
:
10647 expr
= c_parser_string_literal (parser
, parser
->translate_strings_p
,
10650 case CPP_OBJC_STRING
:
10651 gcc_assert (c_dialect_objc ());
10653 = objc_build_string_object (c_parser_peek_token (parser
)->value
);
10654 set_c_expr_source_range (&expr
, tok_range
);
10655 c_parser_consume_token (parser
);
10658 switch (c_parser_peek_token (parser
)->id_kind
)
10662 tree id
= c_parser_peek_token (parser
)->value
;
10663 c_parser_consume_token (parser
);
10664 expr
.value
= build_external_ref (loc
, id
,
10665 (c_parser_peek_token (parser
)->type
10666 == CPP_OPEN_PAREN
),
10667 &expr
.original_type
);
10668 set_c_expr_source_range (&expr
, tok_range
);
10671 case C_ID_CLASSNAME
:
10673 /* Here we parse the Objective-C 2.0 Class.name dot
10675 tree class_name
= c_parser_peek_token (parser
)->value
;
10677 c_parser_consume_token (parser
);
10678 gcc_assert (c_dialect_objc ());
10679 if (!c_parser_require (parser
, CPP_DOT
, "expected %<.%>"))
10684 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10686 c_parser_error (parser
, "expected identifier");
10690 c_token
*component_tok
= c_parser_peek_token (parser
);
10691 component
= component_tok
->value
;
10692 location_t end_loc
= component_tok
->get_finish ();
10693 c_parser_consume_token (parser
);
10694 expr
.value
= objc_build_class_component_ref (class_name
,
10696 set_c_expr_source_range (&expr
, loc
, end_loc
);
10700 c_parser_error (parser
, "expected expression");
10705 case CPP_OPEN_PAREN
:
10706 /* A parenthesized expression, statement expression or compound
10708 if (c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_BRACE
)
10710 /* A statement expression. */
10712 location_t brace_loc
;
10713 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
10714 c_parser_consume_token (parser
);
10715 brace_loc
= c_parser_peek_token (parser
)->location
;
10716 c_parser_consume_token (parser
);
10717 /* If we've not yet started the current function's statement list,
10718 or we're in the parameter scope of an old-style function
10719 declaration, statement expressions are not allowed. */
10720 if (!building_stmt_list_p () || old_style_parameter_scope ())
10722 error_at (loc
, "braced-group within expression allowed "
10723 "only inside a function");
10724 parser
->error
= true;
10725 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
10726 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10730 c_omp_array_section_p
= false;
10731 stmt
= c_begin_stmt_expr ();
10732 c_parser_compound_statement_nostart (parser
);
10733 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10734 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10736 pedwarn (loc
, OPT_Wpedantic
,
10737 "ISO C forbids braced-groups within expressions");
10738 expr
.value
= c_finish_stmt_expr (brace_loc
, stmt
);
10739 set_c_expr_source_range (&expr
, loc
, close_loc
);
10740 mark_exp_read (expr
.value
);
10741 c_omp_array_section_p
= save_c_omp_array_section_p
;
10745 /* A parenthesized expression. */
10746 location_t loc_open_paren
= c_parser_peek_token (parser
)->location
;
10747 c_parser_consume_token (parser
);
10748 expr
= c_parser_expression (parser
);
10749 if (TREE_CODE (expr
.value
) == MODIFY_EXPR
)
10750 suppress_warning (expr
.value
, OPT_Wparentheses
);
10751 if (expr
.original_code
!= C_MAYBE_CONST_EXPR
10752 && expr
.original_code
!= SIZEOF_EXPR
)
10753 expr
.original_code
= ERROR_MARK
;
10754 /* Remember that we saw ( ) around the sizeof. */
10755 if (expr
.original_code
== SIZEOF_EXPR
)
10756 expr
.original_code
= PAREN_SIZEOF_EXPR
;
10757 /* Don't change EXPR.ORIGINAL_TYPE. */
10758 location_t loc_close_paren
= c_parser_peek_token (parser
)->location
;
10759 set_c_expr_source_range (&expr
, loc_open_paren
, loc_close_paren
);
10760 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10761 "expected %<)%>", loc_open_paren
);
10765 switch (c_parser_peek_token (parser
)->keyword
)
10767 case RID_FUNCTION_NAME
:
10768 case RID_PRETTY_FUNCTION_NAME
:
10769 case RID_C99_FUNCTION_NAME
:
10770 expr
= c_parser_predefined_identifier (parser
);
10774 location_t start_loc
= loc
;
10775 c_parser_consume_token (parser
);
10776 matching_parens parens
;
10777 if (!parens
.require_open (parser
))
10782 e1
= c_parser_expr_no_commas (parser
, NULL
);
10783 mark_exp_read (e1
.value
);
10784 e1
.value
= c_fully_fold (e1
.value
, false, NULL
);
10785 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10787 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10791 loc
= c_parser_peek_token (parser
)->location
;
10792 t1
= c_parser_type_name (parser
);
10793 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10794 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10802 tree type_expr
= NULL_TREE
;
10803 expr
.value
= c_build_va_arg (start_loc
, e1
.value
, loc
,
10804 groktypename (t1
, &type_expr
, NULL
));
10807 expr
.value
= build2 (C_MAYBE_CONST_EXPR
,
10808 TREE_TYPE (expr
.value
), type_expr
,
10810 C_MAYBE_CONST_EXPR_NON_CONST (expr
.value
) = true;
10812 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10818 c_parser_consume_token (parser
);
10819 matching_parens parens
;
10820 if (!parens
.require_open (parser
))
10825 t1
= c_parser_type_name (parser
);
10827 parser
->error
= true;
10828 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10829 gcc_assert (parser
->error
);
10832 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10836 tree type
= groktypename (t1
, NULL
, NULL
);
10838 if (type
== error_mark_node
)
10839 offsetof_ref
= error_mark_node
;
10842 offsetof_ref
= build1 (INDIRECT_REF
, type
, null_pointer_node
);
10843 SET_EXPR_LOCATION (offsetof_ref
, loc
);
10845 /* Parse the second argument to __builtin_offsetof. We
10846 must have one identifier, and beyond that we want to
10847 accept sub structure and sub array references. */
10848 if (c_parser_next_token_is (parser
, CPP_NAME
))
10850 c_token
*comp_tok
= c_parser_peek_token (parser
);
10852 = build_component_ref (loc
, offsetof_ref
, comp_tok
->value
,
10853 comp_tok
->location
, UNKNOWN_LOCATION
);
10854 c_parser_consume_token (parser
);
10855 while (c_parser_next_token_is (parser
, CPP_DOT
)
10856 || c_parser_next_token_is (parser
,
10858 || c_parser_next_token_is (parser
,
10861 if (c_parser_next_token_is (parser
, CPP_DEREF
))
10863 loc
= c_parser_peek_token (parser
)->location
;
10864 offsetof_ref
= build_array_ref (loc
,
10866 integer_zero_node
);
10869 else if (c_parser_next_token_is (parser
, CPP_DOT
))
10872 c_parser_consume_token (parser
);
10873 if (c_parser_next_token_is_not (parser
,
10876 c_parser_error (parser
, "expected identifier");
10879 c_token
*comp_tok
= c_parser_peek_token (parser
);
10881 = build_component_ref (loc
, offsetof_ref
,
10883 comp_tok
->location
,
10885 c_parser_consume_token (parser
);
10891 loc
= c_parser_peek_token (parser
)->location
;
10892 c_parser_consume_token (parser
);
10893 ce
= c_parser_expression (parser
);
10894 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
10896 idx
= c_fully_fold (idx
, false, NULL
);
10897 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10899 offsetof_ref
= build_array_ref (loc
, offsetof_ref
, idx
);
10904 c_parser_error (parser
, "expected identifier");
10905 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10906 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10908 expr
.value
= fold_offsetof (offsetof_ref
);
10909 set_c_expr_source_range (&expr
, loc
, end_loc
);
10912 case RID_CHOOSE_EXPR
:
10914 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10915 c_expr_t
*e1_p
, *e2_p
, *e3_p
;
10917 location_t close_paren_loc
;
10919 c_parser_consume_token (parser
);
10920 if (!c_parser_get_builtin_args (parser
,
10921 "__builtin_choose_expr",
10929 if (vec_safe_length (cexpr_list
) != 3)
10931 error_at (loc
, "wrong number of arguments to "
10932 "%<__builtin_choose_expr%>");
10937 e1_p
= &(*cexpr_list
)[0];
10938 e2_p
= &(*cexpr_list
)[1];
10939 e3_p
= &(*cexpr_list
)[2];
10942 mark_exp_read (e2_p
->value
);
10943 mark_exp_read (e3_p
->value
);
10944 if (TREE_CODE (c
) != INTEGER_CST
10945 || !INTEGRAL_TYPE_P (TREE_TYPE (c
)))
10947 "first argument to %<__builtin_choose_expr%> not"
10949 constant_expression_warning (c
);
10950 expr
= integer_zerop (c
) ? *e3_p
: *e2_p
;
10951 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10954 case RID_TYPES_COMPATIBLE_P
:
10956 c_parser_consume_token (parser
);
10957 matching_parens parens
;
10958 if (!parens
.require_open (parser
))
10963 t1
= c_parser_type_name (parser
);
10969 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10971 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10975 t2
= c_parser_type_name (parser
);
10981 location_t close_paren_loc
= c_parser_peek_token (parser
)->location
;
10982 parens
.skip_until_found_close (parser
);
10984 e1
= groktypename (t1
, NULL
, NULL
);
10985 e2
= groktypename (t2
, NULL
, NULL
);
10986 if (e1
== error_mark_node
|| e2
== error_mark_node
)
10992 e1
= TYPE_MAIN_VARIANT (e1
);
10993 e2
= TYPE_MAIN_VARIANT (e2
);
10996 = comptypes (e1
, e2
) ? integer_one_node
: integer_zero_node
;
10997 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11000 case RID_BUILTIN_TGMATH
:
11002 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11003 location_t close_paren_loc
;
11005 c_parser_consume_token (parser
);
11006 if (!c_parser_get_builtin_args (parser
,
11007 "__builtin_tgmath",
11008 &cexpr_list
, false,
11015 if (vec_safe_length (cexpr_list
) < 3)
11017 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
11024 FOR_EACH_VEC_ELT (*cexpr_list
, i
, p
)
11025 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
11026 unsigned int nargs
= check_tgmath_function (&(*cexpr_list
)[0], 1);
11032 if (vec_safe_length (cexpr_list
) < nargs
)
11034 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
11038 unsigned int num_functions
= vec_safe_length (cexpr_list
) - nargs
;
11039 if (num_functions
< 2)
11041 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
11046 /* The first NUM_FUNCTIONS expressions are the function
11047 pointers. The remaining NARGS expressions are the
11048 arguments that are to be passed to one of those
11049 functions, chosen following <tgmath.h> rules. */
11050 for (unsigned int j
= 1; j
< num_functions
; j
++)
11052 unsigned int this_nargs
11053 = check_tgmath_function (&(*cexpr_list
)[j
], j
+ 1);
11054 if (this_nargs
== 0)
11059 if (this_nargs
!= nargs
)
11061 error_at ((*cexpr_list
)[j
].get_location (),
11062 "argument %u of %<__builtin_tgmath%> has "
11063 "wrong number of arguments", j
+ 1);
11069 /* The functions all have the same number of arguments.
11070 Determine whether arguments and return types vary in
11071 ways permitted for <tgmath.h> functions. */
11072 /* The first entry in each of these vectors is for the
11073 return type, subsequent entries for parameter
11075 auto_vec
<enum tgmath_parm_kind
> parm_kind (nargs
+ 1);
11076 auto_vec
<tree
> parm_first (nargs
+ 1);
11077 auto_vec
<bool> parm_complex (nargs
+ 1);
11078 auto_vec
<bool> parm_varies (nargs
+ 1);
11079 tree first_type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[0].value
));
11080 tree first_ret
= TYPE_MAIN_VARIANT (TREE_TYPE (first_type
));
11081 parm_first
.quick_push (first_ret
);
11082 parm_complex
.quick_push (TREE_CODE (first_ret
) == COMPLEX_TYPE
);
11083 parm_varies
.quick_push (false);
11084 function_args_iterator iter
;
11086 unsigned int argpos
;
11087 FOREACH_FUNCTION_ARGS (first_type
, t
, iter
)
11089 if (t
== void_type_node
)
11091 parm_first
.quick_push (TYPE_MAIN_VARIANT (t
));
11092 parm_complex
.quick_push (TREE_CODE (t
) == COMPLEX_TYPE
);
11093 parm_varies
.quick_push (false);
11095 for (unsigned int j
= 1; j
< num_functions
; j
++)
11097 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
11098 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
11099 if (ret
!= parm_first
[0])
11101 parm_varies
[0] = true;
11102 if (!SCALAR_FLOAT_TYPE_P (parm_first
[0])
11103 && !COMPLEX_FLOAT_TYPE_P (parm_first
[0]))
11105 error_at ((*cexpr_list
)[0].get_location (),
11106 "invalid type-generic return type for "
11107 "argument %u of %<__builtin_tgmath%>",
11112 if (!SCALAR_FLOAT_TYPE_P (ret
)
11113 && !COMPLEX_FLOAT_TYPE_P (ret
))
11115 error_at ((*cexpr_list
)[j
].get_location (),
11116 "invalid type-generic return type for "
11117 "argument %u of %<__builtin_tgmath%>",
11123 if (TREE_CODE (ret
) == COMPLEX_TYPE
)
11124 parm_complex
[0] = true;
11126 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
11128 if (t
== void_type_node
)
11130 t
= TYPE_MAIN_VARIANT (t
);
11131 if (t
!= parm_first
[argpos
])
11133 parm_varies
[argpos
] = true;
11134 if (!SCALAR_FLOAT_TYPE_P (parm_first
[argpos
])
11135 && !COMPLEX_FLOAT_TYPE_P (parm_first
[argpos
]))
11137 error_at ((*cexpr_list
)[0].get_location (),
11138 "invalid type-generic type for "
11139 "argument %u of argument %u of "
11140 "%<__builtin_tgmath%>", argpos
, 1);
11144 if (!SCALAR_FLOAT_TYPE_P (t
)
11145 && !COMPLEX_FLOAT_TYPE_P (t
))
11147 error_at ((*cexpr_list
)[j
].get_location (),
11148 "invalid type-generic type for "
11149 "argument %u of argument %u of "
11150 "%<__builtin_tgmath%>", argpos
, j
+ 1);
11155 if (TREE_CODE (t
) == COMPLEX_TYPE
)
11156 parm_complex
[argpos
] = true;
11160 enum tgmath_parm_kind max_variation
= tgmath_fixed
;
11161 for (unsigned int j
= 0; j
<= nargs
; j
++)
11163 enum tgmath_parm_kind this_kind
;
11164 if (parm_varies
[j
])
11166 if (parm_complex
[j
])
11167 max_variation
= this_kind
= tgmath_complex
;
11170 this_kind
= tgmath_real
;
11171 if (max_variation
!= tgmath_complex
)
11172 max_variation
= tgmath_real
;
11176 this_kind
= tgmath_fixed
;
11177 parm_kind
.quick_push (this_kind
);
11179 if (max_variation
== tgmath_fixed
)
11181 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
11182 "all have the same type");
11187 /* Identify a parameter (not the return type) that varies,
11188 including with complex types if any variation includes
11189 complex types; there must be at least one such
11191 unsigned int tgarg
= 0;
11192 for (unsigned int j
= 1; j
<= nargs
; j
++)
11193 if (parm_kind
[j
] == max_variation
)
11200 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
11201 "lack type-generic parameter");
11206 /* Determine the type of the relevant parameter for each
11208 auto_vec
<tree
> tg_type (num_functions
);
11209 for (unsigned int j
= 0; j
< num_functions
; j
++)
11211 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
11213 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
11215 if (argpos
== tgarg
)
11217 tg_type
.quick_push (TYPE_MAIN_VARIANT (t
));
11224 /* Verify that the corresponding types are different for
11225 all the listed functions. Also determine whether all
11226 the types are complex, whether all the types are
11227 standard or binary, and whether all the types are
11229 bool all_complex
= true;
11230 bool all_binary
= true;
11231 bool all_decimal
= true;
11232 hash_set
<tree
> tg_types
;
11233 FOR_EACH_VEC_ELT (tg_type
, i
, t
)
11235 if (TREE_CODE (t
) == COMPLEX_TYPE
)
11236 all_decimal
= false;
11239 all_complex
= false;
11240 if (DECIMAL_FLOAT_TYPE_P (t
))
11241 all_binary
= false;
11243 all_decimal
= false;
11245 if (tg_types
.add (t
))
11247 error_at ((*cexpr_list
)[i
].get_location (),
11248 "duplicate type-generic parameter type for "
11249 "function argument %u of %<__builtin_tgmath%>",
11256 /* Verify that other parameters and the return type whose
11257 types vary have their types varying in the correct
11259 for (unsigned int j
= 0; j
< num_functions
; j
++)
11261 tree exp_type
= tg_type
[j
];
11262 tree exp_real_type
= exp_type
;
11263 if (TREE_CODE (exp_type
) == COMPLEX_TYPE
)
11264 exp_real_type
= TREE_TYPE (exp_type
);
11265 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
11266 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
11267 if ((parm_kind
[0] == tgmath_complex
&& ret
!= exp_type
)
11268 || (parm_kind
[0] == tgmath_real
&& ret
!= exp_real_type
))
11270 error_at ((*cexpr_list
)[j
].get_location (),
11271 "bad return type for function argument %u "
11272 "of %<__builtin_tgmath%>", j
+ 1);
11277 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
11279 if (t
== void_type_node
)
11281 t
= TYPE_MAIN_VARIANT (t
);
11282 if ((parm_kind
[argpos
] == tgmath_complex
11284 || (parm_kind
[argpos
] == tgmath_real
11285 && t
!= exp_real_type
))
11287 error_at ((*cexpr_list
)[j
].get_location (),
11288 "bad type for argument %u of "
11289 "function argument %u of "
11290 "%<__builtin_tgmath%>", argpos
, j
+ 1);
11298 /* The functions listed are a valid set of functions for a
11299 <tgmath.h> macro to select between. Identify the
11300 matching function, if any. First, the argument types
11301 must be combined following <tgmath.h> rules. Integer
11302 types are treated as _Decimal64 if any type-generic
11303 argument is decimal, or if the only alternatives for
11304 type-generic arguments are of decimal types, and are
11305 otherwise treated as _Float32x (or _Complex _Float32x
11306 for complex integer types) if any type-generic argument
11307 has _FloatNx type, otherwise as double (or _Complex
11308 double for complex integer types). After that
11309 adjustment, types are combined following the usual
11310 arithmetic conversions. If the function only accepts
11311 complex arguments, a complex type is produced. */
11312 bool arg_complex
= all_complex
;
11313 bool arg_binary
= all_binary
;
11314 bool arg_int_decimal
= all_decimal
;
11315 bool arg_int_floatnx
= false;
11316 for (unsigned int j
= 1; j
<= nargs
; j
++)
11318 if (parm_kind
[j
] == tgmath_fixed
)
11320 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
11321 tree type
= TREE_TYPE (ce
->value
);
11322 if (!INTEGRAL_TYPE_P (type
)
11323 && !SCALAR_FLOAT_TYPE_P (type
)
11324 && TREE_CODE (type
) != COMPLEX_TYPE
)
11326 error_at (ce
->get_location (),
11327 "invalid type of argument %u of type-generic "
11332 if (DECIMAL_FLOAT_TYPE_P (type
))
11334 arg_int_decimal
= true;
11337 error_at (ce
->get_location (),
11338 "decimal floating-point argument %u to "
11339 "complex-only type-generic function", j
);
11343 else if (all_binary
)
11345 error_at (ce
->get_location (),
11346 "decimal floating-point argument %u to "
11347 "binary-only type-generic function", j
);
11351 else if (arg_complex
)
11353 error_at (ce
->get_location (),
11354 "both complex and decimal floating-point "
11355 "arguments to type-generic function");
11359 else if (arg_binary
)
11361 error_at (ce
->get_location (),
11362 "both binary and decimal floating-point "
11363 "arguments to type-generic function");
11368 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
11370 arg_complex
= true;
11371 if (COMPLEX_FLOAT_TYPE_P (type
))
11375 error_at (ce
->get_location (),
11376 "complex argument %u to "
11377 "decimal-only type-generic function", j
);
11381 else if (arg_int_decimal
)
11383 error_at (ce
->get_location (),
11384 "both complex and decimal floating-point "
11385 "arguments to type-generic function");
11390 else if (SCALAR_FLOAT_TYPE_P (type
))
11395 error_at (ce
->get_location (),
11396 "binary argument %u to "
11397 "decimal-only type-generic function", j
);
11401 else if (arg_int_decimal
)
11403 error_at (ce
->get_location (),
11404 "both binary and decimal floating-point "
11405 "arguments to type-generic function");
11410 tree rtype
= TYPE_MAIN_VARIANT (type
);
11411 if (TREE_CODE (rtype
) == COMPLEX_TYPE
)
11412 rtype
= TREE_TYPE (rtype
);
11413 if (SCALAR_FLOAT_TYPE_P (rtype
))
11414 for (unsigned int j
= 0; j
< NUM_FLOATNX_TYPES
; j
++)
11415 if (rtype
== FLOATNX_TYPE_NODE (j
))
11417 arg_int_floatnx
= true;
11421 tree arg_real
= NULL_TREE
;
11422 for (unsigned int j
= 1; j
<= nargs
; j
++)
11424 if (parm_kind
[j
] == tgmath_fixed
)
11426 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
11427 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (ce
->value
));
11428 if (TREE_CODE (type
) == COMPLEX_TYPE
)
11429 type
= TREE_TYPE (type
);
11430 if (INTEGRAL_TYPE_P (type
))
11431 type
= (arg_int_decimal
11432 ? dfloat64_type_node
11434 ? float32x_type_node
11435 : double_type_node
);
11436 if (arg_real
== NULL_TREE
)
11439 arg_real
= common_type (arg_real
, type
);
11440 if (arg_real
== error_mark_node
)
11446 tree arg_type
= (arg_complex
11447 ? build_complex_type (arg_real
)
11450 /* Look for a function to call with type-generic parameter
11452 c_expr_t
*fn
= NULL
;
11453 for (unsigned int j
= 0; j
< num_functions
; j
++)
11455 if (tg_type
[j
] == arg_type
)
11457 fn
= &(*cexpr_list
)[j
];
11462 && parm_kind
[0] == tgmath_fixed
11463 && SCALAR_FLOAT_TYPE_P (parm_first
[0]))
11465 /* Presume this is a macro that rounds its result to a
11466 narrower type, and look for the first function with
11467 at least the range and precision of the argument
11469 for (unsigned int j
= 0; j
< num_functions
; j
++)
11472 != (TREE_CODE (tg_type
[j
]) == COMPLEX_TYPE
))
11474 tree real_tg_type
= (arg_complex
11475 ? TREE_TYPE (tg_type
[j
])
11477 if (DECIMAL_FLOAT_TYPE_P (arg_real
)
11478 != DECIMAL_FLOAT_TYPE_P (real_tg_type
))
11480 scalar_float_mode arg_mode
11481 = SCALAR_FLOAT_TYPE_MODE (arg_real
);
11482 scalar_float_mode tg_mode
11483 = SCALAR_FLOAT_TYPE_MODE (real_tg_type
);
11484 const real_format
*arg_fmt
= REAL_MODE_FORMAT (arg_mode
);
11485 const real_format
*tg_fmt
= REAL_MODE_FORMAT (tg_mode
);
11486 if (arg_fmt
->b
== tg_fmt
->b
11487 && arg_fmt
->p
<= tg_fmt
->p
11488 && arg_fmt
->emax
<= tg_fmt
->emax
11489 && (arg_fmt
->emin
- arg_fmt
->p
11490 >= tg_fmt
->emin
- tg_fmt
->p
))
11492 fn
= &(*cexpr_list
)[j
];
11499 error_at (loc
, "no matching function for type-generic call");
11504 /* Construct a call to FN. */
11505 vec
<tree
, va_gc
> *args
;
11506 vec_alloc (args
, nargs
);
11507 vec
<tree
, va_gc
> *origtypes
;
11508 vec_alloc (origtypes
, nargs
);
11509 auto_vec
<location_t
> arg_loc (nargs
);
11510 for (unsigned int j
= 0; j
< nargs
; j
++)
11512 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
];
11513 args
->quick_push (ce
->value
);
11514 arg_loc
.quick_push (ce
->get_location ());
11515 origtypes
->quick_push (ce
->original_type
);
11517 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fn
->value
,
11519 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11522 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN
:
11524 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11527 location_t close_paren_loc
;
11529 c_parser_consume_token (parser
);
11530 if (!c_parser_get_builtin_args (parser
,
11531 "__builtin_call_with_static_chain",
11532 &cexpr_list
, false,
11538 if (vec_safe_length (cexpr_list
) != 2)
11540 error_at (loc
, "wrong number of arguments to "
11541 "%<__builtin_call_with_static_chain%>");
11546 expr
= (*cexpr_list
)[0];
11547 e2_p
= &(*cexpr_list
)[1];
11548 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
11549 chain_value
= e2_p
->value
;
11550 mark_exp_read (chain_value
);
11552 if (TREE_CODE (expr
.value
) != CALL_EXPR
)
11553 error_at (loc
, "first argument to "
11554 "%<__builtin_call_with_static_chain%> "
11555 "must be a call expression");
11556 else if (TREE_CODE (TREE_TYPE (chain_value
)) != POINTER_TYPE
)
11557 error_at (loc
, "second argument to "
11558 "%<__builtin_call_with_static_chain%> "
11559 "must be a pointer type");
11561 CALL_EXPR_STATIC_CHAIN (expr
.value
) = chain_value
;
11562 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11565 case RID_BUILTIN_COMPLEX
:
11567 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11568 c_expr_t
*e1_p
, *e2_p
;
11569 location_t close_paren_loc
;
11571 c_parser_consume_token (parser
);
11572 if (!c_parser_get_builtin_args (parser
,
11573 "__builtin_complex",
11574 &cexpr_list
, false,
11581 if (vec_safe_length (cexpr_list
) != 2)
11583 error_at (loc
, "wrong number of arguments to "
11584 "%<__builtin_complex%>");
11589 e1_p
= &(*cexpr_list
)[0];
11590 e2_p
= &(*cexpr_list
)[1];
11592 *e1_p
= convert_lvalue_to_rvalue (loc
, *e1_p
, true, true);
11593 if (TREE_CODE (e1_p
->value
) == EXCESS_PRECISION_EXPR
)
11594 e1_p
->value
= convert (TREE_TYPE (e1_p
->value
),
11595 TREE_OPERAND (e1_p
->value
, 0));
11596 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
11597 if (TREE_CODE (e2_p
->value
) == EXCESS_PRECISION_EXPR
)
11598 e2_p
->value
= convert (TREE_TYPE (e2_p
->value
),
11599 TREE_OPERAND (e2_p
->value
, 0));
11600 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
11601 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
11602 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
))
11603 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
)))
11605 error_at (loc
, "%<__builtin_complex%> operand "
11606 "not of real binary floating-point type");
11610 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p
->value
))
11611 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p
->value
)))
11614 "%<__builtin_complex%> operands of different types");
11618 pedwarn_c90 (loc
, OPT_Wpedantic
,
11619 "ISO C90 does not support complex types");
11620 expr
.value
= build2_loc (loc
, COMPLEX_EXPR
,
11623 (TREE_TYPE (e1_p
->value
))),
11624 e1_p
->value
, e2_p
->value
);
11625 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11628 case RID_BUILTIN_SHUFFLE
:
11630 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11633 location_t close_paren_loc
;
11635 c_parser_consume_token (parser
);
11636 if (!c_parser_get_builtin_args (parser
,
11637 "__builtin_shuffle",
11638 &cexpr_list
, false,
11645 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
11646 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
11648 if (vec_safe_length (cexpr_list
) == 2)
11649 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
11651 (*cexpr_list
)[1].value
);
11653 else if (vec_safe_length (cexpr_list
) == 3)
11654 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
11655 (*cexpr_list
)[1].value
,
11656 (*cexpr_list
)[2].value
);
11659 error_at (loc
, "wrong number of arguments to "
11660 "%<__builtin_shuffle%>");
11663 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11666 case RID_BUILTIN_SHUFFLEVECTOR
:
11668 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11671 location_t close_paren_loc
;
11673 c_parser_consume_token (parser
);
11674 if (!c_parser_get_builtin_args (parser
,
11675 "__builtin_shufflevector",
11676 &cexpr_list
, false,
11683 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
11684 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
11686 if (vec_safe_length (cexpr_list
) < 3)
11688 error_at (loc
, "wrong number of arguments to "
11689 "%<__builtin_shuffle%>");
11694 auto_vec
<tree
, 16> mask
;
11695 for (i
= 2; i
< cexpr_list
->length (); ++i
)
11696 mask
.safe_push ((*cexpr_list
)[i
].value
);
11697 expr
.value
= c_build_shufflevector (loc
, (*cexpr_list
)[0].value
,
11698 (*cexpr_list
)[1].value
,
11701 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11704 case RID_BUILTIN_CONVERTVECTOR
:
11706 location_t start_loc
= loc
;
11707 c_parser_consume_token (parser
);
11708 matching_parens parens
;
11709 if (!parens
.require_open (parser
))
11714 e1
= c_parser_expr_no_commas (parser
, NULL
);
11715 mark_exp_read (e1
.value
);
11716 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
11718 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
11722 loc
= c_parser_peek_token (parser
)->location
;
11723 t1
= c_parser_type_name (parser
);
11724 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
11725 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
11731 tree type_expr
= NULL_TREE
;
11732 expr
.value
= c_build_vec_convert (start_loc
, e1
.value
, loc
,
11733 groktypename (t1
, &type_expr
,
11735 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
11739 case RID_BUILTIN_ASSOC_BARRIER
:
11741 location_t start_loc
= loc
;
11742 c_parser_consume_token (parser
);
11743 matching_parens parens
;
11744 if (!parens
.require_open (parser
))
11749 e1
= c_parser_expr_no_commas (parser
, NULL
);
11750 mark_exp_read (e1
.value
);
11751 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
11752 parens
.skip_until_found_close (parser
);
11753 expr
= parser_build_unary_op (loc
, PAREN_EXPR
, e1
);
11754 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
11757 case RID_BUILTIN_STDC
:
11759 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11761 location_t close_paren_loc
;
11762 enum c_builtin_stdc
{
11763 C_BUILTIN_STDC_BIT_CEIL
,
11764 C_BUILTIN_STDC_BIT_FLOOR
,
11765 C_BUILTIN_STDC_BIT_WIDTH
,
11766 C_BUILTIN_STDC_COUNT_ONES
,
11767 C_BUILTIN_STDC_COUNT_ZEROS
,
11768 C_BUILTIN_STDC_FIRST_LEADING_ONE
,
11769 C_BUILTIN_STDC_FIRST_LEADING_ZERO
,
11770 C_BUILTIN_STDC_FIRST_TRAILING_ONE
,
11771 C_BUILTIN_STDC_FIRST_TRAILING_ZERO
,
11772 C_BUILTIN_STDC_HAS_SINGLE_BIT
,
11773 C_BUILTIN_STDC_LEADING_ONES
,
11774 C_BUILTIN_STDC_LEADING_ZEROS
,
11775 C_BUILTIN_STDC_TRAILING_ONES
,
11776 C_BUILTIN_STDC_TRAILING_ZEROS
,
11778 } stdc_rid
= C_BUILTIN_STDC_MAX
;
11780 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
11781 switch (name
[sizeof ("__builtin_stdc_") - 1])
11784 switch (name
[sizeof ("__builtin_stdc_bit_") - 1])
11787 stdc_rid
= C_BUILTIN_STDC_BIT_CEIL
;
11790 stdc_rid
= C_BUILTIN_STDC_BIT_FLOOR
;
11793 stdc_rid
= C_BUILTIN_STDC_BIT_WIDTH
;
11798 if (name
[sizeof ("__builtin_stdc_count_") - 1] == 'o')
11799 stdc_rid
= C_BUILTIN_STDC_COUNT_ONES
;
11801 stdc_rid
= C_BUILTIN_STDC_COUNT_ZEROS
;
11804 switch (name
[sizeof ("__builtin_stdc_first_trailing_") - 1])
11807 stdc_rid
= C_BUILTIN_STDC_FIRST_LEADING_ONE
;
11810 stdc_rid
= C_BUILTIN_STDC_FIRST_LEADING_ZERO
;
11813 stdc_rid
= C_BUILTIN_STDC_FIRST_TRAILING_ONE
;
11816 stdc_rid
= C_BUILTIN_STDC_FIRST_TRAILING_ZERO
;
11821 stdc_rid
= C_BUILTIN_STDC_HAS_SINGLE_BIT
;
11824 if (name
[sizeof ("__builtin_stdc_leading_") - 1] == 'o')
11825 stdc_rid
= C_BUILTIN_STDC_LEADING_ONES
;
11827 stdc_rid
= C_BUILTIN_STDC_LEADING_ZEROS
;
11830 if (name
[sizeof ("__builtin_stdc_trailing_") - 1] == 'o')
11831 stdc_rid
= C_BUILTIN_STDC_TRAILING_ONES
;
11833 stdc_rid
= C_BUILTIN_STDC_TRAILING_ZEROS
;
11836 gcc_checking_assert (stdc_rid
!= C_BUILTIN_STDC_MAX
);
11838 c_parser_consume_token (parser
);
11839 if (!c_parser_get_builtin_args (parser
, name
,
11840 &cexpr_list
, false,
11847 if (vec_safe_length (cexpr_list
) != 1)
11849 error_at (loc
, "wrong number of arguments to %qs", name
);
11854 arg_p
= &(*cexpr_list
)[0];
11855 *arg_p
= convert_lvalue_to_rvalue (loc
, *arg_p
, true, true);
11856 if (!INTEGRAL_TYPE_P (TREE_TYPE (arg_p
->value
)))
11858 error_at (loc
, "%qs operand not an integral type", name
);
11862 if (TREE_CODE (TREE_TYPE (arg_p
->value
)) == ENUMERAL_TYPE
)
11864 error_at (loc
, "argument %u in call to function "
11865 "%qs has enumerated type", 1, name
);
11869 if (TREE_CODE (TREE_TYPE (arg_p
->value
)) == BOOLEAN_TYPE
)
11871 error_at (loc
, "argument %u in call to function "
11872 "%qs has boolean type", 1, name
);
11876 if (!TYPE_UNSIGNED (TREE_TYPE (arg_p
->value
)))
11878 error_at (loc
, "argument 1 in call to function "
11879 "%qs has signed type", name
);
11883 tree arg
= arg_p
->value
;
11884 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (arg
));
11886 __builtin_stdc_leading_zeros (arg) as
11887 (unsigned int) __builtin_clzg (arg, prec)
11888 __builtin_stdc_leading_ones (arg) as
11889 (unsigned int) __builtin_clzg ((type) ~arg, prec)
11890 __builtin_stdc_trailing_zeros (arg) as
11891 (unsigned int) __builtin_ctzg (arg, prec)
11892 __builtin_stdc_trailing_ones (arg) as
11893 (unsigned int) __builtin_ctzg ((type) ~arg, prec)
11894 __builtin_stdc_first_leading_zero (arg) as
11895 __builtin_clzg ((type) ~arg, -1) + 1U
11896 __builtin_stdc_first_leading_one (arg) as
11897 __builtin_clzg (arg, -1) + 1U
11898 __builtin_stdc_first_trailing_zero (arg) as
11899 __builtin_ctzg ((type) ~arg, -1) + 1U
11900 __builtin_stdc_first_trailing_one (arg) as
11901 __builtin_ctzg (arg, -1) + 1U
11902 __builtin_stdc_count_zeros (arg) as
11903 (unsigned int) __builtin_popcountg ((type) ~arg)
11904 __builtin_stdc_count_ones (arg) as
11905 (unsigned int) __builtin_popcountg (arg)
11906 __builtin_stdc_has_single_bit (arg) as
11907 (_Bool) (__builtin_popcountg (arg) == 1)
11908 __builtin_stdc_bit_width (arg) as
11909 (unsigned int) (prec - __builtin_clzg (arg, prec))
11910 __builtin_stdc_bit_floor (arg) as
11911 arg == 0 ? (type) 0
11912 : (type) 1 << (prec - 1 - __builtin_clzg (arg))
11913 __builtin_stdc_bit_ceil (arg) as
11914 arg <= 1 ? (type) 1
11915 : (type) 2 << (prec - 1 - __builtin_clzg (arg - 1))
11916 without evaluating arg multiple times, type being
11917 __typeof (arg) and prec __builtin_popcountg ((type) ~0)). */
11918 int prec
= TYPE_PRECISION (type
);
11922 case C_BUILTIN_STDC_BIT_CEIL
:
11923 arg
= save_expr (arg
);
11924 barg1
= build2_loc (loc
, PLUS_EXPR
, type
, arg
,
11925 build_int_cst (type
, -1));
11927 case C_BUILTIN_STDC_BIT_FLOOR
:
11928 barg1
= arg
= save_expr (arg
);
11930 case C_BUILTIN_STDC_COUNT_ZEROS
:
11931 case C_BUILTIN_STDC_FIRST_LEADING_ZERO
:
11932 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO
:
11933 case C_BUILTIN_STDC_LEADING_ONES
:
11934 case C_BUILTIN_STDC_TRAILING_ONES
:
11935 barg1
= build1_loc (loc
, BIT_NOT_EXPR
, type
, arg
);
11940 tree barg2
= NULL_TREE
;
11943 case C_BUILTIN_STDC_BIT_WIDTH
:
11944 case C_BUILTIN_STDC_LEADING_ONES
:
11945 case C_BUILTIN_STDC_LEADING_ZEROS
:
11946 case C_BUILTIN_STDC_TRAILING_ONES
:
11947 case C_BUILTIN_STDC_TRAILING_ZEROS
:
11948 barg2
= build_int_cst (integer_type_node
, prec
);
11950 case C_BUILTIN_STDC_FIRST_LEADING_ONE
:
11951 case C_BUILTIN_STDC_FIRST_LEADING_ZERO
:
11952 case C_BUILTIN_STDC_FIRST_TRAILING_ONE
:
11953 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO
:
11954 barg2
= integer_minus_one_node
;
11959 tree fndecl
= NULL_TREE
;
11962 case C_BUILTIN_STDC_BIT_CEIL
:
11963 case C_BUILTIN_STDC_BIT_FLOOR
:
11964 case C_BUILTIN_STDC_BIT_WIDTH
:
11965 case C_BUILTIN_STDC_FIRST_LEADING_ONE
:
11966 case C_BUILTIN_STDC_FIRST_LEADING_ZERO
:
11967 case C_BUILTIN_STDC_LEADING_ONES
:
11968 case C_BUILTIN_STDC_LEADING_ZEROS
:
11969 fndecl
= builtin_decl_explicit (BUILT_IN_CLZG
);
11971 case C_BUILTIN_STDC_FIRST_TRAILING_ONE
:
11972 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO
:
11973 case C_BUILTIN_STDC_TRAILING_ONES
:
11974 case C_BUILTIN_STDC_TRAILING_ZEROS
:
11975 fndecl
= builtin_decl_explicit (BUILT_IN_CTZG
);
11977 case C_BUILTIN_STDC_COUNT_ONES
:
11978 case C_BUILTIN_STDC_COUNT_ZEROS
:
11979 case C_BUILTIN_STDC_HAS_SINGLE_BIT
:
11980 fndecl
= builtin_decl_explicit (BUILT_IN_POPCOUNTG
);
11983 gcc_unreachable ();
11985 /* Construct a call to __builtin_{clz,ctz,popcount}g. */
11986 int nargs
= barg2
!= NULL_TREE
? 2 : 1;
11987 vec
<tree
, va_gc
> *args
;
11988 vec_alloc (args
, nargs
);
11989 vec
<tree
, va_gc
> *origtypes
;
11990 vec_alloc (origtypes
, nargs
);
11991 auto_vec
<location_t
> arg_loc (nargs
);
11992 args
->quick_push (barg1
);
11993 arg_loc
.quick_push (arg_p
->get_location ());
11994 origtypes
->quick_push (arg_p
->original_type
);
11997 args
->quick_push (barg2
);
11998 arg_loc
.quick_push (loc
);
11999 origtypes
->quick_push (integer_type_node
);
12001 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fndecl
,
12003 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
12004 if (expr
.value
== error_mark_node
)
12008 case C_BUILTIN_STDC_BIT_CEIL
:
12009 case C_BUILTIN_STDC_BIT_FLOOR
:
12012 case C_BUILTIN_STDC_BIT_WIDTH
:
12013 expr
.value
= build2_loc (loc
, MINUS_EXPR
, integer_type_node
,
12014 build_int_cst (integer_type_node
,
12015 prec
), expr
.value
);
12017 case C_BUILTIN_STDC_FIRST_LEADING_ONE
:
12018 case C_BUILTIN_STDC_FIRST_LEADING_ZERO
:
12019 case C_BUILTIN_STDC_FIRST_TRAILING_ONE
:
12020 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO
:
12021 expr
.value
= build2_loc (loc
, PLUS_EXPR
, integer_type_node
,
12022 expr
.value
, integer_one_node
);
12024 case C_BUILTIN_STDC_HAS_SINGLE_BIT
:
12025 expr
.value
= build2_loc (loc
, EQ_EXPR
, boolean_type_node
,
12026 expr
.value
, integer_one_node
);
12032 if (stdc_rid
!= C_BUILTIN_STDC_BIT_CEIL
12033 && stdc_rid
!= C_BUILTIN_STDC_BIT_FLOOR
)
12035 if (stdc_rid
!= C_BUILTIN_STDC_HAS_SINGLE_BIT
)
12036 expr
.value
= fold_convert_loc (loc
, unsigned_type_node
,
12040 /* For __builtin_stdc_bit_ceil (0U) or __builtin_stdc_bit_ceil (1U)
12041 or __builtin_stdc_bit_floor (0U) avoid bogus -Wshift-count-*
12042 warnings. The LSHIFT_EXPR is in dead code in that case. */
12043 if (integer_zerop (arg
)
12044 || (stdc_rid
== C_BUILTIN_STDC_BIT_CEIL
&& integer_onep (arg
)))
12045 expr
.value
= build_int_cst (type
, 0);
12048 = build2_loc (loc
, LSHIFT_EXPR
, type
,
12049 build_int_cst (type
,
12051 == C_BUILTIN_STDC_BIT_CEIL
12052 ? 2 : 1)), expr
.value
);
12053 if (stdc_rid
== C_BUILTIN_STDC_BIT_CEIL
)
12054 expr
.value
= build3_loc (loc
, COND_EXPR
, type
,
12055 build2_loc (loc
, LE_EXPR
,
12056 boolean_type_node
, arg
,
12057 build_int_cst (type
, 1)),
12058 build_int_cst (type
, 1),
12061 expr
.value
= build3_loc (loc
, COND_EXPR
, type
,
12062 build2_loc (loc
, EQ_EXPR
,
12063 boolean_type_node
, arg
,
12064 build_int_cst (type
, 0)),
12065 build_int_cst (type
, 0),
12069 case RID_AT_SELECTOR
:
12071 gcc_assert (c_dialect_objc ());
12072 c_parser_consume_token (parser
);
12073 matching_parens parens
;
12074 if (!parens
.require_open (parser
))
12079 tree sel
= c_parser_objc_selector_arg (parser
);
12080 location_t close_loc
= c_parser_peek_token (parser
)->location
;
12081 parens
.skip_until_found_close (parser
);
12082 expr
.value
= objc_build_selector_expr (loc
, sel
);
12083 set_c_expr_source_range (&expr
, loc
, close_loc
);
12086 case RID_AT_PROTOCOL
:
12088 gcc_assert (c_dialect_objc ());
12089 c_parser_consume_token (parser
);
12090 matching_parens parens
;
12091 if (!parens
.require_open (parser
))
12096 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12098 c_parser_error (parser
, "expected identifier");
12099 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
12103 tree id
= c_parser_peek_token (parser
)->value
;
12104 c_parser_consume_token (parser
);
12105 location_t close_loc
= c_parser_peek_token (parser
)->location
;
12106 parens
.skip_until_found_close (parser
);
12107 expr
.value
= objc_build_protocol_expr (id
);
12108 set_c_expr_source_range (&expr
, loc
, close_loc
);
12111 case RID_AT_ENCODE
:
12113 /* Extension to support C-structures in the archiver. */
12114 gcc_assert (c_dialect_objc ());
12115 c_parser_consume_token (parser
);
12116 matching_parens parens
;
12117 if (!parens
.require_open (parser
))
12122 t1
= c_parser_type_name (parser
);
12126 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
12129 location_t close_loc
= c_parser_peek_token (parser
)->location
;
12130 parens
.skip_until_found_close (parser
);
12131 tree type
= groktypename (t1
, NULL
, NULL
);
12132 expr
.value
= objc_build_encode_expr (type
);
12133 set_c_expr_source_range (&expr
, loc
, close_loc
);
12137 expr
= c_parser_generic_selection (parser
);
12139 case RID_OMP_ALL_MEMORY
:
12140 gcc_assert (flag_openmp
);
12141 c_parser_consume_token (parser
);
12142 error_at (loc
, "%<omp_all_memory%> may only be used in OpenMP "
12143 "%<depend%> clause");
12146 /* C23 'nullptr' literal. */
12148 c_parser_consume_token (parser
);
12149 expr
.value
= nullptr_node
;
12150 set_c_expr_source_range (&expr
, tok_range
);
12151 pedwarn_c11 (loc
, OPT_Wpedantic
,
12152 "ISO C does not support %qs before C23", "nullptr");
12155 c_parser_consume_token (parser
);
12156 expr
.value
= boolean_true_node
;
12157 set_c_expr_source_range (&expr
, tok_range
);
12160 c_parser_consume_token (parser
);
12161 expr
.value
= boolean_false_node
;
12162 set_c_expr_source_range (&expr
, tok_range
);
12165 c_parser_error (parser
, "expected expression");
12170 case CPP_OPEN_SQUARE
:
12171 if (c_dialect_objc ())
12173 tree receiver
, args
;
12174 c_parser_consume_token (parser
);
12175 receiver
= c_parser_objc_receiver (parser
);
12176 args
= c_parser_objc_message_args (parser
);
12177 location_t close_loc
= c_parser_peek_token (parser
)->location
;
12178 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
12180 expr
.value
= objc_build_message_expr (receiver
, args
);
12181 set_c_expr_source_range (&expr
, loc
, close_loc
);
12184 /* Else fall through to report error. */
12187 c_parser_error (parser
, "expected expression");
12192 return c_parser_postfix_expression_after_primary
12193 (parser
, EXPR_LOC_OR_LOC (expr
.value
, loc
), expr
);
12196 /* Parse a postfix expression after a parenthesized type name: the
12197 brace-enclosed initializer of a compound literal, possibly followed
12198 by some postfix operators. This is separate because it is not
12199 possible to tell until after the type name whether a cast
12200 expression has a cast or a compound literal, or whether the operand
12201 of sizeof is a parenthesized type name or starts with a compound
12202 literal. TYPE_LOC is the location where TYPE_NAME starts--the
12203 location of the first token after the parentheses around the type
12206 static struct c_expr
12207 c_parser_postfix_expression_after_paren_type (c_parser
*parser
,
12208 struct c_declspecs
*scspecs
,
12209 struct c_type_name
*type_name
,
12210 location_t type_loc
)
12213 struct c_expr init
;
12215 struct c_expr expr
;
12216 location_t start_loc
;
12217 tree type_expr
= NULL_TREE
;
12218 bool type_expr_const
= true;
12219 bool constexpr_p
= scspecs
? scspecs
->constexpr_p
: false;
12220 unsigned int underspec_state
= 0;
12221 check_compound_literal_type (type_loc
, type_name
);
12222 rich_location
richloc (line_table
, type_loc
);
12223 start_loc
= c_parser_peek_token (parser
)->location
;
12226 underspec_state
= start_underspecified_init (start_loc
, NULL_TREE
);
12227 /* A constexpr compound literal is subject to the constraints on
12228 underspecified declarations, which may not declare tags or
12229 members or structures or unions; it is undefined behavior to
12230 declare the members of an enumeration. Where the structure,
12231 union or enumeration type is declared within the compound
12232 literal initializer, this is diagnosed elsewhere as a result
12233 of the above call to start_underspecified_init. Diagnose
12234 here the case of declaring such a type in the type specifiers
12235 of the compound literal. */
12236 switch (type_name
->specs
->typespec_kind
)
12238 case ctsk_tagfirstref
:
12239 case ctsk_tagfirstref_attrs
:
12240 error_at (type_loc
, "%qT declared in %<constexpr%> compound literal",
12241 type_name
->specs
->type
);
12245 error_at (type_loc
, "%qT defined in %<constexpr%> compound literal",
12246 type_name
->specs
->type
);
12253 start_init (NULL_TREE
, NULL
,
12254 (global_bindings_p ()
12255 || (scspecs
&& scspecs
->storage_class
== csc_static
)
12256 || constexpr_p
), constexpr_p
, &richloc
);
12257 type
= groktypename (type_name
, &type_expr
, &type_expr_const
);
12258 if (type
!= error_mark_node
&& C_TYPE_VARIABLE_SIZE (type
))
12260 error_at (type_loc
, "compound literal has variable size");
12261 type
= error_mark_node
;
12263 else if (TREE_CODE (type
) == FUNCTION_TYPE
)
12265 error_at (type_loc
, "compound literal has function type");
12266 type
= error_mark_node
;
12268 if (constexpr_p
&& type
!= error_mark_node
)
12270 tree type_no_array
= strip_array_types (type
);
12271 /* The type of a constexpr object must not be variably modified
12272 (which applies to all compound literals), volatile, atomic or
12273 restrict qualified or have a member with such a qualifier.
12274 const qualification is implicitly added. */
12275 if (TYPE_QUALS (type_no_array
)
12276 & (TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
| TYPE_QUAL_ATOMIC
))
12277 error_at (type_loc
, "invalid qualifiers for %<constexpr%> object");
12278 else if (RECORD_OR_UNION_TYPE_P (type_no_array
)
12279 && C_TYPE_FIELDS_NON_CONSTEXPR (type_no_array
))
12280 error_at (type_loc
, "invalid qualifiers for field of "
12281 "%<constexpr%> object");
12282 type
= c_build_qualified_type (type
,
12283 (TYPE_QUALS (type_no_array
)
12284 | TYPE_QUAL_CONST
));
12286 init
= c_parser_braced_init (parser
, type
, false, NULL
, NULL_TREE
);
12288 finish_underspecified_init (NULL_TREE
, underspec_state
);
12290 maybe_warn_string_init (type_loc
, type
, init
);
12292 if (type
!= error_mark_node
12293 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type
))
12294 && current_function_decl
)
12296 error ("compound literal qualified by address-space qualifier");
12297 type
= error_mark_node
;
12300 if (!pedwarn_c90 (start_loc
, OPT_Wpedantic
,
12301 "ISO C90 forbids compound literals") && scspecs
)
12302 pedwarn_c11 (start_loc
, OPT_Wpedantic
,
12303 "ISO C forbids storage class specifiers in compound literals "
12305 non_const
= ((init
.value
&& TREE_CODE (init
.value
) == CONSTRUCTOR
)
12306 ? CONSTRUCTOR_NON_CONST (init
.value
)
12307 : init
.original_code
== C_MAYBE_CONST_EXPR
);
12308 non_const
|= !type_expr_const
;
12309 unsigned int alignas_align
= 0;
12310 if (type
!= error_mark_node
12311 && type_name
->specs
->align_log
!= -1)
12313 alignas_align
= 1U << type_name
->specs
->align_log
;
12314 if (alignas_align
< min_align_of_type (type
))
12316 error_at (type_name
->specs
->locations
[cdw_alignas
],
12317 "%<_Alignas%> specifiers cannot reduce "
12318 "alignment of compound literal");
12322 expr
.value
= build_compound_literal (start_loc
, type
, init
.value
, non_const
,
12323 alignas_align
, scspecs
);
12324 set_c_expr_source_range (&expr
, init
.src_range
);
12325 expr
.m_decimal
= 0;
12326 expr
.original_code
= ERROR_MARK
;
12327 expr
.original_type
= NULL
;
12328 if (type
!= error_mark_node
12329 && expr
.value
!= error_mark_node
12332 if (TREE_CODE (expr
.value
) == C_MAYBE_CONST_EXPR
)
12334 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr
.value
) == NULL_TREE
);
12335 C_MAYBE_CONST_EXPR_PRE (expr
.value
) = type_expr
;
12339 gcc_assert (!non_const
);
12340 expr
.value
= build2 (C_MAYBE_CONST_EXPR
, type
,
12341 type_expr
, expr
.value
);
12344 return c_parser_postfix_expression_after_primary (parser
, start_loc
, expr
);
12347 /* Callback function for sizeof_pointer_memaccess_warning to compare
12351 sizeof_ptr_memacc_comptypes (tree type1
, tree type2
)
12353 return comptypes (type1
, type2
) == 1;
12356 /* Warn for patterns where abs-like function appears to be used incorrectly,
12357 gracefully ignore any non-abs-like function. The warning location should
12358 be LOC. FNDECL is the declaration of called function, it must be a
12359 BUILT_IN_NORMAL function. ARG is the first and only argument of the
12363 warn_for_abs (location_t loc
, tree fndecl
, tree arg
)
12365 /* Avoid warning in unreachable subexpressions. */
12366 if (c_inhibit_evaluation_warnings
)
12369 tree atype
= TREE_TYPE (arg
);
12371 /* Casts from pointers (and thus arrays and fndecls) will generate
12372 -Wint-conversion warnings. Most other wrong types hopefully lead to type
12373 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
12374 types and possibly other exotic types. */
12375 if (!INTEGRAL_TYPE_P (atype
)
12376 && !SCALAR_FLOAT_TYPE_P (atype
)
12377 && TREE_CODE (atype
) != COMPLEX_TYPE
)
12380 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
12385 case BUILT_IN_LABS
:
12386 case BUILT_IN_LLABS
:
12387 case BUILT_IN_IMAXABS
:
12388 if (!INTEGRAL_TYPE_P (atype
))
12390 if (SCALAR_FLOAT_TYPE_P (atype
))
12391 warning_at (loc
, OPT_Wabsolute_value
,
12392 "using integer absolute value function %qD when "
12393 "argument is of floating-point type %qT",
12395 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12396 warning_at (loc
, OPT_Wabsolute_value
,
12397 "using integer absolute value function %qD when "
12398 "argument is of complex type %qT", fndecl
, atype
);
12400 gcc_unreachable ();
12403 if (TYPE_UNSIGNED (atype
))
12404 warning_at (loc
, OPT_Wabsolute_value
,
12405 "taking the absolute value of unsigned type %qT "
12406 "has no effect", atype
);
12409 CASE_FLT_FN (BUILT_IN_FABS
):
12410 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS
):
12411 if (!SCALAR_FLOAT_TYPE_P (atype
)
12412 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype
)))
12414 if (INTEGRAL_TYPE_P (atype
))
12415 warning_at (loc
, OPT_Wabsolute_value
,
12416 "using floating-point absolute value function %qD "
12417 "when argument is of integer type %qT", fndecl
, atype
);
12418 else if (DECIMAL_FLOAT_TYPE_P (atype
))
12419 warning_at (loc
, OPT_Wabsolute_value
,
12420 "using floating-point absolute value function %qD "
12421 "when argument is of decimal floating-point type %qT",
12423 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12424 warning_at (loc
, OPT_Wabsolute_value
,
12425 "using floating-point absolute value function %qD when "
12426 "argument is of complex type %qT", fndecl
, atype
);
12428 gcc_unreachable ();
12433 CASE_FLT_FN (BUILT_IN_CABS
):
12434 if (TREE_CODE (atype
) != COMPLEX_TYPE
)
12436 if (INTEGRAL_TYPE_P (atype
))
12437 warning_at (loc
, OPT_Wabsolute_value
,
12438 "using complex absolute value function %qD when "
12439 "argument is of integer type %qT", fndecl
, atype
);
12440 else if (SCALAR_FLOAT_TYPE_P (atype
))
12441 warning_at (loc
, OPT_Wabsolute_value
,
12442 "using complex absolute value function %qD when "
12443 "argument is of floating-point type %qT",
12446 gcc_unreachable ();
12452 case BUILT_IN_FABSD32
:
12453 case BUILT_IN_FABSD64
:
12454 case BUILT_IN_FABSD128
:
12455 if (!DECIMAL_FLOAT_TYPE_P (atype
))
12457 if (INTEGRAL_TYPE_P (atype
))
12458 warning_at (loc
, OPT_Wabsolute_value
,
12459 "using decimal floating-point absolute value "
12460 "function %qD when argument is of integer type %qT",
12462 else if (SCALAR_FLOAT_TYPE_P (atype
))
12463 warning_at (loc
, OPT_Wabsolute_value
,
12464 "using decimal floating-point absolute value "
12465 "function %qD when argument is of floating-point "
12466 "type %qT", fndecl
, atype
);
12467 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12468 warning_at (loc
, OPT_Wabsolute_value
,
12469 "using decimal floating-point absolute value "
12470 "function %qD when argument is of complex type %qT",
12473 gcc_unreachable ();
12482 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl
)))
12485 tree ftype
= TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
12486 if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12488 gcc_assert (TREE_CODE (ftype
) == COMPLEX_TYPE
);
12489 atype
= TREE_TYPE (atype
);
12490 ftype
= TREE_TYPE (ftype
);
12493 if (TYPE_PRECISION (ftype
) < TYPE_PRECISION (atype
))
12494 warning_at (loc
, OPT_Wabsolute_value
,
12495 "absolute value function %qD given an argument of type %qT "
12496 "but has parameter of type %qT which may cause truncation "
12497 "of value", fndecl
, atype
, ftype
);
12501 /* Parse a postfix expression after the initial primary or compound
12502 literal; that is, parse a series of postfix operators.
12504 EXPR_LOC is the location of the primary expression. */
12506 static struct c_expr
12507 c_parser_postfix_expression_after_primary (c_parser
*parser
,
12508 location_t expr_loc
,
12509 struct c_expr expr
)
12511 struct c_expr orig_expr
;
12512 tree ident
, idx
, len
;
12513 location_t sizeof_arg_loc
[6], comp_loc
;
12514 tree sizeof_arg
[6];
12515 unsigned int literal_zero_mask
;
12517 vec
<tree
, va_gc
> *exprlist
;
12518 vec
<tree
, va_gc
> *origtypes
= NULL
;
12519 vec
<location_t
> arg_loc
= vNULL
;
12525 location_t op_loc
= c_parser_peek_token (parser
)->location
;
12526 switch (c_parser_peek_token (parser
)->type
)
12528 case CPP_OPEN_SQUARE
:
12529 /* Array reference. */
12530 c_parser_consume_token (parser
);
12531 idx
= len
= NULL_TREE
;
12532 if (!c_omp_array_section_p
12533 || c_parser_next_token_is_not (parser
, CPP_COLON
))
12534 idx
= c_parser_expression (parser
).value
;
12536 if (c_omp_array_section_p
12537 && c_parser_next_token_is (parser
, CPP_COLON
))
12539 c_parser_consume_token (parser
);
12540 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_SQUARE
))
12541 len
= c_parser_expression (parser
).value
;
12543 expr
.value
= build_omp_array_section (op_loc
, expr
.value
, idx
,
12547 expr
.value
= build_array_ref (op_loc
, expr
.value
, idx
);
12549 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
12552 start
= expr
.get_start ();
12553 finish
= parser
->tokens_buf
[0].location
;
12554 set_c_expr_source_range (&expr
, start
, finish
);
12555 expr
.original_code
= ERROR_MARK
;
12556 expr
.original_type
= NULL
;
12557 expr
.m_decimal
= 0;
12559 case CPP_OPEN_PAREN
:
12560 /* Function call. */
12562 matching_parens parens
;
12563 parens
.consume_open (parser
);
12564 for (i
= 0; i
< 6; i
++)
12566 sizeof_arg
[i
] = NULL_TREE
;
12567 sizeof_arg_loc
[i
] = UNKNOWN_LOCATION
;
12569 literal_zero_mask
= 0;
12570 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
12572 else if (TREE_CODE (expr
.value
) == FUNCTION_DECL
12573 && fndecl_built_in_p (expr
.value
, BUILT_IN_CLASSIFY_TYPE
)
12574 && c_parser_next_tokens_start_typename (parser
,
12577 /* __builtin_classify_type (type) */
12578 c_inhibit_evaluation_warnings
++;
12580 struct c_type_name
*type
= c_parser_type_name (parser
);
12581 c_inhibit_evaluation_warnings
--;
12583 struct c_typespec ret
;
12584 ret
.expr
= NULL_TREE
;
12585 ret
.spec
= error_mark_node
;
12586 ret
.expr_const_operands
= false;
12588 ret
.spec
= groktypename (type
, &ret
.expr
,
12589 &ret
.expr_const_operands
);
12590 parens
.skip_until_found_close (parser
);
12591 expr
.value
= build_int_cst (integer_type_node
,
12592 type_to_class (ret
.spec
));
12596 exprlist
= c_parser_expr_list (parser
, true, false, &origtypes
,
12597 sizeof_arg_loc
, sizeof_arg
,
12598 &arg_loc
, &literal_zero_mask
);
12599 parens
.skip_until_found_close (parser
);
12602 mark_exp_read (expr
.value
);
12603 if (warn_sizeof_pointer_memaccess
)
12604 sizeof_pointer_memaccess_warning (sizeof_arg_loc
,
12605 expr
.value
, exprlist
,
12607 sizeof_ptr_memacc_comptypes
);
12608 if (TREE_CODE (expr
.value
) == FUNCTION_DECL
)
12610 if (fndecl_built_in_p (expr
.value
, BUILT_IN_MEMSET
)
12611 && vec_safe_length (exprlist
) == 3)
12613 tree arg0
= (*exprlist
)[0];
12614 tree arg2
= (*exprlist
)[2];
12615 warn_for_memset (expr_loc
, arg0
, arg2
, literal_zero_mask
);
12617 if (warn_absolute_value
12618 && fndecl_built_in_p (expr
.value
, BUILT_IN_NORMAL
)
12619 && vec_safe_length (exprlist
) == 1)
12620 warn_for_abs (expr_loc
, expr
.value
, (*exprlist
)[0]);
12621 if (parser
->omp_for_parse_state
12622 && parser
->omp_for_parse_state
->in_intervening_code
12623 && omp_runtime_api_call (expr
.value
))
12625 error_at (expr_loc
, "calls to the OpenMP runtime API are "
12626 "not permitted in intervening code");
12627 parser
->omp_for_parse_state
->fail
= true;
12629 if (warn_calloc_transposed_args
)
12630 if (tree attr
= lookup_attribute ("alloc_size",
12632 (TREE_TYPE (expr
.value
))))
12633 if (TREE_VALUE (attr
) && TREE_CHAIN (TREE_VALUE (attr
)))
12634 warn_for_calloc (sizeof_arg_loc
, expr
.value
, exprlist
,
12638 start
= expr
.get_start ();
12639 finish
= parser
->tokens_buf
[0].get_finish ();
12641 = c_build_function_call_vec (expr_loc
, arg_loc
, expr
.value
,
12642 exprlist
, origtypes
);
12643 set_c_expr_source_range (&expr
, start
, finish
);
12644 expr
.m_decimal
= 0;
12646 expr
.original_code
= ERROR_MARK
;
12647 if (TREE_CODE (expr
.value
) == INTEGER_CST
12648 && TREE_CODE (orig_expr
.value
) == FUNCTION_DECL
12649 && fndecl_built_in_p (orig_expr
.value
, BUILT_IN_CONSTANT_P
))
12650 expr
.original_code
= C_MAYBE_CONST_EXPR
;
12651 expr
.original_type
= NULL
;
12654 release_tree_vector (exprlist
);
12655 release_tree_vector (origtypes
);
12657 arg_loc
.release ();
12660 /* Structure element reference. */
12661 c_parser_consume_token (parser
);
12662 expr
= default_function_array_conversion (expr_loc
, expr
);
12663 if (c_parser_next_token_is (parser
, CPP_NAME
))
12665 c_token
*comp_tok
= c_parser_peek_token (parser
);
12666 ident
= comp_tok
->value
;
12667 comp_loc
= comp_tok
->location
;
12671 c_parser_error (parser
, "expected identifier");
12673 expr
.original_code
= ERROR_MARK
;
12674 expr
.original_type
= NULL
;
12677 start
= expr
.get_start ();
12678 finish
= c_parser_peek_token (parser
)->get_finish ();
12679 c_parser_consume_token (parser
);
12680 expr
.value
= build_component_ref (op_loc
, expr
.value
, ident
,
12681 comp_loc
, UNKNOWN_LOCATION
);
12682 set_c_expr_source_range (&expr
, start
, finish
);
12683 expr
.original_code
= ERROR_MARK
;
12684 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
12685 expr
.original_type
= NULL
;
12688 /* Remember the original type of a bitfield. */
12689 tree field
= TREE_OPERAND (expr
.value
, 1);
12690 if (TREE_CODE (field
) != FIELD_DECL
)
12691 expr
.original_type
= NULL
;
12693 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
12695 expr
.m_decimal
= 0;
12698 /* Structure element reference. */
12699 c_parser_consume_token (parser
);
12700 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, false);
12701 if (c_parser_next_token_is (parser
, CPP_NAME
))
12703 c_token
*comp_tok
= c_parser_peek_token (parser
);
12704 ident
= comp_tok
->value
;
12705 comp_loc
= comp_tok
->location
;
12709 c_parser_error (parser
, "expected identifier");
12711 expr
.original_code
= ERROR_MARK
;
12712 expr
.original_type
= NULL
;
12715 start
= expr
.get_start ();
12716 finish
= c_parser_peek_token (parser
)->get_finish ();
12717 c_parser_consume_token (parser
);
12718 expr
.value
= build_component_ref (op_loc
,
12719 build_indirect_ref (op_loc
,
12723 expr
.get_location ());
12724 set_c_expr_source_range (&expr
, start
, finish
);
12725 expr
.original_code
= ERROR_MARK
;
12726 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
12727 expr
.original_type
= NULL
;
12730 /* Remember the original type of a bitfield. */
12731 tree field
= TREE_OPERAND (expr
.value
, 1);
12732 if (TREE_CODE (field
) != FIELD_DECL
)
12733 expr
.original_type
= NULL
;
12735 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
12737 expr
.m_decimal
= 0;
12739 case CPP_PLUS_PLUS
:
12740 /* Postincrement. */
12741 start
= expr
.get_start ();
12742 finish
= c_parser_peek_token (parser
)->get_finish ();
12743 c_parser_consume_token (parser
);
12744 expr
= default_function_array_read_conversion (expr_loc
, expr
);
12745 expr
.value
= build_unary_op (op_loc
, POSTINCREMENT_EXPR
,
12746 expr
.value
, false);
12747 set_c_expr_source_range (&expr
, start
, finish
);
12748 expr
.original_code
= ERROR_MARK
;
12749 expr
.original_type
= NULL
;
12751 case CPP_MINUS_MINUS
:
12752 /* Postdecrement. */
12753 start
= expr
.get_start ();
12754 finish
= c_parser_peek_token (parser
)->get_finish ();
12755 c_parser_consume_token (parser
);
12756 expr
= default_function_array_read_conversion (expr_loc
, expr
);
12757 expr
.value
= build_unary_op (op_loc
, POSTDECREMENT_EXPR
,
12758 expr
.value
, false);
12759 set_c_expr_source_range (&expr
, start
, finish
);
12760 expr
.original_code
= ERROR_MARK
;
12761 expr
.original_type
= NULL
;
12769 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
12772 assignment-expression
12773 expression , assignment-expression
12776 static struct c_expr
12777 c_parser_expression (c_parser
*parser
)
12779 location_t tloc
= c_parser_peek_token (parser
)->location
;
12780 struct c_expr expr
;
12781 expr
= c_parser_expr_no_commas (parser
, NULL
);
12782 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12783 expr
= convert_lvalue_to_rvalue (tloc
, expr
, true, false);
12784 while (c_parser_next_token_is (parser
, CPP_COMMA
))
12786 struct c_expr next
;
12788 location_t loc
= c_parser_peek_token (parser
)->location
;
12789 location_t expr_loc
;
12790 c_parser_consume_token (parser
);
12791 expr_loc
= c_parser_peek_token (parser
)->location
;
12792 lhsval
= expr
.value
;
12793 while (TREE_CODE (lhsval
) == COMPOUND_EXPR
12794 || TREE_CODE (lhsval
) == NOP_EXPR
)
12796 if (TREE_CODE (lhsval
) == COMPOUND_EXPR
)
12797 lhsval
= TREE_OPERAND (lhsval
, 1);
12799 lhsval
= TREE_OPERAND (lhsval
, 0);
12801 if (DECL_P (lhsval
) || handled_component_p (lhsval
))
12802 mark_exp_read (lhsval
);
12803 next
= c_parser_expr_no_commas (parser
, NULL
);
12804 next
= convert_lvalue_to_rvalue (expr_loc
, next
, true, false);
12805 expr
.value
= build_compound_expr (loc
, expr
.value
, next
.value
);
12806 expr
.original_code
= COMPOUND_EXPR
;
12807 expr
.original_type
= next
.original_type
;
12808 expr
.m_decimal
= 0;
12813 /* Parse an expression and convert functions or arrays to pointers and
12814 lvalues to rvalues. */
12816 static struct c_expr
12817 c_parser_expression_conv (c_parser
*parser
)
12819 struct c_expr expr
;
12820 location_t loc
= c_parser_peek_token (parser
)->location
;
12821 expr
= c_parser_expression (parser
);
12822 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, false);
12826 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
12827 argument is a literal zero alone and if so, set it in literal_zero_mask. */
12830 c_parser_check_literal_zero (c_parser
*parser
, unsigned *literal_zero_mask
,
12833 if (idx
>= HOST_BITS_PER_INT
)
12836 c_token
*tok
= c_parser_peek_token (parser
);
12845 /* If a parameter is literal zero alone, remember it
12846 for -Wmemset-transposed-args warning. */
12847 if (integer_zerop (tok
->value
)
12848 && !TREE_OVERFLOW (tok
->value
)
12849 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
12850 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
12851 *literal_zero_mask
|= 1U << idx
;
12857 /* Parse a non-empty list of expressions. If CONVERT_P, convert
12858 functions and arrays to pointers and lvalues to rvalues. If
12859 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
12860 locations of function arguments into this vector.
12862 nonempty-expr-list:
12863 assignment-expression
12864 nonempty-expr-list , assignment-expression
12867 static vec
<tree
, va_gc
> *
12868 c_parser_expr_list (c_parser
*parser
, bool convert_p
, bool fold_p
,
12869 vec
<tree
, va_gc
> **p_orig_types
,
12870 location_t
*sizeof_arg_loc
, tree
*sizeof_arg
,
12871 vec
<location_t
> *locations
,
12872 unsigned int *literal_zero_mask
)
12874 vec
<tree
, va_gc
> *ret
;
12875 vec
<tree
, va_gc
> *orig_types
;
12876 struct c_expr expr
;
12877 unsigned int idx
= 0;
12878 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
12879 c_omp_array_section_p
= false;
12881 ret
= make_tree_vector ();
12882 if (p_orig_types
== NULL
)
12885 orig_types
= make_tree_vector ();
12887 if (literal_zero_mask
)
12888 c_parser_check_literal_zero (parser
, literal_zero_mask
, 0);
12889 expr
= c_parser_expr_no_commas (parser
, NULL
);
12891 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true, true);
12893 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
12894 ret
->quick_push (expr
.value
);
12896 orig_types
->quick_push (expr
.original_type
);
12898 locations
->safe_push (expr
.get_location ());
12899 if (sizeof_arg
!= NULL
12900 && (expr
.original_code
== SIZEOF_EXPR
12901 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
12903 sizeof_arg
[0] = c_last_sizeof_arg
;
12904 sizeof_arg_loc
[0] = c_last_sizeof_loc
;
12906 while (c_parser_next_token_is (parser
, CPP_COMMA
))
12908 c_parser_consume_token (parser
);
12909 if (literal_zero_mask
)
12910 c_parser_check_literal_zero (parser
, literal_zero_mask
, idx
+ 1);
12911 expr
= c_parser_expr_no_commas (parser
, NULL
);
12913 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true,
12916 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
12917 vec_safe_push (ret
, expr
.value
);
12919 vec_safe_push (orig_types
, expr
.original_type
);
12921 locations
->safe_push (expr
.get_location ());
12923 && sizeof_arg
!= NULL
12924 && (expr
.original_code
== SIZEOF_EXPR
12925 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
12927 sizeof_arg
[idx
] = c_last_sizeof_arg
;
12928 sizeof_arg_loc
[idx
] = c_last_sizeof_loc
;
12932 *p_orig_types
= orig_types
;
12933 c_omp_array_section_p
= save_c_omp_array_section_p
;
12937 /* Parse Objective-C-specific constructs. */
12939 /* Parse an objc-class-definition.
12941 objc-class-definition:
12942 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
12943 objc-class-instance-variables[opt] objc-methodprotolist @end
12944 @implementation identifier objc-superclass[opt]
12945 objc-class-instance-variables[opt]
12946 @interface identifier ( identifier ) objc-protocol-refs[opt]
12947 objc-methodprotolist @end
12948 @interface identifier ( ) objc-protocol-refs[opt]
12949 objc-methodprotolist @end
12950 @implementation identifier ( identifier )
12955 "@interface identifier (" must start "@interface identifier (
12956 identifier ) ...": objc-methodprotolist in the first production may
12957 not start with a parenthesized identifier as a declarator of a data
12958 definition with no declaration specifiers if the objc-superclass,
12959 objc-protocol-refs and objc-class-instance-variables are omitted. */
12962 c_parser_objc_class_definition (c_parser
*parser
, tree attributes
)
12967 if (c_parser_next_token_is_keyword (parser
, RID_AT_INTERFACE
))
12969 else if (c_parser_next_token_is_keyword (parser
, RID_AT_IMPLEMENTATION
))
12972 gcc_unreachable ();
12974 c_parser_consume_token (parser
);
12975 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12977 c_parser_error (parser
, "expected identifier");
12980 id1
= c_parser_peek_token (parser
)->value
;
12981 location_t loc1
= c_parser_peek_token (parser
)->location
;
12982 c_parser_consume_token (parser
);
12983 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
12985 /* We have a category or class extension. */
12987 tree proto
= NULL_TREE
;
12988 matching_parens parens
;
12989 parens
.consume_open (parser
);
12990 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12992 if (iface_p
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
12994 /* We have a class extension. */
12999 c_parser_error (parser
, "expected identifier or %<)%>");
13000 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
13006 id2
= c_parser_peek_token (parser
)->value
;
13007 c_parser_consume_token (parser
);
13009 parens
.skip_until_found_close (parser
);
13012 objc_start_category_implementation (id1
, id2
);
13015 if (c_parser_next_token_is (parser
, CPP_LESS
))
13016 proto
= c_parser_objc_protocol_refs (parser
);
13017 objc_start_category_interface (id1
, id2
, proto
, attributes
);
13018 c_parser_objc_methodprotolist (parser
);
13019 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
13020 objc_finish_interface ();
13023 if (c_parser_next_token_is (parser
, CPP_COLON
))
13025 c_parser_consume_token (parser
);
13026 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13028 c_parser_error (parser
, "expected identifier");
13031 superclass
= c_parser_peek_token (parser
)->value
;
13032 c_parser_consume_token (parser
);
13035 superclass
= NULL_TREE
;
13038 tree proto
= NULL_TREE
;
13039 if (c_parser_next_token_is (parser
, CPP_LESS
))
13040 proto
= c_parser_objc_protocol_refs (parser
);
13041 objc_start_class_interface (id1
, loc1
, superclass
, proto
, attributes
);
13044 objc_start_class_implementation (id1
, superclass
);
13045 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
13046 c_parser_objc_class_instance_variables (parser
);
13049 objc_continue_interface ();
13050 c_parser_objc_methodprotolist (parser
);
13051 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
13052 objc_finish_interface ();
13056 objc_continue_implementation ();
13061 /* Parse objc-class-instance-variables.
13063 objc-class-instance-variables:
13064 { objc-instance-variable-decl-list[opt] }
13066 objc-instance-variable-decl-list:
13067 objc-visibility-spec
13068 objc-instance-variable-decl ;
13070 objc-instance-variable-decl-list objc-visibility-spec
13071 objc-instance-variable-decl-list objc-instance-variable-decl ;
13072 objc-instance-variable-decl-list ;
13074 objc-visibility-spec:
13079 objc-instance-variable-decl:
13084 c_parser_objc_class_instance_variables (c_parser
*parser
)
13086 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
13087 c_parser_consume_token (parser
);
13088 while (c_parser_next_token_is_not (parser
, CPP_EOF
))
13091 /* Parse any stray semicolon. */
13092 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
13094 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
13095 "extra semicolon");
13096 c_parser_consume_token (parser
);
13099 /* Stop if at the end of the instance variables. */
13100 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
13102 c_parser_consume_token (parser
);
13105 /* Parse any objc-visibility-spec. */
13106 if (c_parser_next_token_is_keyword (parser
, RID_AT_PRIVATE
))
13108 c_parser_consume_token (parser
);
13109 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE
);
13112 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROTECTED
))
13114 c_parser_consume_token (parser
);
13115 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED
);
13118 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PUBLIC
))
13120 c_parser_consume_token (parser
);
13121 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC
);
13124 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PACKAGE
))
13126 c_parser_consume_token (parser
);
13127 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE
);
13130 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
13132 c_parser_pragma (parser
, pragma_external
, NULL
);
13136 /* Parse some comma-separated declarations. */
13137 decls
= c_parser_struct_declaration (parser
, NULL
);
13140 /* There is a syntax error. We want to skip the offending
13141 tokens up to the next ';' (included) or '}'
13144 /* First, skip manually a ')' or ']'. This is because they
13145 reduce the nesting level, so c_parser_skip_until_found()
13146 wouldn't be able to skip past them. */
13147 c_token
*token
= c_parser_peek_token (parser
);
13148 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_CLOSE_SQUARE
)
13149 c_parser_consume_token (parser
);
13151 /* Then, do the standard skipping. */
13152 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
13154 /* We hopefully recovered. Start normal parsing again. */
13155 parser
->error
= false;
13160 /* Comma-separated instance variables are chained together
13161 in reverse order; add them one by one. */
13162 tree ivar
= nreverse (decls
);
13163 for (; ivar
; ivar
= DECL_CHAIN (ivar
))
13164 objc_add_instance_variable (copy_node (ivar
));
13166 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13170 /* Parse an objc-class-declaration.
13172 objc-class-declaration:
13173 @class identifier-list ;
13177 c_parser_objc_class_declaration (c_parser
*parser
)
13179 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_CLASS
));
13180 c_parser_consume_token (parser
);
13181 /* Any identifiers, including those declared as type names, are OK
13186 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13188 c_parser_error (parser
, "expected identifier");
13189 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
13190 parser
->error
= false;
13193 id
= c_parser_peek_token (parser
)->value
;
13194 objc_declare_class (id
);
13195 c_parser_consume_token (parser
);
13196 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13197 c_parser_consume_token (parser
);
13201 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13204 /* Parse an objc-alias-declaration.
13206 objc-alias-declaration:
13207 @compatibility_alias identifier identifier ;
13211 c_parser_objc_alias_declaration (c_parser
*parser
)
13214 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_ALIAS
));
13215 c_parser_consume_token (parser
);
13216 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13218 c_parser_error (parser
, "expected identifier");
13219 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
13222 id1
= c_parser_peek_token (parser
)->value
;
13223 c_parser_consume_token (parser
);
13224 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13226 c_parser_error (parser
, "expected identifier");
13227 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
13230 id2
= c_parser_peek_token (parser
)->value
;
13231 c_parser_consume_token (parser
);
13232 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13233 objc_declare_alias (id1
, id2
);
13236 /* Parse an objc-protocol-definition.
13238 objc-protocol-definition:
13239 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
13240 @protocol identifier-list ;
13242 "@protocol identifier ;" should be resolved as "@protocol
13243 identifier-list ;": objc-methodprotolist may not start with a
13244 semicolon in the first alternative if objc-protocol-refs are
13248 c_parser_objc_protocol_definition (c_parser
*parser
, tree attributes
)
13250 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROTOCOL
));
13252 c_parser_consume_token (parser
);
13253 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13255 c_parser_error (parser
, "expected identifier");
13258 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
13259 || c_parser_peek_2nd_token (parser
)->type
== CPP_SEMICOLON
)
13261 /* Any identifiers, including those declared as type names, are
13266 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13268 c_parser_error (parser
, "expected identifier");
13271 id
= c_parser_peek_token (parser
)->value
;
13272 objc_declare_protocol (id
, attributes
);
13273 c_parser_consume_token (parser
);
13274 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13275 c_parser_consume_token (parser
);
13279 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13283 tree id
= c_parser_peek_token (parser
)->value
;
13284 tree proto
= NULL_TREE
;
13285 c_parser_consume_token (parser
);
13286 if (c_parser_next_token_is (parser
, CPP_LESS
))
13287 proto
= c_parser_objc_protocol_refs (parser
);
13288 parser
->objc_pq_context
= true;
13289 objc_start_protocol (id
, proto
, attributes
);
13290 c_parser_objc_methodprotolist (parser
);
13291 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
13292 parser
->objc_pq_context
= false;
13293 objc_finish_interface ();
13297 /* Parse an objc-method-type.
13303 Return true if it is a class method (+) and false if it is
13304 an instance method (-).
13307 c_parser_objc_method_type (c_parser
*parser
)
13309 switch (c_parser_peek_token (parser
)->type
)
13312 c_parser_consume_token (parser
);
13315 c_parser_consume_token (parser
);
13318 gcc_unreachable ();
13322 /* Parse an objc-method-definition.
13324 objc-method-definition:
13325 objc-method-type objc-method-decl ;[opt] compound-statement
13329 c_parser_objc_method_definition (c_parser
*parser
)
13331 bool is_class_method
= c_parser_objc_method_type (parser
);
13332 tree decl
, attributes
= NULL_TREE
, expr
= NULL_TREE
;
13333 parser
->objc_pq_context
= true;
13334 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
13336 if (decl
== error_mark_node
)
13337 return; /* Bail here. */
13339 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
13341 c_parser_consume_token (parser
);
13342 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
13343 "extra semicolon in method definition specified");
13346 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
13348 c_parser_error (parser
, "expected %<{%>");
13352 parser
->objc_pq_context
= false;
13353 if (objc_start_method_definition (is_class_method
, decl
, attributes
, expr
))
13355 add_stmt (c_parser_compound_statement (parser
));
13356 objc_finish_method_definition (current_function_decl
);
13360 /* This code is executed when we find a method definition
13361 outside of an @implementation context (or invalid for other
13362 reasons). Parse the method (to keep going) but do not emit
13365 c_parser_compound_statement (parser
);
13369 /* Parse an objc-methodprotolist.
13371 objc-methodprotolist:
13373 objc-methodprotolist objc-methodproto
13374 objc-methodprotolist declaration
13375 objc-methodprotolist ;
13379 The declaration is a data definition, which may be missing
13380 declaration specifiers under the same rules and diagnostics as
13381 other data definitions outside functions, and the stray semicolon
13382 is diagnosed the same way as a stray semicolon outside a
13386 c_parser_objc_methodprotolist (c_parser
*parser
)
13390 /* The list is terminated by @end. */
13391 switch (c_parser_peek_token (parser
)->type
)
13393 case CPP_SEMICOLON
:
13394 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
13395 "ISO C does not allow extra %<;%> outside of a function");
13396 c_parser_consume_token (parser
);
13400 c_parser_objc_methodproto (parser
);
13403 c_parser_pragma (parser
, pragma_external
, NULL
);
13408 if (c_parser_next_token_is_keyword (parser
, RID_AT_END
))
13410 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
))
13411 c_parser_objc_at_property_declaration (parser
);
13412 else if (c_parser_next_token_is_keyword (parser
, RID_AT_OPTIONAL
))
13414 objc_set_method_opt (true);
13415 c_parser_consume_token (parser
);
13417 else if (c_parser_next_token_is_keyword (parser
, RID_AT_REQUIRED
))
13419 objc_set_method_opt (false);
13420 c_parser_consume_token (parser
);
13423 c_parser_declaration_or_fndef (parser
, false, false, true,
13430 /* Parse an objc-methodproto.
13433 objc-method-type objc-method-decl ;
13437 c_parser_objc_methodproto (c_parser
*parser
)
13439 bool is_class_method
= c_parser_objc_method_type (parser
);
13440 tree decl
, attributes
= NULL_TREE
;
13442 /* Remember protocol qualifiers in prototypes. */
13443 parser
->objc_pq_context
= true;
13444 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
13446 /* Forget protocol qualifiers now. */
13447 parser
->objc_pq_context
= false;
13449 /* Do not allow the presence of attributes to hide an erroneous
13450 method implementation in the interface section. */
13451 if (!c_parser_next_token_is (parser
, CPP_SEMICOLON
))
13453 c_parser_error (parser
, "expected %<;%>");
13457 if (decl
!= error_mark_node
)
13458 objc_add_method_declaration (is_class_method
, decl
, attributes
);
13460 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13463 /* If we are at a position that method attributes may be present, check that
13464 there are not any parsed already (a syntax error) and then collect any
13465 specified at the current location. Finally, if new attributes were present,
13466 check that the next token is legal ( ';' for decls and '{' for defs). */
13469 c_parser_objc_maybe_method_attributes (c_parser
* parser
, tree
* attributes
)
13474 c_parser_error (parser
,
13475 "method attributes must be specified at the end only");
13476 *attributes
= NULL_TREE
;
13480 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
13481 *attributes
= c_parser_gnu_attributes (parser
);
13483 /* If there were no attributes here, just report any earlier error. */
13484 if (*attributes
== NULL_TREE
|| bad
)
13487 /* If the attributes are followed by a ; or {, then just report any earlier
13489 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
13490 || c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
13493 /* We've got attributes, but not at the end. */
13494 c_parser_error (parser
,
13495 "expected %<;%> or %<{%> after method attribute definition");
13499 /* Parse an objc-method-decl.
13502 ( objc-type-name ) objc-selector
13504 ( objc-type-name ) objc-keyword-selector objc-optparmlist
13505 objc-keyword-selector objc-optparmlist
13508 objc-keyword-selector:
13510 objc-keyword-selector objc-keyword-decl
13513 objc-selector : ( objc-type-name ) identifier
13514 objc-selector : identifier
13515 : ( objc-type-name ) identifier
13519 objc-optparms objc-optellipsis
13523 objc-opt-parms , parameter-declaration
13531 c_parser_objc_method_decl (c_parser
*parser
, bool is_class_method
,
13532 tree
*attributes
, tree
*expr
)
13534 tree type
= NULL_TREE
;
13536 tree parms
= NULL_TREE
;
13537 bool ellipsis
= false;
13538 bool attr_err
= false;
13540 *attributes
= NULL_TREE
;
13541 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13543 matching_parens parens
;
13544 parens
.consume_open (parser
);
13545 type
= c_parser_objc_type_name (parser
);
13546 parens
.skip_until_found_close (parser
);
13548 sel
= c_parser_objc_selector (parser
);
13549 /* If there is no selector, or a colon follows, we have an
13550 objc-keyword-selector. If there is a selector, and a colon does
13551 not follow, that selector ends the objc-method-decl. */
13552 if (!sel
|| c_parser_next_token_is (parser
, CPP_COLON
))
13555 tree list
= NULL_TREE
;
13558 tree atype
= NULL_TREE
, id
, keyworddecl
;
13559 tree param_attr
= NULL_TREE
;
13560 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
13562 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13564 c_parser_consume_token (parser
);
13565 atype
= c_parser_objc_type_name (parser
);
13566 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
13569 /* New ObjC allows attributes on method parameters. */
13570 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
13571 param_attr
= c_parser_gnu_attributes (parser
);
13572 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13574 c_parser_error (parser
, "expected identifier");
13575 return error_mark_node
;
13577 id
= c_parser_peek_token (parser
)->value
;
13578 c_parser_consume_token (parser
);
13579 keyworddecl
= objc_build_keyword_decl (tsel
, atype
, id
, param_attr
);
13580 list
= chainon (list
, keyworddecl
);
13581 tsel
= c_parser_objc_selector (parser
);
13582 if (!tsel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
13586 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
13588 /* Parse the optional parameter list. Optional Objective-C
13589 method parameters follow the C syntax, and may include '...'
13590 to denote a variable number of arguments. */
13591 parms
= make_node (TREE_LIST
);
13592 while (c_parser_next_token_is (parser
, CPP_COMMA
))
13594 struct c_parm
*parm
;
13595 c_parser_consume_token (parser
);
13596 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
13599 c_parser_consume_token (parser
);
13600 attr_err
|= c_parser_objc_maybe_method_attributes
13601 (parser
, attributes
) ;
13604 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
13607 parms
= chainon (parms
,
13608 build_tree_list (NULL_TREE
, grokparm (parm
, expr
)));
13613 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
13617 c_parser_error (parser
, "objective-c method declaration is expected");
13618 return error_mark_node
;
13622 return error_mark_node
;
13624 return objc_build_method_signature (is_class_method
, type
, sel
, parms
, ellipsis
);
13627 /* Parse an objc-type-name.
13630 objc-type-qualifiers[opt] type-name
13631 objc-type-qualifiers[opt]
13633 objc-type-qualifiers:
13634 objc-type-qualifier
13635 objc-type-qualifiers objc-type-qualifier
13637 objc-type-qualifier: one of
13638 in out inout bycopy byref oneway
13642 c_parser_objc_type_name (c_parser
*parser
)
13644 tree quals
= NULL_TREE
;
13645 struct c_type_name
*type_name
= NULL
;
13646 tree type
= NULL_TREE
;
13649 c_token
*token
= c_parser_peek_token (parser
);
13650 if (token
->type
== CPP_KEYWORD
13651 && (token
->keyword
== RID_IN
13652 || token
->keyword
== RID_OUT
13653 || token
->keyword
== RID_INOUT
13654 || token
->keyword
== RID_BYCOPY
13655 || token
->keyword
== RID_BYREF
13656 || token
->keyword
== RID_ONEWAY
))
13658 quals
= chainon (build_tree_list (NULL_TREE
, token
->value
), quals
);
13659 c_parser_consume_token (parser
);
13664 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
13665 type_name
= c_parser_type_name (parser
);
13667 type
= groktypename (type_name
, NULL
, NULL
);
13669 /* If the type is unknown, and error has already been produced and
13670 we need to recover from the error. In that case, use NULL_TREE
13671 for the type, as if no type had been specified; this will use the
13672 default type ('id') which is good for error recovery. */
13673 if (type
== error_mark_node
)
13676 return build_tree_list (quals
, type
);
13679 /* Parse objc-protocol-refs.
13681 objc-protocol-refs:
13682 < identifier-list >
13686 c_parser_objc_protocol_refs (c_parser
*parser
)
13688 tree list
= NULL_TREE
;
13689 gcc_assert (c_parser_next_token_is (parser
, CPP_LESS
));
13690 c_parser_consume_token (parser
);
13691 /* Any identifiers, including those declared as type names, are OK
13696 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13698 c_parser_error (parser
, "expected identifier");
13701 id
= c_parser_peek_token (parser
)->value
;
13702 list
= chainon (list
, build_tree_list (NULL_TREE
, id
));
13703 c_parser_consume_token (parser
);
13704 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13705 c_parser_consume_token (parser
);
13709 c_parser_require (parser
, CPP_GREATER
, "expected %<>%>");
13713 /* Parse an objc-try-catch-finally-statement.
13715 objc-try-catch-finally-statement:
13716 @try compound-statement objc-catch-list[opt]
13717 @try compound-statement objc-catch-list[opt] @finally compound-statement
13720 @catch ( objc-catch-parameter-declaration ) compound-statement
13721 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
13723 objc-catch-parameter-declaration:
13724 parameter-declaration
13727 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
13729 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
13730 for C++. Keep them in sync. */
13733 c_parser_objc_try_catch_finally_statement (c_parser
*parser
)
13735 location_t location
;
13738 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_TRY
));
13739 c_parser_consume_token (parser
);
13740 location
= c_parser_peek_token (parser
)->location
;
13741 objc_maybe_warn_exceptions (location
);
13742 stmt
= c_parser_compound_statement (parser
);
13743 objc_begin_try_stmt (location
, stmt
);
13745 while (c_parser_next_token_is_keyword (parser
, RID_AT_CATCH
))
13747 struct c_parm
*parm
;
13748 tree parameter_declaration
= error_mark_node
;
13749 bool seen_open_paren
= false;
13751 c_parser_consume_token (parser
);
13752 matching_parens parens
;
13753 if (!parens
.require_open (parser
))
13754 seen_open_paren
= true;
13755 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
13757 /* We have "@catch (...)" (where the '...' are literally
13758 what is in the code). Skip the '...'.
13759 parameter_declaration is set to NULL_TREE, and
13760 objc_being_catch_clauses() knows that that means
13762 c_parser_consume_token (parser
);
13763 parameter_declaration
= NULL_TREE
;
13767 /* We have "@catch (NSException *exception)" or something
13768 like that. Parse the parameter declaration. */
13769 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
13771 parameter_declaration
= error_mark_node
;
13773 parameter_declaration
= grokparm (parm
, NULL
);
13775 if (seen_open_paren
)
13776 parens
.require_close (parser
);
13779 /* If there was no open parenthesis, we are recovering from
13780 an error, and we are trying to figure out what mistake
13781 the user has made. */
13783 /* If there is an immediate closing parenthesis, the user
13784 probably forgot the opening one (ie, they typed "@catch
13785 NSException *e)". Parse the closing parenthesis and keep
13787 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
13788 c_parser_consume_token (parser
);
13790 /* If these is no immediate closing parenthesis, the user
13791 probably doesn't know that parenthesis are required at
13792 all (ie, they typed "@catch NSException *e"). So, just
13793 forget about the closing parenthesis and keep going. */
13795 objc_begin_catch_clause (parameter_declaration
);
13796 if (c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
13797 c_parser_compound_statement_nostart (parser
);
13798 objc_finish_catch_clause ();
13800 if (c_parser_next_token_is_keyword (parser
, RID_AT_FINALLY
))
13802 c_parser_consume_token (parser
);
13803 location
= c_parser_peek_token (parser
)->location
;
13804 stmt
= c_parser_compound_statement (parser
);
13805 objc_build_finally_clause (location
, stmt
);
13807 objc_finish_try_stmt ();
13810 /* Parse an objc-synchronized-statement.
13812 objc-synchronized-statement:
13813 @synchronized ( expression ) compound-statement
13817 c_parser_objc_synchronized_statement (c_parser
*parser
)
13821 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNCHRONIZED
));
13822 c_parser_consume_token (parser
);
13823 loc
= c_parser_peek_token (parser
)->location
;
13824 objc_maybe_warn_exceptions (loc
);
13825 matching_parens parens
;
13826 if (parens
.require_open (parser
))
13828 struct c_expr ce
= c_parser_expression (parser
);
13829 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
13831 expr
= c_fully_fold (expr
, false, NULL
);
13832 parens
.skip_until_found_close (parser
);
13835 expr
= error_mark_node
;
13836 stmt
= c_parser_compound_statement (parser
);
13837 objc_build_synchronized (loc
, expr
, stmt
);
13840 /* Parse an objc-selector; return NULL_TREE without an error if the
13841 next token is not an objc-selector.
13846 enum struct union if else while do for switch case default
13847 break continue return goto asm sizeof typeof typeof_unqual __alignof
13848 unsigned long const short volatile signed restrict _Complex
13849 in out inout bycopy byref oneway int char float double void _Bool
13852 ??? Why this selection of keywords but not, for example, storage
13853 class specifiers? */
13856 c_parser_objc_selector (c_parser
*parser
)
13858 c_token
*token
= c_parser_peek_token (parser
);
13859 tree value
= token
->value
;
13860 if (token
->type
== CPP_NAME
)
13862 c_parser_consume_token (parser
);
13865 if (token
->type
!= CPP_KEYWORD
)
13867 switch (token
->keyword
)
13887 case RID_TYPEOF_UNQUAL
:
13907 CASE_RID_FLOATN_NX
:
13911 case RID_AUTO_TYPE
:
13916 c_parser_consume_token (parser
);
13923 /* Parse an objc-selector-arg.
13927 objc-keywordname-list
13929 objc-keywordname-list:
13931 objc-keywordname-list objc-keywordname
13939 c_parser_objc_selector_arg (c_parser
*parser
)
13941 tree sel
= c_parser_objc_selector (parser
);
13942 tree list
= NULL_TREE
;
13944 && c_parser_next_token_is_not (parser
, CPP_COLON
)
13945 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
13949 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
13951 c_parser_consume_token (parser
);
13952 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
13953 list
= chainon (list
, build_tree_list (NULL_TREE
, NULL_TREE
));
13957 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
13959 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
13961 sel
= c_parser_objc_selector (parser
);
13963 && c_parser_next_token_is_not (parser
, CPP_COLON
)
13964 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
13970 /* Parse an objc-receiver.
13979 c_parser_objc_receiver (c_parser
*parser
)
13981 location_t loc
= c_parser_peek_token (parser
)->location
;
13983 if (c_parser_peek_token (parser
)->type
== CPP_NAME
13984 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
13985 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
13987 tree id
= c_parser_peek_token (parser
)->value
;
13988 c_parser_consume_token (parser
);
13989 return objc_get_class_reference (id
);
13991 struct c_expr ce
= c_parser_expression (parser
);
13992 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
13993 return c_fully_fold (ce
.value
, false, NULL
);
13996 /* Parse objc-message-args.
14000 objc-keywordarg-list
14002 objc-keywordarg-list:
14004 objc-keywordarg-list objc-keywordarg
14007 objc-selector : objc-keywordexpr
14012 c_parser_objc_message_args (c_parser
*parser
)
14014 tree sel
= c_parser_objc_selector (parser
);
14015 tree list
= NULL_TREE
;
14016 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
14021 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14022 return error_mark_node
;
14023 keywordexpr
= c_parser_objc_keywordexpr (parser
);
14024 list
= chainon (list
, build_tree_list (sel
, keywordexpr
));
14025 sel
= c_parser_objc_selector (parser
);
14026 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
14032 /* Parse an objc-keywordexpr.
14039 c_parser_objc_keywordexpr (c_parser
*parser
)
14042 vec
<tree
, va_gc
> *expr_list
= c_parser_expr_list (parser
, true, true,
14043 NULL
, NULL
, NULL
, NULL
);
14044 if (vec_safe_length (expr_list
) == 1)
14046 /* Just return the expression, remove a level of
14048 ret
= (*expr_list
)[0];
14052 /* We have a comma expression, we will collapse later. */
14053 ret
= build_tree_list_vec (expr_list
);
14055 release_tree_vector (expr_list
);
14059 /* A check, needed in several places, that ObjC interface, implementation or
14060 method definitions are not prefixed by incorrect items. */
14062 c_parser_objc_diagnose_bad_element_prefix (c_parser
*parser
,
14063 struct c_declspecs
*specs
)
14065 if (!specs
->declspecs_seen_p
|| specs
->non_sc_seen_p
14066 || specs
->typespec_kind
!= ctsk_none
)
14068 c_parser_error (parser
,
14069 "no type or storage class may be specified here,");
14070 c_parser_skip_to_end_of_block_or_statement (parser
);
14076 /* Parse an Objective-C @property declaration. The syntax is:
14078 objc-property-declaration:
14079 '@property' objc-property-attributes[opt] struct-declaration ;
14081 objc-property-attributes:
14082 '(' objc-property-attribute-list ')'
14084 objc-property-attribute-list:
14085 objc-property-attribute
14086 objc-property-attribute-list, objc-property-attribute
14088 objc-property-attribute
14089 'getter' = identifier
14090 'setter' = identifier
14099 @property NSString *name;
14100 @property (readonly) id object;
14101 @property (retain, nonatomic, getter=getTheName) id name;
14102 @property int a, b, c;
14104 PS: This function is identical to cp_parser_objc_at_propery_declaration
14105 for C++. Keep them in sync. */
14107 c_parser_objc_at_property_declaration (c_parser
*parser
)
14109 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
));
14110 location_t loc
= c_parser_peek_token (parser
)->location
;
14111 c_parser_consume_token (parser
); /* Eat '@property'. */
14113 /* Parse the optional attribute list.
14115 A list of parsed, but not verified, attributes. */
14116 vec
<property_attribute_info
*> prop_attr_list
= vNULL
;
14118 bool syntax_error
= false;
14119 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14121 matching_parens parens
;
14123 location_t attr_start
= c_parser_peek_token (parser
)->location
;
14125 parens
.consume_open (parser
);
14127 /* Property attribute keywords are valid now. */
14128 parser
->objc_property_attr_context
= true;
14130 /* Allow @property (), with a warning. */
14131 location_t attr_end
= c_parser_peek_token (parser
)->location
;
14133 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
14135 location_t attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
14136 warning_at (attr_comb
, OPT_Wattributes
,
14137 "empty property attribute list");
14142 c_token
*token
= c_parser_peek_token (parser
);
14143 attr_start
= token
->location
;
14144 attr_end
= get_finish (token
->location
);
14145 location_t attr_comb
= make_location (attr_start
, attr_start
,
14148 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_COMMA
)
14150 warning_at (attr_comb
, OPT_Wattributes
,
14151 "missing property attribute");
14152 if (token
->type
== CPP_CLOSE_PAREN
)
14154 c_parser_consume_token (parser
);
14158 tree attr_name
= NULL_TREE
;
14159 enum rid keyword
= RID_MAX
; /* Not a valid property attribute. */
14160 bool add_at
= false;
14161 if (token
->type
== CPP_KEYWORD
)
14163 keyword
= token
->keyword
;
14164 if (OBJC_IS_AT_KEYWORD (keyword
))
14166 /* For '@' keywords the token value has the keyword,
14167 prepend the '@' for diagnostics. */
14168 attr_name
= token
->value
;
14172 attr_name
= ridpointers
[(int)keyword
];
14174 else if (token
->type
== CPP_NAME
)
14175 attr_name
= token
->value
;
14176 c_parser_consume_token (parser
);
14178 enum objc_property_attribute_kind prop_kind
14179 = objc_prop_attr_kind_for_rid (keyword
);
14180 property_attribute_info
*prop
14181 = new property_attribute_info (attr_name
, attr_comb
, prop_kind
);
14182 prop_attr_list
.safe_push (prop
);
14185 switch (prop
->prop_kind
)
14188 case OBJC_PROPERTY_ATTR_UNKNOWN
:
14190 error_at (attr_comb
, "unknown property attribute %<%s%s%>",
14191 add_at
? "@" : "", IDENTIFIER_POINTER (attr_name
));
14193 error_at (attr_comb
, "unknown property attribute");
14194 prop
->parse_error
= syntax_error
= true;
14197 case OBJC_PROPERTY_ATTR_GETTER
:
14198 case OBJC_PROPERTY_ATTR_SETTER
:
14199 if (c_parser_next_token_is_not (parser
, CPP_EQ
))
14201 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
14202 error_at (attr_comb
, "expected %<=%> after Objective-C %qE",
14204 prop
->parse_error
= syntax_error
= true;
14207 token
= c_parser_peek_token (parser
);
14208 attr_end
= token
->location
;
14209 c_parser_consume_token (parser
); /* eat the = */
14210 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14212 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
14213 error_at (attr_comb
, "expected %qE selector name",
14215 prop
->parse_error
= syntax_error
= true;
14218 /* Get the end of the method name, and consume the name. */
14219 token
= c_parser_peek_token (parser
);
14220 attr_end
= get_finish (token
->location
);
14221 meth_name
= token
->value
;
14222 c_parser_consume_token (parser
);
14223 if (prop
->prop_kind
== OBJC_PROPERTY_ATTR_SETTER
)
14225 if (c_parser_next_token_is_not (parser
, CPP_COLON
))
14227 attr_comb
= make_location (attr_end
, attr_start
,
14229 error_at (attr_comb
, "setter method names must"
14230 " terminate with %<:%>");
14231 prop
->parse_error
= syntax_error
= true;
14235 attr_end
= get_finish (c_parser_peek_token
14236 (parser
)->location
);
14237 c_parser_consume_token (parser
);
14239 attr_comb
= make_location (attr_start
, attr_start
,
14243 attr_comb
= make_location (attr_start
, attr_start
,
14245 prop
->ident
= meth_name
;
14246 /* Updated location including all that was successfully
14248 prop
->prop_loc
= attr_comb
;
14252 /* If we see a comma here, then keep going - even if we already
14253 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
14254 this makes a more useful output and avoid spurious warnings about
14255 missing attributes that are, in fact, specified after the one with
14256 the syntax error. */
14257 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14258 c_parser_consume_token (parser
);
14262 parser
->objc_property_attr_context
= false;
14264 if (syntax_error
&& c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
14265 /* We don't really want to chew the whole of the file looking for a
14266 matching closing parenthesis, so we will try to read the decl and
14267 let the error handling for that close out the statement. */
14270 syntax_error
= false, parens
.skip_until_found_close (parser
);
14273 /* 'properties' is the list of properties that we read. Usually a
14274 single one, but maybe more (eg, in "@property int a, b, c;" there
14276 tree properties
= c_parser_struct_declaration (parser
, NULL
);
14278 if (properties
== error_mark_node
)
14279 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
14282 if (properties
== NULL_TREE
)
14283 c_parser_error (parser
, "expected identifier");
14286 /* Comma-separated properties are chained together in reverse order;
14287 add them one by one. */
14288 properties
= nreverse (properties
);
14289 for (; properties
; properties
= TREE_CHAIN (properties
))
14290 objc_add_property_declaration (loc
, copy_node (properties
),
14293 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
14296 while (!prop_attr_list
.is_empty())
14297 delete prop_attr_list
.pop ();
14298 prop_attr_list
.release ();
14299 parser
->error
= false;
14302 /* Parse an Objective-C @synthesize declaration. The syntax is:
14304 objc-synthesize-declaration:
14305 @synthesize objc-synthesize-identifier-list ;
14307 objc-synthesize-identifier-list:
14308 objc-synthesize-identifier
14309 objc-synthesize-identifier-list, objc-synthesize-identifier
14311 objc-synthesize-identifier
14313 identifier = identifier
14316 @synthesize MyProperty;
14317 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
14319 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
14320 for C++. Keep them in sync.
14323 c_parser_objc_at_synthesize_declaration (c_parser
*parser
)
14325 tree list
= NULL_TREE
;
14327 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNTHESIZE
));
14328 loc
= c_parser_peek_token (parser
)->location
;
14330 c_parser_consume_token (parser
);
14333 tree property
, ivar
;
14334 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14336 c_parser_error (parser
, "expected identifier");
14337 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
14338 /* Once we find the semicolon, we can resume normal parsing.
14339 We have to reset parser->error manually because
14340 c_parser_skip_until_found() won't reset it for us if the
14341 next token is precisely a semicolon. */
14342 parser
->error
= false;
14345 property
= c_parser_peek_token (parser
)->value
;
14346 c_parser_consume_token (parser
);
14347 if (c_parser_next_token_is (parser
, CPP_EQ
))
14349 c_parser_consume_token (parser
);
14350 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14352 c_parser_error (parser
, "expected identifier");
14353 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
14354 parser
->error
= false;
14357 ivar
= c_parser_peek_token (parser
)->value
;
14358 c_parser_consume_token (parser
);
14362 list
= chainon (list
, build_tree_list (ivar
, property
));
14363 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14364 c_parser_consume_token (parser
);
14368 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
14369 objc_add_synthesize_declaration (loc
, list
);
14372 /* Parse an Objective-C @dynamic declaration. The syntax is:
14374 objc-dynamic-declaration:
14375 @dynamic identifier-list ;
14378 @dynamic MyProperty;
14379 @dynamic MyProperty, AnotherProperty;
14381 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
14382 for C++. Keep them in sync.
14385 c_parser_objc_at_dynamic_declaration (c_parser
*parser
)
14387 tree list
= NULL_TREE
;
14389 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_DYNAMIC
));
14390 loc
= c_parser_peek_token (parser
)->location
;
14392 c_parser_consume_token (parser
);
14396 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14398 c_parser_error (parser
, "expected identifier");
14399 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
14400 parser
->error
= false;
14403 property
= c_parser_peek_token (parser
)->value
;
14404 list
= chainon (list
, build_tree_list (NULL_TREE
, property
));
14405 c_parser_consume_token (parser
);
14406 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14407 c_parser_consume_token (parser
);
14411 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
14412 objc_add_dynamic_declaration (loc
, list
);
14416 /* Parse a pragma GCC ivdep. */
14419 c_parse_pragma_ivdep (c_parser
*parser
)
14421 c_parser_consume_pragma (parser
);
14422 c_parser_skip_to_pragma_eol (parser
);
14426 /* Parse a pragma GCC novector. */
14429 c_parse_pragma_novector (c_parser
*parser
)
14431 c_parser_consume_pragma (parser
);
14432 c_parser_skip_to_pragma_eol (parser
);
14436 /* Parse a pragma GCC unroll. */
14438 static unsigned short
14439 c_parser_pragma_unroll (c_parser
*parser
)
14441 unsigned short unroll
;
14442 c_parser_consume_pragma (parser
);
14443 location_t location
= c_parser_peek_token (parser
)->location
;
14444 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
14445 mark_exp_read (expr
);
14446 expr
= c_fully_fold (expr
, false, NULL
);
14447 HOST_WIDE_INT lunroll
= 0;
14448 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
14449 || TREE_CODE (expr
) != INTEGER_CST
14450 || (lunroll
= tree_to_shwi (expr
)) < 0
14451 || lunroll
>= USHRT_MAX
)
14453 error_at (location
, "%<#pragma GCC unroll%> requires an"
14454 " assignment-expression that evaluates to a non-negative"
14455 " integral constant less than %u", USHRT_MAX
);
14460 unroll
= (unsigned short)lunroll
;
14465 c_parser_skip_to_pragma_eol (parser
);
14469 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
14470 should be considered, statements. ALLOW_STMT is true if we're within
14471 the context of a function and such pragmas are to be allowed. Returns
14472 true if we actually parsed such a pragma. */
14475 c_parser_pragma (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
14478 const char *construct
= NULL
;
14480 input_location
= c_parser_peek_token (parser
)->location
;
14481 id
= c_parser_peek_token (parser
)->pragma_kind
;
14482 gcc_assert (id
!= PRAGMA_NONE
);
14483 if (parser
->omp_for_parse_state
14484 && parser
->omp_for_parse_state
->in_intervening_code
14485 && id
>= PRAGMA_OMP__START_
14486 && id
<= PRAGMA_OMP__LAST_
)
14488 error_at (input_location
,
14489 "intervening code must not contain OpenMP directives");
14490 parser
->omp_for_parse_state
->fail
= true;
14491 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14497 case PRAGMA_OACC_DECLARE
:
14498 c_parser_oacc_declare (parser
);
14501 case PRAGMA_OACC_ENTER_DATA
:
14502 if (context
!= pragma_compound
)
14504 construct
= "acc enter data";
14506 if (context
== pragma_stmt
)
14508 error_at (c_parser_peek_token (parser
)->location
,
14509 "%<#pragma %s%> may only be used in compound "
14510 "statements", construct
);
14511 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14516 c_parser_oacc_enter_exit_data (parser
, true);
14519 case PRAGMA_OACC_EXIT_DATA
:
14520 if (context
!= pragma_compound
)
14522 construct
= "acc exit data";
14525 c_parser_oacc_enter_exit_data (parser
, false);
14528 case PRAGMA_OACC_ROUTINE
:
14529 if (context
!= pragma_external
)
14531 error_at (c_parser_peek_token (parser
)->location
,
14532 "%<#pragma acc routine%> must be at file scope");
14533 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14536 c_parser_oacc_routine (parser
, context
);
14539 case PRAGMA_OACC_UPDATE
:
14540 if (context
!= pragma_compound
)
14542 construct
= "acc update";
14545 c_parser_oacc_update (parser
);
14548 case PRAGMA_OMP_BARRIER
:
14549 if (context
!= pragma_compound
)
14551 construct
= "omp barrier";
14554 c_parser_omp_barrier (parser
);
14557 case PRAGMA_OMP_DEPOBJ
:
14558 if (context
!= pragma_compound
)
14560 construct
= "omp depobj";
14563 c_parser_omp_depobj (parser
);
14566 case PRAGMA_OMP_FLUSH
:
14567 if (context
!= pragma_compound
)
14569 construct
= "omp flush";
14572 c_parser_omp_flush (parser
);
14575 case PRAGMA_OMP_TASKWAIT
:
14576 if (context
!= pragma_compound
)
14578 construct
= "omp taskwait";
14581 c_parser_omp_taskwait (parser
);
14584 case PRAGMA_OMP_TASKYIELD
:
14585 if (context
!= pragma_compound
)
14587 construct
= "omp taskyield";
14590 c_parser_omp_taskyield (parser
);
14593 case PRAGMA_OMP_CANCEL
:
14594 if (context
!= pragma_compound
)
14596 construct
= "omp cancel";
14599 c_parser_omp_cancel (parser
);
14602 case PRAGMA_OMP_CANCELLATION_POINT
:
14603 return c_parser_omp_cancellation_point (parser
, context
);
14605 case PRAGMA_OMP_THREADPRIVATE
:
14606 c_parser_omp_threadprivate (parser
);
14609 case PRAGMA_OMP_TARGET
:
14610 return c_parser_omp_target (parser
, context
, if_p
);
14612 case PRAGMA_OMP_BEGIN
:
14613 c_parser_omp_begin (parser
);
14616 case PRAGMA_OMP_END
:
14617 c_parser_omp_end (parser
);
14620 case PRAGMA_OMP_SCAN
:
14621 error_at (c_parser_peek_token (parser
)->location
,
14622 "%<#pragma omp scan%> may only be used in "
14623 "a loop construct with %<inscan%> %<reduction%> clause");
14624 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14627 case PRAGMA_OMP_SECTION
:
14628 error_at (c_parser_peek_token (parser
)->location
,
14629 "%<#pragma omp section%> may only be used in "
14630 "%<#pragma omp sections%> construct");
14631 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14634 case PRAGMA_OMP_DECLARE
:
14635 return c_parser_omp_declare (parser
, context
);
14637 case PRAGMA_OMP_REQUIRES
:
14638 if (context
!= pragma_external
)
14640 error_at (c_parser_peek_token (parser
)->location
,
14641 "%<#pragma %s%> may only be used at file scope",
14643 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14646 c_parser_omp_requires (parser
);
14649 case PRAGMA_OMP_ALLOCATE
:
14650 c_parser_omp_allocate (parser
);
14653 case PRAGMA_OMP_ASSUMES
:
14654 if (context
!= pragma_external
)
14656 error_at (c_parser_peek_token (parser
)->location
,
14657 "%<#pragma %s%> may only be used at file scope",
14659 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14662 c_parser_omp_assumes (parser
);
14665 case PRAGMA_OMP_NOTHING
:
14666 c_parser_omp_nothing (parser
);
14669 case PRAGMA_OMP_ERROR
:
14670 return c_parser_omp_error (parser
, context
);
14672 case PRAGMA_OMP_ORDERED
:
14673 return c_parser_omp_ordered (parser
, context
, if_p
);
14675 case PRAGMA_NOVECTOR
:
14676 case PRAGMA_UNROLL
:
14679 bool novector
= false;
14680 unsigned short unroll
= 0;
14681 bool ivdep
= false;
14685 case PRAGMA_NOVECTOR
:
14686 novector
= c_parse_pragma_novector (parser
);
14688 case PRAGMA_UNROLL
:
14689 unroll
= c_parser_pragma_unroll (parser
);
14692 ivdep
= c_parse_pragma_ivdep (parser
);
14695 gcc_unreachable ();
14698 c_token
*tok
= c_parser_peek_token (parser
);
14699 bool has_more
= tok
->type
== CPP_PRAGMA
;
14702 switch (tok
->pragma_kind
)
14705 ivdep
= c_parse_pragma_ivdep (parser
);
14707 case PRAGMA_UNROLL
:
14708 unroll
= c_parser_pragma_unroll (parser
);
14710 case PRAGMA_NOVECTOR
:
14711 novector
= c_parse_pragma_novector (parser
);
14717 tok
= c_parser_peek_token (parser
);
14718 has_more
= has_more
&& tok
->type
== CPP_PRAGMA
;
14720 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
14721 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
14722 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
14724 c_parser_error (parser
, "for, while or do statement expected");
14727 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
14728 c_parser_for_statement (parser
, ivdep
, unroll
, novector
, if_p
);
14729 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
14730 c_parser_while_statement (parser
, ivdep
, unroll
, novector
, if_p
);
14732 c_parser_do_statement (parser
, ivdep
, unroll
, novector
);
14736 case PRAGMA_GCC_PCH_PREPROCESS
:
14737 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
14738 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14741 case PRAGMA_OACC_WAIT
:
14742 if (context
!= pragma_compound
)
14744 construct
= "acc wait";
14747 /* FALL THROUGH. */
14750 if (id
< PRAGMA_FIRST_EXTERNAL
)
14752 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
14755 c_parser_error (parser
, "expected declaration specifiers");
14756 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14759 c_parser_omp_construct (parser
, if_p
);
14765 c_parser_consume_pragma (parser
);
14766 c_invoke_pragma_handler (id
);
14768 /* Skip to EOL, but suppress any error message. Those will have been
14769 generated by the handler routine through calling error, as opposed
14770 to calling c_parser_error. */
14771 parser
->error
= true;
14772 c_parser_skip_to_pragma_eol (parser
);
14777 /* The interface the pragma parsers have to the lexer. */
14780 pragma_lex (tree
*value
, location_t
*loc
)
14782 c_token
*tok
= c_parser_peek_token (the_parser
);
14783 enum cpp_ttype ret
= tok
->type
;
14785 *value
= tok
->value
;
14787 *loc
= tok
->location
;
14789 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
14791 else if (ret
== CPP_STRING
)
14792 *value
= c_parser_string_literal (the_parser
, false, false).value
;
14795 if (ret
== CPP_KEYWORD
)
14797 c_parser_consume_token (the_parser
);
14804 pragma_lex_discard_to_eol ()
14809 type
= c_parser_peek_token (the_parser
)->type
;
14810 gcc_assert (type
!= CPP_EOF
);
14811 c_parser_consume_token (the_parser
);
14812 } while (type
!= CPP_PRAGMA_EOL
);
14816 c_parser_pragma_pch_preprocess (c_parser
*parser
)
14820 parser
->lex_joined_string
= true;
14821 c_parser_consume_pragma (parser
);
14822 if (c_parser_next_token_is (parser
, CPP_STRING
))
14824 name
= c_parser_peek_token (parser
)->value
;
14825 c_parser_consume_token (parser
);
14828 c_parser_error (parser
, "expected string literal");
14829 c_parser_skip_to_pragma_eol (parser
);
14830 parser
->lex_joined_string
= false;
14833 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
14836 /* OpenACC and OpenMP parsing routines. */
14838 /* Returns name of the next clause.
14839 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
14840 the token is not consumed. Otherwise appropriate pragma_omp_clause is
14841 returned and the token is consumed. */
14843 static pragma_omp_clause
14844 c_parser_omp_clause_name (c_parser
*parser
)
14846 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
14848 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
14849 result
= PRAGMA_OACC_CLAUSE_AUTO
;
14850 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
14851 result
= PRAGMA_OMP_CLAUSE_IF
;
14852 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
14853 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
14854 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
14855 result
= PRAGMA_OMP_CLAUSE_FOR
;
14856 else if (c_parser_next_token_is (parser
, CPP_NAME
))
14858 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14863 if (!strcmp ("affinity", p
))
14864 result
= PRAGMA_OMP_CLAUSE_AFFINITY
;
14865 else if (!strcmp ("aligned", p
))
14866 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
14867 else if (!strcmp ("allocate", p
))
14868 result
= PRAGMA_OMP_CLAUSE_ALLOCATE
;
14869 else if (!strcmp ("async", p
))
14870 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
14871 else if (!strcmp ("attach", p
))
14872 result
= PRAGMA_OACC_CLAUSE_ATTACH
;
14875 if (!strcmp ("bind", p
))
14876 result
= PRAGMA_OMP_CLAUSE_BIND
;
14879 if (!strcmp ("collapse", p
))
14880 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
14881 else if (!strcmp ("copy", p
))
14882 result
= PRAGMA_OACC_CLAUSE_COPY
;
14883 else if (!strcmp ("copyin", p
))
14884 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
14885 else if (!strcmp ("copyout", p
))
14886 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
14887 else if (!strcmp ("copyprivate", p
))
14888 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
14889 else if (!strcmp ("create", p
))
14890 result
= PRAGMA_OACC_CLAUSE_CREATE
;
14893 if (!strcmp ("defaultmap", p
))
14894 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
14895 else if (!strcmp ("delete", p
))
14896 result
= PRAGMA_OACC_CLAUSE_DELETE
;
14897 else if (!strcmp ("depend", p
))
14898 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
14899 else if (!strcmp ("detach", p
))
14900 result
= PRAGMA_OACC_CLAUSE_DETACH
;
14901 else if (!strcmp ("device", p
))
14902 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
14903 else if (!strcmp ("deviceptr", p
))
14904 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
14905 else if (!strcmp ("device_resident", p
))
14906 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
14907 else if (!strcmp ("device_type", p
))
14908 result
= PRAGMA_OMP_CLAUSE_DEVICE_TYPE
;
14909 else if (!strcmp ("dist_schedule", p
))
14910 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
14911 else if (!strcmp ("doacross", p
))
14912 result
= PRAGMA_OMP_CLAUSE_DOACROSS
;
14915 if (!strcmp ("enter", p
))
14916 result
= PRAGMA_OMP_CLAUSE_ENTER
;
14919 if (!strcmp ("filter", p
))
14920 result
= PRAGMA_OMP_CLAUSE_FILTER
;
14921 else if (!strcmp ("final", p
))
14922 result
= PRAGMA_OMP_CLAUSE_FINAL
;
14923 else if (!strcmp ("finalize", p
))
14924 result
= PRAGMA_OACC_CLAUSE_FINALIZE
;
14925 else if (!strcmp ("firstprivate", p
))
14926 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
14927 else if (!strcmp ("from", p
))
14928 result
= PRAGMA_OMP_CLAUSE_FROM
;
14931 if (!strcmp ("gang", p
))
14932 result
= PRAGMA_OACC_CLAUSE_GANG
;
14933 else if (!strcmp ("grainsize", p
))
14934 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
14937 if (!strcmp ("has_device_addr", p
))
14938 result
= PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
;
14939 else if (!strcmp ("hint", p
))
14940 result
= PRAGMA_OMP_CLAUSE_HINT
;
14941 else if (!strcmp ("host", p
))
14942 result
= PRAGMA_OACC_CLAUSE_HOST
;
14945 if (!strcmp ("if_present", p
))
14946 result
= PRAGMA_OACC_CLAUSE_IF_PRESENT
;
14947 else if (!strcmp ("in_reduction", p
))
14948 result
= PRAGMA_OMP_CLAUSE_IN_REDUCTION
;
14949 else if (!strcmp ("inbranch", p
))
14950 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
14951 else if (!strcmp ("independent", p
))
14952 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
14953 else if (!strcmp ("indirect", p
))
14954 result
= PRAGMA_OMP_CLAUSE_INDIRECT
;
14955 else if (!strcmp ("is_device_ptr", p
))
14956 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
14959 if (!strcmp ("lastprivate", p
))
14960 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
14961 else if (!strcmp ("linear", p
))
14962 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
14963 else if (!strcmp ("link", p
))
14964 result
= PRAGMA_OMP_CLAUSE_LINK
;
14967 if (!strcmp ("map", p
))
14968 result
= PRAGMA_OMP_CLAUSE_MAP
;
14969 else if (!strcmp ("mergeable", p
))
14970 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
14973 if (!strcmp ("no_create", p
))
14974 result
= PRAGMA_OACC_CLAUSE_NO_CREATE
;
14975 else if (!strcmp ("nogroup", p
))
14976 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
14977 else if (!strcmp ("nohost", p
))
14978 result
= PRAGMA_OACC_CLAUSE_NOHOST
;
14979 else if (!strcmp ("nontemporal", p
))
14980 result
= PRAGMA_OMP_CLAUSE_NONTEMPORAL
;
14981 else if (!strcmp ("notinbranch", p
))
14982 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
14983 else if (!strcmp ("nowait", p
))
14984 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
14985 else if (!strcmp ("num_gangs", p
))
14986 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
14987 else if (!strcmp ("num_tasks", p
))
14988 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
14989 else if (!strcmp ("num_teams", p
))
14990 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
14991 else if (!strcmp ("num_threads", p
))
14992 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
14993 else if (!strcmp ("num_workers", p
))
14994 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
14997 if (!strcmp ("ordered", p
))
14998 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
14999 else if (!strcmp ("order", p
))
15000 result
= PRAGMA_OMP_CLAUSE_ORDER
;
15003 if (!strcmp ("parallel", p
))
15004 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
15005 else if (!strcmp ("present", p
))
15006 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
15007 /* As of OpenACC 2.5, these are now aliases of the non-present_or
15009 else if (!strcmp ("present_or_copy", p
)
15010 || !strcmp ("pcopy", p
))
15011 result
= PRAGMA_OACC_CLAUSE_COPY
;
15012 else if (!strcmp ("present_or_copyin", p
)
15013 || !strcmp ("pcopyin", p
))
15014 result
= PRAGMA_OACC_CLAUSE_COPYIN
;
15015 else if (!strcmp ("present_or_copyout", p
)
15016 || !strcmp ("pcopyout", p
))
15017 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
15018 else if (!strcmp ("present_or_create", p
)
15019 || !strcmp ("pcreate", p
))
15020 result
= PRAGMA_OACC_CLAUSE_CREATE
;
15021 else if (!strcmp ("priority", p
))
15022 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
15023 else if (!strcmp ("private", p
))
15024 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
15025 else if (!strcmp ("proc_bind", p
))
15026 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
15029 if (!strcmp ("reduction", p
))
15030 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
15033 if (!strcmp ("safelen", p
))
15034 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
15035 else if (!strcmp ("schedule", p
))
15036 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
15037 else if (!strcmp ("sections", p
))
15038 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
15039 else if (!strcmp ("self", p
))
15040 result
= PRAGMA_OACC_CLAUSE_SELF
;
15041 else if (!strcmp ("seq", p
))
15042 result
= PRAGMA_OACC_CLAUSE_SEQ
;
15043 else if (!strcmp ("shared", p
))
15044 result
= PRAGMA_OMP_CLAUSE_SHARED
;
15045 else if (!strcmp ("simd", p
))
15046 result
= PRAGMA_OMP_CLAUSE_SIMD
;
15047 else if (!strcmp ("simdlen", p
))
15048 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
15051 if (!strcmp ("task_reduction", p
))
15052 result
= PRAGMA_OMP_CLAUSE_TASK_REDUCTION
;
15053 else if (!strcmp ("taskgroup", p
))
15054 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
15055 else if (!strcmp ("thread_limit", p
))
15056 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
15057 else if (!strcmp ("threads", p
))
15058 result
= PRAGMA_OMP_CLAUSE_THREADS
;
15059 else if (!strcmp ("tile", p
))
15060 result
= PRAGMA_OACC_CLAUSE_TILE
;
15061 else if (!strcmp ("to", p
))
15062 result
= PRAGMA_OMP_CLAUSE_TO
;
15065 if (!strcmp ("uniform", p
))
15066 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
15067 else if (!strcmp ("untied", p
))
15068 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
15069 else if (!strcmp ("use_device", p
))
15070 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
15071 else if (!strcmp ("use_device_addr", p
))
15072 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
;
15073 else if (!strcmp ("use_device_ptr", p
))
15074 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
15077 if (!strcmp ("vector", p
))
15078 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
15079 else if (!strcmp ("vector_length", p
))
15080 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
15083 if (!strcmp ("wait", p
))
15084 result
= PRAGMA_OACC_CLAUSE_WAIT
;
15085 else if (!strcmp ("worker", p
))
15086 result
= PRAGMA_OACC_CLAUSE_WORKER
;
15091 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
15092 c_parser_consume_token (parser
);
15097 /* Validate that a clause of the given type does not already exist. */
15100 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
15103 if (tree c
= omp_find_clause (clauses
, code
))
15104 error_at (OMP_CLAUSE_LOCATION (c
), "too many %qs clauses", name
);
15108 Parse wait clause or wait directive parameters. */
15111 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
15113 vec
<tree
, va_gc
> *args
;
15116 matching_parens parens
;
15117 if (!parens
.require_open (parser
))
15120 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
15121 args_tree
= build_tree_list_vec (args
);
15123 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
15125 tree targ
= TREE_VALUE (t
);
15127 if (targ
!= error_mark_node
)
15129 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
15131 c_parser_error (parser
, "expression must be integral");
15132 targ
= error_mark_node
;
15136 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
15138 OMP_CLAUSE_DECL (c
) = targ
;
15139 OMP_CLAUSE_CHAIN (c
) = list
;
15145 release_tree_vector (args
);
15146 parens
.require_close (parser
);
15150 /* OpenACC 2.0, OpenMP 2.5:
15153 variable-list , identifier
15155 If KIND is nonzero, create the appropriate node and install the
15156 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
15157 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
15159 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
15160 return the list created.
15162 The optional ALLOW_DEREF argument is true if list items can use the deref
15167 tree low_bound
, length
;
15170 omp_dim (tree lb
, tree len
, location_t lo
, bool nc
)
15171 : low_bound (lb
), length (len
), loc (lo
), no_colon (nc
) {}
15175 c_parser_omp_variable_list (c_parser
*parser
,
15176 location_t clause_loc
,
15177 enum omp_clause_code kind
, tree list
,
15178 bool map_lvalue
= false)
15180 auto_vec
<omp_dim
> dims
;
15181 bool array_section_p
;
15182 auto_vec
<c_token
> tokens
;
15183 unsigned int tokens_avail
= 0;
15184 c_token
*saved_tokens
= NULL
;
15189 tree t
= NULL_TREE
;
15191 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
15193 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
15194 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
15196 struct c_expr expr
;
15197 if (kind
== OMP_CLAUSE_DEPEND
15198 && c_parser_next_token_is_keyword (parser
,
15199 RID_OMP_ALL_MEMORY
)
15200 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
15201 || (c_parser_peek_2nd_token (parser
)->type
15202 == CPP_CLOSE_PAREN
)))
15204 expr
.value
= ridpointers
[RID_OMP_ALL_MEMORY
];
15205 c_parser_consume_token (parser
);
15208 expr
= c_parser_expr_no_commas (parser
, NULL
);
15209 if (expr
.value
!= error_mark_node
)
15211 tree u
= build_omp_clause (clause_loc
, kind
);
15212 OMP_CLAUSE_DECL (u
) = expr
.value
;
15213 OMP_CLAUSE_CHAIN (u
) = list
;
15217 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
15220 c_parser_consume_token (parser
);
15225 tokens
.truncate (0);
15226 unsigned int nesting_depth
= 0;
15229 c_token
*token
= c_parser_peek_token (parser
);
15230 switch (token
->type
)
15233 case CPP_PRAGMA_EOL
:
15235 case CPP_OPEN_BRACE
:
15236 case CPP_OPEN_PAREN
:
15237 case CPP_OPEN_SQUARE
:
15240 case CPP_CLOSE_BRACE
:
15241 case CPP_CLOSE_PAREN
:
15242 case CPP_CLOSE_SQUARE
:
15243 if (nesting_depth
-- == 0)
15247 if (nesting_depth
== 0)
15252 tokens
.safe_push (*token
);
15253 c_parser_consume_token (parser
);
15259 /* Make sure nothing tries to read past the end of the tokens. */
15261 memset (&eof_token
, 0, sizeof (eof_token
));
15262 eof_token
.type
= CPP_EOF
;
15263 tokens
.safe_push (eof_token
);
15264 tokens
.safe_push (eof_token
);
15266 saved_tokens
= parser
->tokens
;
15267 tokens_avail
= parser
->tokens_avail
;
15268 parser
->tokens
= tokens
.address ();
15269 parser
->tokens_avail
= tokens
.length ();
15271 else if (map_lvalue
15272 && (kind
== OMP_CLAUSE_MAP
15273 || kind
== OMP_CLAUSE_TO
15274 || kind
== OMP_CLAUSE_FROM
))
15276 location_t loc
= c_parser_peek_token (parser
)->location
;
15277 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
15278 c_omp_array_section_p
= true;
15279 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15280 if (expr
.value
!= error_mark_node
)
15281 mark_exp_read (expr
.value
);
15282 c_omp_array_section_p
= save_c_omp_array_section_p
;
15283 tree decl
= expr
.value
;
15285 /* This code rewrites a parsed expression containing various tree
15286 codes used to represent array accesses into a more uniform nest of
15287 OMP_ARRAY_SECTION nodes before it is processed by
15288 c-typeck.cc:handle_omp_array_sections_1. It might be more
15289 efficient to move this logic to that function instead, analysing
15290 the parsed expression directly rather than this preprocessed
15291 form. (See also equivalent code in cp/parser.cc,
15292 cp/semantics.cc). */
15294 if (TREE_CODE (decl
) == OMP_ARRAY_SECTION
)
15296 while (TREE_CODE (decl
) == OMP_ARRAY_SECTION
)
15298 tree low_bound
= TREE_OPERAND (decl
, 1);
15299 tree length
= TREE_OPERAND (decl
, 2);
15300 dims
.safe_push (omp_dim (low_bound
, length
, loc
, false));
15301 decl
= TREE_OPERAND (decl
, 0);
15304 while (TREE_CODE (decl
) == ARRAY_REF
15305 || TREE_CODE (decl
) == INDIRECT_REF
15306 || TREE_CODE (decl
) == COMPOUND_EXPR
)
15308 if (TREE_CODE (decl
) == COMPOUND_EXPR
)
15310 decl
= TREE_OPERAND (decl
, 1);
15313 else if (TREE_CODE (decl
) == INDIRECT_REF
)
15315 dims
.safe_push (omp_dim (integer_zero_node
,
15316 integer_one_node
, loc
, true));
15317 decl
= TREE_OPERAND (decl
, 0);
15319 else /* ARRAY_REF. */
15321 tree index
= TREE_OPERAND (decl
, 1);
15322 dims
.safe_push (omp_dim (index
, integer_one_node
, loc
,
15324 decl
= TREE_OPERAND (decl
, 0);
15328 for (int i
= dims
.length () - 1; i
>= 0; i
--)
15329 decl
= build_omp_array_section (loc
, decl
, dims
[i
].low_bound
,
15332 else if (TREE_CODE (decl
) == INDIRECT_REF
)
15334 /* Turn indirection of a pointer "*foo" into "foo[0:1]". */
15335 decl
= TREE_OPERAND (decl
, 0);
15338 decl
= build_omp_array_section (loc
, decl
, integer_zero_node
,
15341 else if (TREE_CODE (decl
) == ARRAY_REF
)
15343 tree idx
= TREE_OPERAND (decl
, 1);
15345 decl
= TREE_OPERAND (decl
, 0);
15348 decl
= build_omp_array_section (loc
, decl
, idx
, integer_one_node
);
15350 else if (TREE_CODE (decl
) == NON_LVALUE_EXPR
15351 || CONVERT_EXPR_P (decl
))
15352 decl
= TREE_OPERAND (decl
, 0);
15354 tree u
= build_omp_clause (clause_loc
, kind
);
15355 OMP_CLAUSE_DECL (u
) = decl
;
15356 OMP_CLAUSE_CHAIN (u
) = list
;
15362 if (c_parser_next_token_is (parser
, CPP_NAME
)
15363 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
15365 t
= lookup_name (c_parser_peek_token (parser
)->value
);
15367 if (t
== NULL_TREE
)
15369 undeclared_variable (c_parser_peek_token (parser
)->location
,
15370 c_parser_peek_token (parser
)->value
);
15371 t
= error_mark_node
;
15374 c_parser_consume_token (parser
);
15376 else if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
15377 && (c_parser_peek_token (parser
)->keyword
== RID_FUNCTION_NAME
15378 || (c_parser_peek_token (parser
)->keyword
15379 == RID_PRETTY_FUNCTION_NAME
)
15380 || (c_parser_peek_token (parser
)->keyword
15381 == RID_C99_FUNCTION_NAME
)))
15382 t
= c_parser_predefined_identifier (parser
).value
;
15386 c_parser_error (parser
, "expected identifier");
15390 if (t
== error_mark_node
)
15392 else if (kind
!= 0)
15396 case OMP_CLAUSE__CACHE_
:
15397 /* The OpenACC cache directive explicitly only allows "array
15398 elements or subarrays". */
15399 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
15401 c_parser_error (parser
, "expected %<[%>");
15402 t
= error_mark_node
;
15406 case OMP_CLAUSE_MAP
:
15407 case OMP_CLAUSE_FROM
:
15408 case OMP_CLAUSE_TO
:
15409 start_component_ref
:
15410 while (c_parser_next_token_is (parser
, CPP_DOT
)
15411 || c_parser_next_token_is (parser
, CPP_DEREF
))
15413 location_t op_loc
= c_parser_peek_token (parser
)->location
;
15414 location_t arrow_loc
= UNKNOWN_LOCATION
;
15415 if (c_parser_next_token_is (parser
, CPP_DEREF
))
15419 t_expr
.original_code
= ERROR_MARK
;
15420 t_expr
.original_type
= NULL
;
15421 set_c_expr_source_range (&t_expr
, op_loc
, op_loc
);
15422 t_expr
.m_decimal
= 0;
15423 t_expr
= convert_lvalue_to_rvalue (op_loc
, t_expr
,
15425 t
= build_indirect_ref (op_loc
, t_expr
.value
, RO_ARROW
);
15426 arrow_loc
= t_expr
.get_location ();
15428 c_parser_consume_token (parser
);
15429 if (!c_parser_next_token_is (parser
, CPP_NAME
))
15431 c_parser_error (parser
, "expected identifier");
15432 t
= error_mark_node
;
15436 c_token
*comp_tok
= c_parser_peek_token (parser
);
15437 tree ident
= comp_tok
->value
;
15438 location_t comp_loc
= comp_tok
->location
;
15439 c_parser_consume_token (parser
);
15440 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
,
15444 case OMP_CLAUSE_AFFINITY
:
15445 case OMP_CLAUSE_DEPEND
:
15446 case OMP_CLAUSE_REDUCTION
:
15447 case OMP_CLAUSE_IN_REDUCTION
:
15448 case OMP_CLAUSE_TASK_REDUCTION
:
15449 case OMP_CLAUSE_HAS_DEVICE_ADDR
:
15450 array_section_p
= false;
15452 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
15454 location_t loc
= UNKNOWN_LOCATION
;
15455 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
15456 bool no_colon
= false;
15458 c_parser_consume_token (parser
);
15459 if (!c_parser_next_token_is (parser
, CPP_COLON
))
15461 location_t expr_loc
15462 = c_parser_peek_token (parser
)->location
;
15463 c_expr expr
= c_parser_expression (parser
);
15464 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
15466 low_bound
= expr
.value
;
15469 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
15471 length
= integer_one_node
;
15476 /* Look for `:'. */
15477 if (!c_parser_require (parser
, CPP_COLON
,
15480 t
= error_mark_node
;
15483 array_section_p
= true;
15484 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
15486 location_t expr_loc
15487 = c_parser_peek_token (parser
)->location
;
15488 c_expr expr
= c_parser_expression (parser
);
15489 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
15491 length
= expr
.value
;
15494 /* Look for the closing `]'. */
15495 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
15498 t
= error_mark_node
;
15502 dims
.safe_push (omp_dim (low_bound
, length
, loc
, no_colon
));
15505 if (t
!= error_mark_node
)
15507 if ((kind
== OMP_CLAUSE_MAP
15508 || kind
== OMP_CLAUSE_FROM
15509 || kind
== OMP_CLAUSE_TO
)
15510 && !array_section_p
15511 && (c_parser_next_token_is (parser
, CPP_DOT
)
15512 || c_parser_next_token_is (parser
, CPP_DEREF
)))
15514 for (unsigned i
= 0; i
< dims
.length (); i
++)
15516 gcc_assert (dims
[i
].length
== integer_one_node
);
15517 t
= build_array_ref (dims
[i
].loc
,
15518 t
, dims
[i
].low_bound
);
15520 goto start_component_ref
;
15523 for (unsigned i
= 0; i
< dims
.length (); i
++)
15524 t
= build_omp_array_section (clause_loc
, t
,
15529 if ((kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
15530 && t
!= error_mark_node
15531 && parser
->tokens_avail
!= 2)
15533 if (array_section_p
)
15535 error_at (c_parser_peek_token (parser
)->location
,
15536 "expected %<)%> or %<,%>");
15537 t
= error_mark_node
;
15541 parser
->tokens
= tokens
.address ();
15542 parser
->tokens_avail
= tokens
.length ();
15544 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
15545 if (t
!= error_mark_node
&& parser
->tokens_avail
!= 2)
15547 error_at (c_parser_peek_token (parser
)->location
,
15548 "expected %<)%> or %<,%>");
15549 t
= error_mark_node
;
15558 if (t
!= error_mark_node
)
15560 tree u
= build_omp_clause (clause_loc
, kind
);
15561 OMP_CLAUSE_DECL (u
) = t
;
15562 OMP_CLAUSE_CHAIN (u
) = list
;
15567 list
= tree_cons (t
, NULL_TREE
, list
);
15569 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
15571 parser
->tokens
= saved_tokens
;
15572 parser
->tokens_avail
= tokens_avail
;
15576 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
15579 c_parser_consume_token (parser
);
15586 /* Similarly, but expect leading and trailing parenthesis. This is a very
15587 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
15588 argument is true if list items can use the deref (->) operator. */
15591 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
15592 tree list
, bool map_lvalue
= false)
15594 /* The clauses location. */
15595 location_t loc
= c_parser_peek_token (parser
)->location
;
15597 if (parser
->in_omp_decl_attribute
)
15601 tree u
= build_omp_clause (loc
, kind
);
15602 OMP_CLAUSE_DECL (u
) = parser
->in_omp_decl_attribute
;
15603 OMP_CLAUSE_CHAIN (u
) = list
;
15607 return tree_cons (parser
->in_omp_decl_attribute
, NULL_TREE
, list
);
15610 matching_parens parens
;
15611 if (parens
.require_open (parser
))
15613 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
, map_lvalue
);
15614 parens
.skip_until_found_close (parser
);
15620 copy ( variable-list )
15621 copyin ( variable-list )
15622 copyout ( variable-list )
15623 create ( variable-list )
15624 delete ( variable-list )
15625 present ( variable-list )
15628 no_create ( variable-list )
15629 attach ( variable-list )
15630 detach ( variable-list ) */
15633 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
15636 enum gomp_map_kind kind
;
15639 case PRAGMA_OACC_CLAUSE_ATTACH
:
15640 kind
= GOMP_MAP_ATTACH
;
15642 case PRAGMA_OACC_CLAUSE_COPY
:
15643 kind
= GOMP_MAP_TOFROM
;
15645 case PRAGMA_OACC_CLAUSE_COPYIN
:
15646 kind
= GOMP_MAP_TO
;
15648 case PRAGMA_OACC_CLAUSE_COPYOUT
:
15649 kind
= GOMP_MAP_FROM
;
15651 case PRAGMA_OACC_CLAUSE_CREATE
:
15652 kind
= GOMP_MAP_ALLOC
;
15654 case PRAGMA_OACC_CLAUSE_DELETE
:
15655 kind
= GOMP_MAP_RELEASE
;
15657 case PRAGMA_OACC_CLAUSE_DETACH
:
15658 kind
= GOMP_MAP_DETACH
;
15660 case PRAGMA_OACC_CLAUSE_DEVICE
:
15661 kind
= GOMP_MAP_FORCE_TO
;
15663 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
15664 kind
= GOMP_MAP_DEVICE_RESIDENT
;
15666 case PRAGMA_OACC_CLAUSE_LINK
:
15667 kind
= GOMP_MAP_LINK
;
15669 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
15670 kind
= GOMP_MAP_IF_PRESENT
;
15672 case PRAGMA_OACC_CLAUSE_PRESENT
:
15673 kind
= GOMP_MAP_FORCE_PRESENT
;
15675 case PRAGMA_OACC_CLAUSE_SELF
:
15676 /* "The 'host' clause is a synonym for the 'self' clause." */
15677 case PRAGMA_OACC_CLAUSE_HOST
:
15678 kind
= GOMP_MAP_FORCE_FROM
;
15681 gcc_unreachable ();
15684 nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_MAP
, list
, false);
15686 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15687 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
15693 deviceptr ( variable-list ) */
15696 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
15698 location_t loc
= c_parser_peek_token (parser
)->location
;
15701 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
15702 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
15703 variable-list must only allow for pointer variables. */
15704 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
15705 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
15707 tree v
= TREE_PURPOSE (t
);
15709 /* FIXME diagnostics: Ideally we should keep individual
15710 locations for all the variables in the var list to make the
15711 following errors more precise. Perhaps
15712 c_parser_omp_var_list_parens() should construct a list of
15713 locations to go along with the var list. */
15715 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
15716 error_at (loc
, "%qD is not a variable", v
);
15717 else if (TREE_TYPE (v
) == error_mark_node
)
15719 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
15720 error_at (loc
, "%qD is not a pointer variable", v
);
15722 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
15723 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
15724 OMP_CLAUSE_DECL (u
) = v
;
15725 OMP_CLAUSE_CHAIN (u
) = list
;
15732 /* OpenACC 2.0, OpenMP 3.0:
15733 collapse ( constant-expression ) */
15736 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
15738 tree c
, num
= error_mark_node
;
15742 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
15743 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
15745 loc
= c_parser_peek_token (parser
)->location
;
15746 matching_parens parens
;
15747 if (parens
.require_open (parser
))
15749 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
15750 parens
.skip_until_found_close (parser
);
15752 if (num
== error_mark_node
)
15754 mark_exp_read (num
);
15755 num
= c_fully_fold (num
, false, NULL
);
15756 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
15757 || !tree_fits_shwi_p (num
)
15758 || (n
= tree_to_shwi (num
)) <= 0
15762 "collapse argument needs positive constant integer expression");
15765 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
15766 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
15767 OMP_CLAUSE_CHAIN (c
) = list
;
15772 copyin ( variable-list ) */
15775 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
15777 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
15781 copyprivate ( variable-list ) */
15784 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
15786 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
15790 default ( none | shared )
15793 default ( private | firstprivate )
15796 default ( none | present ) */
15799 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
15801 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
15802 location_t loc
= c_parser_peek_token (parser
)->location
;
15805 matching_parens parens
;
15806 if (!parens
.require_open (parser
))
15808 if (c_parser_next_token_is (parser
, CPP_NAME
))
15810 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15815 if (strcmp ("none", p
) != 0)
15817 kind
= OMP_CLAUSE_DEFAULT_NONE
;
15823 if (strcmp ("present", p
) != 0)
15825 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
15829 if (strcmp ("private", p
) != 0)
15831 kind
= OMP_CLAUSE_DEFAULT_PRIVATE
;
15836 if (strcmp ("firstprivate", p
) != 0 || is_oacc
)
15838 kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
15842 if (strcmp ("shared", p
) != 0 || is_oacc
)
15844 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
15851 c_parser_consume_token (parser
);
15857 c_parser_error (parser
, "expected %<none%> or %<present%>");
15859 c_parser_error (parser
, "expected %<none%>, %<shared%>, "
15860 "%<private%> or %<firstprivate%>");
15862 parens
.skip_until_found_close (parser
);
15864 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
15867 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
15868 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
15869 OMP_CLAUSE_CHAIN (c
) = list
;
15870 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
15876 firstprivate ( variable-list ) */
15879 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
15881 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
15885 final ( expression ) */
15888 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
15890 location_t loc
= c_parser_peek_token (parser
)->location
;
15891 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
15893 matching_parens parens
;
15895 if (!parens
.require_open (parser
))
15896 t
= error_mark_node
;
15899 location_t eloc
= c_parser_peek_token (parser
)->location
;
15900 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15901 t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
15902 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
15903 t
= c_fully_fold (t
, false, NULL
);
15904 parens
.skip_until_found_close (parser
);
15907 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
15909 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
15910 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
15911 OMP_CLAUSE_CHAIN (c
) = list
;
15915 c_parser_error (parser
, "expected %<(%>");
15921 indirect [( expression )]
15925 c_parser_omp_clause_indirect (c_parser
*parser
, tree list
)
15927 location_t location
= c_parser_peek_token (parser
)->location
;
15930 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
15932 matching_parens parens
;
15933 if (!parens
.require_open (parser
))
15936 location_t loc
= c_parser_peek_token (parser
)->location
;
15937 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15938 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
15939 t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
);
15940 t
= c_fully_fold (t
, false, NULL
);
15941 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
15942 || TREE_CODE (t
) != INTEGER_CST
)
15944 c_parser_error (parser
, "expected constant logical expression");
15947 parens
.skip_until_found_close (parser
);
15950 t
= integer_one_node
;
15952 check_no_duplicate_clause (list
, OMP_CLAUSE_INDIRECT
, "indirect");
15954 tree c
= build_omp_clause (location
, OMP_CLAUSE_INDIRECT
);
15955 OMP_CLAUSE_INDIRECT_EXPR (c
) = t
;
15956 OMP_CLAUSE_CHAIN (c
) = list
;
15961 /* OpenACC, OpenMP 2.5:
15965 if ( directive-name-modifier : expression )
15967 directive-name-modifier:
15968 parallel | task | taskloop | target data | target | target update
15969 | target enter data | target exit data
15972 directive-name-modifier:
15973 ... | simd | cancel */
15976 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
15978 location_t location
= c_parser_peek_token (parser
)->location
;
15979 enum tree_code if_modifier
= ERROR_MARK
;
15981 matching_parens parens
;
15982 if (!parens
.require_open (parser
))
15985 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
15987 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15989 if (strcmp (p
, "cancel") == 0)
15990 if_modifier
= VOID_CST
;
15991 else if (strcmp (p
, "parallel") == 0)
15992 if_modifier
= OMP_PARALLEL
;
15993 else if (strcmp (p
, "simd") == 0)
15994 if_modifier
= OMP_SIMD
;
15995 else if (strcmp (p
, "task") == 0)
15996 if_modifier
= OMP_TASK
;
15997 else if (strcmp (p
, "taskloop") == 0)
15998 if_modifier
= OMP_TASKLOOP
;
15999 else if (strcmp (p
, "target") == 0)
16001 if_modifier
= OMP_TARGET
;
16002 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
16004 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
16005 if (strcmp ("data", p
) == 0)
16006 if_modifier
= OMP_TARGET_DATA
;
16007 else if (strcmp ("update", p
) == 0)
16008 if_modifier
= OMP_TARGET_UPDATE
;
16009 else if (strcmp ("enter", p
) == 0)
16010 if_modifier
= OMP_TARGET_ENTER_DATA
;
16011 else if (strcmp ("exit", p
) == 0)
16012 if_modifier
= OMP_TARGET_EXIT_DATA
;
16013 if (if_modifier
!= OMP_TARGET
)
16016 c_parser_consume_token (parser
);
16020 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
16021 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
16023 if_modifier
= ERROR_MARK
;
16025 if (if_modifier
== OMP_TARGET_ENTER_DATA
16026 || if_modifier
== OMP_TARGET_EXIT_DATA
)
16028 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
16030 p
= IDENTIFIER_POINTER
16031 (c_parser_peek_2nd_token (parser
)->value
);
16032 if (strcmp ("data", p
) == 0)
16036 c_parser_consume_token (parser
);
16040 = c_parser_peek_2nd_token (parser
)->location
;
16041 error_at (loc
, "expected %<data%>");
16042 if_modifier
= ERROR_MARK
;
16047 if (if_modifier
!= ERROR_MARK
)
16049 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16051 c_parser_consume_token (parser
);
16052 c_parser_consume_token (parser
);
16058 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
16059 error_at (loc
, "expected %<:%>");
16061 if_modifier
= ERROR_MARK
;
16066 location_t loc
= c_parser_peek_token (parser
)->location
;
16067 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16068 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
16069 tree t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
), c
;
16070 t
= c_fully_fold (t
, false, NULL
);
16071 parens
.skip_until_found_close (parser
);
16073 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
16074 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
16076 if (if_modifier
!= ERROR_MARK
16077 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
16079 const char *p
= NULL
;
16080 switch (if_modifier
)
16082 case VOID_CST
: p
= "cancel"; break;
16083 case OMP_PARALLEL
: p
= "parallel"; break;
16084 case OMP_SIMD
: p
= "simd"; break;
16085 case OMP_TASK
: p
= "task"; break;
16086 case OMP_TASKLOOP
: p
= "taskloop"; break;
16087 case OMP_TARGET_DATA
: p
= "target data"; break;
16088 case OMP_TARGET
: p
= "target"; break;
16089 case OMP_TARGET_UPDATE
: p
= "target update"; break;
16090 case OMP_TARGET_ENTER_DATA
: p
= "target enter data"; break;
16091 case OMP_TARGET_EXIT_DATA
: p
= "target exit data"; break;
16092 default: gcc_unreachable ();
16094 error_at (location
, "too many %<if%> clauses with %qs modifier",
16098 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
16101 error_at (location
, "too many %<if%> clauses");
16103 error_at (location
, "too many %<if%> clauses without modifier");
16106 else if (if_modifier
== ERROR_MARK
16107 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
16109 error_at (location
, "if any %<if%> clause has modifier, then all "
16110 "%<if%> clauses have to use modifier");
16115 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
16116 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
16117 OMP_CLAUSE_IF_EXPR (c
) = t
;
16118 OMP_CLAUSE_CHAIN (c
) = list
;
16123 lastprivate ( variable-list )
16126 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
16129 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
16131 /* The clauses location. */
16132 location_t loc
= c_parser_peek_token (parser
)->location
;
16134 if (c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
16136 bool conditional
= false;
16137 if (c_parser_next_token_is (parser
, CPP_NAME
)
16138 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16141 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16142 if (strcmp (p
, "conditional") == 0)
16144 conditional
= true;
16145 c_parser_consume_token (parser
);
16146 c_parser_consume_token (parser
);
16149 tree nlist
= c_parser_omp_variable_list (parser
, loc
,
16150 OMP_CLAUSE_LASTPRIVATE
, list
);
16151 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
16153 for (tree c
= nlist
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16154 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 1;
16164 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
16168 /* FIXME: Should we allow duplicates? */
16169 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
16171 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
16172 OMP_CLAUSE_MERGEABLE
);
16173 OMP_CLAUSE_CHAIN (c
) = list
;
16182 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
16185 location_t loc
= c_parser_peek_token (parser
)->location
;
16187 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
16189 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
16190 OMP_CLAUSE_CHAIN (c
) = list
;
16195 num_threads ( expression ) */
16198 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
16200 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
16201 matching_parens parens
;
16202 if (parens
.require_open (parser
))
16204 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16205 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16206 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16207 tree c
, t
= expr
.value
;
16208 t
= c_fully_fold (t
, false, NULL
);
16210 parens
.skip_until_found_close (parser
);
16212 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16214 c_parser_error (parser
, "expected integer expression");
16218 /* Attempt to statically determine when the number isn't positive. */
16219 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
16220 build_int_cst (TREE_TYPE (t
), 0));
16221 protected_set_expr_location (c
, expr_loc
);
16222 if (c
== boolean_true_node
)
16224 warning_at (expr_loc
, OPT_Wopenmp
,
16225 "%<num_threads%> value must be positive");
16226 t
= integer_one_node
;
16229 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
16231 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
16232 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
16233 OMP_CLAUSE_CHAIN (c
) = list
;
16241 num_tasks ( expression )
16244 num_tasks ( strict : expression ) */
16247 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
16249 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
16250 matching_parens parens
;
16251 if (parens
.require_open (parser
))
16253 bool strict
= false;
16254 if (c_parser_next_token_is (parser
, CPP_NAME
)
16255 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
16256 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
16260 c_parser_consume_token (parser
);
16261 c_parser_consume_token (parser
);
16264 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16265 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16266 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16267 tree c
, t
= expr
.value
;
16268 t
= c_fully_fold (t
, false, NULL
);
16270 parens
.skip_until_found_close (parser
);
16272 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16274 c_parser_error (parser
, "expected integer expression");
16278 /* Attempt to statically determine when the number isn't positive. */
16279 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
16280 build_int_cst (TREE_TYPE (t
), 0));
16281 if (CAN_HAVE_LOCATION_P (c
))
16282 SET_EXPR_LOCATION (c
, expr_loc
);
16283 if (c
== boolean_true_node
)
16285 warning_at (expr_loc
, OPT_Wopenmp
,
16286 "%<num_tasks%> value must be positive");
16287 t
= integer_one_node
;
16290 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
16292 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
16293 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
16294 OMP_CLAUSE_NUM_TASKS_STRICT (c
) = strict
;
16295 OMP_CLAUSE_CHAIN (c
) = list
;
16303 grainsize ( expression )
16306 grainsize ( strict : expression ) */
16309 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
16311 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
16312 matching_parens parens
;
16313 if (parens
.require_open (parser
))
16315 bool strict
= false;
16316 if (c_parser_next_token_is (parser
, CPP_NAME
)
16317 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
16318 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
16322 c_parser_consume_token (parser
);
16323 c_parser_consume_token (parser
);
16326 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16327 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16328 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16329 tree c
, t
= expr
.value
;
16330 t
= c_fully_fold (t
, false, NULL
);
16332 parens
.skip_until_found_close (parser
);
16334 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16336 c_parser_error (parser
, "expected integer expression");
16340 /* Attempt to statically determine when the number isn't positive. */
16341 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
16342 build_int_cst (TREE_TYPE (t
), 0));
16343 if (CAN_HAVE_LOCATION_P (c
))
16344 SET_EXPR_LOCATION (c
, expr_loc
);
16345 if (c
== boolean_true_node
)
16347 warning_at (expr_loc
, OPT_Wopenmp
,
16348 "%<grainsize%> value must be positive");
16349 t
= integer_one_node
;
16352 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
16354 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
16355 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
16356 OMP_CLAUSE_GRAINSIZE_STRICT (c
) = strict
;
16357 OMP_CLAUSE_CHAIN (c
) = list
;
16365 priority ( expression ) */
16368 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
16370 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
16371 matching_parens parens
;
16372 if (parens
.require_open (parser
))
16374 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16375 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16376 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16377 tree c
, t
= expr
.value
;
16378 t
= c_fully_fold (t
, false, NULL
);
16380 parens
.skip_until_found_close (parser
);
16382 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16384 c_parser_error (parser
, "expected integer expression");
16388 /* Attempt to statically determine when the number isn't
16390 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
16391 build_int_cst (TREE_TYPE (t
), 0));
16392 if (CAN_HAVE_LOCATION_P (c
))
16393 SET_EXPR_LOCATION (c
, expr_loc
);
16394 if (c
== boolean_true_node
)
16396 warning_at (expr_loc
, OPT_Wopenmp
,
16397 "%<priority%> value must be non-negative");
16398 t
= integer_one_node
;
16401 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
16403 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
16404 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
16405 OMP_CLAUSE_CHAIN (c
) = list
;
16413 hint ( expression ) */
16416 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
16418 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
16419 matching_parens parens
;
16420 if (parens
.require_open (parser
))
16422 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16423 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16424 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16425 tree c
, t
= expr
.value
;
16426 t
= c_fully_fold (t
, false, NULL
);
16427 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
16428 || TREE_CODE (t
) != INTEGER_CST
16429 || tree_int_cst_sgn (t
) == -1)
16431 c_parser_error (parser
, "expected constant integer expression "
16432 "with valid sync-hint value");
16435 parens
.skip_until_found_close (parser
);
16436 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
16438 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
16439 OMP_CLAUSE_HINT_EXPR (c
) = t
;
16440 OMP_CLAUSE_CHAIN (c
) = list
;
16448 filter ( integer-expression ) */
16451 c_parser_omp_clause_filter (c_parser
*parser
, tree list
)
16453 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
16454 matching_parens parens
;
16455 if (parens
.require_open (parser
))
16457 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16458 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16459 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16460 tree c
, t
= expr
.value
;
16461 t
= c_fully_fold (t
, false, NULL
);
16462 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16464 c_parser_error (parser
, "expected integer expression");
16467 parens
.skip_until_found_close (parser
);
16468 check_no_duplicate_clause (list
, OMP_CLAUSE_FILTER
, "filter");
16470 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_FILTER
);
16471 OMP_CLAUSE_FILTER_EXPR (c
) = t
;
16472 OMP_CLAUSE_CHAIN (c
) = list
;
16480 defaultmap ( tofrom : scalar )
16483 defaultmap ( implicit-behavior [ : variable-category ] ) */
16486 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
16488 location_t loc
= c_parser_peek_token (parser
)->location
;
16491 enum omp_clause_defaultmap_kind behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
16492 enum omp_clause_defaultmap_kind category
16493 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
16495 matching_parens parens
;
16496 if (!parens
.require_open (parser
))
16498 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
16500 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
16503 c_parser_error (parser
, "expected %<alloc%>, %<to%>, %<from%>, "
16504 "%<tofrom%>, %<firstprivate%>, %<none%> "
16509 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16514 if (strcmp ("alloc", p
) == 0)
16515 behavior
= OMP_CLAUSE_DEFAULTMAP_ALLOC
;
16517 goto invalid_behavior
;
16521 if (strcmp ("default", p
) == 0)
16522 behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
16524 goto invalid_behavior
;
16528 if (strcmp ("firstprivate", p
) == 0)
16529 behavior
= OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
16530 else if (strcmp ("from", p
) == 0)
16531 behavior
= OMP_CLAUSE_DEFAULTMAP_FROM
;
16533 goto invalid_behavior
;
16537 if (strcmp ("none", p
) == 0)
16538 behavior
= OMP_CLAUSE_DEFAULTMAP_NONE
;
16540 goto invalid_behavior
;
16544 if (strcmp ("present", p
) == 0)
16545 behavior
= OMP_CLAUSE_DEFAULTMAP_PRESENT
;
16547 goto invalid_behavior
;
16551 if (strcmp ("tofrom", p
) == 0)
16552 behavior
= OMP_CLAUSE_DEFAULTMAP_TOFROM
;
16553 else if (strcmp ("to", p
) == 0)
16554 behavior
= OMP_CLAUSE_DEFAULTMAP_TO
;
16556 goto invalid_behavior
;
16560 goto invalid_behavior
;
16562 c_parser_consume_token (parser
);
16564 if (!c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
16566 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16568 if (!c_parser_next_token_is (parser
, CPP_NAME
))
16571 c_parser_error (parser
, "expected %<scalar%>, %<aggregate%>, "
16572 "%<pointer%> or %<all%>");
16575 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16579 if (strcmp ("aggregate", p
) == 0)
16580 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
;
16581 else if (strcmp ("all", p
) == 0)
16582 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
;
16584 goto invalid_category
;
16588 if (strcmp ("pointer", p
) == 0)
16589 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
;
16591 goto invalid_category
;
16595 if (strcmp ("scalar", p
) == 0)
16596 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
;
16598 goto invalid_category
;
16602 goto invalid_category
;
16605 c_parser_consume_token (parser
);
16607 parens
.skip_until_found_close (parser
);
16609 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
16610 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEFAULTMAP
16611 && (category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16612 || category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16613 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
) == category
16614 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
16615 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
16616 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
16617 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
)))
16619 enum omp_clause_defaultmap_kind cat
= category
;
16620 location_t loc
= OMP_CLAUSE_LOCATION (c
);
16621 if (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16622 || (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16623 && (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
16624 != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)))
16625 cat
= OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
);
16629 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
16632 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
:
16635 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
16638 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
16641 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
16645 gcc_unreachable ();
16648 error_at (loc
, "too many %<defaultmap%> clauses with %qs category",
16651 error_at (loc
, "too many %<defaultmap%> clauses with unspecified "
16656 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
16657 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c
, behavior
, category
);
16658 OMP_CLAUSE_CHAIN (c
) = list
;
16662 parens
.skip_until_found_close (parser
);
16667 use_device ( variable-list )
16670 use_device_ptr ( variable-list ) */
16673 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
16675 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
16680 use_device_addr ( variable-list ) */
16683 c_parser_omp_clause_use_device_addr (c_parser
*parser
, tree list
)
16685 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_ADDR
,
16690 has_device_addr ( variable-list ) */
16693 c_parser_omp_clause_has_device_addr (c_parser
*parser
, tree list
)
16695 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_HAS_DEVICE_ADDR
,
16700 is_device_ptr ( variable-list ) */
16703 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
16705 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
16709 num_gangs ( expression )
16710 num_workers ( expression )
16711 vector_length ( expression ) */
16714 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
16717 location_t loc
= c_parser_peek_token (parser
)->location
;
16719 matching_parens parens
;
16720 if (!parens
.require_open (parser
))
16723 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16724 c_expr expr
= c_parser_expression (parser
);
16725 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16726 tree c
, t
= expr
.value
;
16727 t
= c_fully_fold (t
, false, NULL
);
16729 parens
.skip_until_found_close (parser
);
16731 if (t
== error_mark_node
)
16733 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16735 error_at (expr_loc
, "%qs expression must be integral",
16736 omp_clause_code_name
[code
]);
16740 /* Attempt to statically determine when the number isn't positive. */
16741 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
16742 build_int_cst (TREE_TYPE (t
), 0));
16743 protected_set_expr_location (c
, expr_loc
);
16744 if (c
== boolean_true_node
)
16746 warning_at (expr_loc
, 0,
16747 "%qs value must be positive",
16748 omp_clause_code_name
[code
]);
16749 t
= integer_one_node
;
16752 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
16754 c
= build_omp_clause (loc
, code
);
16755 OMP_CLAUSE_OPERAND (c
, 0) = t
;
16756 OMP_CLAUSE_CHAIN (c
) = list
;
16762 gang [( gang-arg-list )]
16763 worker [( [num:] int-expr )]
16764 vector [( [length:] int-expr )]
16766 where gang-arg is one of:
16771 and size-expr may be:
16778 c_parser_oacc_shape_clause (c_parser
*parser
, location_t loc
,
16779 omp_clause_code kind
,
16780 const char *str
, tree list
)
16782 const char *id
= "num";
16783 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
16785 if (kind
== OMP_CLAUSE_VECTOR
)
16788 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
16790 c_parser_consume_token (parser
);
16794 c_token
*next
= c_parser_peek_token (parser
);
16797 /* Gang static argument. */
16798 if (kind
== OMP_CLAUSE_GANG
16799 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
16801 c_parser_consume_token (parser
);
16803 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16804 goto cleanup_error
;
16807 if (ops
[idx
] != NULL_TREE
)
16809 c_parser_error (parser
, "too many %<static%> arguments");
16810 goto cleanup_error
;
16813 /* Check for the '*' argument. */
16814 if (c_parser_next_token_is (parser
, CPP_MULT
)
16815 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
16816 || c_parser_peek_2nd_token (parser
)->type
16817 == CPP_CLOSE_PAREN
))
16819 c_parser_consume_token (parser
);
16820 ops
[idx
] = integer_minus_one_node
;
16822 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16824 c_parser_consume_token (parser
);
16831 /* Worker num: argument and vector length: arguments. */
16832 else if (c_parser_next_token_is (parser
, CPP_NAME
)
16833 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
16834 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16836 c_parser_consume_token (parser
); /* id */
16837 c_parser_consume_token (parser
); /* ':' */
16840 /* Now collect the actual argument. */
16841 if (ops
[idx
] != NULL_TREE
)
16843 c_parser_error (parser
, "unexpected argument");
16844 goto cleanup_error
;
16847 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16848 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
16849 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
16850 tree expr
= cexpr
.value
;
16851 if (expr
== error_mark_node
)
16852 goto cleanup_error
;
16854 expr
= c_fully_fold (expr
, false, NULL
);
16856 /* Attempt to statically determine when the number isn't a
16857 positive integer. */
16859 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
16861 c_parser_error (parser
, "expected integer expression");
16865 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
16866 build_int_cst (TREE_TYPE (expr
), 0));
16867 if (c
== boolean_true_node
)
16869 warning_at (loc
, 0,
16870 "%qs value must be positive", str
);
16871 expr
= integer_one_node
;
16876 if (kind
== OMP_CLAUSE_GANG
16877 && c_parser_next_token_is (parser
, CPP_COMMA
))
16879 c_parser_consume_token (parser
);
16886 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
16887 goto cleanup_error
;
16890 check_no_duplicate_clause (list
, kind
, str
);
16892 c
= build_omp_clause (loc
, kind
);
16895 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
16897 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
16898 OMP_CLAUSE_CHAIN (c
) = list
;
16903 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
16915 c_parser_oacc_simple_clause (location_t loc
, enum omp_clause_code code
,
16918 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
16920 tree c
= build_omp_clause (loc
, code
);
16921 OMP_CLAUSE_CHAIN (c
) = list
;
16927 async [( int-expr )] */
16930 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
16933 location_t loc
= c_parser_peek_token (parser
)->location
;
16935 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
16937 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
16939 c_parser_consume_token (parser
);
16941 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
16942 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16943 c_parser_error (parser
, "expected integer expression");
16944 else if (t
== error_mark_node
16945 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
16949 t
= c_fully_fold (t
, false, NULL
);
16951 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
16953 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
16954 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
16955 OMP_CLAUSE_CHAIN (c
) = list
;
16962 tile ( size-expr-list ) */
16965 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
16967 tree c
, expr
= error_mark_node
;
16969 tree tile
= NULL_TREE
;
16971 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
16972 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
16974 loc
= c_parser_peek_token (parser
)->location
;
16975 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
16980 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
16983 if (c_parser_next_token_is (parser
, CPP_MULT
)
16984 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
16985 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
16987 c_parser_consume_token (parser
);
16988 expr
= integer_zero_node
;
16992 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16993 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
16994 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
16995 expr
= cexpr
.value
;
16997 if (expr
== error_mark_node
)
16999 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
17004 expr
= c_fully_fold (expr
, false, NULL
);
17006 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
17007 || !tree_fits_shwi_p (expr
)
17008 || tree_to_shwi (expr
) <= 0)
17010 error_at (expr_loc
, "%<tile%> argument needs positive"
17011 " integral constant");
17012 expr
= integer_zero_node
;
17016 tile
= tree_cons (NULL_TREE
, expr
, tile
);
17018 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
17020 /* Consume the trailing ')'. */
17021 c_parser_consume_token (parser
);
17023 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
17024 tile
= nreverse (tile
);
17025 OMP_CLAUSE_TILE_LIST (c
) = tile
;
17026 OMP_CLAUSE_CHAIN (c
) = list
;
17031 wait [( int-expr-list )] */
17034 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
17036 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17038 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
17039 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
17042 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
17044 OMP_CLAUSE_DECL (c
) = build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
17045 OMP_CLAUSE_CHAIN (c
) = list
;
17053 self [( expression )] */
17056 c_parser_oacc_compute_clause_self (c_parser
*parser
, tree list
)
17059 location_t location
= c_parser_peek_token (parser
)->location
;
17060 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
17062 matching_parens parens
;
17063 parens
.consume_open (parser
);
17065 location_t loc
= c_parser_peek_token (parser
)->location
;
17066 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17067 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
17068 t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
);
17069 t
= c_fully_fold (t
, false, NULL
);
17070 parens
.skip_until_found_close (parser
);
17073 t
= truthvalue_true_node
;
17075 for (tree c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
17076 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SELF
)
17078 error_at (location
, "too many %<self%> clauses");
17082 tree c
= build_omp_clause (location
, OMP_CLAUSE_SELF
);
17083 OMP_CLAUSE_SELF_EXPR (c
) = t
;
17084 OMP_CLAUSE_CHAIN (c
) = list
;
17089 order ( concurrent )
17092 order ( order-modifier : concurrent )
17099 c_parser_omp_clause_order (c_parser
*parser
, tree list
)
17101 location_t loc
= c_parser_peek_token (parser
)->location
;
17104 bool unconstrained
= false;
17105 bool reproducible
= false;
17107 matching_parens parens
;
17108 if (!parens
.require_open (parser
))
17110 if (c_parser_next_token_is (parser
, CPP_NAME
)
17111 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
17113 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17114 if (strcmp (p
, "unconstrained") == 0)
17115 unconstrained
= true;
17116 else if (strcmp (p
, "reproducible") == 0)
17117 reproducible
= true;
17120 c_parser_error (parser
, "expected %<reproducible%> or "
17121 "%<unconstrained%>");
17124 c_parser_consume_token (parser
);
17125 c_parser_consume_token (parser
);
17127 if (!c_parser_next_token_is (parser
, CPP_NAME
))
17129 c_parser_error (parser
, "expected %<concurrent%>");
17132 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17133 if (strcmp (p
, "concurrent") != 0)
17135 c_parser_error (parser
, "expected %<concurrent%>");
17138 c_parser_consume_token (parser
);
17139 parens
.skip_until_found_close (parser
);
17140 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDER
, "order");
17141 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDER
);
17142 OMP_CLAUSE_ORDER_UNCONSTRAINED (c
) = unconstrained
;
17143 OMP_CLAUSE_ORDER_REPRODUCIBLE (c
) = reproducible
;
17144 OMP_CLAUSE_CHAIN (c
) = list
;
17148 parens
.skip_until_found_close (parser
);
17154 bind ( teams | parallel | thread ) */
17157 c_parser_omp_clause_bind (c_parser
*parser
, tree list
)
17159 location_t loc
= c_parser_peek_token (parser
)->location
;
17162 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
17164 matching_parens parens
;
17165 if (!parens
.require_open (parser
))
17167 if (!c_parser_next_token_is (parser
, CPP_NAME
))
17170 c_parser_error (parser
,
17171 "expected %<teams%>, %<parallel%> or %<thread%>");
17172 parens
.skip_until_found_close (parser
);
17175 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17176 if (strcmp (p
, "teams") == 0)
17177 kind
= OMP_CLAUSE_BIND_TEAMS
;
17178 else if (strcmp (p
, "parallel") == 0)
17179 kind
= OMP_CLAUSE_BIND_PARALLEL
;
17180 else if (strcmp (p
, "thread") != 0)
17182 c_parser_consume_token (parser
);
17183 parens
.skip_until_found_close (parser
);
17184 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
17185 c
= build_omp_clause (loc
, OMP_CLAUSE_BIND
);
17186 OMP_CLAUSE_BIND_KIND (c
) = kind
;
17187 OMP_CLAUSE_CHAIN (c
) = list
;
17196 ordered ( constant-expression ) */
17199 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
17201 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
17203 tree c
, num
= NULL_TREE
;
17205 location_t loc
= c_parser_peek_token (parser
)->location
;
17206 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17208 matching_parens parens
;
17209 parens
.consume_open (parser
);
17210 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
17211 parens
.skip_until_found_close (parser
);
17213 if (num
== error_mark_node
)
17217 mark_exp_read (num
);
17218 num
= c_fully_fold (num
, false, NULL
);
17219 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
17220 || !tree_fits_shwi_p (num
)
17221 || (n
= tree_to_shwi (num
)) <= 0
17224 error_at (loc
, "ordered argument needs positive "
17225 "constant integer expression");
17229 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
17230 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
17231 OMP_CLAUSE_CHAIN (c
) = list
;
17236 private ( variable-list ) */
17239 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
17241 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
17245 reduction ( reduction-operator : variable-list )
17247 reduction-operator:
17248 One of: + * - & ^ | && ||
17252 reduction-operator:
17253 One of: + * - & ^ | && || max min
17257 reduction-operator:
17258 One of: + * - & ^ | && ||
17262 reduction ( reduction-modifier, reduction-operator : variable-list )
17263 in_reduction ( reduction-operator : variable-list )
17264 task_reduction ( reduction-operator : variable-list ) */
17267 c_parser_omp_clause_reduction (c_parser
*parser
, enum omp_clause_code kind
,
17268 bool is_omp
, tree list
)
17270 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17271 matching_parens parens
;
17272 if (parens
.require_open (parser
))
17275 bool inscan
= false;
17276 enum tree_code code
= ERROR_MARK
;
17277 tree reduc_id
= NULL_TREE
;
17279 if (kind
== OMP_CLAUSE_REDUCTION
&& is_omp
)
17281 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
17282 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
17284 c_parser_consume_token (parser
);
17285 c_parser_consume_token (parser
);
17287 else if (c_parser_next_token_is (parser
, CPP_NAME
)
17288 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
17291 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17292 if (strcmp (p
, "task") == 0)
17294 else if (strcmp (p
, "inscan") == 0)
17296 if (task
|| inscan
)
17298 c_parser_consume_token (parser
);
17299 c_parser_consume_token (parser
);
17304 switch (c_parser_peek_token (parser
)->type
)
17316 code
= BIT_AND_EXPR
;
17319 code
= BIT_XOR_EXPR
;
17322 code
= BIT_IOR_EXPR
;
17325 code
= TRUTH_ANDIF_EXPR
;
17328 code
= TRUTH_ORIF_EXPR
;
17333 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17334 if (strcmp (p
, "min") == 0)
17339 if (strcmp (p
, "max") == 0)
17344 reduc_id
= c_parser_peek_token (parser
)->value
;
17348 c_parser_error (parser
,
17349 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
17350 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
17351 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
17354 c_parser_consume_token (parser
);
17355 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
17356 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
17360 nl
= c_parser_omp_variable_list (parser
, clause_loc
, kind
, list
);
17361 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
17363 tree d
= OMP_CLAUSE_DECL (c
), type
;
17364 if (TREE_CODE (d
) != OMP_ARRAY_SECTION
)
17365 type
= TREE_TYPE (d
);
17371 TREE_CODE (t
) == OMP_ARRAY_SECTION
;
17372 t
= TREE_OPERAND (t
, 0))
17374 type
= TREE_TYPE (t
);
17377 if (TREE_CODE (type
) != POINTER_TYPE
17378 && TREE_CODE (type
) != ARRAY_TYPE
)
17380 type
= TREE_TYPE (type
);
17384 while (TREE_CODE (type
) == ARRAY_TYPE
)
17385 type
= TREE_TYPE (type
);
17386 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
17388 OMP_CLAUSE_REDUCTION_TASK (c
) = 1;
17390 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 1;
17391 if (code
== ERROR_MARK
17392 || !(INTEGRAL_TYPE_P (type
)
17393 || SCALAR_FLOAT_TYPE_P (type
)
17394 || TREE_CODE (type
) == COMPLEX_TYPE
))
17395 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
17396 = c_omp_reduction_lookup (reduc_id
,
17397 TYPE_MAIN_VARIANT (type
));
17402 parens
.skip_until_found_close (parser
);
17408 schedule ( schedule-kind )
17409 schedule ( schedule-kind , expression )
17412 static | dynamic | guided | runtime | auto
17415 schedule ( schedule-modifier : schedule-kind )
17416 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
17424 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
17427 location_t loc
= c_parser_peek_token (parser
)->location
;
17428 int modifiers
= 0, nmodifiers
= 0;
17430 matching_parens parens
;
17431 if (!parens
.require_open (parser
))
17434 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
17436 location_t comma
= UNKNOWN_LOCATION
;
17437 while (c_parser_next_token_is (parser
, CPP_NAME
))
17439 tree kind
= c_parser_peek_token (parser
)->value
;
17440 const char *p
= IDENTIFIER_POINTER (kind
);
17441 if (strcmp ("simd", p
) == 0)
17442 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
17443 else if (strcmp ("monotonic", p
) == 0)
17444 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
17445 else if (strcmp ("nonmonotonic", p
) == 0)
17446 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
17449 comma
= UNKNOWN_LOCATION
;
17450 c_parser_consume_token (parser
);
17451 if (nmodifiers
++ == 0
17452 && c_parser_next_token_is (parser
, CPP_COMMA
))
17454 comma
= c_parser_peek_token (parser
)->location
;
17455 c_parser_consume_token (parser
);
17459 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
17463 if (comma
!= UNKNOWN_LOCATION
)
17464 error_at (comma
, "expected %<:%>");
17466 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
17467 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
17468 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
17469 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
17471 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
17476 if (c_parser_next_token_is (parser
, CPP_NAME
))
17478 tree kind
= c_parser_peek_token (parser
)->value
;
17479 const char *p
= IDENTIFIER_POINTER (kind
);
17484 if (strcmp ("dynamic", p
) != 0)
17486 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
17490 if (strcmp ("guided", p
) != 0)
17492 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
17496 if (strcmp ("runtime", p
) != 0)
17498 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
17505 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
17506 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
17507 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
17508 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
17512 c_parser_consume_token (parser
);
17513 if (c_parser_next_token_is (parser
, CPP_COMMA
))
17516 c_parser_consume_token (parser
);
17518 here
= c_parser_peek_token (parser
)->location
;
17519 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17520 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
17522 t
= c_fully_fold (t
, false, NULL
);
17524 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
17525 error_at (here
, "schedule %<runtime%> does not take "
17526 "a %<chunk_size%> parameter");
17527 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
17529 "schedule %<auto%> does not take "
17530 "a %<chunk_size%> parameter");
17531 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
17532 || TREE_CODE (TREE_TYPE (t
)) == BITINT_TYPE
)
17534 /* Attempt to statically determine when the number isn't
17536 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
17537 build_int_cst (TREE_TYPE (t
), 0));
17538 protected_set_expr_location (s
, loc
);
17539 if (s
== boolean_true_node
)
17541 warning_at (loc
, OPT_Wopenmp
,
17542 "chunk size value must be positive");
17543 t
= integer_one_node
;
17545 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
17548 c_parser_error (parser
, "expected integer expression");
17550 parens
.skip_until_found_close (parser
);
17553 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
17554 "expected %<,%> or %<)%>");
17556 OMP_CLAUSE_SCHEDULE_KIND (c
)
17557 = (enum omp_clause_schedule_kind
)
17558 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
17560 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
17561 OMP_CLAUSE_CHAIN (c
) = list
;
17565 c_parser_error (parser
, "invalid schedule kind");
17566 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
17571 shared ( variable-list ) */
17574 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
17576 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
17583 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
17587 /* FIXME: Should we allow duplicates? */
17588 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
17590 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
17591 OMP_CLAUSE_UNTIED
);
17592 OMP_CLAUSE_CHAIN (c
) = list
;
17602 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
17603 enum omp_clause_code code
, tree list
)
17605 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
17607 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
17608 OMP_CLAUSE_CHAIN (c
) = list
;
17620 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
17621 enum omp_clause_code code
, tree list
)
17623 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
17624 OMP_CLAUSE_CHAIN (c
) = list
;
17633 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
17635 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
17636 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
17637 OMP_CLAUSE_NOGROUP
);
17638 OMP_CLAUSE_CHAIN (c
) = list
;
17647 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
17648 enum omp_clause_code code
, tree list
)
17650 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
17651 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
17652 OMP_CLAUSE_CHAIN (c
) = list
;
17657 num_teams ( expression )
17660 num_teams ( expression : expression ) */
17663 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
17665 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
17666 matching_parens parens
;
17667 if (parens
.require_open (parser
))
17669 location_t upper_loc
= c_parser_peek_token (parser
)->location
;
17670 location_t lower_loc
= UNKNOWN_LOCATION
;
17671 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17672 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
17673 tree c
, upper
= expr
.value
, lower
= NULL_TREE
;
17674 upper
= c_fully_fold (upper
, false, NULL
);
17676 if (c_parser_next_token_is (parser
, CPP_COLON
))
17678 c_parser_consume_token (parser
);
17679 lower_loc
= upper_loc
;
17681 upper_loc
= c_parser_peek_token (parser
)->location
;
17682 expr
= c_parser_expr_no_commas (parser
, NULL
);
17683 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
17684 upper
= expr
.value
;
17685 upper
= c_fully_fold (upper
, false, NULL
);
17688 parens
.skip_until_found_close (parser
);
17690 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper
))
17691 || (lower
&& !INTEGRAL_TYPE_P (TREE_TYPE (lower
))))
17693 c_parser_error (parser
, "expected integer expression");
17697 /* Attempt to statically determine when the number isn't positive. */
17698 c
= fold_build2_loc (upper_loc
, LE_EXPR
, boolean_type_node
, upper
,
17699 build_int_cst (TREE_TYPE (upper
), 0));
17700 protected_set_expr_location (c
, upper_loc
);
17701 if (c
== boolean_true_node
)
17703 warning_at (upper_loc
, OPT_Wopenmp
,
17704 "%<num_teams%> value must be positive");
17705 upper
= integer_one_node
;
17709 c
= fold_build2_loc (lower_loc
, LE_EXPR
, boolean_type_node
, lower
,
17710 build_int_cst (TREE_TYPE (lower
), 0));
17711 protected_set_expr_location (c
, lower_loc
);
17712 if (c
== boolean_true_node
)
17714 warning_at (lower_loc
, OPT_Wopenmp
,
17715 "%<num_teams%> value must be positive");
17718 else if (TREE_CODE (lower
) == INTEGER_CST
17719 && TREE_CODE (upper
) == INTEGER_CST
17720 && tree_int_cst_lt (upper
, lower
))
17722 warning_at (lower_loc
, OPT_Wopenmp
,
17723 "%<num_teams%> lower bound %qE bigger than upper "
17724 "bound %qE", lower
, upper
);
17729 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
17731 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
17732 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c
) = upper
;
17733 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
) = lower
;
17734 OMP_CLAUSE_CHAIN (c
) = list
;
17742 thread_limit ( expression ) */
17745 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
17747 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
17748 matching_parens parens
;
17749 if (parens
.require_open (parser
))
17751 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17752 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17753 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17754 tree c
, t
= expr
.value
;
17755 t
= c_fully_fold (t
, false, NULL
);
17757 parens
.skip_until_found_close (parser
);
17759 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
17761 c_parser_error (parser
, "expected integer expression");
17765 /* Attempt to statically determine when the number isn't positive. */
17766 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
17767 build_int_cst (TREE_TYPE (t
), 0));
17768 protected_set_expr_location (c
, expr_loc
);
17769 if (c
== boolean_true_node
)
17771 warning_at (expr_loc
, OPT_Wopenmp
,
17772 "%<thread_limit%> value must be positive");
17773 t
= integer_one_node
;
17776 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
17779 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
17780 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
17781 OMP_CLAUSE_CHAIN (c
) = list
;
17789 aligned ( variable-list )
17790 aligned ( variable-list : constant-expression ) */
17793 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
17795 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17798 matching_parens parens
;
17799 if (!parens
.require_open (parser
))
17802 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
17803 OMP_CLAUSE_ALIGNED
, list
);
17805 if (c_parser_next_token_is (parser
, CPP_COLON
))
17807 c_parser_consume_token (parser
);
17808 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17809 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17810 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17811 tree alignment
= expr
.value
;
17812 alignment
= c_fully_fold (alignment
, false, NULL
);
17813 if (TREE_CODE (alignment
) != INTEGER_CST
17814 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
17815 || tree_int_cst_sgn (alignment
) != 1)
17817 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
17818 "be positive constant integer expression");
17819 alignment
= NULL_TREE
;
17822 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
17823 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
17826 parens
.skip_until_found_close (parser
);
17831 allocate ( variable-list )
17832 allocate ( expression : variable-list )
17835 allocate ( allocator-modifier : variable-list )
17836 allocate ( allocator-modifier , allocator-modifier : variable-list )
17838 allocator-modifier:
17839 allocator ( expression )
17840 align ( expression ) */
17843 c_parser_omp_clause_allocate (c_parser
*parser
, tree list
)
17845 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17847 tree allocator
= NULL_TREE
;
17848 tree align
= NULL_TREE
;
17850 matching_parens parens
;
17851 if (!parens
.require_open (parser
))
17854 if ((c_parser_next_token_is_not (parser
, CPP_NAME
)
17855 && c_parser_next_token_is_not (parser
, CPP_KEYWORD
))
17856 || (c_parser_peek_2nd_token (parser
)->type
!= CPP_COMMA
17857 && c_parser_peek_2nd_token (parser
)->type
!= CPP_CLOSE_PAREN
))
17859 bool has_modifiers
= false;
17860 tree orig_type
= NULL_TREE
;
17861 if (c_parser_next_token_is (parser
, CPP_NAME
)
17862 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
17864 unsigned int n
= 3;
17866 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17867 if ((strcmp (p
, "allocator") == 0 || strcmp (p
, "align") == 0)
17868 && c_parser_check_balanced_raw_token_sequence (parser
, &n
)
17869 && (c_parser_peek_nth_token_raw (parser
, n
)->type
17870 == CPP_CLOSE_PAREN
))
17872 if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
17874 has_modifiers
= true;
17875 else if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
17877 && (c_parser_peek_nth_token_raw (parser
, n
+ 2)->type
17879 && (c_parser_peek_nth_token_raw (parser
, n
+ 3)->type
17880 == CPP_OPEN_PAREN
))
17882 c_token
*tok
= c_parser_peek_nth_token_raw (parser
, n
+ 2);
17883 const char *q
= IDENTIFIER_POINTER (tok
->value
);
17885 if ((strcmp (q
, "allocator") == 0
17886 || strcmp (q
, "align") == 0)
17887 && c_parser_check_balanced_raw_token_sequence (parser
,
17889 && (c_parser_peek_nth_token_raw (parser
, n
)->type
17890 == CPP_CLOSE_PAREN
)
17891 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
17893 has_modifiers
= true;
17898 c_parser_consume_token (parser
);
17899 matching_parens parens2
;;
17900 parens2
.require_open (parser
);
17901 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17902 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17903 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17904 if (expr
.value
== error_mark_node
)
17906 else if (strcmp (p
, "allocator") == 0)
17908 allocator
= expr
.value
;
17909 allocator
= c_fully_fold (allocator
, false, NULL
);
17910 orig_type
= expr
.original_type
17911 ? expr
.original_type
: TREE_TYPE (allocator
);
17912 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
17916 align
= expr
.value
;
17917 align
= c_fully_fold (align
, false, NULL
);
17919 parens2
.skip_until_found_close (parser
);
17920 if (c_parser_next_token_is (parser
, CPP_COMMA
))
17922 c_parser_consume_token (parser
);
17923 c_token
*tok
= c_parser_peek_token (parser
);
17924 const char *q
= "";
17925 if (c_parser_next_token_is (parser
, CPP_NAME
))
17926 q
= IDENTIFIER_POINTER (tok
->value
);
17927 if (strcmp (q
, "allocator") != 0 && strcmp (q
, "align") != 0)
17929 c_parser_error (parser
, "expected %<allocator%> or "
17931 parens
.skip_until_found_close (parser
);
17934 else if (strcmp (p
, q
) == 0)
17936 error_at (tok
->location
, "duplicate %qs modifier", p
);
17937 parens
.skip_until_found_close (parser
);
17940 c_parser_consume_token (parser
);
17941 if (!parens2
.require_open (parser
))
17943 parens
.skip_until_found_close (parser
);
17946 expr_loc
= c_parser_peek_token (parser
)->location
;
17947 expr
= c_parser_expr_no_commas (parser
, NULL
);
17948 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
17950 if (strcmp (q
, "allocator") == 0)
17952 allocator
= expr
.value
;
17953 allocator
= c_fully_fold (allocator
, false, NULL
);
17954 orig_type
= expr
.original_type
17955 ? expr
.original_type
: TREE_TYPE (allocator
);
17956 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
17960 align
= expr
.value
;
17961 align
= c_fully_fold (align
, false, NULL
);
17963 parens2
.skip_until_found_close (parser
);
17967 if (!has_modifiers
)
17969 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17970 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17971 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17972 allocator
= expr
.value
;
17973 allocator
= c_fully_fold (allocator
, false, NULL
);
17974 orig_type
= expr
.original_type
17975 ? expr
.original_type
: TREE_TYPE (allocator
);
17976 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
17979 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
17980 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
17981 || (TYPE_NAME (orig_type
)
17982 != get_identifier ("omp_allocator_handle_t"))))
17984 error_at (clause_loc
, "%<allocate%> clause allocator expression "
17985 "has type %qT rather than "
17986 "%<omp_allocator_handle_t%>",
17987 TREE_TYPE (allocator
));
17988 allocator
= NULL_TREE
;
17991 && (!INTEGRAL_TYPE_P (TREE_TYPE (align
))
17992 || !tree_fits_uhwi_p (align
)
17993 || !integer_pow2p (align
)))
17995 error_at (clause_loc
, "%<allocate%> clause %<align%> modifier "
17996 "argument needs to be positive constant "
17997 "power of two integer expression");
18000 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18002 parens
.skip_until_found_close (parser
);
18007 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
18008 OMP_CLAUSE_ALLOCATE
, list
);
18010 if (allocator
|| align
)
18011 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18013 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
18014 OMP_CLAUSE_ALLOCATE_ALIGN (c
) = align
;
18017 parens
.skip_until_found_close (parser
);
18022 linear ( variable-list )
18023 linear ( variable-list : expression )
18026 linear ( modifier ( variable-list ) )
18027 linear ( modifier ( variable-list ) : expression )
18033 linear ( variable-list : modifiers-list )
18037 step ( expression ) */
18040 c_parser_omp_clause_linear (c_parser
*parser
, tree list
)
18042 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18044 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
18045 bool old_linear_modifier
= false;
18047 matching_parens parens
;
18048 if (!parens
.require_open (parser
))
18051 if (c_parser_next_token_is (parser
, CPP_NAME
))
18053 c_token
*tok
= c_parser_peek_token (parser
);
18054 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18055 if (strcmp ("val", p
) == 0)
18056 kind
= OMP_CLAUSE_LINEAR_VAL
;
18057 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
18058 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
18059 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
18061 old_linear_modifier
= true;
18062 c_parser_consume_token (parser
);
18063 c_parser_consume_token (parser
);
18067 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
18068 OMP_CLAUSE_LINEAR
, list
);
18070 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
18071 parens
.skip_until_found_close (parser
);
18073 if (c_parser_next_token_is (parser
, CPP_COLON
))
18075 c_parser_consume_token (parser
);
18076 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18077 bool has_modifiers
= false;
18078 if (kind
== OMP_CLAUSE_LINEAR_DEFAULT
18079 && c_parser_next_token_is (parser
, CPP_NAME
))
18081 c_token
*tok
= c_parser_peek_token (parser
);
18082 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18083 unsigned int pos
= 0;
18084 if (strcmp ("val", p
) == 0)
18086 else if (strcmp ("step", p
) == 0
18087 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
18090 if (c_parser_check_balanced_raw_token_sequence (parser
, &pos
)
18091 && (c_parser_peek_nth_token_raw (parser
, pos
)->type
18092 == CPP_CLOSE_PAREN
))
18099 tok
= c_parser_peek_nth_token_raw (parser
, pos
);
18100 if (tok
->type
== CPP_COMMA
|| tok
->type
== CPP_CLOSE_PAREN
)
18101 has_modifiers
= true;
18107 while (c_parser_next_token_is (parser
, CPP_NAME
))
18109 c_token
*tok
= c_parser_peek_token (parser
);
18110 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18111 if (strcmp ("val", p
) == 0)
18113 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
18114 error_at (tok
->location
, "multiple linear modifiers");
18115 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
18116 c_parser_consume_token (parser
);
18118 else if (strcmp ("step", p
) == 0)
18120 c_parser_consume_token (parser
);
18121 matching_parens parens2
;
18122 if (parens2
.require_open (parser
))
18125 error_at (tok
->location
,
18126 "multiple %<step%> modifiers");
18127 expr_loc
= c_parser_peek_token (parser
)->location
;
18128 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18129 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
18131 step
= c_fully_fold (expr
.value
, false, NULL
);
18132 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
18134 error_at (clause_loc
, "%<linear%> clause step "
18135 "expression must be integral");
18136 step
= integer_one_node
;
18138 parens2
.skip_until_found_close (parser
);
18145 if (c_parser_next_token_is (parser
, CPP_COMMA
))
18147 c_parser_consume_token (parser
);
18153 step
= integer_one_node
;
18157 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18158 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18159 step
= c_fully_fold (expr
.value
, false, NULL
);
18160 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
18162 error_at (clause_loc
, "%<linear%> clause step expression must "
18164 step
= integer_one_node
;
18170 step
= integer_one_node
;
18172 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18174 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
18175 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
18176 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c
) = old_linear_modifier
;
18179 parens
.skip_until_found_close (parser
);
18184 nontemporal ( variable-list ) */
18187 c_parser_omp_clause_nontemporal (c_parser
*parser
, tree list
)
18189 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_NONTEMPORAL
, list
);
18193 safelen ( constant-expression ) */
18196 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
18198 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18201 matching_parens parens
;
18202 if (!parens
.require_open (parser
))
18205 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18206 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18207 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18209 t
= c_fully_fold (t
, false, NULL
);
18210 if (TREE_CODE (t
) != INTEGER_CST
18211 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
18212 || tree_int_cst_sgn (t
) != 1)
18214 error_at (clause_loc
, "%<safelen%> clause expression must "
18215 "be positive constant integer expression");
18219 parens
.skip_until_found_close (parser
);
18220 if (t
== NULL_TREE
|| t
== error_mark_node
)
18223 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
18225 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
18226 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
18227 OMP_CLAUSE_CHAIN (c
) = list
;
18232 simdlen ( constant-expression ) */
18235 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
18237 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18240 matching_parens parens
;
18241 if (!parens
.require_open (parser
))
18244 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18245 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18246 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18248 t
= c_fully_fold (t
, false, NULL
);
18249 if (TREE_CODE (t
) != INTEGER_CST
18250 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
18251 || tree_int_cst_sgn (t
) != 1)
18253 error_at (clause_loc
, "%<simdlen%> clause expression must "
18254 "be positive constant integer expression");
18258 parens
.skip_until_found_close (parser
);
18259 if (t
== NULL_TREE
|| t
== error_mark_node
)
18262 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
18264 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
18265 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
18266 OMP_CLAUSE_CHAIN (c
) = list
;
18272 identifier [+/- integer]
18273 vec , identifier [+/- integer]
18277 c_parser_omp_clause_doacross_sink (c_parser
*parser
, location_t clause_loc
,
18278 tree list
, bool depend_p
)
18281 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
18282 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
18284 c_parser_error (parser
, "expected identifier");
18290 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18291 if (strcmp (p
, "omp_cur_iteration") == 0
18292 && c_parser_peek_2nd_token (parser
)->type
== CPP_MINUS
18293 && c_parser_peek_nth_token (parser
, 3)->type
== CPP_NUMBER
18294 && c_parser_peek_nth_token (parser
, 4)->type
== CPP_CLOSE_PAREN
)
18296 tree val
= c_parser_peek_nth_token (parser
, 3)->value
;
18297 if (integer_onep (val
))
18299 c_parser_consume_token (parser
);
18300 c_parser_consume_token (parser
);
18301 c_parser_consume_token (parser
);
18302 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
18303 OMP_CLAUSE_DOACROSS_KIND (u
) = OMP_CLAUSE_DOACROSS_SINK
;
18304 OMP_CLAUSE_CHAIN (u
) = list
;
18312 while (c_parser_next_token_is (parser
, CPP_NAME
)
18313 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
18315 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
18316 tree addend
= NULL
;
18318 if (t
== NULL_TREE
)
18320 undeclared_variable (c_parser_peek_token (parser
)->location
,
18321 c_parser_peek_token (parser
)->value
);
18322 t
= error_mark_node
;
18325 c_parser_consume_token (parser
);
18328 if (c_parser_next_token_is (parser
, CPP_MINUS
))
18330 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
18332 addend
= integer_zero_node
;
18334 goto add_to_vector
;
18336 c_parser_consume_token (parser
);
18338 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
18340 c_parser_error (parser
, "expected integer");
18344 addend
= c_parser_peek_token (parser
)->value
;
18345 if (TREE_CODE (addend
) != INTEGER_CST
)
18347 c_parser_error (parser
, "expected integer");
18350 c_parser_consume_token (parser
);
18353 if (t
!= error_mark_node
)
18355 vec
= tree_cons (addend
, t
, vec
);
18357 OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec
) = 1;
18360 if (c_parser_next_token_is_not (parser
, CPP_COMMA
)
18361 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
18362 || c_parser_peek_2nd_token (parser
)->id_kind
!= C_ID_ID
)
18365 c_parser_consume_token (parser
);
18368 if (vec
== NULL_TREE
)
18371 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
18372 OMP_CLAUSE_DOACROSS_KIND (u
) = OMP_CLAUSE_DOACROSS_SINK
;
18373 OMP_CLAUSE_DOACROSS_DEPEND (u
) = depend_p
;
18374 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
18375 OMP_CLAUSE_CHAIN (u
) = list
;
18380 iterators ( iterators-definition )
18382 iterators-definition:
18384 iterator-specifier , iterators-definition
18386 iterator-specifier:
18387 identifier = range-specification
18388 iterator-type identifier = range-specification
18390 range-specification:
18392 begin : end : step */
18395 c_parser_omp_iterators (c_parser
*parser
)
18397 tree ret
= NULL_TREE
, *last
= &ret
;
18398 c_parser_consume_token (parser
);
18402 matching_parens parens
;
18403 if (!parens
.require_open (parser
))
18404 return error_mark_node
;
18408 tree iter_type
= NULL_TREE
, type_expr
= NULL_TREE
;
18409 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
18411 struct c_type_name
*type
= c_parser_type_name (parser
);
18413 iter_type
= groktypename (type
, &type_expr
, NULL
);
18415 if (iter_type
== NULL_TREE
)
18416 iter_type
= integer_type_node
;
18418 location_t loc
= c_parser_peek_token (parser
)->location
;
18419 if (!c_parser_next_token_is (parser
, CPP_NAME
))
18421 c_parser_error (parser
, "expected identifier");
18425 tree id
= c_parser_peek_token (parser
)->value
;
18426 c_parser_consume_token (parser
);
18428 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18431 location_t eloc
= c_parser_peek_token (parser
)->location
;
18432 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18433 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
18434 tree begin
= expr
.value
;
18436 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18439 eloc
= c_parser_peek_token (parser
)->location
;
18440 expr
= c_parser_expr_no_commas (parser
, NULL
);
18441 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
18442 tree end
= expr
.value
;
18444 tree step
= integer_one_node
;
18445 if (c_parser_next_token_is (parser
, CPP_COLON
))
18447 c_parser_consume_token (parser
);
18448 eloc
= c_parser_peek_token (parser
)->location
;
18449 expr
= c_parser_expr_no_commas (parser
, NULL
);
18450 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
18454 tree iter_var
= build_decl (loc
, VAR_DECL
, id
, iter_type
);
18455 DECL_ARTIFICIAL (iter_var
) = 1;
18456 DECL_CONTEXT (iter_var
) = current_function_decl
;
18457 pushdecl (iter_var
);
18459 *last
= make_tree_vec (6);
18460 TREE_VEC_ELT (*last
, 0) = iter_var
;
18461 TREE_VEC_ELT (*last
, 1) = begin
;
18462 TREE_VEC_ELT (*last
, 2) = end
;
18463 TREE_VEC_ELT (*last
, 3) = step
;
18464 last
= &TREE_CHAIN (*last
);
18466 if (c_parser_next_token_is (parser
, CPP_COMMA
))
18468 c_parser_consume_token (parser
);
18475 parens
.skip_until_found_close (parser
);
18476 return ret
? ret
: error_mark_node
;
18480 affinity ( [aff-modifier :] variable-list )
18482 iterator ( iterators-definition ) */
18485 c_parser_omp_clause_affinity (c_parser
*parser
, tree list
)
18487 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18488 tree nl
, iterators
= NULL_TREE
;
18490 matching_parens parens
;
18491 if (!parens
.require_open (parser
))
18494 if (c_parser_next_token_is (parser
, CPP_NAME
))
18496 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18497 bool parse_iter
= ((strcmp ("iterator", p
) == 0)
18498 && (c_parser_peek_2nd_token (parser
)->type
18499 == CPP_OPEN_PAREN
));
18503 parse_iter
= (c_parser_check_balanced_raw_token_sequence (parser
, &n
)
18504 && (c_parser_peek_nth_token_raw (parser
, n
)->type
18505 == CPP_CLOSE_PAREN
)
18506 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
18511 iterators
= c_parser_omp_iterators (parser
);
18512 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18516 parens
.skip_until_found_close (parser
);
18521 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_AFFINITY
,
18525 tree block
= pop_scope ();
18526 if (iterators
!= error_mark_node
)
18528 TREE_VEC_ELT (iterators
, 5) = block
;
18529 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18530 OMP_CLAUSE_DECL (c
) = build_tree_list (iterators
,
18531 OMP_CLAUSE_DECL (c
));
18535 parens
.skip_until_found_close (parser
);
18541 depend ( depend-kind: variable-list )
18549 depend ( sink : vec )
18552 depend ( depend-modifier , depend-kind: variable-list )
18555 in | out | inout | mutexinoutset | depobj | inoutset
18558 iterator ( iterators-definition ) */
18561 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
18563 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18564 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_LAST
;
18565 enum omp_clause_doacross_kind dkind
= OMP_CLAUSE_DOACROSS_LAST
;
18566 tree nl
, c
, iterators
= NULL_TREE
;
18568 matching_parens parens
;
18569 if (!parens
.require_open (parser
))
18574 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
18577 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18578 if (strcmp ("iterator", p
) == 0 && iterators
== NULL_TREE
)
18580 iterators
= c_parser_omp_iterators (parser
);
18581 c_parser_require (parser
, CPP_COMMA
, "expected %<,%>");
18584 if (strcmp ("in", p
) == 0)
18585 kind
= OMP_CLAUSE_DEPEND_IN
;
18586 else if (strcmp ("inout", p
) == 0)
18587 kind
= OMP_CLAUSE_DEPEND_INOUT
;
18588 else if (strcmp ("inoutset", p
) == 0)
18589 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
18590 else if (strcmp ("mutexinoutset", p
) == 0)
18591 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
18592 else if (strcmp ("out", p
) == 0)
18593 kind
= OMP_CLAUSE_DEPEND_OUT
;
18594 else if (strcmp ("depobj", p
) == 0)
18595 kind
= OMP_CLAUSE_DEPEND_DEPOBJ
;
18596 else if (strcmp ("sink", p
) == 0)
18597 dkind
= OMP_CLAUSE_DOACROSS_SINK
;
18598 else if (strcmp ("source", p
) == 0)
18599 dkind
= OMP_CLAUSE_DOACROSS_SOURCE
;
18606 c_parser_consume_token (parser
);
18609 && (dkind
== OMP_CLAUSE_DOACROSS_SOURCE
18610 || dkind
== OMP_CLAUSE_DOACROSS_SINK
))
18613 error_at (clause_loc
, "%<iterator%> modifier incompatible with %qs",
18614 dkind
== OMP_CLAUSE_DOACROSS_SOURCE
? "source" : "sink");
18615 iterators
= NULL_TREE
;
18618 if (dkind
== OMP_CLAUSE_DOACROSS_SOURCE
)
18620 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
18621 OMP_CLAUSE_DOACROSS_KIND (c
) = dkind
;
18622 OMP_CLAUSE_DOACROSS_DEPEND (c
) = 1;
18623 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
18624 OMP_CLAUSE_CHAIN (c
) = list
;
18625 parens
.skip_until_found_close (parser
);
18629 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18632 if (dkind
== OMP_CLAUSE_DOACROSS_SINK
)
18633 nl
= c_parser_omp_clause_doacross_sink (parser
, clause_loc
, list
, true);
18636 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
18637 OMP_CLAUSE_DEPEND
, list
);
18641 tree block
= pop_scope ();
18642 if (iterators
== error_mark_node
)
18643 iterators
= NULL_TREE
;
18645 TREE_VEC_ELT (iterators
, 5) = block
;
18648 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18650 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
18652 OMP_CLAUSE_DECL (c
)
18653 = build_tree_list (iterators
, OMP_CLAUSE_DECL (c
));
18657 parens
.skip_until_found_close (parser
);
18661 c_parser_error (parser
, "invalid depend kind");
18663 parens
.skip_until_found_close (parser
);
18670 doacross ( source : )
18671 doacross ( source : omp_cur_iteration )
18673 doacross ( sink : vec )
18674 doacross ( sink : omp_cur_iteration - logical_iteration ) */
18677 c_parser_omp_clause_doacross (c_parser
*parser
, tree list
)
18679 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18680 enum omp_clause_doacross_kind kind
= OMP_CLAUSE_DOACROSS_LAST
;
18684 matching_parens parens
;
18685 if (!parens
.require_open (parser
))
18688 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
18691 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18692 if (strcmp ("sink", p
) == 0)
18693 kind
= OMP_CLAUSE_DOACROSS_SINK
;
18694 else if (strcmp ("source", p
) == 0)
18695 kind
= OMP_CLAUSE_DOACROSS_SOURCE
;
18699 c_parser_consume_token (parser
);
18701 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18704 if (kind
== OMP_CLAUSE_DOACROSS_SOURCE
)
18706 if (c_parser_next_token_is (parser
, CPP_NAME
)
18707 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
18708 "omp_cur_iteration") == 0)
18709 c_parser_consume_token (parser
);
18710 nl
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
18711 OMP_CLAUSE_DOACROSS_KIND (nl
) = OMP_CLAUSE_DOACROSS_SOURCE
;
18712 OMP_CLAUSE_DECL (nl
) = NULL_TREE
;
18713 OMP_CLAUSE_CHAIN (nl
) = list
;
18716 nl
= c_parser_omp_clause_doacross_sink (parser
, clause_loc
, list
, false);
18718 parens
.skip_until_found_close (parser
);
18722 c_parser_error (parser
, "invalid doacross kind");
18724 parens
.skip_until_found_close (parser
);
18729 map ( map-kind: variable-list )
18730 map ( variable-list )
18733 alloc | to | from | tofrom
18737 alloc | to | from | tofrom | release | delete
18739 map ( always [,] map-kind: variable-list )
18742 map ( [map-type-modifier[,] ...] map-kind: variable-list )
18748 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
18750 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18751 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
18754 matching_parens parens
;
18755 if (!parens
.require_open (parser
))
18759 int map_kind_pos
= 0;
18760 while (c_parser_peek_nth_token_raw (parser
, pos
)->type
== CPP_NAME
)
18762 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COLON
)
18764 map_kind_pos
= pos
;
18768 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COMMA
)
18773 int always_modifier
= 0;
18774 int close_modifier
= 0;
18775 int present_modifier
= 0;
18776 for (int pos
= 1; pos
< map_kind_pos
; ++pos
)
18778 c_token
*tok
= c_parser_peek_token (parser
);
18780 if (tok
->type
== CPP_COMMA
)
18782 c_parser_consume_token (parser
);
18786 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18787 if (strcmp ("always", p
) == 0)
18789 if (always_modifier
)
18791 c_parser_error (parser
, "too many %<always%> modifiers");
18792 parens
.skip_until_found_close (parser
);
18797 else if (strcmp ("close", p
) == 0)
18799 if (close_modifier
)
18801 c_parser_error (parser
, "too many %<close%> modifiers");
18802 parens
.skip_until_found_close (parser
);
18807 else if (strcmp ("present", p
) == 0)
18809 if (present_modifier
)
18811 c_parser_error (parser
, "too many %<present%> modifiers");
18812 parens
.skip_until_found_close (parser
);
18815 present_modifier
++;
18819 c_parser_error (parser
, "%<map%> clause with map-type modifier other "
18820 "than %<always%>, %<close%> or %<present%>");
18821 parens
.skip_until_found_close (parser
);
18825 c_parser_consume_token (parser
);
18828 if (c_parser_next_token_is (parser
, CPP_NAME
)
18829 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
18831 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18832 int always_present_modifier
= always_modifier
&& present_modifier
;
18834 if (strcmp ("alloc", p
) == 0)
18835 kind
= present_modifier
? GOMP_MAP_PRESENT_ALLOC
: GOMP_MAP_ALLOC
;
18836 else if (strcmp ("to", p
) == 0)
18837 kind
= (always_present_modifier
? GOMP_MAP_ALWAYS_PRESENT_TO
18838 : present_modifier
? GOMP_MAP_PRESENT_TO
18839 : always_modifier
? GOMP_MAP_ALWAYS_TO
18841 else if (strcmp ("from", p
) == 0)
18842 kind
= (always_present_modifier
? GOMP_MAP_ALWAYS_PRESENT_FROM
18843 : present_modifier
? GOMP_MAP_PRESENT_FROM
18844 : always_modifier
? GOMP_MAP_ALWAYS_FROM
18846 else if (strcmp ("tofrom", p
) == 0)
18847 kind
= (always_present_modifier
? GOMP_MAP_ALWAYS_PRESENT_TOFROM
18848 : present_modifier
? GOMP_MAP_PRESENT_TOFROM
18849 : always_modifier
? GOMP_MAP_ALWAYS_TOFROM
18850 : GOMP_MAP_TOFROM
);
18851 else if (strcmp ("release", p
) == 0)
18852 kind
= GOMP_MAP_RELEASE
;
18853 else if (strcmp ("delete", p
) == 0)
18854 kind
= GOMP_MAP_DELETE
;
18857 c_parser_error (parser
, "invalid map kind");
18858 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
18862 c_parser_consume_token (parser
);
18863 c_parser_consume_token (parser
);
18866 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
,
18869 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18870 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
18872 parens
.skip_until_found_close (parser
);
18877 device ( expression )
18880 device ( [device-modifier :] integer-expression )
18883 ancestor | device_num */
18886 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
18888 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18889 location_t expr_loc
;
18892 bool ancestor
= false;
18894 matching_parens parens
;
18895 if (!parens
.require_open (parser
))
18898 if (c_parser_next_token_is (parser
, CPP_NAME
)
18899 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
18901 c_token
*tok
= c_parser_peek_token (parser
);
18902 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18903 if (strcmp ("ancestor", p
) == 0)
18905 /* A requires directive with the reverse_offload clause must be
18907 if ((omp_requires_mask
& OMP_REQUIRES_REVERSE_OFFLOAD
) == 0)
18909 error_at (tok
->location
, "%<ancestor%> device modifier not "
18910 "preceded by %<requires%> directive "
18911 "with %<reverse_offload%> clause");
18912 parens
.skip_until_found_close (parser
);
18917 else if (strcmp ("device_num", p
) == 0)
18921 error_at (tok
->location
, "expected %<ancestor%> or %<device_num%>");
18922 parens
.skip_until_found_close (parser
);
18925 c_parser_consume_token (parser
);
18926 c_parser_consume_token (parser
);
18929 expr_loc
= c_parser_peek_token (parser
)->location
;
18930 expr
= c_parser_expr_no_commas (parser
, NULL
);
18931 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18933 t
= c_fully_fold (t
, false, NULL
);
18935 parens
.skip_until_found_close (parser
);
18937 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
18939 c_parser_error (parser
, "expected integer expression");
18942 if (ancestor
&& TREE_CODE (t
) == INTEGER_CST
&& !integer_onep (t
))
18944 error_at (expr_loc
, "the %<device%> clause expression must evaluate to "
18949 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
18951 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
18953 OMP_CLAUSE_DEVICE_ID (c
) = t
;
18954 OMP_CLAUSE_CHAIN (c
) = list
;
18955 OMP_CLAUSE_DEVICE_ANCESTOR (c
) = ancestor
;
18962 dist_schedule ( static )
18963 dist_schedule ( static , expression ) */
18966 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
18968 tree c
, t
= NULL_TREE
;
18969 location_t loc
= c_parser_peek_token (parser
)->location
;
18971 matching_parens parens
;
18972 if (!parens
.require_open (parser
))
18975 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
18977 c_parser_error (parser
, "invalid dist_schedule kind");
18978 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
18983 c_parser_consume_token (parser
);
18984 if (c_parser_next_token_is (parser
, CPP_COMMA
))
18986 c_parser_consume_token (parser
);
18988 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18989 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18990 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18992 t
= c_fully_fold (t
, false, NULL
);
18993 parens
.skip_until_found_close (parser
);
18996 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
18997 "expected %<,%> or %<)%>");
18999 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
19000 "dist_schedule"); */
19001 if (omp_find_clause (list
, OMP_CLAUSE_DIST_SCHEDULE
))
19002 warning_at (loc
, OPT_Wopenmp
, "too many %qs clauses", "dist_schedule");
19003 if (t
== error_mark_node
)
19006 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
19007 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
19008 OMP_CLAUSE_CHAIN (c
) = list
;
19013 proc_bind ( proc-bind-kind )
19016 primary | master | close | spread
19017 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
19020 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
19022 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
19023 enum omp_clause_proc_bind_kind kind
;
19026 matching_parens parens
;
19027 if (!parens
.require_open (parser
))
19030 if (c_parser_next_token_is (parser
, CPP_NAME
))
19032 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19033 if (strcmp ("primary", p
) == 0)
19034 kind
= OMP_CLAUSE_PROC_BIND_PRIMARY
;
19035 else if (strcmp ("master", p
) == 0)
19036 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
19037 else if (strcmp ("close", p
) == 0)
19038 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
19039 else if (strcmp ("spread", p
) == 0)
19040 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
19047 check_no_duplicate_clause (list
, OMP_CLAUSE_PROC_BIND
, "proc_bind");
19048 c_parser_consume_token (parser
);
19049 parens
.skip_until_found_close (parser
);
19050 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
19051 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
19052 OMP_CLAUSE_CHAIN (c
) = list
;
19056 c_parser_error (parser
, "invalid proc_bind kind");
19057 parens
.skip_until_found_close (parser
);
19062 device_type ( host | nohost | any ) */
19065 c_parser_omp_clause_device_type (c_parser
*parser
, tree list
)
19067 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
19068 enum omp_clause_device_type_kind kind
;
19071 matching_parens parens
;
19072 if (!parens
.require_open (parser
))
19075 if (c_parser_next_token_is (parser
, CPP_NAME
))
19077 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19078 if (strcmp ("host", p
) == 0)
19079 kind
= OMP_CLAUSE_DEVICE_TYPE_HOST
;
19080 else if (strcmp ("nohost", p
) == 0)
19081 kind
= OMP_CLAUSE_DEVICE_TYPE_NOHOST
;
19082 else if (strcmp ("any", p
) == 0)
19083 kind
= OMP_CLAUSE_DEVICE_TYPE_ANY
;
19090 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE_TYPE
,
19092 c_parser_consume_token (parser
);
19093 parens
.skip_until_found_close (parser
);
19094 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE_TYPE
);
19095 OMP_CLAUSE_DEVICE_TYPE_KIND (c
) = kind
;
19096 OMP_CLAUSE_CHAIN (c
) = list
;
19100 c_parser_error (parser
, "expected %<host%>, %<nohost%> or %<any%>");
19101 parens
.skip_until_found_close (parser
);
19106 from ( variable-list )
19107 to ( variable-list )
19110 from ( [present :] variable-list )
19111 to ( [present :] variable-list ) */
19114 c_parser_omp_clause_from_to (c_parser
*parser
, enum omp_clause_code kind
,
19117 location_t loc
= c_parser_peek_token (parser
)->location
;
19118 matching_parens parens
;
19119 if (!parens
.require_open (parser
))
19122 bool present
= false;
19123 c_token
*token
= c_parser_peek_token (parser
);
19125 if (token
->type
== CPP_NAME
19126 && strcmp (IDENTIFIER_POINTER (token
->value
), "present") == 0
19127 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
19130 c_parser_consume_token (parser
);
19131 c_parser_consume_token (parser
);
19134 tree nl
= c_parser_omp_variable_list (parser
, loc
, kind
, list
);
19135 parens
.skip_until_found_close (parser
);
19138 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
19139 OMP_CLAUSE_MOTION_PRESENT (c
) = 1;
19145 uniform ( variable-list ) */
19148 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
19150 /* The clauses location. */
19151 location_t loc
= c_parser_peek_token (parser
)->location
;
19153 matching_parens parens
;
19154 if (parens
.require_open (parser
))
19156 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
19158 parens
.skip_until_found_close (parser
);
19164 detach ( event-handle ) */
19167 c_parser_omp_clause_detach (c_parser
*parser
, tree list
)
19169 matching_parens parens
;
19170 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
19172 if (!parens
.require_open (parser
))
19175 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
19176 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
19178 c_parser_error (parser
, "expected identifier");
19179 parens
.skip_until_found_close (parser
);
19183 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
19184 if (t
== NULL_TREE
)
19186 undeclared_variable (c_parser_peek_token (parser
)->location
,
19187 c_parser_peek_token (parser
)->value
);
19188 parens
.skip_until_found_close (parser
);
19191 c_parser_consume_token (parser
);
19193 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (t
));
19194 if (!INTEGRAL_TYPE_P (type
)
19195 || TREE_CODE (type
) != ENUMERAL_TYPE
19196 || TYPE_NAME (type
) != get_identifier ("omp_event_handle_t"))
19198 error_at (clause_loc
, "%<detach%> clause event handle "
19199 "has type %qT rather than "
19200 "%<omp_event_handle_t%>",
19202 parens
.skip_until_found_close (parser
);
19206 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DETACH
);
19207 OMP_CLAUSE_DECL (u
) = t
;
19208 OMP_CLAUSE_CHAIN (u
) = list
;
19209 parens
.skip_until_found_close (parser
);
19213 /* Parse all OpenACC clauses. The set clauses allowed by the directive
19214 is a bitmask in MASK. Return the list of clauses found. */
19217 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
19218 const char *where
, bool finish_p
= true,
19219 bool target_p
= false)
19221 tree clauses
= NULL
;
19224 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19227 pragma_omp_clause c_kind
;
19228 const char *c_name
;
19229 tree prev
= clauses
;
19231 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
19232 c_parser_consume_token (parser
);
19234 here
= c_parser_peek_token (parser
)->location
;
19235 c_kind
= c_parser_omp_clause_name (parser
);
19239 case PRAGMA_OACC_CLAUSE_ASYNC
:
19240 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
19243 case PRAGMA_OACC_CLAUSE_AUTO
:
19244 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_AUTO
,
19248 case PRAGMA_OACC_CLAUSE_ATTACH
:
19249 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19252 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
19253 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
19254 c_name
= "collapse";
19256 case PRAGMA_OACC_CLAUSE_COPY
:
19257 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19260 case PRAGMA_OACC_CLAUSE_COPYIN
:
19261 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19264 case PRAGMA_OACC_CLAUSE_COPYOUT
:
19265 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19266 c_name
= "copyout";
19268 case PRAGMA_OACC_CLAUSE_CREATE
:
19269 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19272 case PRAGMA_OACC_CLAUSE_DELETE
:
19273 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19276 case PRAGMA_OMP_CLAUSE_DEFAULT
:
19277 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
19278 c_name
= "default";
19280 case PRAGMA_OACC_CLAUSE_DETACH
:
19281 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19284 case PRAGMA_OACC_CLAUSE_DEVICE
:
19285 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19288 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
19289 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
19290 c_name
= "deviceptr";
19292 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
19293 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19294 c_name
= "device_resident";
19296 case PRAGMA_OACC_CLAUSE_FINALIZE
:
19297 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_FINALIZE
,
19299 c_name
= "finalize";
19301 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
19302 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
19303 c_name
= "firstprivate";
19305 case PRAGMA_OACC_CLAUSE_GANG
:
19307 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_GANG
,
19310 case PRAGMA_OACC_CLAUSE_HOST
:
19311 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19314 case PRAGMA_OACC_CLAUSE_IF
:
19315 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
19318 case PRAGMA_OACC_CLAUSE_IF_PRESENT
:
19319 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_IF_PRESENT
,
19321 c_name
= "if_present";
19323 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
19324 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_INDEPENDENT
,
19326 c_name
= "independent";
19328 case PRAGMA_OACC_CLAUSE_LINK
:
19329 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19332 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
19333 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19334 c_name
= "no_create";
19336 case PRAGMA_OACC_CLAUSE_NOHOST
:
19337 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_NOHOST
,
19341 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
19342 clauses
= c_parser_oacc_single_int_clause (parser
,
19343 OMP_CLAUSE_NUM_GANGS
,
19345 c_name
= "num_gangs";
19347 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
19348 clauses
= c_parser_oacc_single_int_clause (parser
,
19349 OMP_CLAUSE_NUM_WORKERS
,
19351 c_name
= "num_workers";
19353 case PRAGMA_OACC_CLAUSE_PRESENT
:
19354 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19355 c_name
= "present";
19357 case PRAGMA_OACC_CLAUSE_PRIVATE
:
19358 clauses
= c_parser_omp_clause_private (parser
, clauses
);
19359 c_name
= "private";
19361 case PRAGMA_OACC_CLAUSE_REDUCTION
:
19363 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
19365 c_name
= "reduction";
19367 case PRAGMA_OACC_CLAUSE_SELF
:
19368 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OACC_CLAUSE_HOST
)) == 0)
19369 /* OpenACC compute construct */
19370 clauses
= c_parser_oacc_compute_clause_self (parser
, clauses
);
19372 /* OpenACC 'update' directive */
19373 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19376 case PRAGMA_OACC_CLAUSE_SEQ
:
19377 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_SEQ
,
19381 case PRAGMA_OACC_CLAUSE_TILE
:
19382 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
19385 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
19386 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
19387 c_name
= "use_device";
19389 case PRAGMA_OACC_CLAUSE_VECTOR
:
19391 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_VECTOR
,
19394 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
19395 clauses
= c_parser_oacc_single_int_clause (parser
,
19396 OMP_CLAUSE_VECTOR_LENGTH
,
19398 c_name
= "vector_length";
19400 case PRAGMA_OACC_CLAUSE_WAIT
:
19401 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
19404 case PRAGMA_OACC_CLAUSE_WORKER
:
19406 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_WORKER
,
19410 c_parser_error (parser
, "expected an OpenACC clause");
19416 if (((mask
>> c_kind
) & 1) == 0)
19418 /* Remove the invalid clause(s) from the list to avoid
19419 confusing the rest of the compiler. */
19421 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
19426 c_parser_skip_to_pragma_eol (parser
);
19429 return c_finish_omp_clauses (clauses
, target_p
? C_ORT_ACC_TARGET
19435 /* Parse all OpenMP clauses. The set clauses allowed by the directive
19436 is a bitmask in MASK. Return the list of clauses found.
19437 FINISH_P set if c_finish_omp_clauses should be called.
19438 NESTED non-zero if clauses should be terminated by closing paren instead
19439 of end of pragma. If it is 2, additionally commas are required in between
19443 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
19444 const char *where
, bool finish_p
= true,
19447 tree clauses
= NULL
;
19450 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19453 pragma_omp_clause c_kind
;
19454 const char *c_name
;
19455 tree prev
= clauses
;
19457 if (nested
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
19460 if (!first
|| nested
!= 2)
19462 if (c_parser_next_token_is (parser
, CPP_COMMA
))
19463 c_parser_consume_token (parser
);
19464 else if (nested
== 2)
19465 error_at (c_parser_peek_token (parser
)->location
,
19466 "clauses in %<simd%> trait should be separated "
19470 here
= c_parser_peek_token (parser
)->location
;
19471 c_kind
= c_parser_omp_clause_name (parser
);
19475 case PRAGMA_OMP_CLAUSE_BIND
:
19476 clauses
= c_parser_omp_clause_bind (parser
, clauses
);
19479 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
19480 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
19481 c_name
= "collapse";
19483 case PRAGMA_OMP_CLAUSE_COPYIN
:
19484 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
19487 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
19488 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
19489 c_name
= "copyprivate";
19491 case PRAGMA_OMP_CLAUSE_DEFAULT
:
19492 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
19493 c_name
= "default";
19495 case PRAGMA_OMP_CLAUSE_DETACH
:
19496 clauses
= c_parser_omp_clause_detach (parser
, clauses
);
19499 case PRAGMA_OMP_CLAUSE_FILTER
:
19500 clauses
= c_parser_omp_clause_filter (parser
, clauses
);
19503 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
19504 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
19505 c_name
= "firstprivate";
19507 case PRAGMA_OMP_CLAUSE_FINAL
:
19508 clauses
= c_parser_omp_clause_final (parser
, clauses
);
19511 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
19512 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
19513 c_name
= "grainsize";
19515 case PRAGMA_OMP_CLAUSE_HINT
:
19516 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
19519 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
19520 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
19521 c_name
= "defaultmap";
19523 case PRAGMA_OMP_CLAUSE_IF
:
19524 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
19527 case PRAGMA_OMP_CLAUSE_IN_REDUCTION
:
19529 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_IN_REDUCTION
,
19531 c_name
= "in_reduction";
19533 case PRAGMA_OMP_CLAUSE_INDIRECT
:
19534 clauses
= c_parser_omp_clause_indirect (parser
, clauses
);
19535 c_name
= "indirect";
19537 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
19538 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
19539 c_name
= "lastprivate";
19541 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
19542 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
19543 c_name
= "mergeable";
19545 case PRAGMA_OMP_CLAUSE_NOWAIT
:
19546 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
19549 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
19550 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
19551 c_name
= "num_tasks";
19553 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
19554 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
19555 c_name
= "num_threads";
19557 case PRAGMA_OMP_CLAUSE_ORDER
:
19558 clauses
= c_parser_omp_clause_order (parser
, clauses
);
19561 case PRAGMA_OMP_CLAUSE_ORDERED
:
19562 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
19563 c_name
= "ordered";
19565 case PRAGMA_OMP_CLAUSE_PRIORITY
:
19566 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
19567 c_name
= "priority";
19569 case PRAGMA_OMP_CLAUSE_PRIVATE
:
19570 clauses
= c_parser_omp_clause_private (parser
, clauses
);
19571 c_name
= "private";
19573 case PRAGMA_OMP_CLAUSE_REDUCTION
:
19575 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
19577 c_name
= "reduction";
19579 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
19580 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
19581 c_name
= "schedule";
19583 case PRAGMA_OMP_CLAUSE_SHARED
:
19584 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
19587 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION
:
19589 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_TASK_REDUCTION
,
19591 c_name
= "task_reduction";
19593 case PRAGMA_OMP_CLAUSE_UNTIED
:
19594 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
19597 case PRAGMA_OMP_CLAUSE_INBRANCH
:
19598 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
19600 c_name
= "inbranch";
19602 case PRAGMA_OMP_CLAUSE_NONTEMPORAL
:
19603 clauses
= c_parser_omp_clause_nontemporal (parser
, clauses
);
19604 c_name
= "nontemporal";
19606 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
19607 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
19609 c_name
= "notinbranch";
19611 case PRAGMA_OMP_CLAUSE_PARALLEL
:
19613 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
19615 c_name
= "parallel";
19619 error_at (here
, "%qs must be the first clause of %qs",
19624 case PRAGMA_OMP_CLAUSE_FOR
:
19626 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
19630 goto clause_not_first
;
19632 case PRAGMA_OMP_CLAUSE_SECTIONS
:
19634 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
19636 c_name
= "sections";
19638 goto clause_not_first
;
19640 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
19642 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
19644 c_name
= "taskgroup";
19646 goto clause_not_first
;
19648 case PRAGMA_OMP_CLAUSE_LINK
:
19650 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
19653 case PRAGMA_OMP_CLAUSE_TO
:
19654 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
19656 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
19658 for (tree c
= nl
; c
!= clauses
; c
= OMP_CLAUSE_CHAIN (c
))
19659 OMP_CLAUSE_ENTER_TO (c
) = 1;
19663 clauses
= c_parser_omp_clause_from_to (parser
, OMP_CLAUSE_TO
,
19667 case PRAGMA_OMP_CLAUSE_FROM
:
19668 clauses
= c_parser_omp_clause_from_to (parser
, OMP_CLAUSE_FROM
,
19672 case PRAGMA_OMP_CLAUSE_UNIFORM
:
19673 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
19674 c_name
= "uniform";
19676 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
19677 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
19678 c_name
= "num_teams";
19680 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
19681 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
19682 c_name
= "thread_limit";
19684 case PRAGMA_OMP_CLAUSE_ALIGNED
:
19685 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
19686 c_name
= "aligned";
19688 case PRAGMA_OMP_CLAUSE_ALLOCATE
:
19689 clauses
= c_parser_omp_clause_allocate (parser
, clauses
);
19690 c_name
= "allocate";
19692 case PRAGMA_OMP_CLAUSE_LINEAR
:
19693 clauses
= c_parser_omp_clause_linear (parser
, clauses
);
19696 case PRAGMA_OMP_CLAUSE_AFFINITY
:
19697 clauses
= c_parser_omp_clause_affinity (parser
, clauses
);
19698 c_name
= "affinity";
19700 case PRAGMA_OMP_CLAUSE_DEPEND
:
19701 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
19704 case PRAGMA_OMP_CLAUSE_DOACROSS
:
19705 clauses
= c_parser_omp_clause_doacross (parser
, clauses
);
19706 c_name
= "doacross";
19708 case PRAGMA_OMP_CLAUSE_MAP
:
19709 clauses
= c_parser_omp_clause_map (parser
, clauses
);
19712 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
19713 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
19714 c_name
= "use_device_ptr";
19716 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
:
19717 clauses
= c_parser_omp_clause_use_device_addr (parser
, clauses
);
19718 c_name
= "use_device_addr";
19720 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
:
19721 clauses
= c_parser_omp_clause_has_device_addr (parser
, clauses
);
19722 c_name
= "has_device_addr";
19724 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
19725 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
19726 c_name
= "is_device_ptr";
19728 case PRAGMA_OMP_CLAUSE_DEVICE
:
19729 clauses
= c_parser_omp_clause_device (parser
, clauses
);
19732 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
19733 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
19734 c_name
= "dist_schedule";
19736 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
19737 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
19738 c_name
= "proc_bind";
19740 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE
:
19741 clauses
= c_parser_omp_clause_device_type (parser
, clauses
);
19742 c_name
= "device_type";
19744 case PRAGMA_OMP_CLAUSE_SAFELEN
:
19745 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
19746 c_name
= "safelen";
19748 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
19749 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
19750 c_name
= "simdlen";
19752 case PRAGMA_OMP_CLAUSE_NOGROUP
:
19753 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
19754 c_name
= "nogroup";
19756 case PRAGMA_OMP_CLAUSE_THREADS
:
19758 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
19760 c_name
= "threads";
19762 case PRAGMA_OMP_CLAUSE_SIMD
:
19764 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
19768 case PRAGMA_OMP_CLAUSE_ENTER
:
19770 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
19775 c_parser_error (parser
, "expected an OpenMP clause");
19781 if (((mask
>> c_kind
) & 1) == 0)
19783 /* Remove the invalid clause(s) from the list to avoid
19784 confusing the rest of the compiler. */
19786 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
19792 c_parser_skip_to_pragma_eol (parser
);
19796 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
19797 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
19798 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
19804 /* OpenACC 2.0, OpenMP 2.5:
19808 In practice, we're also interested in adding the statement to an
19809 outer node. So it is convenient if we work around the fact that
19810 c_parser_statement calls add_stmt. */
19813 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
19815 tree stmt
= push_stmt_list ();
19816 parser
->omp_attrs_forbidden_p
= true;
19817 c_parser_statement (parser
, if_p
);
19818 return pop_stmt_list (stmt
);
19822 # pragma acc cache (variable-list) new-line
19824 LOC is the location of the #pragma token.
19828 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
19830 tree stmt
, clauses
;
19832 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE__CACHE_
, NULL
);
19833 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
19835 c_parser_skip_to_pragma_eol (parser
);
19837 stmt
= make_node (OACC_CACHE
);
19838 TREE_TYPE (stmt
) = void_type_node
;
19839 OACC_CACHE_CLAUSES (stmt
) = clauses
;
19840 SET_EXPR_LOCATION (stmt
, loc
);
19847 # pragma acc data oacc-data-clause[optseq] new-line
19850 LOC is the location of the #pragma token.
19853 #define OACC_DATA_CLAUSE_MASK \
19854 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
19855 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19856 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19857 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19858 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19859 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
19860 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19861 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
19862 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
19863 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
19866 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
19868 tree stmt
, clauses
, block
;
19870 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
19871 "#pragma acc data");
19873 block
= c_begin_omp_parallel ();
19874 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19876 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
19882 # pragma acc declare oacc-data-clause[optseq] new-line
19885 #define OACC_DECLARE_CLAUSE_MASK \
19886 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19888 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19889 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19890 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
19892 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
19893 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
19896 c_parser_oacc_declare (c_parser
*parser
)
19898 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
19899 tree clauses
, stmt
, t
, decl
;
19901 bool error
= false;
19903 c_parser_consume_pragma (parser
);
19905 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
19906 "#pragma acc declare");
19909 error_at (pragma_loc
,
19910 "no valid clauses specified in %<#pragma acc declare%>");
19914 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
19916 location_t loc
= OMP_CLAUSE_LOCATION (t
);
19917 decl
= OMP_CLAUSE_DECL (t
);
19918 if (!DECL_P (decl
))
19920 error_at (loc
, "array section in %<#pragma acc declare%>");
19925 switch (OMP_CLAUSE_MAP_KIND (t
))
19927 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19928 case GOMP_MAP_ALLOC
:
19930 case GOMP_MAP_FORCE_DEVICEPTR
:
19931 case GOMP_MAP_DEVICE_RESIDENT
:
19934 case GOMP_MAP_LINK
:
19935 if (!global_bindings_p ()
19936 && (TREE_STATIC (decl
)
19937 || !DECL_EXTERNAL (decl
)))
19940 "%qD must be a global variable in "
19941 "%<#pragma acc declare link%>",
19949 if (global_bindings_p ())
19951 error_at (loc
, "invalid OpenACC clause at file scope");
19955 if (DECL_EXTERNAL (decl
))
19958 "invalid use of %<extern%> variable %qD "
19959 "in %<#pragma acc declare%>", decl
);
19963 else if (TREE_PUBLIC (decl
))
19966 "invalid use of %<global%> variable %qD "
19967 "in %<#pragma acc declare%>", decl
);
19974 if (!c_check_in_current_scope (decl
))
19977 "%qD must be a variable declared in the same scope as "
19978 "%<#pragma acc declare%>", decl
);
19983 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
19984 || lookup_attribute ("omp declare target link",
19985 DECL_ATTRIBUTES (decl
)))
19987 error_at (loc
, "variable %qD used more than once with "
19988 "%<#pragma acc declare%>", decl
);
19997 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
19998 id
= get_identifier ("omp declare target link");
20000 id
= get_identifier ("omp declare target");
20002 DECL_ATTRIBUTES (decl
)
20003 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
20005 if (global_bindings_p ())
20007 symtab_node
*node
= symtab_node::get (decl
);
20010 node
->offloadable
= 1;
20011 if (ENABLE_OFFLOADING
)
20013 g
->have_offload
= true;
20014 if (is_a
<varpool_node
*> (node
))
20015 vec_safe_push (offload_vars
, decl
);
20022 if (error
|| global_bindings_p ())
20025 stmt
= make_node (OACC_DECLARE
);
20026 TREE_TYPE (stmt
) = void_type_node
;
20027 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
20028 SET_EXPR_LOCATION (stmt
, pragma_loc
);
20036 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
20040 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
20043 LOC is the location of the #pragma token.
20046 #define OACC_ENTER_DATA_CLAUSE_MASK \
20047 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20048 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20049 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20050 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20051 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20052 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20054 #define OACC_EXIT_DATA_CLAUSE_MASK \
20055 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20056 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20057 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20058 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
20059 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
20060 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
20061 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20064 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
20066 location_t loc
= c_parser_peek_token (parser
)->location
;
20067 tree clauses
, stmt
;
20068 const char *p
= "";
20070 c_parser_consume_pragma (parser
);
20072 if (c_parser_next_token_is (parser
, CPP_NAME
))
20074 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20075 c_parser_consume_token (parser
);
20078 if (strcmp (p
, "data") != 0)
20080 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
20081 enter
? "enter" : "exit");
20082 parser
->error
= true;
20083 c_parser_skip_to_pragma_eol (parser
);
20088 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
20089 "#pragma acc enter data");
20091 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
20092 "#pragma acc exit data");
20094 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
20096 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
20097 enter
? "enter" : "exit");
20101 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
20102 TREE_TYPE (stmt
) = void_type_node
;
20103 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
20104 SET_EXPR_LOCATION (stmt
, loc
);
20110 # pragma acc host_data oacc-data-clause[optseq] new-line
20114 #define OACC_HOST_DATA_CLAUSE_MASK \
20115 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
20116 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20117 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
20120 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
20122 tree stmt
, clauses
, block
;
20124 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
20125 "#pragma acc host_data", false);
20126 if (!omp_find_clause (clauses
, OMP_CLAUSE_USE_DEVICE_PTR
))
20128 error_at (loc
, "%<host_data%> construct requires %<use_device%> clause");
20129 return error_mark_node
;
20131 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
20132 block
= c_begin_omp_parallel ();
20133 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
20134 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
20141 # pragma acc loop oacc-loop-clause[optseq] new-line
20144 LOC is the location of the #pragma token.
20147 #define OACC_LOOP_CLAUSE_MASK \
20148 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
20149 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20150 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20151 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
20152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
20153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
20154 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
20155 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
20156 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
20157 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
20159 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
20160 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
20162 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
20164 strcat (p_name
, " loop");
20165 mask
|= OACC_LOOP_CLAUSE_MASK
;
20167 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
20168 /*finish_p=*/cclauses
== NULL
,
20169 /*target=*/is_parallel
);
20172 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
20174 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC_TARGET
);
20176 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
20179 tree block
= c_begin_compound_stmt (true);
20180 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
20182 block
= c_end_compound_stmt (loc
, block
, true);
20189 # pragma acc kernels oacc-kernels-clause[optseq] new-line
20194 # pragma acc parallel oacc-parallel-clause[optseq] new-line
20199 # pragma acc serial oacc-serial-clause[optseq] new-line
20202 LOC is the location of the #pragma token.
20205 #define OACC_KERNELS_CLAUSE_MASK \
20206 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20207 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20208 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20209 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20210 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20211 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20212 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20213 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20214 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20215 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20216 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
20217 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
20218 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20219 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20220 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
20221 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20223 #define OACC_PARALLEL_CLAUSE_MASK \
20224 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20225 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20226 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20227 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20228 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20229 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20230 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20231 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20232 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20233 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20234 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20235 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
20236 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
20237 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
20238 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20239 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20240 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20241 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
20242 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20244 #define OACC_SERIAL_CLAUSE_MASK \
20245 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20247 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20249 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20250 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20251 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20252 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20253 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20254 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20255 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20256 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
20257 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20258 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20259 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20260 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20263 c_parser_oacc_compute (location_t loc
, c_parser
*parser
,
20264 enum pragma_kind p_kind
, char *p_name
, bool *if_p
)
20266 omp_clause_mask mask
;
20267 enum tree_code code
;
20270 case PRAGMA_OACC_KERNELS
:
20271 strcat (p_name
, " kernels");
20272 mask
= OACC_KERNELS_CLAUSE_MASK
;
20273 code
= OACC_KERNELS
;
20275 case PRAGMA_OACC_PARALLEL
:
20276 strcat (p_name
, " parallel");
20277 mask
= OACC_PARALLEL_CLAUSE_MASK
;
20278 code
= OACC_PARALLEL
;
20280 case PRAGMA_OACC_SERIAL
:
20281 strcat (p_name
, " serial");
20282 mask
= OACC_SERIAL_CLAUSE_MASK
;
20283 code
= OACC_SERIAL
;
20286 gcc_unreachable ();
20289 if (c_parser_next_token_is (parser
, CPP_NAME
))
20291 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20292 if (strcmp (p
, "loop") == 0)
20294 c_parser_consume_token (parser
);
20295 tree block
= c_begin_omp_parallel ();
20297 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
20298 return c_finish_omp_construct (loc
, code
, block
, clauses
);
20302 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
20306 tree block
= c_begin_omp_parallel ();
20307 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
20309 return c_finish_omp_construct (loc
, code
, block
, clauses
);
20313 # pragma acc routine oacc-routine-clause[optseq] new-line
20314 function-definition
20316 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
20319 #define OACC_ROUTINE_CLAUSE_MASK \
20320 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
20321 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
20322 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
20323 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
20324 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
20326 /* Parse an OpenACC routine directive. For named directives, we apply
20327 immediately to the named function. For unnamed ones we then parse
20328 a declaration or definition, which must be for a function. */
20331 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
20333 gcc_checking_assert (context
== pragma_external
);
20335 oacc_routine_data data
;
20336 data
.error_seen
= false;
20337 data
.fndecl_seen
= false;
20338 data
.loc
= c_parser_peek_token (parser
)->location
;
20340 c_parser_consume_pragma (parser
);
20342 /* Look for optional '( name )'. */
20343 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
20345 c_parser_consume_token (parser
); /* '(' */
20347 tree decl
= NULL_TREE
;
20348 c_token
*name_token
= c_parser_peek_token (parser
);
20349 location_t name_loc
= name_token
->location
;
20350 if (name_token
->type
== CPP_NAME
20351 && (name_token
->id_kind
== C_ID_ID
20352 || name_token
->id_kind
== C_ID_TYPENAME
))
20354 decl
= lookup_name (name_token
->value
);
20356 error_at (name_loc
,
20357 "%qE has not been declared", name_token
->value
);
20358 c_parser_consume_token (parser
);
20361 c_parser_error (parser
, "expected function name");
20364 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
20366 c_parser_skip_to_pragma_eol (parser
, false);
20371 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
20372 "#pragma acc routine");
20373 /* The clauses are in reverse order; fix that to make later diagnostic
20374 emission easier. */
20375 data
.clauses
= nreverse (data
.clauses
);
20377 if (TREE_CODE (decl
) != FUNCTION_DECL
)
20379 error_at (name_loc
, "%qD does not refer to a function", decl
);
20383 c_finish_oacc_routine (&data
, decl
, false);
20385 else /* No optional '( name )'. */
20388 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
20389 "#pragma acc routine");
20390 /* The clauses are in reverse order; fix that to make later diagnostic
20391 emission easier. */
20392 data
.clauses
= nreverse (data
.clauses
);
20394 /* Emit a helpful diagnostic if there's another pragma following this
20395 one. Also don't allow a static assertion declaration, as in the
20396 following we'll just parse a *single* "declaration or function
20397 definition", and the static assertion counts an one. */
20398 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
20399 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
20401 error_at (data
.loc
,
20402 "%<#pragma acc routine%> not immediately followed by"
20403 " function declaration or definition");
20404 /* ..., and then just keep going. */
20408 /* We only have to consider the pragma_external case here. */
20409 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20410 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
20412 int ext
= disable_extension_diagnostics ();
20414 c_parser_consume_token (parser
);
20415 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20416 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
20417 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
20418 NULL
, NULL
, false, NULL
, &data
);
20419 restore_extension_diagnostics (ext
);
20422 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
20423 NULL
, NULL
, false, NULL
, &data
);
20427 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
20428 IS_DEFN is true if we're applying it to the definition. */
20431 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
20434 /* Keep going if we're in error reporting mode. */
20435 if (data
->error_seen
20436 || fndecl
== error_mark_node
)
20439 if (data
->fndecl_seen
)
20441 error_at (data
->loc
,
20442 "%<#pragma acc routine%> not immediately followed by"
20443 " a single function declaration or definition");
20444 data
->error_seen
= true;
20447 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
20449 error_at (data
->loc
,
20450 "%<#pragma acc routine%> not immediately followed by"
20451 " function declaration or definition");
20452 data
->error_seen
= true;
20457 = oacc_verify_routine_clauses (fndecl
, &data
->clauses
, data
->loc
,
20458 "#pragma acc routine");
20459 if (compatible
< 0)
20461 data
->error_seen
= true;
20464 if (compatible
> 0)
20469 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
20471 error_at (data
->loc
,
20473 ? G_("%<#pragma acc routine%> must be applied before use")
20474 : G_("%<#pragma acc routine%> must be applied before"
20476 data
->error_seen
= true;
20480 /* Set the routine's level of parallelism. */
20481 tree dims
= oacc_build_routine_dims (data
->clauses
);
20482 oacc_replace_fn_attrib (fndecl
, dims
);
20484 /* Add an "omp declare target" attribute. */
20485 DECL_ATTRIBUTES (fndecl
)
20486 = tree_cons (get_identifier ("omp declare target"),
20487 data
->clauses
, DECL_ATTRIBUTES (fndecl
));
20490 /* Remember that we've used this "#pragma acc routine". */
20491 data
->fndecl_seen
= true;
20495 # pragma acc update oacc-update-clause[optseq] new-line
20498 #define OACC_UPDATE_CLAUSE_MASK \
20499 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20500 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
20501 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
20502 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20503 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
20504 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20505 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20508 c_parser_oacc_update (c_parser
*parser
)
20510 location_t loc
= c_parser_peek_token (parser
)->location
;
20512 c_parser_consume_pragma (parser
);
20514 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
20515 "#pragma acc update");
20516 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
20519 "%<#pragma acc update%> must contain at least one "
20520 "%<device%> or %<host%> or %<self%> clause");
20527 tree stmt
= make_node (OACC_UPDATE
);
20528 TREE_TYPE (stmt
) = void_type_node
;
20529 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
20530 SET_EXPR_LOCATION (stmt
, loc
);
20535 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
20537 LOC is the location of the #pragma token.
20540 #define OACC_WAIT_CLAUSE_MASK \
20541 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
20544 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
20546 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
20548 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
20549 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
20551 strcpy (p_name
, " wait");
20552 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
20553 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
20559 struct c_omp_loc_tree
20565 /* Check whether the expression used in the allocator clause is declared or
20566 modified between the variable declaration and its allocate directive. */
20568 c_check_omp_allocate_allocator_r (tree
*tp
, int *, void *data
)
20570 tree var
= ((struct c_omp_loc_tree
*) data
)->var
;
20571 location_t loc
= ((struct c_omp_loc_tree
*) data
)->loc
;
20572 if (TREE_CODE (*tp
) == VAR_DECL
&& c_check_in_current_scope (*tp
))
20574 if (linemap_location_before_p (line_table
, DECL_SOURCE_LOCATION (var
),
20575 DECL_SOURCE_LOCATION (*tp
)))
20577 error_at (loc
, "variable %qD used in the %<allocator%> clause must "
20578 "be declared before %qD", *tp
, var
);
20579 inform (DECL_SOURCE_LOCATION (*tp
), "declared here");
20580 inform (DECL_SOURCE_LOCATION (var
),
20581 "to be allocated variable declared here");
20586 gcc_assert (cur_stmt_list
20587 && TREE_CODE (cur_stmt_list
) == STATEMENT_LIST
);
20589 tree_stmt_iterator l
= tsi_last (cur_stmt_list
);
20590 while (!tsi_end_p (l
))
20592 if (linemap_location_before_p (line_table
, EXPR_LOCATION (*l
),
20593 DECL_SOURCE_LOCATION (var
)))
20595 if (TREE_CODE (*l
) == MODIFY_EXPR
20596 && TREE_OPERAND (*l
, 0) == *tp
)
20599 "variable %qD used in the %<allocator%> clause "
20600 "must not be modified between declaration of %qD "
20601 "and its %<allocate%> directive", *tp
, var
);
20602 inform (EXPR_LOCATION (*l
), "modified here");
20603 inform (DECL_SOURCE_LOCATION (var
),
20604 "to be allocated variable declared here");
20615 # pragma omp allocate (list) clauses
20618 allocator (omp_allocator_handle_t expression)
20620 OpenMP 5.1 additional clause:
20621 align (constant-expression)] */
20624 c_parser_omp_allocate (c_parser
*parser
)
20626 tree alignment
= NULL_TREE
;
20627 tree allocator
= NULL_TREE
;
20628 c_parser_consume_pragma (parser
);
20629 location_t loc
= c_parser_peek_token (parser
)->location
;
20630 location_t allocator_loc
= UNKNOWN_LOCATION
;
20631 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ALLOCATE
, NULL_TREE
);
20634 if (c_parser_next_token_is (parser
, CPP_COMMA
)
20635 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
20636 c_parser_consume_token (parser
);
20637 if (!c_parser_next_token_is (parser
, CPP_NAME
))
20639 matching_parens parens
;
20640 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20641 c_parser_consume_token (parser
);
20642 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
20643 if (strcmp ("align", p
) != 0 && strcmp ("allocator", p
) != 0)
20645 error_at (c_parser_peek_token (parser
)->location
,
20646 "expected %<allocator%> or %<align%>");
20649 if (!parens
.require_open (parser
))
20652 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
20653 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
20654 expr_loc
= c_parser_peek_token (parser
)->location
;
20655 if (expr
.value
== error_mark_node
)
20657 else if (p
[2] == 'i' && alignment
)
20659 error_at (expr_loc
, "too many %qs clauses", "align");
20662 else if (p
[2] == 'i')
20664 alignment
= c_fully_fold (expr
.value
, false, NULL
);
20665 if (TREE_CODE (alignment
) != INTEGER_CST
20666 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
20667 || tree_int_cst_sgn (alignment
) != 1
20668 || !integer_pow2p (alignment
))
20670 error_at (expr_loc
, "%<align%> clause argument needs to be "
20671 "positive constant power of two integer "
20673 alignment
= NULL_TREE
;
20676 else if (allocator
)
20678 error_at (expr_loc
, "too many %qs clauses", "allocator");
20683 allocator
= c_fully_fold (expr
.value
, false, NULL
);
20684 allocator_loc
= expr_loc
;
20686 = expr
.original_type
? expr
.original_type
: TREE_TYPE (allocator
);
20687 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
20688 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
20689 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
20690 || TYPE_NAME (orig_type
)
20691 != get_identifier ("omp_allocator_handle_t"))
20693 error_at (expr_loc
,
20694 "%<allocator%> clause allocator expression has type "
20695 "%qT rather than %<omp_allocator_handle_t%>",
20696 TREE_TYPE (allocator
));
20697 allocator
= NULL_TREE
;
20700 parens
.skip_until_found_close (parser
);
20702 c_parser_skip_to_pragma_eol (parser
);
20704 c_mark_decl_jump_unsafe_in_current_scope ();
20705 for (tree c
= nl
; c
!= NULL_TREE
; c
= OMP_CLAUSE_CHAIN (c
))
20707 tree var
= OMP_CLAUSE_DECL (c
);
20708 if (TREE_CODE (var
) == PARM_DECL
)
20710 error_at (OMP_CLAUSE_LOCATION (nl
),
20711 "function parameter %qD may not appear as list item in an "
20712 "%<allocate%> directive", var
);
20715 if (!c_check_in_current_scope (var
))
20717 error_at (OMP_CLAUSE_LOCATION (nl
),
20718 "%<allocate%> directive must be in the same scope as %qD",
20720 inform (DECL_SOURCE_LOCATION (var
), "declared here");
20723 if (lookup_attribute ("omp allocate", DECL_ATTRIBUTES (var
)))
20725 error_at (OMP_CLAUSE_LOCATION (nl
),
20726 "%qD already appeared as list item in an "
20727 "%<allocate%> directive", var
);
20730 if (TREE_STATIC (var
))
20732 if (allocator
== NULL_TREE
&& allocator_loc
== UNKNOWN_LOCATION
)
20733 error_at (loc
, "%<allocator%> clause required for "
20734 "static variable %qD", var
);
20736 && (wi::to_widest (allocator
) < 1
20737 || wi::to_widest (allocator
) > 8))
20738 /* 8 = largest predefined memory allocator. */
20739 error_at (allocator_loc
,
20740 "%<allocator%> clause requires a predefined allocator as "
20741 "%qD is static", var
);
20743 sorry_at (OMP_CLAUSE_LOCATION (nl
),
20744 "%<#pragma omp allocate%> for static variables like "
20745 "%qD not yet supported", var
);
20750 struct c_omp_loc_tree data
20751 = {EXPR_LOC_OR_LOC (allocator
, OMP_CLAUSE_LOCATION (nl
)), var
};
20752 walk_tree (&allocator
, c_check_omp_allocate_allocator_r
, &data
, NULL
);
20754 DECL_ATTRIBUTES (var
) = tree_cons (get_identifier ("omp allocate"),
20755 build_tree_list (allocator
, alignment
),
20756 DECL_ATTRIBUTES (var
));
20761 # pragma omp atomic new-line
20765 x binop= expr | x++ | ++x | x-- | --x
20767 +, *, -, /, &, ^, |, <<, >>
20769 where x is an lvalue expression with scalar type.
20772 # pragma omp atomic new-line
20775 # pragma omp atomic read new-line
20778 # pragma omp atomic write new-line
20781 # pragma omp atomic update new-line
20784 # pragma omp atomic capture new-line
20787 # pragma omp atomic capture new-line
20795 expression-stmt | x = x binop expr
20797 v = expression-stmt
20799 { v = x; update-stmt; } | { update-stmt; v = x; }
20803 expression-stmt | x = x binop expr | x = expr binop x
20807 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
20810 # pragma omp atomic compare new-line
20811 conditional-update-atomic
20813 # pragma omp atomic compare capture new-line
20814 conditional-update-capture-atomic
20816 conditional-update-atomic:
20817 cond-expr-stmt | cond-update-stmt
20819 x = expr ordop x ? expr : x;
20820 x = x ordop expr ? expr : x;
20821 x = x == e ? d : x;
20823 if (expr ordop x) { x = expr; }
20824 if (x ordop expr) { x = expr; }
20825 if (x == e) { x = d; }
20828 conditional-update-capture-atomic:
20830 { v = x; cond-expr-stmt }
20831 { cond-expr-stmt v = x; }
20832 { v = x; cond-update-stmt }
20833 { cond-update-stmt v = x; }
20834 if (x == e) { x = d; } else { v = x; }
20835 { r = x == e; if (r) { x = d; } }
20836 { r = x == e; if (r) { x = d; } else { v = x; } }
20838 where x, r and v are lvalue expressions with scalar type,
20839 expr, e and d are expressions with scalar type and e might be
20842 LOC is the location of the #pragma token. */
20845 c_parser_omp_atomic (location_t loc
, c_parser
*parser
, bool openacc
)
20847 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
, r
= NULL_TREE
;
20848 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
20849 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
20850 enum tree_code code
= ERROR_MARK
, opcode
= NOP_EXPR
;
20851 enum omp_memory_order memory_order
= OMP_MEMORY_ORDER_UNSPECIFIED
;
20852 struct c_expr expr
;
20854 bool structured_block
= false;
20855 bool swapped
= false;
20857 tree clauses
= NULL_TREE
;
20858 bool capture
= false;
20859 bool compare
= false;
20861 enum omp_memory_order fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
20862 bool no_semicolon
= false;
20863 bool extra_scope
= false;
20865 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
20867 if (c_parser_next_token_is (parser
, CPP_COMMA
)
20868 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
20869 c_parser_consume_token (parser
);
20871 if (c_parser_next_token_is (parser
, CPP_NAME
))
20874 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20875 location_t cloc
= c_parser_peek_token (parser
)->location
;
20876 enum tree_code new_code
= ERROR_MARK
;
20877 enum omp_memory_order new_memory_order
20878 = OMP_MEMORY_ORDER_UNSPECIFIED
;
20879 bool new_capture
= false;
20880 bool new_compare
= false;
20881 bool new_weak
= false;
20882 enum omp_memory_order new_fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
20884 if (!strcmp (p
, "read"))
20885 new_code
= OMP_ATOMIC_READ
;
20886 else if (!strcmp (p
, "write"))
20887 new_code
= NOP_EXPR
;
20888 else if (!strcmp (p
, "update"))
20889 new_code
= OMP_ATOMIC
;
20890 else if (openacc
&& !strcmp (p
, "capture"))
20891 new_code
= OMP_ATOMIC_CAPTURE_NEW
;
20895 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
20896 "or %<capture%> clause");
20898 else if (!strcmp (p
, "capture"))
20899 new_capture
= true;
20900 else if (!strcmp (p
, "compare"))
20901 new_compare
= true;
20902 else if (!strcmp (p
, "weak"))
20904 else if (!strcmp (p
, "fail"))
20906 matching_parens parens
;
20908 c_parser_consume_token (parser
);
20909 if (!parens
.require_open (parser
))
20912 if (c_parser_next_token_is (parser
, CPP_NAME
))
20915 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20917 if (!strcmp (q
, "seq_cst"))
20918 new_fail
= OMP_MEMORY_ORDER_SEQ_CST
;
20919 else if (!strcmp (q
, "acquire"))
20920 new_fail
= OMP_MEMORY_ORDER_ACQUIRE
;
20921 else if (!strcmp (q
, "relaxed"))
20922 new_fail
= OMP_MEMORY_ORDER_RELAXED
;
20925 if (new_fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
20927 c_parser_consume_token (parser
);
20928 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
20929 error_at (cloc
, "too many %qs clauses", "fail");
20934 c_parser_error (parser
, "expected %<seq_cst%>, %<acquire%> "
20936 parens
.skip_until_found_close (parser
);
20939 else if (!strcmp (p
, "seq_cst"))
20940 new_memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
20941 else if (!strcmp (p
, "acq_rel"))
20942 new_memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
20943 else if (!strcmp (p
, "release"))
20944 new_memory_order
= OMP_MEMORY_ORDER_RELEASE
;
20945 else if (!strcmp (p
, "acquire"))
20946 new_memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
20947 else if (!strcmp (p
, "relaxed"))
20948 new_memory_order
= OMP_MEMORY_ORDER_RELAXED
;
20949 else if (!strcmp (p
, "hint"))
20951 c_parser_consume_token (parser
);
20952 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
20958 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
20959 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
20960 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
20961 "%<relaxed%> or %<hint%> clause");
20965 if (new_code
!= ERROR_MARK
)
20967 /* OpenACC permits 'update capture'. */
20969 && code
== OMP_ATOMIC
20970 && new_code
== OMP_ATOMIC_CAPTURE_NEW
)
20972 else if (code
!= ERROR_MARK
)
20973 error_at (cloc
, "too many atomic clauses");
20977 else if (new_memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
20979 if (memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
20980 error_at (cloc
, "too many memory order clauses");
20982 memory_order
= new_memory_order
;
20984 else if (new_capture
)
20987 error_at (cloc
, "too many %qs clauses", "capture");
20991 else if (new_compare
)
20994 error_at (cloc
, "too many %qs clauses", "compare");
21001 error_at (cloc
, "too many %qs clauses", "weak");
21005 c_parser_consume_token (parser
);
21011 c_parser_skip_to_pragma_eol (parser
);
21013 if (code
== ERROR_MARK
)
21017 if (code
!= OMP_ATOMIC
)
21018 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
21019 "clauses", "capture");
21021 code
= OMP_ATOMIC_CAPTURE_NEW
;
21023 if (compare
&& code
!= OMP_ATOMIC
&& code
!= OMP_ATOMIC_CAPTURE_NEW
)
21025 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
21026 "clauses", "compare");
21029 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
&& !compare
)
21031 error_at (loc
, "%qs clause requires %qs clause", "fail", "compare");
21032 fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
21034 if (weak
&& !compare
)
21036 error_at (loc
, "%qs clause requires %qs clause", "weak", "compare");
21040 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
21041 else if (memory_order
== OMP_MEMORY_ORDER_UNSPECIFIED
)
21044 = (enum omp_requires
) (omp_requires_mask
21045 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
);
21046 switch ((enum omp_memory_order
)
21047 (omp_requires_mask
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
))
21049 case OMP_MEMORY_ORDER_UNSPECIFIED
:
21050 case OMP_MEMORY_ORDER_RELAXED
:
21051 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
21053 case OMP_MEMORY_ORDER_SEQ_CST
:
21054 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21056 case OMP_MEMORY_ORDER_ACQUIRE
:
21057 if (code
== NOP_EXPR
) /* atomic write */
21059 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
21060 "%<acquire%> clause implicitly provided by a "
21061 "%<requires%> directive");
21062 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21065 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
21067 case OMP_MEMORY_ORDER_RELEASE
:
21068 if (code
== OMP_ATOMIC_READ
)
21070 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
21071 "%<release%> clause implicitly provided by a "
21072 "%<requires%> directive");
21073 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21076 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
21078 case OMP_MEMORY_ORDER_ACQ_REL
:
21081 case OMP_ATOMIC_READ
:
21082 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
21084 case NOP_EXPR
: /* atomic write */
21085 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
21088 memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
21093 gcc_unreachable ();
21099 case OMP_ATOMIC_READ
:
21100 if (memory_order
== OMP_MEMORY_ORDER_RELEASE
)
21102 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
21103 "%<release%> clause");
21104 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21106 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
21107 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
21109 case NOP_EXPR
: /* atomic write */
21110 if (memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
21112 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
21113 "%<acquire%> clause");
21114 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21116 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
21117 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
21122 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
21124 = (enum omp_memory_order
) (memory_order
21125 | (fail
<< OMP_FAIL_MEMORY_ORDER_SHIFT
));
21129 case OMP_ATOMIC_READ
:
21130 case NOP_EXPR
: /* atomic write */
21131 v
= c_parser_cast_expression (parser
, NULL
).value
;
21132 non_lvalue_p
= !lvalue_p (v
);
21133 v
= c_fully_fold (v
, false, NULL
, true);
21134 if (v
== error_mark_node
)
21137 v
= non_lvalue (v
);
21138 loc
= c_parser_peek_token (parser
)->location
;
21139 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21141 if (code
== NOP_EXPR
)
21143 lhs
= c_parser_expression (parser
).value
;
21144 lhs
= c_fully_fold (lhs
, false, NULL
);
21145 if (lhs
== error_mark_node
)
21150 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
21151 non_lvalue_p
= !lvalue_p (lhs
);
21152 lhs
= c_fully_fold (lhs
, false, NULL
, true);
21153 if (lhs
== error_mark_node
)
21156 lhs
= non_lvalue (lhs
);
21158 if (code
== NOP_EXPR
)
21160 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
21168 case OMP_ATOMIC_CAPTURE_NEW
:
21169 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
21171 c_parser_consume_token (parser
);
21172 structured_block
= true;
21175 && c_parser_next_token_is_keyword (parser
, RID_IF
))
21179 v
= c_parser_cast_expression (parser
, NULL
).value
;
21180 non_lvalue_p
= !lvalue_p (v
);
21181 v
= c_fully_fold (v
, false, NULL
, true);
21182 if (v
== error_mark_node
)
21185 v
= non_lvalue (v
);
21186 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21188 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
21190 eloc
= c_parser_peek_token (parser
)->location
;
21191 error_at (eloc
, "expected expression");
21200 /* For structured_block case we don't know yet whether
21201 old or new x should be captured. */
21203 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
21205 c_parser_consume_token (parser
);
21207 matching_parens parens
;
21208 if (!parens
.require_open (parser
))
21210 eloc
= c_parser_peek_token (parser
)->location
;
21214 cmp_expr
= c_parser_cast_expression (parser
, NULL
);
21215 cmp_expr
= default_function_array_conversion (eloc
, cmp_expr
);
21218 cmp_expr
= c_parser_binary_expression (parser
, NULL
, void_list_node
);
21219 parens
.skip_until_found_close (parser
);
21220 if (cmp_expr
.value
== error_mark_node
)
21224 if (!c_tree_equal (cmp_expr
.value
, unfolded_lhs
))
21226 cmp_expr
.value
= rhs1
;
21228 gcc_assert (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
);
21230 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
21232 else if (!structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
21234 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
21235 "expected %<==%> comparison in %<if%> condition");
21238 else if (TREE_CODE (cmp_expr
.value
) != GT_EXPR
21239 && TREE_CODE (cmp_expr
.value
) != LT_EXPR
)
21241 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
21242 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
21246 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
21249 extra_scope
= true;
21250 eloc
= c_parser_peek_token (parser
)->location
;
21251 expr
= c_parser_cast_expression (parser
, NULL
);
21253 expr
= default_function_array_conversion (eloc
, expr
);
21254 unfolded_lhs
= expr
.value
;
21255 lhs
= c_fully_fold (lhs
, false, NULL
, true);
21257 if (lhs
== error_mark_node
)
21259 if (!lvalue_p (unfolded_lhs
))
21260 lhs
= non_lvalue (lhs
);
21261 if (!c_parser_next_token_is (parser
, CPP_EQ
))
21263 c_parser_error (parser
, "expected %<=%>");
21266 c_parser_consume_token (parser
);
21267 eloc
= c_parser_peek_token (parser
)->location
;
21268 expr
= c_parser_expr_no_commas (parser
, NULL
);
21271 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
21274 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
21277 extra_scope
= false;
21278 no_semicolon
= true;
21280 if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), unfolded_lhs
))
21282 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
21284 opcode
= COND_EXPR
;
21285 rhs
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
21286 false, NULL
, true);
21287 rhs1
= c_fully_fold (rhs1
, false, NULL
, true);
21289 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), rhs1
))
21291 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
21292 ? MIN_EXPR
: MAX_EXPR
);
21293 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
21294 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 0),
21295 false, NULL
, true);
21300 else if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
21302 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), unfolded_lhs
)
21303 && c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), rhs1
))
21305 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
21306 ? MAX_EXPR
: MIN_EXPR
);
21307 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
21308 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
21309 false, NULL
, true);
21314 c_parser_error (parser
,
21315 "invalid form of %<#pragma omp atomic compare%>");
21319 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
21321 if (code
!= OMP_ATOMIC_CAPTURE_NEW
21322 || (structured_block
&& r
== NULL_TREE
)
21323 || TREE_CODE (cmp_expr
.value
) != EQ_EXPR
)
21325 eloc
= c_parser_peek_token (parser
)->location
;
21326 error_at (eloc
, "unexpected %<else%>");
21330 c_parser_consume_token (parser
);
21332 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
21335 extra_scope
= true;
21336 v
= c_parser_cast_expression (parser
, NULL
).value
;
21337 non_lvalue_p
= !lvalue_p (v
);
21338 v
= c_fully_fold (v
, false, NULL
, true);
21339 if (v
== error_mark_node
)
21342 v
= non_lvalue (v
);
21343 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21346 expr
= c_parser_expr_no_commas (parser
, NULL
);
21348 if (!c_tree_equal (expr
.value
, unfolded_lhs
))
21351 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
21354 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
21357 extra_scope
= false;
21358 code
= OMP_ATOMIC_CAPTURE_OLD
;
21359 if (r
== NULL_TREE
)
21360 /* Signal to c_finish_omp_atomic that in
21361 if (x == e) { x = d; } else { v = x; }
21362 case the store to v should be conditional. */
21363 r
= void_list_node
;
21365 else if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
21367 c_parser_require_keyword (parser
, RID_ELSE
, "expected %<else%>");
21370 else if (code
== OMP_ATOMIC_CAPTURE_NEW
21376 eloc
= c_parser_peek_token (parser
)->location
;
21377 expr
= c_parser_cast_expression (parser
, NULL
);
21379 expr
= default_function_array_conversion (eloc
, expr
);
21380 unfolded_lhs
= expr
.value
;
21381 lhs
= c_fully_fold (lhs
, false, NULL
, true);
21383 switch (TREE_CODE (lhs
))
21386 error_at (eloc
, "invalid form of %<pragma omp atomic compare%>");
21390 c_parser_skip_to_end_of_block_or_statement (parser
);
21391 if (extra_scope
&& c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
21392 c_parser_consume_token (parser
);
21393 if (structured_block
)
21395 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
21396 c_parser_consume_token (parser
);
21397 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
21399 c_parser_skip_to_end_of_block_or_statement (parser
);
21400 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
21401 c_parser_consume_token (parser
);
21406 case POSTINCREMENT_EXPR
:
21407 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
21408 code
= OMP_ATOMIC_CAPTURE_OLD
;
21410 case PREINCREMENT_EXPR
:
21411 lhs
= TREE_OPERAND (lhs
, 0);
21412 unfolded_lhs
= NULL_TREE
;
21413 opcode
= PLUS_EXPR
;
21414 rhs
= integer_one_node
;
21416 goto invalid_compare
;
21419 case POSTDECREMENT_EXPR
:
21420 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
21421 code
= OMP_ATOMIC_CAPTURE_OLD
;
21423 case PREDECREMENT_EXPR
:
21424 lhs
= TREE_OPERAND (lhs
, 0);
21425 unfolded_lhs
= NULL_TREE
;
21426 opcode
= MINUS_EXPR
;
21427 rhs
= integer_one_node
;
21429 goto invalid_compare
;
21432 case COMPOUND_EXPR
:
21433 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
21434 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
21435 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
21436 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
21437 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
21438 (TREE_OPERAND (lhs
, 1), 0), 0))))
21439 /* Undo effects of boolean_increment for post {in,de}crement. */
21440 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
21443 if (TREE_CODE (lhs
) == MODIFY_EXPR
21444 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs
, 0))))
21446 /* Undo effects of boolean_increment. */
21447 if (integer_onep (TREE_OPERAND (lhs
, 1)))
21449 /* This is pre or post increment. */
21450 rhs
= TREE_OPERAND (lhs
, 1);
21451 lhs
= TREE_OPERAND (lhs
, 0);
21452 unfolded_lhs
= NULL_TREE
;
21454 if (code
== OMP_ATOMIC_CAPTURE_NEW
21455 && !structured_block
21456 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
21457 code
= OMP_ATOMIC_CAPTURE_OLD
;
21459 goto invalid_compare
;
21462 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
21463 && TREE_OPERAND (lhs
, 0)
21464 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
21466 /* This is pre or post decrement. */
21467 rhs
= TREE_OPERAND (lhs
, 1);
21468 lhs
= TREE_OPERAND (lhs
, 0);
21469 unfolded_lhs
= NULL_TREE
;
21471 if (code
== OMP_ATOMIC_CAPTURE_NEW
21472 && !structured_block
21473 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
21474 code
= OMP_ATOMIC_CAPTURE_OLD
;
21476 goto invalid_compare
;
21482 if (!lvalue_p (unfolded_lhs
))
21483 lhs
= non_lvalue (lhs
);
21484 if (compare
&& !c_parser_next_token_is (parser
, CPP_EQ
))
21486 c_parser_error (parser
, "expected %<=%>");
21489 switch (c_parser_peek_token (parser
)->type
)
21492 opcode
= MULT_EXPR
;
21495 opcode
= TRUNC_DIV_EXPR
;
21498 opcode
= PLUS_EXPR
;
21501 opcode
= MINUS_EXPR
;
21503 case CPP_LSHIFT_EQ
:
21504 opcode
= LSHIFT_EXPR
;
21506 case CPP_RSHIFT_EQ
:
21507 opcode
= RSHIFT_EXPR
;
21510 opcode
= BIT_AND_EXPR
;
21513 opcode
= BIT_IOR_EXPR
;
21516 opcode
= BIT_XOR_EXPR
;
21519 c_parser_consume_token (parser
);
21520 eloc
= c_parser_peek_token (parser
)->location
;
21521 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
21523 switch (TREE_CODE (rhs1
))
21526 case TRUNC_DIV_EXPR
:
21537 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
21539 opcode
= TREE_CODE (rhs1
);
21540 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21542 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
21546 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
21548 opcode
= TREE_CODE (rhs1
);
21549 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
21551 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21553 swapped
= !commutative_tree_code (opcode
);
21560 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) != GT_EXPR
21561 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != LT_EXPR
21562 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != EQ_EXPR
)
21564 if (!TREE_OPERAND (rhs1
, 1))
21566 if (!c_tree_equal (TREE_OPERAND (rhs1
, 2), unfolded_lhs
))
21568 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
21571 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
21573 opcode
= COND_EXPR
;
21574 rhs
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
21576 false, NULL
, true);
21577 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false,
21581 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
21582 TREE_OPERAND (rhs1
, 1)))
21584 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
21585 ? MIN_EXPR
: MAX_EXPR
);
21586 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21588 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
21590 false, NULL
, true);
21594 else if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
21596 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
21599 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
21600 TREE_OPERAND (rhs1
, 1)))
21602 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
21603 ? MAX_EXPR
: MIN_EXPR
);
21604 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21606 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
21608 false, NULL
, true);
21615 || code
!= OMP_ATOMIC_CAPTURE_NEW
21616 || !structured_block
21620 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
21621 && c_parser_peek_2nd_token (parser
)->keyword
== RID_IF
)
21625 c_parser_consume_token (parser
);
21634 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
21636 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
21638 code
= OMP_ATOMIC_CAPTURE_OLD
;
21641 expr
= default_function_array_read_conversion (eloc
, expr
);
21642 unfolded_lhs1
= expr
.value
;
21643 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
21645 c_parser_consume_token (parser
);
21648 if (structured_block
&& !compare
)
21651 expr
= default_function_array_read_conversion (eloc
, expr
);
21652 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
21657 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
21660 c_parser_error (parser
,
21661 "invalid operator for %<#pragma omp atomic%>");
21665 /* Arrange to pass the location of the assignment operator to
21666 c_finish_omp_atomic. */
21667 loc
= c_parser_peek_token (parser
)->location
;
21668 c_parser_consume_token (parser
);
21669 eloc
= c_parser_peek_token (parser
)->location
;
21670 expr
= c_parser_expression (parser
);
21671 expr
= default_function_array_read_conversion (eloc
, expr
);
21673 rhs
= c_fully_fold (rhs
, false, NULL
, true);
21677 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
&& r
== NULL_TREE
)
21680 && !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
21682 no_semicolon
= false;
21683 v
= c_parser_cast_expression (parser
, NULL
).value
;
21684 non_lvalue_p
= !lvalue_p (v
);
21685 v
= c_fully_fold (v
, false, NULL
, true);
21686 if (v
== error_mark_node
)
21689 v
= non_lvalue (v
);
21690 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21692 eloc
= c_parser_peek_token (parser
)->location
;
21693 expr
= c_parser_cast_expression (parser
, NULL
);
21695 expr
= default_function_array_read_conversion (eloc
, expr
);
21696 unfolded_lhs1
= expr
.value
;
21697 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
21698 if (lhs1
== error_mark_node
)
21700 if (!lvalue_p (unfolded_lhs1
))
21701 lhs1
= non_lvalue (lhs1
);
21703 if (structured_block
)
21706 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
21707 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
21710 if (weak
&& opcode
!= COND_EXPR
)
21712 error_at (loc
, "%<weak%> clause requires atomic equality comparison");
21715 if (unfolded_lhs
&& unfolded_lhs1
21716 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
21718 error ("%<#pragma omp atomic capture%> uses two different "
21719 "expressions for memory");
21720 stmt
= error_mark_node
;
21723 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
, r
,
21724 swapped
, memory_order
, weak
);
21725 if (stmt
!= error_mark_node
)
21728 if (!structured_block
&& !no_semicolon
)
21729 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
21734 # pragma omp barrier new-line
21738 c_parser_omp_barrier (c_parser
*parser
)
21740 location_t loc
= c_parser_peek_token (parser
)->location
;
21741 c_parser_consume_pragma (parser
);
21742 c_parser_skip_to_pragma_eol (parser
);
21744 c_finish_omp_barrier (loc
);
21748 # pragma omp critical [(name)] new-line
21752 # pragma omp critical [(name) [hint(expression)]] new-line
21754 LOC is the location of the #pragma itself. */
21756 #define OMP_CRITICAL_CLAUSE_MASK \
21757 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
21760 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
21762 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
21764 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
21766 c_parser_consume_token (parser
);
21767 if (c_parser_next_token_is (parser
, CPP_NAME
))
21769 name
= c_parser_peek_token (parser
)->value
;
21770 c_parser_consume_token (parser
);
21771 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
21774 c_parser_error (parser
, "expected identifier");
21776 if (c_parser_next_token_is (parser
, CPP_COMMA
)
21777 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
21778 c_parser_consume_token (parser
);
21780 clauses
= c_parser_omp_all_clauses (parser
, OMP_CRITICAL_CLAUSE_MASK
,
21781 "#pragma omp critical");
21782 stmt
= c_parser_omp_structured_block (parser
, if_p
);
21783 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
21787 # pragma omp depobj ( depobj ) depobj-clause new-line
21790 depend (dependence-type : locator)
21792 update (dependence-type)
21794 OpenMP 5.2 additionally:
21804 c_parser_omp_depobj (c_parser
*parser
)
21806 location_t loc
= c_parser_peek_token (parser
)->location
;
21807 c_parser_consume_pragma (parser
);
21808 matching_parens parens
;
21809 if (!parens
.require_open (parser
))
21811 c_parser_skip_to_pragma_eol (parser
);
21815 tree depobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
21816 if (depobj
!= error_mark_node
)
21818 if (!lvalue_p (depobj
))
21820 error_at (EXPR_LOC_OR_LOC (depobj
, loc
),
21821 "%<depobj%> expression is not lvalue expression");
21822 depobj
= error_mark_node
;
21826 tree addr
= build_unary_op (EXPR_LOC_OR_LOC (depobj
, loc
), ADDR_EXPR
,
21828 if (addr
== error_mark_node
)
21829 depobj
= error_mark_node
;
21831 depobj
= build_indirect_ref (EXPR_LOC_OR_LOC (depobj
, loc
),
21832 addr
, RO_UNARY_STAR
);
21836 parens
.skip_until_found_close (parser
);
21837 tree clause
= NULL_TREE
;
21838 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_INVALID
;
21839 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21840 c_parser_consume_token (parser
);
21841 location_t c_loc
= c_parser_peek_token (parser
)->location
;
21842 if (c_parser_next_token_is (parser
, CPP_NAME
))
21844 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21846 c_parser_consume_token (parser
);
21847 if (!strcmp ("depend", p
))
21849 clause
= c_parser_omp_clause_depend (parser
, NULL_TREE
);
21850 clause
= c_finish_omp_clauses (clause
, C_ORT_OMP
);
21852 clause
= error_mark_node
;
21854 else if (!strcmp ("destroy", p
))
21856 matching_parens c_parens
;
21857 kind
= OMP_CLAUSE_DEPEND_LAST
;
21858 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
21859 && c_parens
.require_open (parser
))
21861 tree destobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
21862 if (!lvalue_p (destobj
))
21863 error_at (EXPR_LOC_OR_LOC (destobj
, c_loc
),
21864 "%<destroy%> expression is not lvalue expression");
21865 else if (depobj
!= error_mark_node
21866 && !operand_equal_p (destobj
, depobj
,
21867 OEP_MATCH_SIDE_EFFECTS
21868 | OEP_LEXICOGRAPHIC
))
21869 warning_at (EXPR_LOC_OR_LOC (destobj
, c_loc
), OPT_Wopenmp
,
21870 "the %<destroy%> expression %qE should be the same "
21871 "as the %<depobj%> argument %qE", destobj
, depobj
);
21872 c_parens
.skip_until_found_close (parser
);
21875 else if (!strcmp ("update", p
))
21877 matching_parens c_parens
;
21878 if (c_parens
.require_open (parser
))
21880 location_t c2_loc
= c_parser_peek_token (parser
)->location
;
21881 if (c_parser_next_token_is (parser
, CPP_NAME
))
21884 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21886 c_parser_consume_token (parser
);
21887 if (!strcmp ("in", p2
))
21888 kind
= OMP_CLAUSE_DEPEND_IN
;
21889 else if (!strcmp ("out", p2
))
21890 kind
= OMP_CLAUSE_DEPEND_OUT
;
21891 else if (!strcmp ("inout", p2
))
21892 kind
= OMP_CLAUSE_DEPEND_INOUT
;
21893 else if (!strcmp ("mutexinoutset", p2
))
21894 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
21895 else if (!strcmp ("inoutset", p2
))
21896 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
21898 if (kind
== OMP_CLAUSE_DEPEND_INVALID
)
21900 clause
= error_mark_node
;
21901 error_at (c2_loc
, "expected %<in%>, %<out%>, %<inout%>, "
21902 "%<mutexinoutset%> or %<inoutset%>");
21904 c_parens
.skip_until_found_close (parser
);
21907 clause
= error_mark_node
;
21910 if (!clause
&& kind
== OMP_CLAUSE_DEPEND_INVALID
)
21912 clause
= error_mark_node
;
21913 error_at (c_loc
, "expected %<depend%>, %<destroy%> or %<update%> clause");
21915 c_parser_skip_to_pragma_eol (parser
);
21917 c_finish_omp_depobj (loc
, depobj
, kind
, clause
);
21922 # pragma omp flush flush-vars[opt] new-line
21928 # pragma omp flush memory-order-clause new-line */
21931 c_parser_omp_flush (c_parser
*parser
)
21933 location_t loc
= c_parser_peek_token (parser
)->location
;
21934 c_parser_consume_pragma (parser
);
21935 enum memmodel mo
= MEMMODEL_LAST
;
21936 if (c_parser_next_token_is (parser
, CPP_COMMA
)
21937 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
21938 c_parser_consume_token (parser
);
21939 if (c_parser_next_token_is (parser
, CPP_NAME
))
21942 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21944 if (!strcmp (p
, "seq_cst"))
21945 mo
= MEMMODEL_SEQ_CST
;
21946 else if (!strcmp (p
, "acq_rel"))
21947 mo
= MEMMODEL_ACQ_REL
;
21948 else if (!strcmp (p
, "release"))
21949 mo
= MEMMODEL_RELEASE
;
21950 else if (!strcmp (p
, "acquire"))
21951 mo
= MEMMODEL_ACQUIRE
;
21953 error_at (c_parser_peek_token (parser
)->location
,
21954 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
21956 c_parser_consume_token (parser
);
21958 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
21960 if (mo
!= MEMMODEL_LAST
)
21961 error_at (c_parser_peek_token (parser
)->location
,
21962 "%<flush%> list specified together with memory order "
21964 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
21966 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21967 c_parser_error (parser
, "expected %<(%> or end of line");
21968 c_parser_skip_to_pragma_eol (parser
);
21970 c_finish_omp_flush (loc
, mo
);
21973 /* Return true if next tokens contain a standard attribute that contains
21974 omp::directive (DIRECTIVE). */
21977 c_parser_omp_section_scan (c_parser
*parser
, const char *directive
,
21980 if (!c_parser_nth_token_starts_std_attributes (parser
, 1))
21982 unsigned int n
= 3;
21983 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
21985 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
21986 if (token
->type
!= CPP_CLOSE_SQUARE
)
21988 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
21989 if (token
->type
!= CPP_CLOSE_SQUARE
)
21993 if (c_parser_peek_nth_token_raw (parser
, 3)->type
== CPP_NAME
21994 && c_parser_peek_nth_token_raw (parser
, 4)->type
== CPP_OPEN_PAREN
21995 && c_parser_peek_nth_token_raw (parser
, 5)->type
== CPP_NAME
)
21997 tree first
= c_parser_peek_nth_token_raw (parser
, 3)->value
;
21998 tree second
= c_parser_peek_nth_token_raw (parser
, 5)->value
;
21999 if (strcmp (IDENTIFIER_POINTER (first
), "directive")
22000 && strcmp (IDENTIFIER_POINTER (first
), "__directive__"))
22002 if (strcmp (IDENTIFIER_POINTER (second
), directive
))
22007 location_t first_loc
= c_parser_peek_token (parser
)->location
;
22008 location_t last_loc
= c_parser_peek_nth_token_raw (parser
, n
+ 1)->location
;
22009 location_t middle_loc
= UNKNOWN_LOCATION
;
22010 tree std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
22013 for (tree attr
= std_attrs
; attr
; attr
= TREE_CHAIN (attr
))
22014 if (is_attribute_namespace_p ("omp", attr
)
22015 && is_attribute_p ("directive", get_attribute_name (attr
)))
22017 for (tree a
= TREE_VALUE (attr
); a
; a
= TREE_CHAIN (a
))
22019 tree d
= TREE_VALUE (a
);
22020 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
22021 c_token
*first
= C_TOKEN_VEC_TOKENS (d
)->address ();
22023 if (first
->type
== CPP_NAME
22024 && strcmp (IDENTIFIER_POINTER (first
->value
),
22028 if (middle_loc
== UNKNOWN_LOCATION
)
22029 middle_loc
= first
->location
;
22035 if (cnt
!= 1 || TREE_CHAIN (std_attrs
))
22037 error_at (make_location (first_loc
, last_loc
, middle_loc
),
22038 "%<[[omp::directive(%s)]]%> must be the only specified "
22039 "attribute on a statement", directive
);
22042 c_parser_handle_statement_omp_attributes (parser
, std_attrs
, NULL
);
22046 /* Parse an OpenMP structured block sequence. KIND is the corresponding
22047 separating directive. */
22050 c_parser_omp_structured_block_sequence (c_parser
*parser
,
22051 enum pragma_kind kind
)
22053 tree stmt
= push_stmt_list ();
22054 c_parser_statement (parser
, NULL
);
22057 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
22059 if (c_parser_next_token_is (parser
, CPP_EOF
))
22062 if (kind
!= PRAGMA_NONE
22063 && c_parser_peek_token (parser
)->pragma_kind
== kind
)
22066 if (kind
!= PRAGMA_NONE
22067 && c_parser_omp_section_scan (parser
,
22068 kind
== PRAGMA_OMP_SCAN
22069 ? "scan" : "section", false))
22072 c_parser_statement (parser
, NULL
);
22075 return pop_stmt_list (stmt
);
22081 { structured-block scan-directive structured-block } */
22084 c_parser_omp_scan_loop_body (c_parser
*parser
, bool open_brace_parsed
)
22088 tree clauses
= NULL_TREE
;
22089 bool found_scan
= false;
22091 loc
= c_parser_peek_token (parser
)->location
;
22092 if (!open_brace_parsed
22093 && !c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
22095 /* Avoid skipping until the end of the block. */
22096 parser
->error
= false;
22100 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SCAN
)
22101 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_OMP_SCAN
);
22104 warning_at (c_parser_peek_token (parser
)->location
, OPT_Wopenmp
,
22105 "%<#pragma omp scan%> with zero preceding executable "
22107 substmt
= build_empty_stmt (loc
);
22109 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, NULL_TREE
);
22110 SET_EXPR_LOCATION (substmt
, loc
);
22111 add_stmt (substmt
);
22113 loc
= c_parser_peek_token (parser
)->location
;
22114 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SCAN
)
22116 enum omp_clause_code clause
= OMP_CLAUSE_ERROR
;
22119 c_parser_consume_pragma (parser
);
22121 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22122 c_parser_consume_token (parser
);
22124 if (c_parser_next_token_is (parser
, CPP_NAME
))
22127 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22128 if (strcmp (p
, "inclusive") == 0)
22129 clause
= OMP_CLAUSE_INCLUSIVE
;
22130 else if (strcmp (p
, "exclusive") == 0)
22131 clause
= OMP_CLAUSE_EXCLUSIVE
;
22133 if (clause
!= OMP_CLAUSE_ERROR
)
22135 c_parser_consume_token (parser
);
22136 clauses
= c_parser_omp_var_list_parens (parser
, clause
, NULL_TREE
);
22139 c_parser_error (parser
, "expected %<inclusive%> or "
22140 "%<exclusive%> clause");
22141 c_parser_skip_to_pragma_eol (parser
);
22144 error ("expected %<#pragma omp scan%>");
22146 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
22147 if (!c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
22148 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_NONE
);
22152 warning_at (loc
, OPT_Wopenmp
,
22153 "%<#pragma omp scan%> with zero succeeding executable "
22155 substmt
= build_empty_stmt (loc
);
22157 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, clauses
);
22158 SET_EXPR_LOCATION (substmt
, loc
);
22159 add_stmt (substmt
);
22161 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
22166 /* This function parses a single level of a loop nest, invoking itself
22167 recursively if necessary.
22169 loop-nest :: for (...) loop-body
22170 loop-body :: loop-nest
22171 | { [intervening-code] loop-body [intervening-code] }
22173 intervening-code :: structured-block-sequence
22174 final-loop-body :: structured-block
22176 For a collapsed loop nest, only a single OMP_FOR is built, pulling out
22177 all the iterator information from the inner loops into the
22178 parser->omp_for_parse_state structure.
22180 The iterator decl, init, cond, and incr are stored in vectors.
22182 Initialization code for iterator variables is collected into
22183 parser->omp_for_parse_state->pre_body and ends up inserted directly
22184 into the OMP_FOR structure. */
22187 c_parser_omp_loop_nest (c_parser
*parser
, bool *if_p
)
22189 tree decl
, cond
, incr
, init
;
22190 tree body
= NULL_TREE
;
22191 matching_parens parens
;
22193 unsigned char save_in_statement
;
22196 struct omp_for_parse_data
*omp_for_parse_state
22197 = parser
->omp_for_parse_state
;
22198 gcc_assert (omp_for_parse_state
);
22199 int depth
= omp_for_parse_state
->depth
;
22201 /* We have already matched the FOR token but not consumed it yet. */
22202 loc
= c_parser_peek_token (parser
)->location
;
22203 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
22204 c_parser_consume_token (parser
);
22206 /* Forbid break/continue in the loop initializer, condition, and
22207 increment expressions. */
22208 save_in_statement
= in_statement
;
22209 in_statement
= IN_OMP_BLOCK
;
22211 /* We are not in intervening code now. */
22212 omp_for_parse_state
->in_intervening_code
= false;
22214 if (!parens
.require_open (parser
))
22216 omp_for_parse_state
->fail
= true;
22220 /* An implicit scope block surrounds each level of FOR loop, for
22221 declarations of iteration variables at this loop depth. */
22222 loop_scope
= c_begin_compound_stmt (true);
22224 /* Parse the initialization declaration or expression. */
22225 if (c_parser_next_tokens_start_declaration (parser
))
22227 /* This is a declaration, which must be added to the pre_body code. */
22228 tree this_pre_body
= push_stmt_list ();
22229 c_in_omp_for
= true;
22230 c_parser_declaration_or_fndef (parser
, true, true, true, true, true);
22231 c_in_omp_for
= false;
22232 this_pre_body
= pop_stmt_list (this_pre_body
);
22233 append_to_statement_list_force (this_pre_body
,
22234 &(omp_for_parse_state
->pre_body
));
22235 decl
= check_for_loop_decls (omp_for_parse_state
->for_loc
, flag_isoc99
);
22238 if (DECL_INITIAL (decl
) == error_mark_node
)
22239 decl
= error_mark_node
;
22242 else if (c_parser_next_token_is (parser
, CPP_NAME
)
22243 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
22245 struct c_expr decl_exp
;
22246 struct c_expr init_exp
;
22247 location_t init_loc
;
22249 decl_exp
= c_parser_postfix_expression (parser
);
22250 decl
= decl_exp
.value
;
22252 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
22254 init_loc
= c_parser_peek_token (parser
)->location
;
22255 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
22256 init_exp
= default_function_array_read_conversion (init_loc
,
22258 c_in_omp_for
= true;
22259 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
22260 NOP_EXPR
, init_loc
, init_exp
.value
,
22261 init_exp
.original_type
);
22262 c_in_omp_for
= false;
22263 init
= c_process_expr_stmt (init_loc
, init
);
22265 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
22270 c_parser_error (parser
,
22271 "expected iteration declaration or initialization");
22272 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
22274 omp_for_parse_state
->fail
= true;
22278 /* Parse the loop condition. */
22280 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
22282 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
22283 c_in_omp_for
= true;
22284 struct c_expr cond_expr
22285 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
22286 c_in_omp_for
= false;
22288 cond
= cond_expr
.value
;
22289 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
22290 switch (cond_expr
.original_code
)
22298 if (omp_for_parse_state
->code
!= OACC_LOOP
)
22302 /* Can't be cond = error_mark_node, because we want to preserve
22303 the location until c_finish_omp_for. */
22304 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
22307 protected_set_expr_location (cond
, cond_loc
);
22309 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
22311 /* Parse the increment expression. */
22313 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
22315 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
22317 incr
= c_process_expr_stmt (incr_loc
,
22318 c_parser_expression (parser
).value
);
22320 parens
.skip_until_found_close (parser
);
22322 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
22323 omp_for_parse_state
->fail
= true;
22326 TREE_VEC_ELT (omp_for_parse_state
->declv
, depth
) = decl
;
22327 TREE_VEC_ELT (omp_for_parse_state
->initv
, depth
) = init
;
22328 TREE_VEC_ELT (omp_for_parse_state
->condv
, depth
) = cond
;
22329 TREE_VEC_ELT (omp_for_parse_state
->incrv
, depth
) = incr
;
22333 moreloops
= depth
< omp_for_parse_state
->count
- 1;
22334 omp_for_parse_state
->want_nested_loop
= moreloops
;
22335 if (moreloops
&& c_parser_next_token_is_keyword (parser
, RID_FOR
))
22337 omp_for_parse_state
->depth
++;
22338 body
= c_parser_omp_loop_nest (parser
, if_p
);
22339 omp_for_parse_state
->depth
--;
22341 else if (moreloops
&& c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
22343 /* This is the open brace in the loop-body grammar production. Rather
22344 than trying to special-case braces, just parse it as a compound
22345 statement and handle the nested loop-body case there. Note that
22346 when we see a further open brace inside the compound statement
22347 loop-body, we don't know whether it is the start of intervening
22348 code that is a compound statement, or a level of braces
22349 surrounding a nested loop-body. Use the WANT_NESTED_LOOP state
22350 bit to ensure we have only one nested loop at each level. */
22351 omp_for_parse_state
->in_intervening_code
= true;
22352 body
= c_parser_compound_statement (parser
, NULL
);
22353 omp_for_parse_state
->in_intervening_code
= false;
22354 if (omp_for_parse_state
->want_nested_loop
)
22356 /* We have already parsed the whole loop body and not found a
22358 error_at (omp_for_parse_state
->for_loc
,
22359 "not enough nested loops");
22360 omp_for_parse_state
->fail
= true;
22366 /* This is the final-loop-body case in the grammar: we have
22367 something that is not a FOR and not an open brace. */
22370 /* If we were expecting a nested loop, give an error and mark
22371 that parsing has failed, and try to recover by parsing the
22372 body as regular code without further collapsing. */
22373 error_at (omp_for_parse_state
->for_loc
,
22374 "not enough nested loops");
22375 omp_for_parse_state
->fail
= true;
22377 in_statement
= IN_OMP_FOR
;
22378 parser
->omp_for_parse_state
= NULL
;
22379 body
= push_stmt_list ();
22380 if (omp_for_parse_state
->inscan
)
22381 c_parser_omp_scan_loop_body (parser
, false);
22383 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
22384 body
= pop_stmt_list (body
);
22385 parser
->omp_for_parse_state
= omp_for_parse_state
;
22387 in_statement
= save_in_statement
;
22388 omp_for_parse_state
->want_nested_loop
= false;
22389 omp_for_parse_state
->in_intervening_code
= true;
22391 /* Pop and return the implicit scope surrounding this level of loop.
22392 If the iteration variable at this depth was bound in the for loop,
22393 pull out and save the binding. Later in c_parser_omp_for_loop,
22394 these bindings will be moved to the scope surrounding the entire
22395 OMP_FOR. That keeps the gimplifier happy later on, and meanwhile
22396 we have already resolved all references to the iteration variable
22397 in its true scope. */
22399 body
= c_end_compound_stmt (loc
, loop_scope
, true);
22400 if (decl
&& TREE_CODE (body
) == BIND_EXPR
)
22402 tree t
= BIND_EXPR_VARS (body
);
22403 tree prev
= NULL_TREE
, next
= NULL_TREE
;
22406 next
= DECL_CHAIN (t
);
22410 DECL_CHAIN (prev
) = next
;
22413 BIND_EXPR_VARS (body
) = next
;
22414 BLOCK_VARS (BIND_EXPR_BLOCK (body
)) = next
;
22416 DECL_CHAIN (t
) = omp_for_parse_state
->bindings
;
22417 omp_for_parse_state
->bindings
= t
;
22426 if (BIND_EXPR_VARS (body
) == NULL_TREE
)
22427 body
= BIND_EXPR_BODY (body
);
22433 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
22434 The real trick here is to determine the loop control variable early
22435 so that we can push a new decl if necessary to make it private.
22436 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
22440 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
22441 tree clauses
, tree
*cclauses
, bool *if_p
)
22443 tree body
, stmt
, cl
;
22444 tree ret
= NULL_TREE
;
22445 tree ordered_cl
= NULL_TREE
;
22446 int i
, collapse
= 1, ordered
= 0, count
;
22447 bool tiling
= false;
22448 bool inscan
= false;
22449 struct omp_for_parse_data data
;
22450 struct omp_for_parse_data
*save_data
= parser
->omp_for_parse_state
;
22452 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
22453 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
22454 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
22455 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
22458 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
22460 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
22461 && OMP_CLAUSE_ORDERED_EXPR (cl
))
22464 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
22466 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_REDUCTION
22467 && OMP_CLAUSE_REDUCTION_INSCAN (cl
)
22468 && (code
== OMP_SIMD
|| code
== OMP_FOR
))
22471 if (ordered
&& ordered
< collapse
)
22473 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
22474 "%<ordered%> clause parameter is less than %<collapse%>");
22475 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
22476 = build_int_cst (NULL_TREE
, collapse
);
22477 ordered
= collapse
;
22480 gcc_assert (tiling
|| (collapse
>= 1 && ordered
>= 0));
22481 count
= ordered
? ordered
: collapse
;
22483 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
))
22485 c_parser_error (parser
, "for statement expected");
22489 /* Initialize parse state for recursive descent. */
22490 data
.declv
= make_tree_vec (count
);
22491 data
.initv
= make_tree_vec (count
);
22492 data
.condv
= make_tree_vec (count
);
22493 data
.incrv
= make_tree_vec (count
);
22494 data
.pre_body
= NULL_TREE
;;
22495 data
.bindings
= NULL_TREE
;
22496 data
.for_loc
= c_parser_peek_token (parser
)->location
;
22497 data
.count
= count
;
22499 data
.want_nested_loop
= true;
22500 data
.ordered
= ordered
> 0;
22501 data
.in_intervening_code
= false;
22502 data
.perfect_nesting_fail
= false;
22504 data
.inscan
= inscan
;
22505 data
.saw_intervening_code
= false;
22507 parser
->omp_for_parse_state
= &data
;
22509 body
= c_parser_omp_loop_nest (parser
, if_p
);
22511 /* Add saved bindings for iteration variables that were declared in
22512 the nested for loop to the scope surrounding the entire loop. */
22513 for (tree t
= data
.bindings
; t
; )
22515 tree n
= TREE_CHAIN (t
);
22516 TREE_CHAIN (t
) = NULL_TREE
;
22521 /* Only bother calling c_finish_omp_for if we haven't already generated
22522 an error from the initialization parsing. */
22525 c_in_omp_for
= true;
22526 stmt
= c_finish_omp_for (loc
, code
, data
.declv
, NULL
, data
.initv
,
22527 data
.condv
, data
.incrv
,
22528 body
, data
.pre_body
, true);
22529 c_in_omp_for
= false;
22531 /* Check for iterators appearing in lb, b or incr expressions. */
22532 if (stmt
&& !c_omp_check_loop_iv (stmt
, data
.declv
, NULL
))
22535 /* Check for errors involving lb/ub/incr expressions referencing
22536 variables declared in intervening code. */
22537 if (data
.saw_intervening_code
22538 && !c_omp_check_loop_binding_exprs (stmt
, NULL
))
22545 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (stmt
)); i
++)
22547 tree init
= TREE_VEC_ELT (OMP_FOR_INIT (stmt
), i
);
22548 gcc_assert (TREE_CODE (init
) == MODIFY_EXPR
);
22549 tree decl
= TREE_OPERAND (init
, 0);
22550 tree cond
= TREE_VEC_ELT (OMP_FOR_COND (stmt
), i
);
22551 gcc_assert (COMPARISON_CLASS_P (cond
));
22552 gcc_assert (TREE_OPERAND (cond
, 0) == decl
);
22554 tree op0
= TREE_OPERAND (init
, 1);
22555 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
22556 || TREE_CODE (op0
) != TREE_VEC
)
22557 TREE_OPERAND (init
, 1) = c_fully_fold (op0
, false, NULL
);
22560 TREE_VEC_ELT (op0
, 1)
22561 = c_fully_fold (TREE_VEC_ELT (op0
, 1), false, NULL
);
22562 TREE_VEC_ELT (op0
, 2)
22563 = c_fully_fold (TREE_VEC_ELT (op0
, 2), false, NULL
);
22566 tree op1
= TREE_OPERAND (cond
, 1);
22567 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
22568 || TREE_CODE (op1
) != TREE_VEC
)
22569 TREE_OPERAND (cond
, 1) = c_fully_fold (op1
, false, NULL
);
22572 TREE_VEC_ELT (op1
, 1)
22573 = c_fully_fold (TREE_VEC_ELT (op1
, 1), false, NULL
);
22574 TREE_VEC_ELT (op1
, 2)
22575 = c_fully_fold (TREE_VEC_ELT (op1
, 2), false, NULL
);
22579 if (cclauses
!= NULL
22580 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
22583 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
22584 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
22585 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
22586 c
= &OMP_CLAUSE_CHAIN (*c
);
22589 for (i
= 0; i
< count
; i
++)
22590 if (TREE_VEC_ELT (data
.declv
, i
) == OMP_CLAUSE_DECL (*c
))
22593 c
= &OMP_CLAUSE_CHAIN (*c
);
22594 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
22597 "iteration variable %qD should not be firstprivate",
22598 OMP_CLAUSE_DECL (*c
));
22599 *c
= OMP_CLAUSE_CHAIN (*c
);
22603 /* Move lastprivate (decl) clause to
22604 OMP_FOR_CLAUSES. */
22606 *c
= OMP_CLAUSE_CHAIN (*c
);
22607 if (code
== OMP_SIMD
)
22609 OMP_CLAUSE_CHAIN (l
)
22610 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
22611 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
22615 OMP_CLAUSE_CHAIN (l
) = clauses
;
22621 OMP_FOR_CLAUSES (stmt
) = clauses
;
22626 parser
->omp_for_parse_state
= save_data
;
22630 /* Helper function for OpenMP parsing, split clauses and call
22631 finish_omp_clauses on each of the set of clauses afterwards. */
22634 omp_split_clauses (location_t loc
, enum tree_code code
,
22635 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
22638 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
22639 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
22641 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
],
22642 i
== C_OMP_CLAUSE_SPLIT_TARGET
22643 ? C_ORT_OMP_TARGET
: C_ORT_OMP
);
22647 #pragma omp loop loop-clause[optseq] new-line
22650 LOC is the location of the #pragma token.
22653 #define OMP_LOOP_CLAUSE_MASK \
22654 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22655 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22656 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22657 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22658 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
22659 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22662 c_parser_omp_loop (location_t loc
, c_parser
*parser
,
22663 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22666 tree block
, clauses
, ret
;
22668 strcat (p_name
, " loop");
22669 mask
|= OMP_LOOP_CLAUSE_MASK
;
22671 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22674 omp_split_clauses (loc
, OMP_LOOP
, mask
, clauses
, cclauses
);
22675 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_LOOP
];
22678 block
= c_begin_compound_stmt (true);
22679 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_LOOP
, clauses
, cclauses
, if_p
);
22680 block
= c_end_compound_stmt (loc
, block
, true);
22687 #pragma omp simd simd-clause[optseq] new-line
22690 LOC is the location of the #pragma token.
22693 #define OMP_SIMD_CLAUSE_MASK \
22694 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
22695 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
22696 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
22697 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
22698 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22699 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22700 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22701 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22702 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22703 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
22704 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22707 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
22708 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22711 tree block
, clauses
, ret
;
22713 strcat (p_name
, " simd");
22714 mask
|= OMP_SIMD_CLAUSE_MASK
;
22716 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22719 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
22720 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
22723 block
= c_begin_compound_stmt (true);
22724 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
22725 block
= c_end_compound_stmt (loc
, block
, true);
22732 #pragma omp for for-clause[optseq] new-line
22736 #pragma omp for simd for-simd-clause[optseq] new-line
22739 LOC is the location of the #pragma token.
22742 #define OMP_FOR_CLAUSE_MASK \
22743 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22745 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22746 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
22747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
22749 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
22750 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22751 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
22752 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22753 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22756 c_parser_omp_for (location_t loc
, c_parser
*parser
,
22757 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22760 tree block
, clauses
, ret
;
22762 strcat (p_name
, " for");
22763 mask
|= OMP_FOR_CLAUSE_MASK
;
22764 /* parallel for{, simd} disallows nowait clause, but for
22765 target {teams distribute ,}parallel for{, simd} it should be accepted. */
22766 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
22767 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
22768 /* Composite distribute parallel for{, simd} disallows ordered clause. */
22769 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
22770 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
22772 if (c_parser_next_token_is (parser
, CPP_NAME
))
22774 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22776 if (strcmp (p
, "simd") == 0)
22778 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22779 if (cclauses
== NULL
)
22780 cclauses
= cclauses_buf
;
22782 c_parser_consume_token (parser
);
22783 if (!flag_openmp
) /* flag_openmp_simd */
22784 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
22786 block
= c_begin_compound_stmt (true);
22787 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
22788 block
= c_end_compound_stmt (loc
, block
, true);
22789 if (ret
== NULL_TREE
)
22791 ret
= make_node (OMP_FOR
);
22792 TREE_TYPE (ret
) = void_type_node
;
22793 OMP_FOR_BODY (ret
) = block
;
22794 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
22795 SET_EXPR_LOCATION (ret
, loc
);
22800 if (!flag_openmp
) /* flag_openmp_simd */
22802 c_parser_skip_to_pragma_eol (parser
, false);
22806 /* Composite distribute parallel for disallows linear clause. */
22807 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
22808 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
22810 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22813 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
22814 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
22817 block
= c_begin_compound_stmt (true);
22818 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
22819 block
= c_end_compound_stmt (loc
, block
, true);
22825 static tree
c_parser_omp_taskloop (location_t
, c_parser
*, char *,
22826 omp_clause_mask
, tree
*, bool *);
22829 # pragma omp master new-line
22832 LOC is the location of the #pragma token.
22836 c_parser_omp_master (location_t loc
, c_parser
*parser
,
22837 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22840 tree block
, clauses
, ret
;
22842 strcat (p_name
, " master");
22844 if (c_parser_next_token_is (parser
, CPP_NAME
))
22846 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22848 if (strcmp (p
, "taskloop") == 0)
22850 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22851 if (cclauses
== NULL
)
22852 cclauses
= cclauses_buf
;
22854 c_parser_consume_token (parser
);
22855 if (!flag_openmp
) /* flag_openmp_simd */
22856 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
22858 block
= c_begin_compound_stmt (true);
22859 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
22861 block
= c_end_compound_stmt (loc
, block
, true);
22862 if (ret
== NULL_TREE
)
22864 ret
= c_finish_omp_master (loc
, block
);
22865 OMP_MASTER_COMBINED (ret
) = 1;
22869 if (!flag_openmp
) /* flag_openmp_simd */
22871 c_parser_skip_to_pragma_eol (parser
, false);
22877 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, false);
22878 omp_split_clauses (loc
, OMP_MASTER
, mask
, clauses
, cclauses
);
22881 c_parser_skip_to_pragma_eol (parser
);
22883 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
22888 # pragma omp masked masked-clauses new-line
22891 LOC is the location of the #pragma token.
22894 #define OMP_MASKED_CLAUSE_MASK \
22895 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
22898 c_parser_omp_masked (location_t loc
, c_parser
*parser
,
22899 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22902 tree block
, clauses
, ret
;
22904 strcat (p_name
, " masked");
22905 mask
|= OMP_MASKED_CLAUSE_MASK
;
22907 if (c_parser_next_token_is (parser
, CPP_NAME
))
22909 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22911 if (strcmp (p
, "taskloop") == 0)
22913 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22914 if (cclauses
== NULL
)
22915 cclauses
= cclauses_buf
;
22917 c_parser_consume_token (parser
);
22918 if (!flag_openmp
) /* flag_openmp_simd */
22919 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
22921 block
= c_begin_compound_stmt (true);
22922 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
22924 block
= c_end_compound_stmt (loc
, block
, true);
22925 if (ret
== NULL_TREE
)
22927 ret
= c_finish_omp_masked (loc
, block
,
22928 cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
]);
22929 OMP_MASKED_COMBINED (ret
) = 1;
22933 if (!flag_openmp
) /* flag_openmp_simd */
22935 c_parser_skip_to_pragma_eol (parser
, false);
22939 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22942 omp_split_clauses (loc
, OMP_MASKED
, mask
, clauses
, cclauses
);
22943 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
];
22946 return c_finish_omp_masked (loc
, c_parser_omp_structured_block (parser
,
22952 # pragma omp ordered new-line
22956 # pragma omp ordered ordered-clauses new-line
22959 # pragma omp ordered depend-clauses new-line
22962 # pragma omp ordered doacross-clauses new-line */
22964 #define OMP_ORDERED_CLAUSE_MASK \
22965 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
22966 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
22968 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
22969 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
22970 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
22973 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
22976 location_t loc
= c_parser_peek_token (parser
)->location
;
22977 c_parser_consume_pragma (parser
);
22979 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
22981 c_parser_error (parser
, "expected declaration specifiers");
22982 c_parser_skip_to_pragma_eol (parser
, false);
22987 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22990 if (c_parser_peek_nth_token (parser
, n
)->type
== CPP_NAME
)
22993 = IDENTIFIER_POINTER (c_parser_peek_nth_token (parser
, n
)->value
);
22995 if (!strcmp ("depend", p
) || !strcmp ("doacross", p
))
22997 if (!flag_openmp
) /* flag_openmp_simd */
22999 c_parser_skip_to_pragma_eol (parser
, false);
23002 if (context
== pragma_stmt
)
23005 "%<#pragma omp ordered%> with %qs clause may "
23006 "only be used in compound statements", p
);
23007 c_parser_skip_to_pragma_eol (parser
, false);
23012 = c_parser_omp_all_clauses (parser
,
23013 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
23014 "#pragma omp ordered");
23015 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
23020 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
23021 "#pragma omp ordered");
23023 if (!flag_openmp
/* flag_openmp_simd */
23024 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
23027 c_finish_omp_ordered (loc
, clauses
,
23028 c_parser_omp_structured_block (parser
, if_p
));
23035 { section-sequence }
23038 section-directive[opt] structured-block
23039 section-sequence section-directive structured-block
23041 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
23043 SECTIONS_LOC is the location of the #pragma omp sections. */
23046 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
23048 tree stmt
, substmt
;
23049 bool error_suppress
= false;
23052 loc
= c_parser_peek_token (parser
)->location
;
23053 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
23055 /* Avoid skipping until the end of the block. */
23056 parser
->error
= false;
23060 stmt
= push_stmt_list ();
23062 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
23063 && !c_parser_omp_section_scan (parser
, "section", true))
23065 substmt
= c_parser_omp_structured_block_sequence (parser
,
23066 PRAGMA_OMP_SECTION
);
23067 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
23068 SET_EXPR_LOCATION (substmt
, loc
);
23069 add_stmt (substmt
);
23074 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
23076 if (c_parser_next_token_is (parser
, CPP_EOF
))
23079 loc
= c_parser_peek_token (parser
)->location
;
23080 c_parser_omp_section_scan (parser
, "section", false);
23081 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
23083 c_parser_consume_pragma (parser
);
23084 c_parser_skip_to_pragma_eol (parser
);
23085 error_suppress
= false;
23087 else if (!error_suppress
)
23089 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
23090 error_suppress
= true;
23093 substmt
= c_parser_omp_structured_block_sequence (parser
,
23094 PRAGMA_OMP_SECTION
);
23095 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
23096 SET_EXPR_LOCATION (substmt
, loc
);
23097 add_stmt (substmt
);
23099 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
23100 "expected %<#pragma omp section%> or %<}%>");
23102 substmt
= pop_stmt_list (stmt
);
23104 stmt
= make_node (OMP_SECTIONS
);
23105 SET_EXPR_LOCATION (stmt
, sections_loc
);
23106 TREE_TYPE (stmt
) = void_type_node
;
23107 OMP_SECTIONS_BODY (stmt
) = substmt
;
23109 return add_stmt (stmt
);
23113 # pragma omp sections sections-clause[optseq] newline
23116 LOC is the location of the #pragma token.
23119 #define OMP_SECTIONS_CLAUSE_MASK \
23120 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23121 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23122 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23123 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23124 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23125 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23128 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
23129 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
23131 tree block
, clauses
, ret
;
23133 strcat (p_name
, " sections");
23134 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
23136 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
23138 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23141 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
23142 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
23145 block
= c_begin_compound_stmt (true);
23146 ret
= c_parser_omp_sections_scope (loc
, parser
);
23148 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
23149 block
= c_end_compound_stmt (loc
, block
, true);
23156 # pragma omp parallel parallel-clause[optseq] new-line
23158 # pragma omp parallel for parallel-for-clause[optseq] new-line
23160 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
23164 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
23167 LOC is the location of the #pragma token.
23170 #define OMP_PARALLEL_CLAUSE_MASK \
23171 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23172 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23173 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23174 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23175 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23176 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
23177 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23178 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
23179 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23180 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
23183 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
23184 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23187 tree stmt
, clauses
, block
;
23189 strcat (p_name
, " parallel");
23190 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
23191 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
23192 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
23193 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
23194 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
23196 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
23198 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23199 if (cclauses
== NULL
)
23200 cclauses
= cclauses_buf
;
23202 c_parser_consume_token (parser
);
23203 if (!flag_openmp
) /* flag_openmp_simd */
23204 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
23205 block
= c_begin_omp_parallel ();
23206 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
23208 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23210 if (ret
== NULL_TREE
)
23212 OMP_PARALLEL_COMBINED (stmt
) = 1;
23215 /* When combined with distribute, parallel has to be followed by for.
23216 #pragma omp target parallel is allowed though. */
23218 && (mask
& (OMP_CLAUSE_MASK_1
23219 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
23221 error_at (loc
, "expected %<for%> after %qs", p_name
);
23222 c_parser_skip_to_pragma_eol (parser
);
23225 else if (c_parser_next_token_is (parser
, CPP_NAME
))
23227 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23228 if (cclauses
== NULL
&& strcmp (p
, "masked") == 0)
23230 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23231 cclauses
= cclauses_buf
;
23233 c_parser_consume_token (parser
);
23234 if (!flag_openmp
) /* flag_openmp_simd */
23235 return c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
23237 block
= c_begin_omp_parallel ();
23238 tree ret
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
23240 stmt
= c_finish_omp_parallel (loc
,
23241 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23245 /* masked does have just filter clause, but during gimplification
23246 isn't represented by a gimplification omp context, so for
23247 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
23249 #pragma omp parallel masked
23250 #pragma omp taskloop simd lastprivate (x)
23251 isn't confused with
23252 #pragma omp parallel masked taskloop simd lastprivate (x) */
23253 if (OMP_MASKED_COMBINED (ret
))
23254 OMP_PARALLEL_COMBINED (stmt
) = 1;
23257 else if (cclauses
== NULL
&& strcmp (p
, "master") == 0)
23259 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23260 cclauses
= cclauses_buf
;
23262 c_parser_consume_token (parser
);
23263 if (!flag_openmp
) /* flag_openmp_simd */
23264 return c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
23266 block
= c_begin_omp_parallel ();
23267 tree ret
= c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
23269 stmt
= c_finish_omp_parallel (loc
,
23270 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23274 /* master doesn't have any clauses and during gimplification
23275 isn't represented by a gimplification omp context, so for
23276 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
23278 #pragma omp parallel master
23279 #pragma omp taskloop simd lastprivate (x)
23280 isn't confused with
23281 #pragma omp parallel master taskloop simd lastprivate (x) */
23282 if (OMP_MASTER_COMBINED (ret
))
23283 OMP_PARALLEL_COMBINED (stmt
) = 1;
23286 else if (strcmp (p
, "loop") == 0)
23288 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23289 if (cclauses
== NULL
)
23290 cclauses
= cclauses_buf
;
23292 c_parser_consume_token (parser
);
23293 if (!flag_openmp
) /* flag_openmp_simd */
23294 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
23296 block
= c_begin_omp_parallel ();
23297 tree ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
23300 = c_finish_omp_parallel (loc
,
23301 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23303 if (ret
== NULL_TREE
)
23305 OMP_PARALLEL_COMBINED (stmt
) = 1;
23308 else if (!flag_openmp
) /* flag_openmp_simd */
23310 c_parser_skip_to_pragma_eol (parser
, false);
23313 else if (cclauses
== NULL
&& strcmp (p
, "sections") == 0)
23315 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23316 cclauses
= cclauses_buf
;
23318 c_parser_consume_token (parser
);
23319 block
= c_begin_omp_parallel ();
23320 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
23321 stmt
= c_finish_omp_parallel (loc
,
23322 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23324 OMP_PARALLEL_COMBINED (stmt
) = 1;
23328 else if (!flag_openmp
) /* flag_openmp_simd */
23330 c_parser_skip_to_pragma_eol (parser
, false);
23334 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23337 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
23338 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
23341 block
= c_begin_omp_parallel ();
23342 parser
->omp_attrs_forbidden_p
= true;
23343 c_parser_statement (parser
, if_p
);
23344 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
23350 # pragma omp single single-clause[optseq] new-line
23353 LOC is the location of the #pragma.
23356 #define OMP_SINGLE_CLAUSE_MASK \
23357 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23358 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23359 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
23360 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23361 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23364 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
23366 tree stmt
= make_node (OMP_SINGLE
);
23367 SET_EXPR_LOCATION (stmt
, loc
);
23368 TREE_TYPE (stmt
) = void_type_node
;
23370 OMP_SINGLE_CLAUSES (stmt
)
23371 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
23372 "#pragma omp single");
23373 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
23375 return add_stmt (stmt
);
23379 # pragma omp scope scope-clause[optseq] new-line
23382 LOC is the location of the #pragma.
23385 #define OMP_SCOPE_CLAUSE_MASK \
23386 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23387 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23388 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23389 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23390 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23393 c_parser_omp_scope (location_t loc
, c_parser
*parser
, bool *if_p
)
23395 tree stmt
= make_node (OMP_SCOPE
);
23396 SET_EXPR_LOCATION (stmt
, loc
);
23397 TREE_TYPE (stmt
) = void_type_node
;
23399 OMP_SCOPE_CLAUSES (stmt
)
23400 = c_parser_omp_all_clauses (parser
, OMP_SCOPE_CLAUSE_MASK
,
23401 "#pragma omp scope");
23402 OMP_SCOPE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
23404 return add_stmt (stmt
);
23408 # pragma omp task task-clause[optseq] new-line
23410 LOC is the location of the #pragma.
23413 #define OMP_TASK_CLAUSE_MASK \
23414 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23415 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
23416 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23417 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23418 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23419 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23420 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
23421 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
23422 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23423 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
23424 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23425 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
23426 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
23427 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
23430 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
23432 tree clauses
, block
;
23434 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
23435 "#pragma omp task");
23437 block
= c_begin_omp_task ();
23438 parser
->omp_attrs_forbidden_p
= true;
23439 c_parser_statement (parser
, if_p
);
23440 return c_finish_omp_task (loc
, clauses
, block
);
23444 # pragma omp taskwait new-line
23447 # pragma omp taskwait taskwait-clause[optseq] new-line
23450 #define OMP_TASKWAIT_CLAUSE_MASK \
23451 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23452 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23455 c_parser_omp_taskwait (c_parser
*parser
)
23457 location_t loc
= c_parser_peek_token (parser
)->location
;
23458 c_parser_consume_pragma (parser
);
23461 = c_parser_omp_all_clauses (parser
, OMP_TASKWAIT_CLAUSE_MASK
,
23462 "#pragma omp taskwait");
23466 tree stmt
= make_node (OMP_TASK
);
23467 TREE_TYPE (stmt
) = void_node
;
23468 OMP_TASK_CLAUSES (stmt
) = clauses
;
23469 OMP_TASK_BODY (stmt
) = NULL_TREE
;
23470 SET_EXPR_LOCATION (stmt
, loc
);
23474 c_finish_omp_taskwait (loc
);
23478 # pragma omp taskyield new-line
23482 c_parser_omp_taskyield (c_parser
*parser
)
23484 location_t loc
= c_parser_peek_token (parser
)->location
;
23485 c_parser_consume_pragma (parser
);
23486 c_parser_skip_to_pragma_eol (parser
);
23488 c_finish_omp_taskyield (loc
);
23492 # pragma omp taskgroup new-line
23495 # pragma omp taskgroup taskgroup-clause[optseq] new-line
23498 #define OMP_TASKGROUP_CLAUSE_MASK \
23499 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23500 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
23503 c_parser_omp_taskgroup (location_t loc
, c_parser
*parser
, bool *if_p
)
23505 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_TASKGROUP_CLAUSE_MASK
,
23506 "#pragma omp taskgroup");
23508 tree body
= c_parser_omp_structured_block (parser
, if_p
);
23509 return c_finish_omp_taskgroup (loc
, body
, clauses
);
23513 # pragma omp cancel cancel-clause[optseq] new-line
23515 LOC is the location of the #pragma.
23518 #define OMP_CANCEL_CLAUSE_MASK \
23519 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23520 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23521 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23522 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
23523 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
23526 c_parser_omp_cancel (c_parser
*parser
)
23528 location_t loc
= c_parser_peek_token (parser
)->location
;
23530 c_parser_consume_pragma (parser
);
23531 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
23532 "#pragma omp cancel");
23534 c_finish_omp_cancel (loc
, clauses
);
23538 # pragma omp cancellation point cancelpt-clause[optseq] new-line
23540 LOC is the location of the #pragma.
23543 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
23544 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
23550 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
23552 location_t loc
= c_parser_peek_token (parser
)->location
;
23554 bool point_seen
= false;
23556 c_parser_consume_pragma (parser
);
23557 if (c_parser_next_token_is (parser
, CPP_NAME
))
23559 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23560 if (strcmp (p
, "point") == 0)
23562 c_parser_consume_token (parser
);
23568 c_parser_error (parser
, "expected %<point%>");
23569 c_parser_skip_to_pragma_eol (parser
);
23573 if (context
!= pragma_compound
)
23575 if (context
== pragma_stmt
)
23577 "%<#pragma %s%> may only be used in compound statements",
23578 "omp cancellation point");
23580 c_parser_error (parser
, "expected declaration specifiers");
23581 c_parser_skip_to_pragma_eol (parser
, false);
23586 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
23587 "#pragma omp cancellation point");
23589 c_finish_omp_cancellation_point (loc
, clauses
);
23594 #pragma omp distribute distribute-clause[optseq] new-line
23597 #define OMP_DISTRIBUTE_CLAUSE_MASK \
23598 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23599 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23600 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23601 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
23602 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23603 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23604 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
23607 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
23608 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23611 tree clauses
, block
, ret
;
23613 strcat (p_name
, " distribute");
23614 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
23616 if (c_parser_next_token_is (parser
, CPP_NAME
))
23618 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23620 bool parallel
= false;
23622 if (strcmp (p
, "simd") == 0)
23625 parallel
= strcmp (p
, "parallel") == 0;
23626 if (parallel
|| simd
)
23628 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23629 if (cclauses
== NULL
)
23630 cclauses
= cclauses_buf
;
23631 c_parser_consume_token (parser
);
23632 if (!flag_openmp
) /* flag_openmp_simd */
23635 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
23638 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
23641 block
= c_begin_compound_stmt (true);
23643 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
23646 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
23648 block
= c_end_compound_stmt (loc
, block
, true);
23651 ret
= make_node (OMP_DISTRIBUTE
);
23652 TREE_TYPE (ret
) = void_type_node
;
23653 OMP_FOR_BODY (ret
) = block
;
23654 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
23655 SET_EXPR_LOCATION (ret
, loc
);
23660 if (!flag_openmp
) /* flag_openmp_simd */
23662 c_parser_skip_to_pragma_eol (parser
, false);
23666 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23669 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
23670 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
23673 block
= c_begin_compound_stmt (true);
23674 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
23676 block
= c_end_compound_stmt (loc
, block
, true);
23683 # pragma omp teams teams-clause[optseq] new-line
23684 structured-block */
23686 #define OMP_TEAMS_CLAUSE_MASK \
23687 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23688 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23689 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23690 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23691 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
23692 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
23693 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23694 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
23697 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
23698 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23701 tree clauses
, block
, ret
;
23703 strcat (p_name
, " teams");
23704 mask
|= OMP_TEAMS_CLAUSE_MASK
;
23706 if (c_parser_next_token_is (parser
, CPP_NAME
))
23708 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23709 if (strcmp (p
, "distribute") == 0)
23711 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23712 if (cclauses
== NULL
)
23713 cclauses
= cclauses_buf
;
23715 c_parser_consume_token (parser
);
23716 if (!flag_openmp
) /* flag_openmp_simd */
23717 return c_parser_omp_distribute (loc
, parser
, p_name
, mask
,
23719 block
= c_begin_omp_parallel ();
23720 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
23722 block
= c_end_compound_stmt (loc
, block
, true);
23725 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
23726 ret
= make_node (OMP_TEAMS
);
23727 TREE_TYPE (ret
) = void_type_node
;
23728 OMP_TEAMS_CLAUSES (ret
) = clauses
;
23729 OMP_TEAMS_BODY (ret
) = block
;
23730 OMP_TEAMS_COMBINED (ret
) = 1;
23731 SET_EXPR_LOCATION (ret
, loc
);
23732 return add_stmt (ret
);
23734 else if (strcmp (p
, "loop") == 0)
23736 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23737 if (cclauses
== NULL
)
23738 cclauses
= cclauses_buf
;
23740 c_parser_consume_token (parser
);
23741 if (!flag_openmp
) /* flag_openmp_simd */
23742 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
23744 block
= c_begin_omp_parallel ();
23745 ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
23746 block
= c_end_compound_stmt (loc
, block
, true);
23749 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
23750 ret
= make_node (OMP_TEAMS
);
23751 TREE_TYPE (ret
) = void_type_node
;
23752 OMP_TEAMS_CLAUSES (ret
) = clauses
;
23753 OMP_TEAMS_BODY (ret
) = block
;
23754 OMP_TEAMS_COMBINED (ret
) = 1;
23755 SET_EXPR_LOCATION (ret
, loc
);
23756 return add_stmt (ret
);
23759 if (!flag_openmp
) /* flag_openmp_simd */
23761 c_parser_skip_to_pragma_eol (parser
, false);
23765 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23768 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
23769 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
23772 tree stmt
= make_node (OMP_TEAMS
);
23773 TREE_TYPE (stmt
) = void_type_node
;
23774 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
23775 block
= c_begin_omp_parallel ();
23776 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
23777 OMP_TEAMS_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
23778 SET_EXPR_LOCATION (stmt
, loc
);
23780 return add_stmt (stmt
);
23784 # pragma omp target data target-data-clause[optseq] new-line
23785 structured-block */
23787 #define OMP_TARGET_DATA_CLAUSE_MASK \
23788 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23789 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
23790 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23791 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
23792 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
23795 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
23799 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
23802 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
23803 "#pragma omp target data");
23804 c_omp_adjust_map_clauses (clauses
, false);
23806 for (tree
*pc
= &clauses
; *pc
;)
23808 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
23809 switch (OMP_CLAUSE_MAP_KIND (*pc
))
23812 case GOMP_MAP_ALWAYS_TO
:
23813 case GOMP_MAP_PRESENT_TO
:
23814 case GOMP_MAP_ALWAYS_PRESENT_TO
:
23815 case GOMP_MAP_FROM
:
23816 case GOMP_MAP_ALWAYS_FROM
:
23817 case GOMP_MAP_PRESENT_FROM
:
23818 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
23819 case GOMP_MAP_TOFROM
:
23820 case GOMP_MAP_ALWAYS_TOFROM
:
23821 case GOMP_MAP_PRESENT_TOFROM
:
23822 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
23823 case GOMP_MAP_ALLOC
:
23824 case GOMP_MAP_PRESENT_ALLOC
:
23827 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
23828 case GOMP_MAP_ALWAYS_POINTER
:
23829 case GOMP_MAP_ATTACH_DETACH
:
23830 case GOMP_MAP_ATTACH
:
23834 error_at (OMP_CLAUSE_LOCATION (*pc
),
23835 "%<#pragma omp target data%> with map-type other "
23836 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
23837 "on %<map%> clause");
23838 *pc
= OMP_CLAUSE_CHAIN (*pc
);
23841 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
23842 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
23844 pc
= &OMP_CLAUSE_CHAIN (*pc
);
23851 "%<#pragma omp target data%> must contain at least "
23852 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
23857 tree stmt
= make_node (OMP_TARGET_DATA
);
23858 TREE_TYPE (stmt
) = void_type_node
;
23859 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
23860 keep_next_level ();
23861 tree block
= c_begin_compound_stmt (true);
23862 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
23863 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
23865 SET_EXPR_LOCATION (stmt
, loc
);
23866 return add_stmt (stmt
);
23870 # pragma omp target update target-update-clause[optseq] new-line */
23872 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
23873 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
23874 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
23875 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23876 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23877 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23878 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23881 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
23882 enum pragma_context context
)
23884 if (context
== pragma_stmt
)
23886 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
23887 "omp target update");
23888 c_parser_skip_to_pragma_eol (parser
, false);
23893 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
23894 "#pragma omp target update");
23895 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
23896 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
23899 "%<#pragma omp target update%> must contain at least one "
23900 "%<from%> or %<to%> clauses");
23906 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
23908 tree stmt
= make_node (OMP_TARGET_UPDATE
);
23909 TREE_TYPE (stmt
) = void_type_node
;
23910 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
23911 SET_EXPR_LOCATION (stmt
, loc
);
23917 # pragma omp target enter data target-data-clause[optseq] new-line */
23919 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
23920 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23921 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
23922 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23923 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23924 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23927 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
23928 enum pragma_context context
)
23930 bool data_seen
= false;
23931 if (c_parser_next_token_is (parser
, CPP_NAME
))
23933 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23934 if (strcmp (p
, "data") == 0)
23936 c_parser_consume_token (parser
);
23942 c_parser_error (parser
, "expected %<data%>");
23943 c_parser_skip_to_pragma_eol (parser
);
23947 if (context
== pragma_stmt
)
23949 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
23950 "omp target enter data");
23951 c_parser_skip_to_pragma_eol (parser
, false);
23957 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
23960 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
23961 "#pragma omp target enter data");
23962 c_omp_adjust_map_clauses (clauses
, false);
23964 for (tree
*pc
= &clauses
; *pc
;)
23966 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
23967 switch (OMP_CLAUSE_MAP_KIND (*pc
))
23970 case GOMP_MAP_ALWAYS_TO
:
23971 case GOMP_MAP_PRESENT_TO
:
23972 case GOMP_MAP_ALWAYS_PRESENT_TO
:
23973 case GOMP_MAP_ALLOC
:
23974 case GOMP_MAP_PRESENT_ALLOC
:
23977 case GOMP_MAP_TOFROM
:
23978 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_TO
);
23981 case GOMP_MAP_ALWAYS_TOFROM
:
23982 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_TO
);
23985 case GOMP_MAP_PRESENT_TOFROM
:
23986 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_PRESENT_TO
);
23989 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
23990 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_PRESENT_TO
);
23993 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
23994 case GOMP_MAP_ALWAYS_POINTER
:
23995 case GOMP_MAP_ATTACH_DETACH
:
23996 case GOMP_MAP_ATTACH
:
24000 error_at (OMP_CLAUSE_LOCATION (*pc
),
24001 "%<#pragma omp target enter data%> with map-type other "
24002 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
24003 *pc
= OMP_CLAUSE_CHAIN (*pc
);
24006 pc
= &OMP_CLAUSE_CHAIN (*pc
);
24013 "%<#pragma omp target enter data%> must contain at least "
24014 "one %<map%> clause");
24018 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
24019 TREE_TYPE (stmt
) = void_type_node
;
24020 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
24021 SET_EXPR_LOCATION (stmt
, loc
);
24027 # pragma omp target exit data target-data-clause[optseq] new-line */
24029 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
24030 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24031 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24032 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24033 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24034 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
24037 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
24038 enum pragma_context context
)
24040 bool data_seen
= false;
24041 if (c_parser_next_token_is (parser
, CPP_NAME
))
24043 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24044 if (strcmp (p
, "data") == 0)
24046 c_parser_consume_token (parser
);
24052 c_parser_error (parser
, "expected %<data%>");
24053 c_parser_skip_to_pragma_eol (parser
);
24057 if (context
== pragma_stmt
)
24059 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
24060 "omp target exit data");
24061 c_parser_skip_to_pragma_eol (parser
, false);
24067 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
24070 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
24071 "#pragma omp target exit data", false);
24072 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP_EXIT_DATA
);
24073 c_omp_adjust_map_clauses (clauses
, false);
24075 for (tree
*pc
= &clauses
; *pc
;)
24077 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
24078 switch (OMP_CLAUSE_MAP_KIND (*pc
))
24080 case GOMP_MAP_FROM
:
24081 case GOMP_MAP_ALWAYS_FROM
:
24082 case GOMP_MAP_PRESENT_FROM
:
24083 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
24084 case GOMP_MAP_RELEASE
:
24085 case GOMP_MAP_DELETE
:
24088 case GOMP_MAP_TOFROM
:
24089 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_FROM
);
24092 case GOMP_MAP_ALWAYS_TOFROM
:
24093 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_FROM
);
24096 case GOMP_MAP_PRESENT_TOFROM
:
24097 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_PRESENT_FROM
);
24100 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
24101 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_PRESENT_FROM
);
24104 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
24105 case GOMP_MAP_ALWAYS_POINTER
:
24106 case GOMP_MAP_ATTACH_DETACH
:
24107 case GOMP_MAP_DETACH
:
24111 error_at (OMP_CLAUSE_LOCATION (*pc
),
24112 "%<#pragma omp target exit data%> with map-type other "
24113 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
24114 "on %<map%> clause");
24115 *pc
= OMP_CLAUSE_CHAIN (*pc
);
24118 pc
= &OMP_CLAUSE_CHAIN (*pc
);
24125 "%<#pragma omp target exit data%> must contain at least one "
24130 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
24131 TREE_TYPE (stmt
) = void_type_node
;
24132 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
24133 SET_EXPR_LOCATION (stmt
, loc
);
24139 # pragma omp target target-clause[optseq] new-line
24140 structured-block */
24142 #define OMP_TARGET_CLAUSE_MASK \
24143 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24144 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24145 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24146 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24147 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
24148 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
24149 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
24150 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
24151 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
24152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
24153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
24154 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
24155 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
24158 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
24160 location_t loc
= c_parser_peek_token (parser
)->location
;
24161 c_parser_consume_pragma (parser
);
24162 tree
*pc
= NULL
, stmt
, block
;
24164 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
24166 c_parser_error (parser
, "expected declaration specifiers");
24167 c_parser_skip_to_pragma_eol (parser
);
24173 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
24175 if (c_parser_next_token_is (parser
, CPP_NAME
))
24177 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24178 enum tree_code ccode
= ERROR_MARK
;
24180 if (strcmp (p
, "teams") == 0)
24182 else if (strcmp (p
, "parallel") == 0)
24183 ccode
= OMP_PARALLEL
;
24184 else if (strcmp (p
, "simd") == 0)
24186 if (ccode
!= ERROR_MARK
)
24188 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
24189 char p_name
[sizeof ("#pragma omp target teams distribute "
24190 "parallel for simd")];
24192 c_parser_consume_token (parser
);
24193 strcpy (p_name
, "#pragma omp target");
24194 if (!flag_openmp
) /* flag_openmp_simd */
24200 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
24201 OMP_TARGET_CLAUSE_MASK
,
24205 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
24206 OMP_TARGET_CLAUSE_MASK
,
24210 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
24211 OMP_TARGET_CLAUSE_MASK
,
24215 gcc_unreachable ();
24217 return stmt
!= NULL_TREE
;
24219 keep_next_level ();
24220 tree block
= c_begin_compound_stmt (true), ret
;
24224 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
24225 OMP_TARGET_CLAUSE_MASK
, cclauses
,
24229 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
24230 OMP_TARGET_CLAUSE_MASK
, cclauses
,
24234 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
24235 OMP_TARGET_CLAUSE_MASK
, cclauses
,
24239 gcc_unreachable ();
24241 block
= c_end_compound_stmt (loc
, block
, true);
24242 if (ret
== NULL_TREE
)
24244 if (ccode
== OMP_TEAMS
)
24245 /* For combined target teams, ensure the num_teams and
24246 thread_limit clause expressions are evaluated on the host,
24247 before entering the target construct. */
24248 for (tree c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
24249 c
; c
= OMP_CLAUSE_CHAIN (c
))
24250 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
24251 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
24253 i
<= (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
); ++i
)
24254 if (OMP_CLAUSE_OPERAND (c
, i
)
24255 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, i
)) != INTEGER_CST
)
24257 tree expr
= OMP_CLAUSE_OPERAND (c
, i
);
24258 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
24259 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
24260 expr
, NULL_TREE
, NULL_TREE
);
24262 OMP_CLAUSE_OPERAND (c
, i
) = expr
;
24263 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
24264 OMP_CLAUSE_FIRSTPRIVATE
);
24265 OMP_CLAUSE_DECL (tc
) = tmp
;
24266 OMP_CLAUSE_CHAIN (tc
)
24267 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
24268 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
24270 tree stmt
= make_node (OMP_TARGET
);
24271 TREE_TYPE (stmt
) = void_type_node
;
24272 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
24273 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
24274 OMP_TARGET_BODY (stmt
) = block
;
24275 OMP_TARGET_COMBINED (stmt
) = 1;
24276 SET_EXPR_LOCATION (stmt
, loc
);
24278 pc
= &OMP_TARGET_CLAUSES (stmt
);
24279 goto check_clauses
;
24281 else if (!flag_openmp
) /* flag_openmp_simd */
24283 c_parser_skip_to_pragma_eol (parser
, false);
24286 else if (strcmp (p
, "data") == 0)
24288 c_parser_consume_token (parser
);
24289 c_parser_omp_target_data (loc
, parser
, if_p
);
24292 else if (strcmp (p
, "enter") == 0)
24294 c_parser_consume_token (parser
);
24295 return c_parser_omp_target_enter_data (loc
, parser
, context
);
24297 else if (strcmp (p
, "exit") == 0)
24299 c_parser_consume_token (parser
);
24300 return c_parser_omp_target_exit_data (loc
, parser
, context
);
24302 else if (strcmp (p
, "update") == 0)
24304 c_parser_consume_token (parser
);
24305 return c_parser_omp_target_update (loc
, parser
, context
);
24308 if (!flag_openmp
) /* flag_openmp_simd */
24310 c_parser_skip_to_pragma_eol (parser
, false);
24314 stmt
= make_node (OMP_TARGET
);
24315 TREE_TYPE (stmt
) = void_type_node
;
24317 OMP_TARGET_CLAUSES (stmt
)
24318 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
24319 "#pragma omp target", false);
24320 for (tree c
= OMP_TARGET_CLAUSES (stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
24321 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
)
24323 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
24324 OMP_CLAUSE_DECL (nc
) = OMP_CLAUSE_DECL (c
);
24325 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_ALWAYS_TOFROM
);
24326 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
24327 OMP_CLAUSE_CHAIN (c
) = nc
;
24329 OMP_TARGET_CLAUSES (stmt
)
24330 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt
), C_ORT_OMP_TARGET
);
24331 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
24333 pc
= &OMP_TARGET_CLAUSES (stmt
);
24334 keep_next_level ();
24335 block
= c_begin_compound_stmt (true);
24336 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
24337 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
24339 SET_EXPR_LOCATION (stmt
, loc
);
24345 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
24346 switch (OMP_CLAUSE_MAP_KIND (*pc
))
24349 case GOMP_MAP_ALWAYS_TO
:
24350 case GOMP_MAP_PRESENT_TO
:
24351 case GOMP_MAP_ALWAYS_PRESENT_TO
:
24352 case GOMP_MAP_FROM
:
24353 case GOMP_MAP_ALWAYS_FROM
:
24354 case GOMP_MAP_PRESENT_FROM
:
24355 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
24356 case GOMP_MAP_TOFROM
:
24357 case GOMP_MAP_ALWAYS_TOFROM
:
24358 case GOMP_MAP_PRESENT_TOFROM
:
24359 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
24360 case GOMP_MAP_ALLOC
:
24361 case GOMP_MAP_PRESENT_ALLOC
:
24362 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
24363 case GOMP_MAP_ALWAYS_POINTER
:
24364 case GOMP_MAP_POINTER
:
24365 case GOMP_MAP_ATTACH_DETACH
:
24366 case GOMP_MAP_ATTACH
:
24369 error_at (OMP_CLAUSE_LOCATION (*pc
),
24370 "%<#pragma omp target%> with map-type other "
24371 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
24372 "on %<map%> clause");
24373 *pc
= OMP_CLAUSE_CHAIN (*pc
);
24376 pc
= &OMP_CLAUSE_CHAIN (*pc
);
24378 cfun
->has_omp_target
= true;
24383 # pragma omp declare simd declare-simd-clauses[optseq] new-line
24386 # pragma omp declare variant (identifier) match(context-selector) new-line
24389 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
24390 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
24391 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
24392 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
24393 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
24394 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
24395 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
24398 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
24400 c_token
*token
= c_parser_peek_token (parser
);
24401 gcc_assert (token
->type
== CPP_NAME
);
24402 tree kind
= token
->value
;
24403 gcc_assert (strcmp (IDENTIFIER_POINTER (kind
), "simd") == 0
24404 || strcmp (IDENTIFIER_POINTER (kind
), "variant") == 0);
24406 auto_vec
<c_token
> clauses
;
24407 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
24409 c_token
*token
= c_parser_peek_token (parser
);
24410 if (token
->type
== CPP_EOF
)
24412 c_parser_skip_to_pragma_eol (parser
);
24415 clauses
.safe_push (*token
);
24416 c_parser_consume_token (parser
);
24418 clauses
.safe_push (*c_parser_peek_token (parser
));
24419 c_parser_skip_to_pragma_eol (parser
);
24421 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
24423 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_DECLARE
24424 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
24425 || c_parser_peek_2nd_token (parser
)->value
!= kind
)
24427 error ("%<#pragma omp declare %s%> must be followed by "
24428 "function declaration or definition or another "
24429 "%<#pragma omp declare %s%>",
24430 IDENTIFIER_POINTER (kind
), IDENTIFIER_POINTER (kind
));
24433 c_parser_consume_pragma (parser
);
24434 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
24436 c_token
*token
= c_parser_peek_token (parser
);
24437 if (token
->type
== CPP_EOF
)
24439 c_parser_skip_to_pragma_eol (parser
);
24442 clauses
.safe_push (*token
);
24443 c_parser_consume_token (parser
);
24445 clauses
.safe_push (*c_parser_peek_token (parser
));
24446 c_parser_skip_to_pragma_eol (parser
);
24449 /* Make sure nothing tries to read past the end of the tokens. */
24451 memset (&eof_token
, 0, sizeof (eof_token
));
24452 eof_token
.type
= CPP_EOF
;
24453 clauses
.safe_push (eof_token
);
24454 clauses
.safe_push (eof_token
);
24458 case pragma_external
:
24459 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24460 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
24462 int ext
= disable_extension_diagnostics ();
24464 c_parser_consume_token (parser
);
24465 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24466 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
24467 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
24469 restore_extension_diagnostics (ext
);
24472 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
24475 case pragma_struct
:
24478 error ("%<#pragma omp declare %s%> must be followed by "
24479 "function declaration or definition",
24480 IDENTIFIER_POINTER (kind
));
24482 case pragma_compound
:
24483 bool have_std_attrs
;
24485 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
24486 if (have_std_attrs
)
24487 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
24489 std_attrs
= NULL_TREE
;
24490 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24491 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
24493 int ext
= disable_extension_diagnostics ();
24495 c_parser_consume_token (parser
);
24496 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24497 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
24498 if (c_parser_next_tokens_start_declaration (parser
)
24499 || c_parser_nth_token_starts_std_attributes (parser
, 1))
24501 c_parser_declaration_or_fndef (parser
, true, true, true, true,
24502 true, NULL
, &clauses
,
24503 have_std_attrs
, std_attrs
);
24504 restore_extension_diagnostics (ext
);
24507 restore_extension_diagnostics (ext
);
24509 else if (c_parser_next_tokens_start_declaration (parser
))
24511 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
24512 NULL
, &clauses
, have_std_attrs
,
24516 error ("%<#pragma omp declare %s%> must be followed by "
24517 "function declaration or definition",
24518 IDENTIFIER_POINTER (kind
));
24521 gcc_unreachable ();
24528 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
24531 score(score-expression)
24533 Note that this function returns a list of trait selectors for the
24534 trait-selector-set SET. */
24537 c_parser_omp_context_selector (c_parser
*parser
, enum omp_tss_code set
,
24540 tree ret
= NULL_TREE
;
24544 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24545 || c_parser_next_token_is (parser
, CPP_NAME
))
24546 selector
= c_parser_peek_token (parser
)->value
;
24549 c_parser_error (parser
, "expected trait selector name");
24550 return error_mark_node
;
24552 enum omp_ts_code sel
24553 = omp_lookup_ts_code (set
, IDENTIFIER_POINTER (selector
));
24555 if (sel
== OMP_TRAIT_INVALID
)
24557 /* Per the spec, "Implementations can ignore specified selectors
24558 that are not those described in this section"; however, we
24559 must record such selectors because they cause match failures. */
24560 warning_at (c_parser_peek_token (parser
)->location
, OPT_Wopenmp
,
24561 "unknown selector %qs for context selector set %qs",
24562 IDENTIFIER_POINTER (selector
), omp_tss_map
[set
]);
24563 c_parser_consume_token (parser
);
24564 ret
= make_trait_selector (sel
, NULL_TREE
, NULL_TREE
, ret
);
24565 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
24566 c_parser_balanced_token_sequence (parser
);
24567 if (c_parser_next_token_is (parser
, CPP_COMMA
))
24569 c_parser_consume_token (parser
);
24576 c_parser_consume_token (parser
);
24578 tree properties
= NULL_TREE
;
24579 tree scoreval
= NULL_TREE
;
24580 enum omp_tp_type property_kind
= omp_ts_map
[sel
].tp_type
;
24581 bool allow_score
= omp_ts_map
[sel
].allow_score
;
24584 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
24586 if (property_kind
== OMP_TRAIT_PROPERTY_NONE
)
24588 error_at (c_parser_peek_token (parser
)->location
,
24589 "selector %qs does not accept any properties",
24590 IDENTIFIER_POINTER (selector
));
24591 return error_mark_node
;
24594 matching_parens parens
;
24595 parens
.require_open (parser
);
24597 c_token
*token
= c_parser_peek_token (parser
);
24598 if (c_parser_next_token_is (parser
, CPP_NAME
)
24599 && strcmp (IDENTIFIER_POINTER (token
->value
), "score") == 0
24600 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
24602 c_parser_consume_token (parser
);
24604 matching_parens parens2
;
24605 parens2
.require_open (parser
);
24606 tree score
= c_parser_expr_no_commas (parser
, NULL
).value
;
24607 parens2
.skip_until_found_close (parser
);
24608 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
24610 error_at (token
->location
,
24611 "%<score%> cannot be specified in traits "
24612 "in the %qs trait-selector-set",
24614 else if (score
!= error_mark_node
)
24616 mark_exp_read (score
);
24617 score
= c_fully_fold (score
, false, NULL
);
24618 if (!INTEGRAL_TYPE_P (TREE_TYPE (score
))
24619 || TREE_CODE (score
) != INTEGER_CST
)
24620 error_at (token
->location
, "%<score%> argument must "
24621 "be constant integer expression");
24622 else if (tree_int_cst_sgn (score
) < 0)
24623 error_at (token
->location
, "%<score%> argument must "
24624 "be non-negative");
24628 token
= c_parser_peek_token (parser
);
24631 switch (property_kind
)
24633 case OMP_TRAIT_PROPERTY_ID
:
24634 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24635 || c_parser_next_token_is (parser
, CPP_NAME
))
24637 tree prop
= c_parser_peek_token (parser
)->value
;
24638 c_parser_consume_token (parser
);
24639 properties
= make_trait_property (prop
, NULL_TREE
,
24644 c_parser_error (parser
, "expected identifier");
24645 return error_mark_node
;
24648 case OMP_TRAIT_PROPERTY_NAME_LIST
:
24651 tree prop
= OMP_TP_NAMELIST_NODE
;
24652 tree value
= NULL_TREE
;
24653 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24654 || c_parser_next_token_is (parser
, CPP_NAME
))
24656 value
= c_parser_peek_token (parser
)->value
;
24657 c_parser_consume_token (parser
);
24659 else if (c_parser_next_token_is (parser
, CPP_STRING
))
24660 value
= c_parser_string_literal (parser
, false,
24664 c_parser_error (parser
, "expected identifier or "
24666 return error_mark_node
;
24669 properties
= make_trait_property (prop
, value
, properties
);
24671 if (c_parser_next_token_is (parser
, CPP_COMMA
))
24672 c_parser_consume_token (parser
);
24678 case OMP_TRAIT_PROPERTY_DEV_NUM_EXPR
:
24679 case OMP_TRAIT_PROPERTY_BOOL_EXPR
:
24680 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
24681 if (t
!= error_mark_node
)
24684 t
= c_fully_fold (t
, false, NULL
);
24685 /* FIXME: this is bogus, both device_num and
24686 condition selectors allow arbitrary expressions. */
24687 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
24688 || !tree_fits_shwi_p (t
))
24689 error_at (token
->location
, "property must be "
24690 "constant integer expression");
24692 properties
= make_trait_property (NULL_TREE
, t
,
24696 return error_mark_node
;
24698 case OMP_TRAIT_PROPERTY_CLAUSE_LIST
:
24699 if (sel
== OMP_TRAIT_CONSTRUCT_SIMD
)
24701 if (parms
== NULL_TREE
)
24703 error_at (token
->location
, "properties for %<simd%> "
24704 "selector may not be specified in "
24705 "%<metadirective%>");
24706 return error_mark_node
;
24709 c
= c_parser_omp_all_clauses (parser
,
24710 OMP_DECLARE_SIMD_CLAUSE_MASK
,
24712 c
= c_omp_declare_simd_clauses_to_numbers (parms
24714 ? NULL_TREE
: parms
,
24718 else if (sel
== OMP_TRAIT_IMPLEMENTATION_REQUIRES
)
24720 /* FIXME: The "requires" selector was added in OpenMP 5.1.
24721 Currently only the now-deprecated syntax
24722 from OpenMP 5.0 is supported. */
24723 sorry_at (token
->location
,
24724 "%<requires%> selector is not supported yet");
24725 return error_mark_node
;
24728 gcc_unreachable ();
24731 gcc_unreachable ();
24734 parens
.skip_until_found_close (parser
);
24735 properties
= nreverse (properties
);
24737 else if (property_kind
!= OMP_TRAIT_PROPERTY_NONE
24738 && property_kind
!= OMP_TRAIT_PROPERTY_CLAUSE_LIST
24739 && property_kind
!= OMP_TRAIT_PROPERTY_EXTENSION
)
24741 c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>");
24742 return error_mark_node
;
24745 ret
= make_trait_selector (sel
, scoreval
, properties
, ret
);
24747 if (c_parser_next_token_is (parser
, CPP_COMMA
))
24748 c_parser_consume_token (parser
);
24754 return nreverse (ret
);
24759 trait-set-selector[,trait-set-selector[,...]]
24761 trait-set-selector:
24762 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
24764 trait-set-selector-name:
24771 c_parser_omp_context_selector_specification (c_parser
*parser
, tree parms
)
24773 tree ret
= NULL_TREE
;
24776 const char *setp
= "";
24777 if (c_parser_next_token_is (parser
, CPP_NAME
))
24778 setp
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24779 enum omp_tss_code set
= omp_lookup_tss_code (setp
);
24781 if (set
== OMP_TRAIT_SET_INVALID
)
24783 c_parser_error (parser
, "expected context selector set name");
24784 return error_mark_node
;
24787 c_parser_consume_token (parser
);
24789 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
24790 return error_mark_node
;
24792 matching_braces braces
;
24793 if (!braces
.require_open (parser
))
24794 return error_mark_node
;
24796 tree selectors
= c_parser_omp_context_selector (parser
, set
, parms
);
24797 if (selectors
== error_mark_node
)
24798 ret
= error_mark_node
;
24799 else if (ret
!= error_mark_node
)
24800 ret
= make_trait_set_selector (set
, selectors
, ret
);
24802 braces
.skip_until_found_close (parser
);
24804 if (c_parser_next_token_is (parser
, CPP_COMMA
))
24805 c_parser_consume_token (parser
);
24811 if (ret
== error_mark_node
)
24813 return nreverse (ret
);
24816 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
24817 that into "omp declare variant base" attribute. */
24820 c_finish_omp_declare_variant (c_parser
*parser
, tree fndecl
, tree parms
)
24822 matching_parens parens
;
24823 if (!parens
.require_open (parser
))
24826 c_parser_skip_to_pragma_eol (parser
, false);
24830 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
24831 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
24833 c_parser_error (parser
, "expected identifier");
24837 c_token
*token
= c_parser_peek_token (parser
);
24838 tree variant
= lookup_name (token
->value
);
24840 if (variant
== NULL_TREE
)
24842 undeclared_variable (token
->location
, token
->value
);
24843 variant
= error_mark_node
;
24846 c_parser_consume_token (parser
);
24848 parens
.require_close (parser
);
24850 if (c_parser_next_token_is (parser
, CPP_COMMA
)
24851 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
24852 c_parser_consume_token (parser
);
24854 const char *clause
= "";
24855 location_t match_loc
= c_parser_peek_token (parser
)->location
;
24856 if (c_parser_next_token_is (parser
, CPP_NAME
))
24857 clause
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24858 if (strcmp (clause
, "match"))
24860 c_parser_error (parser
, "expected %<match%>");
24864 c_parser_consume_token (parser
);
24866 if (!parens
.require_open (parser
))
24869 if (parms
== NULL_TREE
)
24870 parms
= error_mark_node
;
24872 tree ctx
= c_parser_omp_context_selector_specification (parser
, parms
);
24873 if (ctx
== error_mark_node
)
24875 ctx
= omp_check_context_selector (match_loc
, ctx
);
24876 if (ctx
!= error_mark_node
&& variant
!= error_mark_node
)
24878 if (TREE_CODE (variant
) != FUNCTION_DECL
)
24880 error_at (token
->location
, "variant %qD is not a function", variant
);
24881 variant
= error_mark_node
;
24883 else if (!omp_get_context_selector (ctx
, OMP_TRAIT_SET_CONSTRUCT
,
24884 OMP_TRAIT_CONSTRUCT_SIMD
)
24885 && !comptypes (TREE_TYPE (fndecl
), TREE_TYPE (variant
)))
24887 error_at (token
->location
, "variant %qD and base %qD have "
24888 "incompatible types", variant
, fndecl
);
24889 variant
= error_mark_node
;
24891 else if (fndecl_built_in_p (variant
)
24892 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
24893 "__builtin_", strlen ("__builtin_")) == 0
24894 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
24895 "__sync_", strlen ("__sync_")) == 0
24896 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
24897 "__atomic_", strlen ("__atomic_")) == 0))
24899 error_at (token
->location
, "variant %qD is a built-in", variant
);
24900 variant
= error_mark_node
;
24902 if (variant
!= error_mark_node
)
24904 C_DECL_USED (variant
) = 1;
24906 = omp_get_context_selector_list (ctx
, OMP_TRAIT_SET_CONSTRUCT
);
24907 omp_mark_declare_variant (match_loc
, variant
, construct
);
24908 if (omp_context_selector_matches (ctx
))
24911 = tree_cons (get_identifier ("omp declare variant base"),
24912 build_tree_list (variant
, ctx
),
24913 DECL_ATTRIBUTES (fndecl
));
24914 DECL_ATTRIBUTES (fndecl
) = attr
;
24919 parens
.require_close (parser
);
24920 c_parser_skip_to_pragma_eol (parser
);
24923 /* Finalize #pragma omp declare simd or #pragma omp declare variant
24924 clauses after FNDECL has been parsed, and put that into "omp declare simd"
24925 or "omp declare variant base" attribute. */
24928 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
24929 vec
<c_token
> *pclauses
)
24931 vec
<c_token
> &clauses
= *pclauses
;
24933 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
24934 indicates error has been reported and CPP_PRAGMA that
24935 c_finish_omp_declare_simd has already processed the tokens. */
24936 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
24938 const char *kind
= "simd";
24939 if (clauses
.exists ()
24940 && (clauses
[0].type
== CPP_NAME
|| clauses
[0].type
== CPP_PRAGMA
))
24941 kind
= IDENTIFIER_POINTER (clauses
[0].value
);
24942 gcc_assert (strcmp (kind
, "simd") == 0 || strcmp (kind
, "variant") == 0);
24943 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
24945 error ("%<#pragma omp declare %s%> not immediately followed by "
24946 "a function declaration or definition", kind
);
24947 clauses
[0].type
= CPP_EOF
;
24950 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
24952 error_at (DECL_SOURCE_LOCATION (fndecl
),
24953 "%<#pragma omp declare %s%> not immediately followed by "
24954 "a single function declaration or definition", kind
);
24955 clauses
[0].type
= CPP_EOF
;
24959 if (parms
== NULL_TREE
)
24960 parms
= DECL_ARGUMENTS (fndecl
);
24962 unsigned int tokens_avail
= parser
->tokens_avail
;
24963 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
24965 parser
->tokens
= clauses
.address ();
24966 parser
->tokens_avail
= clauses
.length ();
24968 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
24969 while (parser
->tokens_avail
> 3)
24971 c_token
*token
= c_parser_peek_token (parser
);
24972 gcc_assert (token
->type
== CPP_NAME
);
24973 kind
= IDENTIFIER_POINTER (token
->value
);
24974 c_parser_consume_token (parser
);
24975 parser
->in_pragma
= true;
24977 if (strcmp (kind
, "simd") == 0)
24980 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
24981 "#pragma omp declare simd");
24982 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
24983 if (c
!= NULL_TREE
)
24984 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
24985 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
24986 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
24987 DECL_ATTRIBUTES (fndecl
) = c
;
24991 gcc_assert (strcmp (kind
, "variant") == 0);
24992 c_finish_omp_declare_variant (parser
, fndecl
, parms
);
24996 parser
->tokens
= &parser
->tokens_buf
[0];
24997 parser
->tokens_avail
= tokens_avail
;
24998 if (clauses
.exists ())
24999 clauses
[0].type
= CPP_PRAGMA
;
25002 /* D should be C_TOKEN_VEC from omp::decl attribute. If it contains
25003 a threadprivate, groupprivate, allocate or declare target directive,
25004 return true and parse it for DECL. */
25007 c_maybe_parse_omp_decl (tree decl
, tree d
)
25009 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
25010 vec
<c_token
, va_gc
> *toks
= C_TOKEN_VEC_TOKENS (d
);
25011 c_token
*first
= toks
->address ();
25012 c_token
*last
= first
+ toks
->length ();
25013 const char *directive
[3] = {};
25014 for (int j
= 0; j
< 3; j
++)
25016 tree id
= NULL_TREE
;
25017 if (first
+ j
== last
)
25019 if (first
[j
].type
== CPP_NAME
)
25020 id
= first
[j
].value
;
25021 else if (first
[j
].type
== CPP_KEYWORD
)
25022 id
= ridpointers
[(int) first
[j
].keyword
];
25025 directive
[j
] = IDENTIFIER_POINTER (id
);
25027 const c_omp_directive
*dir
= NULL
;
25029 dir
= c_omp_categorize_directive (directive
[0], directive
[1],
25033 error_at (first
->location
,
25034 "unknown OpenMP directive name in "
25035 "%qs attribute argument", "omp::decl");
25038 if (dir
->id
!= PRAGMA_OMP_THREADPRIVATE
25039 /* && dir->id != PRAGMA_OMP_GROUPPRIVATE */
25040 && dir
->id
!= PRAGMA_OMP_ALLOCATE
25041 && (dir
->id
!= PRAGMA_OMP_DECLARE
25042 || strcmp (directive
[1], "target") != 0))
25045 if (!flag_openmp
&& !dir
->simd
)
25048 c_parser
*parser
= the_parser
;
25049 unsigned int tokens_avail
= parser
->tokens_avail
;
25050 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
25052 vec_safe_reserve (toks
, last
- first
+ 2, true);
25054 tok
.type
= CPP_PRAGMA
;
25055 tok
.keyword
= RID_MAX
;
25056 tok
.pragma_kind
= pragma_kind (dir
->id
);
25057 tok
.location
= first
->location
;
25058 toks
->quick_push (tok
);
25059 while (++first
< last
)
25060 toks
->quick_push (*first
);
25062 tok
.type
= CPP_PRAGMA_EOL
;
25063 tok
.keyword
= RID_MAX
;
25064 tok
.location
= last
[-1].location
;
25065 toks
->quick_push (tok
);
25067 tok
.type
= CPP_EOF
;
25068 tok
.keyword
= RID_MAX
;
25069 tok
.location
= last
[-1].location
;
25070 tok
.flags
= tokens_avail
;
25071 toks
->quick_push (tok
);
25072 parser
->in_omp_decl_attribute
= decl
;
25073 parser
->tokens
= toks
->address ();
25074 parser
->tokens_avail
= toks
->length ();
25075 parser
->in_omp_attribute_pragma
= toks
;
25076 c_parser_pragma (parser
, pragma_external
, NULL
);
25077 parser
->in_omp_decl_attribute
= NULL_TREE
;
25082 # pragma omp declare target new-line
25083 declarations and definitions
25084 # pragma omp end declare target new-line
25087 # pragma omp declare target ( extended-list ) new-line
25089 # pragma omp declare target declare-target-clauses[seq] new-line */
25091 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
25092 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
25093 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
25094 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
25095 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
25096 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
25099 c_parser_omp_declare_target (c_parser
*parser
)
25101 tree clauses
= NULL_TREE
;
25102 int device_type
= 0;
25103 bool indirect
= false;
25104 bool only_device_type_or_indirect
= true;
25105 if (c_parser_next_token_is (parser
, CPP_NAME
)
25106 || (c_parser_next_token_is (parser
, CPP_COMMA
)
25107 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
))
25108 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
25109 "#pragma omp declare target");
25110 else if (parser
->in_omp_decl_attribute
25111 || c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
25113 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
25115 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
25116 c_parser_skip_to_pragma_eol (parser
);
25120 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25121 c_parser_skip_to_pragma_eol (parser
);
25122 c_omp_declare_target_attr attr
= { attr_syntax
, -1, 0 };
25123 vec_safe_push (current_omp_declare_target_attribute
, attr
);
25126 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
25128 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
25129 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
25130 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_INDIRECT
)
25131 indirect
|= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c
));
25133 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
25135 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
25136 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_INDIRECT
)
25138 tree t
= OMP_CLAUSE_DECL (c
), id
;
25139 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
25140 tree at2
= lookup_attribute ("omp declare target link",
25141 DECL_ATTRIBUTES (t
));
25142 only_device_type_or_indirect
= false;
25143 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
25145 id
= get_identifier ("omp declare target link");
25146 std::swap (at1
, at2
);
25149 id
= get_identifier ("omp declare target");
25152 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_ENTER
)
25153 error_at (OMP_CLAUSE_LOCATION (c
),
25154 "%qD specified both in declare target %<link%> and %qs"
25155 " clauses", t
, OMP_CLAUSE_ENTER_TO (c
) ? "to" : "enter");
25157 error_at (OMP_CLAUSE_LOCATION (c
),
25158 "%qD specified both in declare target %<link%> and "
25159 "%<to%> or %<enter%> clauses", t
);
25164 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
25165 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
25168 symtab_node
*node
= symtab_node::get (t
);
25171 node
->offloadable
= 1;
25172 if (ENABLE_OFFLOADING
)
25174 g
->have_offload
= true;
25175 if (is_a
<varpool_node
*> (node
))
25176 vec_safe_push (offload_vars
, t
);
25180 if (TREE_CODE (t
) != FUNCTION_DECL
)
25182 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_HOST
) != 0)
25184 tree at3
= lookup_attribute ("omp declare target host",
25185 DECL_ATTRIBUTES (t
));
25186 if (at3
== NULL_TREE
)
25188 id
= get_identifier ("omp declare target host");
25189 DECL_ATTRIBUTES (t
)
25190 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
25193 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_NOHOST
) != 0)
25195 tree at3
= lookup_attribute ("omp declare target nohost",
25196 DECL_ATTRIBUTES (t
));
25197 if (at3
== NULL_TREE
)
25199 id
= get_identifier ("omp declare target nohost");
25200 DECL_ATTRIBUTES (t
)
25201 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
25206 tree at4
= lookup_attribute ("omp declare target indirect",
25207 DECL_ATTRIBUTES (t
));
25208 if (at4
== NULL_TREE
)
25210 id
= get_identifier ("omp declare target indirect");
25211 DECL_ATTRIBUTES (t
)
25212 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
25216 if ((device_type
|| indirect
) && only_device_type_or_indirect
)
25217 error_at (OMP_CLAUSE_LOCATION (clauses
),
25218 "directive with only %<device_type%> or %<indirect%> clauses");
25219 if (indirect
&& device_type
&& device_type
!= OMP_CLAUSE_DEVICE_TYPE_ANY
)
25220 error_at (OMP_CLAUSE_LOCATION (clauses
),
25221 "%<device_type%> clause must specify 'any' when used with "
25222 "an %<indirect%> clause");
25226 #pragma omp begin assumes clauses[optseq] new-line
25228 #pragma omp begin declare target clauses[optseq] new-line */
25230 #define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \
25231 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
25232 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
25235 c_parser_omp_begin (c_parser
*parser
)
25237 const char *p
= "";
25238 c_parser_consume_pragma (parser
);
25239 if (c_parser_next_token_is (parser
, CPP_NAME
))
25240 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25241 if (strcmp (p
, "declare") == 0)
25243 c_parser_consume_token (parser
);
25245 if (c_parser_next_token_is (parser
, CPP_NAME
))
25246 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25247 if (strcmp (p
, "target") == 0)
25249 c_parser_consume_token (parser
);
25250 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25252 = c_parser_omp_all_clauses (parser
,
25253 OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK
,
25254 "#pragma omp begin declare target");
25255 int device_type
= 0;
25257 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
25259 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
25260 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
25261 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_INDIRECT
)
25262 indirect
|= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c
));
25264 c_omp_declare_target_attr attr
= { attr_syntax
, device_type
,
25266 vec_safe_push (current_omp_declare_target_attribute
, attr
);
25270 c_parser_error (parser
, "expected %<target%>");
25271 c_parser_skip_to_pragma_eol (parser
);
25274 else if (strcmp (p
, "assumes") == 0)
25276 c_parser_consume_token (parser
);
25277 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25278 c_parser_omp_assumption_clauses (parser
, false);
25279 struct c_omp_begin_assumes_data a
= { attr_syntax
};
25280 vec_safe_push (current_omp_begin_assumes
, a
);
25284 c_parser_error (parser
, "expected %<declare target%> or %<assumes%>");
25285 c_parser_skip_to_pragma_eol (parser
);
25290 #pragma omp end declare target
25293 #pragma omp end assumes */
25296 c_parser_omp_end (c_parser
*parser
)
25298 location_t loc
= c_parser_peek_token (parser
)->location
;
25299 const char *p
= "";
25300 c_parser_consume_pragma (parser
);
25301 if (c_parser_next_token_is (parser
, CPP_NAME
))
25302 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25303 if (strcmp (p
, "declare") == 0)
25305 c_parser_consume_token (parser
);
25306 if (c_parser_next_token_is (parser
, CPP_NAME
)
25307 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
25309 c_parser_consume_token (parser
);
25312 c_parser_error (parser
, "expected %<target%>");
25313 c_parser_skip_to_pragma_eol (parser
);
25316 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25317 c_parser_skip_to_pragma_eol (parser
);
25318 if (!vec_safe_length (current_omp_declare_target_attribute
))
25319 error_at (loc
, "%<#pragma omp end declare target%> without "
25320 "corresponding %<#pragma omp declare target%> or "
25321 "%<#pragma omp begin declare target%>");
25324 c_omp_declare_target_attr
25325 a
= current_omp_declare_target_attribute
->pop ();
25326 if (a
.attr_syntax
!= attr_syntax
)
25330 "%qs in attribute syntax terminated "
25331 "with %qs in pragma syntax",
25332 a
.device_type
>= 0 ? "begin declare target"
25333 : "declare target",
25334 "end declare target");
25337 "%qs in pragma syntax terminated "
25338 "with %qs in attribute syntax",
25339 a
.device_type
>= 0 ? "begin declare target"
25340 : "declare target",
25341 "end declare target");
25345 else if (strcmp (p
, "assumes") == 0)
25347 c_parser_consume_token (parser
);
25348 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25349 c_parser_skip_to_pragma_eol (parser
);
25350 if (!vec_safe_length (current_omp_begin_assumes
))
25351 error_at (loc
, "%qs without corresponding %qs",
25352 "#pragma omp end assumes", "#pragma omp begin assumes");
25355 c_omp_begin_assumes_data
25356 a
= current_omp_begin_assumes
->pop ();
25357 if (a
.attr_syntax
!= attr_syntax
)
25361 "%qs in attribute syntax terminated "
25362 "with %qs in pragma syntax",
25363 "begin assumes", "end assumes");
25366 "%qs in pragma syntax terminated "
25367 "with %qs in attribute syntax",
25368 "begin assumes", "end assumes");
25374 c_parser_error (parser
, "expected %<declare%> or %<assumes%>");
25375 c_parser_skip_to_pragma_eol (parser
);
25380 #pragma omp declare reduction (reduction-id : typename-list : expression) \
25381 initializer-clause[opt] new-line
25383 initializer-clause:
25384 initializer (omp_priv = initializer)
25385 initializer (function-name (argument-list)) */
25388 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
25390 unsigned int tokens_avail
= 0, i
;
25391 c_token
*saved_tokens
= NULL
;
25392 vec
<tree
> types
= vNULL
;
25393 vec
<c_token
> clauses
= vNULL
;
25394 enum tree_code reduc_code
= ERROR_MARK
;
25395 tree reduc_id
= NULL_TREE
;
25397 location_t rloc
= c_parser_peek_token (parser
)->location
;
25399 if (context
== pragma_struct
|| context
== pragma_param
)
25401 error ("%<#pragma omp declare reduction%> not at file or block scope");
25405 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
25408 switch (c_parser_peek_token (parser
)->type
)
25411 reduc_code
= PLUS_EXPR
;
25414 reduc_code
= MULT_EXPR
;
25417 reduc_code
= MINUS_EXPR
;
25420 reduc_code
= BIT_AND_EXPR
;
25423 reduc_code
= BIT_XOR_EXPR
;
25426 reduc_code
= BIT_IOR_EXPR
;
25429 reduc_code
= TRUTH_ANDIF_EXPR
;
25432 reduc_code
= TRUTH_ORIF_EXPR
;
25436 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25437 if (strcmp (p
, "min") == 0)
25439 reduc_code
= MIN_EXPR
;
25442 if (strcmp (p
, "max") == 0)
25444 reduc_code
= MAX_EXPR
;
25447 reduc_id
= c_parser_peek_token (parser
)->value
;
25450 c_parser_error (parser
,
25451 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
25452 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
25456 tree orig_reduc_id
, reduc_decl
;
25457 orig_reduc_id
= reduc_id
;
25458 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
25459 reduc_decl
= c_omp_reduction_decl (reduc_id
);
25460 c_parser_consume_token (parser
);
25462 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
25467 location_t loc
= c_parser_peek_token (parser
)->location
;
25468 struct c_type_name
*ctype
= c_parser_type_name (parser
);
25471 type
= groktypename (ctype
, NULL
, NULL
);
25472 if (type
== error_mark_node
)
25474 else if ((INTEGRAL_TYPE_P (type
)
25475 || SCALAR_FLOAT_TYPE_P (type
)
25476 || TREE_CODE (type
) == COMPLEX_TYPE
)
25477 && orig_reduc_id
== NULL_TREE
)
25478 error_at (loc
, "predeclared arithmetic type in "
25479 "%<#pragma omp declare reduction%>");
25480 else if (TREE_CODE (type
) == FUNCTION_TYPE
25481 || TREE_CODE (type
) == ARRAY_TYPE
)
25482 error_at (loc
, "function or array type in "
25483 "%<#pragma omp declare reduction%>");
25484 else if (TYPE_ATOMIC (type
))
25485 error_at (loc
, "%<_Atomic%> qualified type in "
25486 "%<#pragma omp declare reduction%>");
25487 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
25488 error_at (loc
, "const, volatile or restrict qualified type in "
25489 "%<#pragma omp declare reduction%>");
25493 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
25494 if (comptypes (TREE_PURPOSE (t
), type
))
25496 error_at (loc
, "redeclaration of %qs "
25497 "%<#pragma omp declare reduction%> for "
25499 IDENTIFIER_POINTER (reduc_id
)
25500 + sizeof ("omp declare reduction ") - 1,
25503 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
25505 error_at (ploc
, "previous %<#pragma omp declare "
25509 if (t
== NULL_TREE
)
25510 types
.safe_push (type
);
25512 if (c_parser_next_token_is (parser
, CPP_COMMA
))
25513 c_parser_consume_token (parser
);
25521 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
25522 || types
.is_empty ())
25525 clauses
.release ();
25529 c_token
*token
= c_parser_peek_token (parser
);
25530 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
25532 c_parser_consume_token (parser
);
25534 c_parser_skip_to_pragma_eol (parser
);
25538 if (types
.length () > 1)
25540 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
25542 c_token
*token
= c_parser_peek_token (parser
);
25543 if (token
->type
== CPP_EOF
)
25545 clauses
.safe_push (*token
);
25546 c_parser_consume_token (parser
);
25548 clauses
.safe_push (*c_parser_peek_token (parser
));
25549 c_parser_skip_to_pragma_eol (parser
);
25551 /* Make sure nothing tries to read past the end of the tokens. */
25553 memset (&eof_token
, 0, sizeof (eof_token
));
25554 eof_token
.type
= CPP_EOF
;
25555 clauses
.safe_push (eof_token
);
25556 clauses
.safe_push (eof_token
);
25559 int errs
= errorcount
;
25560 FOR_EACH_VEC_ELT (types
, i
, type
)
25562 saved_tokens
= parser
->tokens
;
25563 tokens_avail
= parser
->tokens_avail
;
25564 if (!clauses
.is_empty ())
25566 parser
->tokens
= clauses
.address ();
25567 parser
->tokens_avail
= clauses
.length ();
25568 parser
->in_pragma
= true;
25571 bool nested
= current_function_decl
!= NULL_TREE
;
25573 c_push_function_context ();
25574 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
25575 reduc_id
, default_function_type
);
25576 current_function_decl
= fndecl
;
25577 allocate_struct_function (fndecl
, true);
25579 tree stmt
= push_stmt_list ();
25580 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
25581 warn about these. */
25582 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
25583 get_identifier ("omp_out"), type
);
25584 DECL_ARTIFICIAL (omp_out
) = 1;
25585 DECL_CONTEXT (omp_out
) = fndecl
;
25586 pushdecl (omp_out
);
25587 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
25588 get_identifier ("omp_in"), type
);
25589 DECL_ARTIFICIAL (omp_in
) = 1;
25590 DECL_CONTEXT (omp_in
) = fndecl
;
25592 struct c_expr combiner
= c_parser_expression (parser
);
25593 struct c_expr initializer
;
25594 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
25596 initializer
.set_error ();
25597 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
25599 else if (c_parser_next_token_is (parser
, CPP_COMMA
)
25600 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
25601 c_parser_consume_token (parser
);
25603 && (c_parser_next_token_is (parser
, CPP_NAME
)
25604 && strcmp (IDENTIFIER_POINTER
25605 (c_parser_peek_token (parser
)->value
),
25606 "initializer") == 0))
25608 c_parser_consume_token (parser
);
25611 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
25612 get_identifier ("omp_priv"), type
);
25613 DECL_ARTIFICIAL (omp_priv
) = 1;
25614 DECL_INITIAL (omp_priv
) = error_mark_node
;
25615 DECL_CONTEXT (omp_priv
) = fndecl
;
25616 pushdecl (omp_priv
);
25617 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
25618 get_identifier ("omp_orig"), type
);
25619 DECL_ARTIFICIAL (omp_orig
) = 1;
25620 DECL_CONTEXT (omp_orig
) = fndecl
;
25621 pushdecl (omp_orig
);
25622 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
25624 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
25626 c_parser_error (parser
, "expected %<omp_priv%> or "
25630 else if (strcmp (IDENTIFIER_POINTER
25631 (c_parser_peek_token (parser
)->value
),
25634 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
25635 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
25637 c_parser_error (parser
, "expected function-name %<(%>");
25641 initializer
= c_parser_postfix_expression (parser
);
25642 if (initializer
.value
25643 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
25646 tree c
= initializer
.value
;
25647 for (j
= 0; j
< call_expr_nargs (c
); j
++)
25649 tree a
= CALL_EXPR_ARG (c
, j
);
25651 if (TREE_CODE (a
) == ADDR_EXPR
25652 && TREE_OPERAND (a
, 0) == omp_priv
)
25655 if (j
== call_expr_nargs (c
))
25656 error ("one of the initializer call arguments should be "
25662 c_parser_consume_token (parser
);
25663 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
25667 tree st
= push_stmt_list ();
25668 location_t loc
= c_parser_peek_token (parser
)->location
;
25669 rich_location
richloc (line_table
, loc
);
25670 start_init (omp_priv
, NULL_TREE
, false, false, &richloc
);
25671 struct c_expr init
= c_parser_initializer (parser
, omp_priv
);
25673 finish_decl (omp_priv
, loc
, init
.value
,
25674 init
.original_type
, NULL_TREE
);
25675 pop_stmt_list (st
);
25679 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
25685 c_parser_skip_to_pragma_eol (parser
);
25687 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
25688 DECL_INITIAL (reduc_decl
));
25689 DECL_INITIAL (reduc_decl
) = t
;
25690 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
25691 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
25692 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
25693 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
25694 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
25695 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
25698 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
25699 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
25700 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
25701 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
25702 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
25703 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
25704 walk_tree (&DECL_INITIAL (omp_priv
),
25705 c_check_omp_declare_reduction_r
,
25706 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
25710 pop_stmt_list (stmt
);
25712 if (cfun
->language
!= NULL
)
25714 ggc_free (cfun
->language
);
25715 cfun
->language
= NULL
;
25718 current_function_decl
= NULL_TREE
;
25720 c_pop_function_context ();
25722 if (!clauses
.is_empty ())
25724 parser
->tokens
= saved_tokens
;
25725 parser
->tokens_avail
= tokens_avail
;
25729 if (errs
!= errorcount
)
25733 clauses
.release ();
25739 #pragma omp declare simd declare-simd-clauses[optseq] new-line
25740 #pragma omp declare reduction (reduction-id : typename-list : expression) \
25741 initializer-clause[opt] new-line
25742 #pragma omp declare target new-line
25745 #pragma omp declare variant (identifier) match (context-selector) */
25748 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
25750 c_parser_consume_pragma (parser
);
25751 if (c_parser_next_token_is (parser
, CPP_NAME
))
25753 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25754 if (strcmp (p
, "simd") == 0)
25756 /* c_parser_consume_token (parser); done in
25757 c_parser_omp_declare_simd. */
25758 c_parser_omp_declare_simd (parser
, context
);
25761 if (strcmp (p
, "reduction") == 0)
25763 c_parser_consume_token (parser
);
25764 c_parser_omp_declare_reduction (parser
, context
);
25767 if (!flag_openmp
) /* flag_openmp_simd */
25769 c_parser_skip_to_pragma_eol (parser
, false);
25772 if (strcmp (p
, "target") == 0)
25774 c_parser_consume_token (parser
);
25775 c_parser_omp_declare_target (parser
);
25778 if (strcmp (p
, "variant") == 0)
25780 /* c_parser_consume_token (parser); done in
25781 c_parser_omp_declare_simd. */
25782 c_parser_omp_declare_simd (parser
, context
);
25787 c_parser_error (parser
, "expected %<simd%>, %<reduction%>, "
25788 "%<target%> or %<variant%>");
25789 c_parser_skip_to_pragma_eol (parser
);
25794 #pragma omp requires clauses[optseq] new-line */
25797 c_parser_omp_requires (c_parser
*parser
)
25799 enum omp_requires new_req
= (enum omp_requires
) 0;
25801 c_parser_consume_pragma (parser
);
25803 location_t loc
= c_parser_peek_token (parser
)->location
;
25804 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
25806 if (c_parser_next_token_is (parser
, CPP_COMMA
)
25807 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
25808 c_parser_consume_token (parser
);
25810 if (c_parser_next_token_is (parser
, CPP_NAME
))
25813 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25814 location_t cloc
= c_parser_peek_token (parser
)->location
;
25815 enum omp_requires this_req
= (enum omp_requires
) 0;
25817 if (!strcmp (p
, "unified_address"))
25818 this_req
= OMP_REQUIRES_UNIFIED_ADDRESS
;
25819 else if (!strcmp (p
, "unified_shared_memory"))
25820 this_req
= OMP_REQUIRES_UNIFIED_SHARED_MEMORY
;
25821 else if (!strcmp (p
, "dynamic_allocators"))
25822 this_req
= OMP_REQUIRES_DYNAMIC_ALLOCATORS
;
25823 else if (!strcmp (p
, "reverse_offload"))
25824 this_req
= OMP_REQUIRES_REVERSE_OFFLOAD
;
25825 else if (!strcmp (p
, "atomic_default_mem_order"))
25827 c_parser_consume_token (parser
);
25829 matching_parens parens
;
25830 if (parens
.require_open (parser
))
25832 if (c_parser_next_token_is (parser
, CPP_NAME
))
25834 tree v
= c_parser_peek_token (parser
)->value
;
25835 p
= IDENTIFIER_POINTER (v
);
25837 if (!strcmp (p
, "seq_cst"))
25839 = (enum omp_requires
) OMP_MEMORY_ORDER_SEQ_CST
;
25840 else if (!strcmp (p
, "relaxed"))
25842 = (enum omp_requires
) OMP_MEMORY_ORDER_RELAXED
;
25843 else if (!strcmp (p
, "release"))
25845 = (enum omp_requires
) OMP_MEMORY_ORDER_RELEASE
;
25846 else if (!strcmp (p
, "acq_rel"))
25848 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQ_REL
;
25849 else if (!strcmp (p
, "acquire"))
25851 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQUIRE
;
25855 error_at (c_parser_peek_token (parser
)->location
,
25856 "expected %<acq_rel%>, %<acquire%>, "
25857 "%<relaxed%>, %<release%> or %<seq_cst%>");
25858 switch (c_parser_peek_token (parser
)->type
)
25861 case CPP_PRAGMA_EOL
:
25862 case CPP_CLOSE_PAREN
:
25865 if (c_parser_peek_2nd_token (parser
)->type
25866 == CPP_CLOSE_PAREN
)
25867 c_parser_consume_token (parser
);
25872 c_parser_consume_token (parser
);
25874 parens
.skip_until_found_close (parser
);
25877 c_parser_skip_to_pragma_eol (parser
, false);
25885 error_at (cloc
, "expected %<unified_address%>, "
25886 "%<unified_shared_memory%>, "
25887 "%<dynamic_allocators%>, "
25888 "%<reverse_offload%> "
25889 "or %<atomic_default_mem_order%> clause");
25890 c_parser_skip_to_pragma_eol (parser
, false);
25894 c_parser_consume_token (parser
);
25897 if ((this_req
& ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
25899 if ((this_req
& new_req
) != 0)
25900 error_at (cloc
, "too many %qs clauses", p
);
25901 if (this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
25902 && (omp_requires_mask
& OMP_REQUIRES_TARGET_USED
) != 0)
25903 error_at (cloc
, "%qs clause used lexically after first "
25904 "target construct or offloading API", p
);
25906 else if ((new_req
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
25908 error_at (cloc
, "too many %qs clauses",
25909 "atomic_default_mem_order");
25910 this_req
= (enum omp_requires
) 0;
25912 else if ((omp_requires_mask
25913 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
25915 error_at (cloc
, "more than one %<atomic_default_mem_order%>"
25916 " clause in a single compilation unit");
25918 = (enum omp_requires
)
25920 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
);
25922 else if ((omp_requires_mask
25923 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
) != 0)
25924 error_at (cloc
, "%<atomic_default_mem_order%> clause used "
25925 "lexically after first %<atomic%> construct "
25926 "without memory order clause");
25927 new_req
= (enum omp_requires
) (new_req
| this_req
);
25929 = (enum omp_requires
) (omp_requires_mask
| this_req
);
25935 c_parser_skip_to_pragma_eol (parser
);
25938 error_at (loc
, "%<pragma omp requires%> requires at least one clause");
25941 /* Helper function for c_parser_omp_taskloop.
25942 Disallow zero sized or potentially zero sized task reductions. */
25945 c_finish_taskloop_clauses (tree clauses
)
25947 tree
*pc
= &clauses
;
25948 for (tree c
= clauses
; c
; c
= *pc
)
25950 bool remove
= false;
25951 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
25953 tree type
= strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
25954 if (integer_zerop (TYPE_SIZE_UNIT (type
)))
25956 error_at (OMP_CLAUSE_LOCATION (c
),
25957 "zero sized type %qT in %<reduction%> clause", type
);
25960 else if (TREE_CODE (TYPE_SIZE_UNIT (type
)) != INTEGER_CST
)
25962 error_at (OMP_CLAUSE_LOCATION (c
),
25963 "variable sized type %qT in %<reduction%> clause",
25969 *pc
= OMP_CLAUSE_CHAIN (c
);
25971 pc
= &OMP_CLAUSE_CHAIN (c
);
25977 #pragma omp taskloop taskloop-clause[optseq] new-line
25980 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
25983 #define OMP_TASKLOOP_CLAUSE_MASK \
25984 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
25985 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
25986 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
25987 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
25988 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
25989 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
25990 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
25991 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
25992 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
25993 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
25994 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
25995 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
25996 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
25997 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
25998 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
25999 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
26000 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
26003 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
26004 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
26007 tree clauses
, block
, ret
;
26009 strcat (p_name
, " taskloop");
26010 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
26011 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
26013 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
)) != 0)
26014 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_IN_REDUCTION
);
26016 if (c_parser_next_token_is (parser
, CPP_NAME
))
26018 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
26020 if (strcmp (p
, "simd") == 0)
26022 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
26023 if (cclauses
== NULL
)
26024 cclauses
= cclauses_buf
;
26025 c_parser_consume_token (parser
);
26026 if (!flag_openmp
) /* flag_openmp_simd */
26027 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
26029 block
= c_begin_compound_stmt (true);
26030 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
26031 block
= c_end_compound_stmt (loc
, block
, true);
26034 ret
= make_node (OMP_TASKLOOP
);
26035 TREE_TYPE (ret
) = void_type_node
;
26036 OMP_FOR_BODY (ret
) = block
;
26037 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
26038 OMP_FOR_CLAUSES (ret
)
26039 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret
));
26040 SET_EXPR_LOCATION (ret
, loc
);
26045 if (!flag_openmp
) /* flag_openmp_simd */
26047 c_parser_skip_to_pragma_eol (parser
, false);
26051 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
26054 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
26055 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
26058 clauses
= c_finish_taskloop_clauses (clauses
);
26059 block
= c_begin_compound_stmt (true);
26060 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
26061 block
= c_end_compound_stmt (loc
, block
, true);
26068 #pragma omp nothing new-line */
26071 c_parser_omp_nothing (c_parser
*parser
)
26073 c_parser_consume_pragma (parser
);
26074 c_parser_skip_to_pragma_eol (parser
);
26078 #pragma omp error clauses[optseq] new-line */
26081 c_parser_omp_error (c_parser
*parser
, enum pragma_context context
)
26083 int at_compilation
= -1;
26084 int severity_fatal
= -1;
26085 tree message
= NULL_TREE
;
26087 location_t loc
= c_parser_peek_token (parser
)->location
;
26089 c_parser_consume_pragma (parser
);
26091 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
26093 if (c_parser_next_token_is (parser
, CPP_COMMA
)
26094 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
26095 c_parser_consume_token (parser
);
26097 if (!c_parser_next_token_is (parser
, CPP_NAME
))
26101 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
26102 location_t cloc
= c_parser_peek_token (parser
)->location
;
26103 static const char *args
[] = {
26104 "execution", "compilation", "warning", "fatal"
26107 int idx
= 0, n
= -1;
26108 tree m
= NULL_TREE
;
26110 if (!strcmp (p
, "at"))
26111 v
= &at_compilation
;
26112 else if (!strcmp (p
, "severity"))
26114 v
= &severity_fatal
;
26117 else if (strcmp (p
, "message"))
26120 "expected %<at%>, %<severity%> or %<message%> clause");
26121 c_parser_skip_to_pragma_eol (parser
, false);
26125 c_parser_consume_token (parser
);
26127 matching_parens parens
;
26128 if (parens
.require_open (parser
))
26132 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
26133 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
26134 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
26135 m
= convert (const_string_type_node
, expr
.value
);
26136 m
= c_fully_fold (m
, false, NULL
);
26140 if (c_parser_next_token_is (parser
, CPP_NAME
))
26142 tree val
= c_parser_peek_token (parser
)->value
;
26143 const char *q
= IDENTIFIER_POINTER (val
);
26145 if (!strcmp (q
, args
[idx
]))
26147 else if (!strcmp (q
, args
[idx
+ 1]))
26152 error_at (c_parser_peek_token (parser
)->location
,
26153 "expected %qs or %qs", args
[idx
], args
[idx
+ 1]);
26155 switch (c_parser_peek_token (parser
)->type
)
26158 case CPP_PRAGMA_EOL
:
26159 case CPP_CLOSE_PAREN
:
26162 if (c_parser_peek_2nd_token (parser
)->type
26163 == CPP_CLOSE_PAREN
)
26164 c_parser_consume_token (parser
);
26169 c_parser_consume_token (parser
);
26172 parens
.skip_until_found_close (parser
);
26178 error_at (cloc
, "too many %qs clauses", p
);
26188 error_at (cloc
, "too many %qs clauses", p
);
26198 c_parser_skip_to_pragma_eol (parser
);
26202 if (at_compilation
== -1)
26203 at_compilation
= 1;
26204 if (severity_fatal
== -1)
26205 severity_fatal
= 1;
26206 if (!at_compilation
)
26208 if (context
!= pragma_compound
)
26210 error_at (loc
, "%<#pragma omp error%> with %<at(execution)%> clause "
26211 "may only be used in compound statements");
26215 = builtin_decl_explicit (severity_fatal
? BUILT_IN_GOMP_ERROR
26216 : BUILT_IN_GOMP_WARNING
);
26218 message
= build_zero_cst (const_string_type_node
);
26219 tree stmt
= build_call_expr_loc (loc
, fndecl
, 2, message
,
26220 build_all_ones_cst (size_type_node
));
26224 const char *msg
= NULL
;
26227 msg
= c_getstr (message
);
26229 msg
= _("<message unknown at compile time>");
26232 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
26233 "%<pragma omp error%> encountered: %s", msg
);
26235 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
26236 "%<pragma omp error%> encountered");
26240 /* Assumption clauses:
26242 absent (directive-name-list)
26243 contains (directive-name-list)
26250 c_parser_omp_assumption_clauses (c_parser
*parser
, bool is_assume
)
26252 bool no_openmp
= false;
26253 bool no_openmp_routines
= false;
26254 bool no_parallelism
= false;
26255 bitmap_head absent_head
, contains_head
;
26257 bitmap_obstack_initialize (NULL
);
26258 bitmap_initialize (&absent_head
, &bitmap_default_obstack
);
26259 bitmap_initialize (&contains_head
, &bitmap_default_obstack
);
26261 if (c_parser_next_token_is (parser
, CPP_PRAGMA_EOL
))
26262 error_at (c_parser_peek_token (parser
)->location
,
26263 "expected at least one assumption clause");
26265 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
26267 if (c_parser_next_token_is (parser
, CPP_COMMA
)
26268 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
26269 c_parser_consume_token (parser
);
26271 if (!c_parser_next_token_is (parser
, CPP_NAME
))
26275 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
26276 location_t cloc
= c_parser_peek_token (parser
)->location
;
26278 if (!strcmp (p
, "no_openmp"))
26280 c_parser_consume_token (parser
);
26282 error_at (cloc
, "too many %qs clauses", "no_openmp");
26285 else if (!strcmp (p
, "no_openmp_routines"))
26287 c_parser_consume_token (parser
);
26288 if (no_openmp_routines
)
26289 error_at (cloc
, "too many %qs clauses", "no_openmp_routines");
26290 no_openmp_routines
= true;
26292 else if (!strcmp (p
, "no_parallelism"))
26294 c_parser_consume_token (parser
);
26295 if (no_parallelism
)
26296 error_at (cloc
, "too many %qs clauses", "no_parallelism");
26297 no_parallelism
= true;
26299 else if (!strcmp (p
, "holds"))
26301 c_parser_consume_token (parser
);
26302 matching_parens parens
;
26303 if (parens
.require_open (parser
))
26305 location_t eloc
= c_parser_peek_token (parser
)->location
;
26306 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
26307 tree t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
26308 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
26309 t
= c_fully_fold (t
, false, NULL
);
26310 if (is_assume
&& t
!= error_mark_node
)
26312 tree fn
= build_call_expr_internal_loc (eloc
, IFN_ASSUME
,
26317 parens
.skip_until_found_close (parser
);
26320 else if (!strcmp (p
, "absent") || !strcmp (p
, "contains"))
26322 c_parser_consume_token (parser
);
26323 matching_parens parens
;
26324 if (parens
.require_open (parser
))
26328 const char *directive
[3] = {};
26330 location_t dloc
= c_parser_peek_token (parser
)->location
;
26331 for (i
= 0; i
< 3; i
++)
26334 if (c_parser_peek_nth_token (parser
, i
+ 1)->type
26336 id
= c_parser_peek_nth_token (parser
, i
+ 1)->value
;
26337 else if (c_parser_peek_nth_token (parser
, i
+ 1)->keyword
26341 = c_parser_peek_nth_token (parser
, i
+ 1)->keyword
;
26342 id
= ridpointers
[rid
];
26346 directive
[i
] = IDENTIFIER_POINTER (id
);
26349 error_at (dloc
, "expected directive name");
26352 const struct c_omp_directive
*dir
26353 = c_omp_categorize_directive (directive
[0],
26357 || dir
->kind
== C_OMP_DIR_DECLARATIVE
26358 || dir
->kind
== C_OMP_DIR_INFORMATIONAL
26359 || dir
->id
== PRAGMA_OMP_END
26360 || (!dir
->second
&& directive
[1])
26361 || (!dir
->third
&& directive
[2]))
26362 error_at (dloc
, "unknown OpenMP directive name in "
26363 "%qs clause argument", p
);
26366 int id
= dir
- c_omp_directives
;
26367 if (bitmap_bit_p (p
[0] == 'a' ? &contains_head
26368 : &absent_head
, id
))
26369 error_at (dloc
, "%<%s%s%s%s%s%> directive "
26370 "mentioned in both %<absent%> and "
26371 "%<contains%> clauses",
26373 directive
[1] ? " " : "",
26374 directive
[1] ? directive
[1] : "",
26375 directive
[2] ? " " : "",
26376 directive
[2] ? directive
[2] : "");
26377 else if (!bitmap_set_bit (p
[0] == 'a'
26379 : &contains_head
, id
))
26380 error_at (dloc
, "%<%s%s%s%s%s%> directive "
26381 "mentioned multiple times in %qs "
26384 directive
[1] ? " " : "",
26385 directive
[1] ? directive
[1] : "",
26386 directive
[2] ? " " : "",
26387 directive
[2] ? directive
[2] : "", p
);
26390 c_parser_consume_token (parser
);
26392 if (c_parser_next_token_is (parser
, CPP_COMMA
))
26393 c_parser_consume_token (parser
);
26398 parens
.skip_until_found_close (parser
);
26401 else if (startswith (p
, "ext_"))
26403 warning_at (cloc
, OPT_Wopenmp
, "unknown assumption clause %qs", p
);
26404 c_parser_consume_token (parser
);
26405 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
26407 matching_parens parens
;
26408 parens
.consume_open (parser
);
26409 c_parser_balanced_token_sequence (parser
);
26410 parens
.require_close (parser
);
26415 c_parser_consume_token (parser
);
26416 error_at (cloc
, "expected assumption clause");
26420 c_parser_skip_to_pragma_eol (parser
);
26424 #pragma omp assume clauses[optseq] new-line */
26427 c_parser_omp_assume (c_parser
*parser
, bool *if_p
)
26429 c_parser_omp_assumption_clauses (parser
, true);
26430 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
26434 #pragma omp assumes clauses[optseq] new-line */
26437 c_parser_omp_assumes (c_parser
*parser
)
26439 c_parser_consume_pragma (parser
);
26440 c_parser_omp_assumption_clauses (parser
, false);
26443 /* Main entry point to parsing most OpenMP pragmas. */
26446 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
26448 enum pragma_kind p_kind
;
26451 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
26452 omp_clause_mask
mask (0);
26454 loc
= c_parser_peek_token (parser
)->location
;
26455 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
26456 c_parser_consume_pragma (parser
);
26460 case PRAGMA_OACC_ATOMIC
:
26461 c_parser_omp_atomic (loc
, parser
, true);
26463 case PRAGMA_OACC_CACHE
:
26464 strcpy (p_name
, "#pragma acc");
26465 stmt
= c_parser_oacc_cache (loc
, parser
);
26467 case PRAGMA_OACC_DATA
:
26468 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
26470 case PRAGMA_OACC_HOST_DATA
:
26471 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
26473 case PRAGMA_OACC_KERNELS
:
26474 case PRAGMA_OACC_PARALLEL
:
26475 case PRAGMA_OACC_SERIAL
:
26476 strcpy (p_name
, "#pragma acc");
26477 stmt
= c_parser_oacc_compute (loc
, parser
, p_kind
, p_name
, if_p
);
26479 case PRAGMA_OACC_LOOP
:
26480 strcpy (p_name
, "#pragma acc");
26481 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26483 case PRAGMA_OACC_WAIT
:
26484 strcpy (p_name
, "#pragma wait");
26485 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
26487 case PRAGMA_OMP_ATOMIC
:
26488 c_parser_omp_atomic (loc
, parser
, false);
26490 case PRAGMA_OMP_CRITICAL
:
26491 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
26493 case PRAGMA_OMP_DISTRIBUTE
:
26494 strcpy (p_name
, "#pragma omp");
26495 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26497 case PRAGMA_OMP_FOR
:
26498 strcpy (p_name
, "#pragma omp");
26499 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26501 case PRAGMA_OMP_LOOP
:
26502 strcpy (p_name
, "#pragma omp");
26503 stmt
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26505 case PRAGMA_OMP_MASKED
:
26506 strcpy (p_name
, "#pragma omp");
26507 stmt
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26509 case PRAGMA_OMP_MASTER
:
26510 strcpy (p_name
, "#pragma omp");
26511 stmt
= c_parser_omp_master (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26513 case PRAGMA_OMP_PARALLEL
:
26514 strcpy (p_name
, "#pragma omp");
26515 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26517 case PRAGMA_OMP_SCOPE
:
26518 stmt
= c_parser_omp_scope (loc
, parser
, if_p
);
26520 case PRAGMA_OMP_SECTIONS
:
26521 strcpy (p_name
, "#pragma omp");
26522 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
26524 case PRAGMA_OMP_SIMD
:
26525 strcpy (p_name
, "#pragma omp");
26526 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26528 case PRAGMA_OMP_SINGLE
:
26529 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
26531 case PRAGMA_OMP_TASK
:
26532 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
26534 case PRAGMA_OMP_TASKGROUP
:
26535 stmt
= c_parser_omp_taskgroup (loc
, parser
, if_p
);
26537 case PRAGMA_OMP_TASKLOOP
:
26538 strcpy (p_name
, "#pragma omp");
26539 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26541 case PRAGMA_OMP_TEAMS
:
26542 strcpy (p_name
, "#pragma omp");
26543 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26545 case PRAGMA_OMP_ASSUME
:
26546 c_parser_omp_assume (parser
, if_p
);
26549 gcc_unreachable ();
26552 if (stmt
&& stmt
!= error_mark_node
)
26553 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
26558 # pragma omp threadprivate (variable-list) */
26561 c_parser_omp_threadprivate (c_parser
*parser
)
26566 c_parser_consume_pragma (parser
);
26567 loc
= c_parser_peek_token (parser
)->location
;
26568 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
26570 /* Mark every variable in VARS to be assigned thread local storage. */
26571 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
26573 tree v
= TREE_PURPOSE (t
);
26575 /* FIXME diagnostics: Ideally we should keep individual
26576 locations for all the variables in the var list to make the
26577 following errors more precise. Perhaps
26578 c_parser_omp_var_list_parens() should construct a list of
26579 locations to go along with the var list. */
26581 /* If V had already been marked threadprivate, it doesn't matter
26582 whether it had been used prior to this point. */
26584 error_at (loc
, "%qD is not a variable", v
);
26585 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
26586 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
26587 else if (! is_global_var (v
))
26588 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
26589 else if (TREE_TYPE (v
) == error_mark_node
)
26591 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
26592 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
26595 if (! DECL_THREAD_LOCAL_P (v
))
26597 set_decl_tls_model (v
, decl_default_tls_model (v
));
26598 /* If rtl has been already set for this var, call
26599 make_decl_rtl once again, so that encode_section_info
26600 has a chance to look at the new decl flags. */
26601 if (DECL_RTL_SET_P (v
))
26604 C_DECL_THREADPRIVATE_P (v
) = 1;
26608 c_parser_skip_to_pragma_eol (parser
);
26611 /* Parse a transaction attribute (GCC Extension).
26613 transaction-attribute:
26615 attribute-specifier
26619 c_parser_transaction_attributes (c_parser
*parser
)
26621 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
26622 return c_parser_gnu_attributes (parser
);
26624 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
26626 return c_parser_std_attribute_specifier (parser
, true);
26629 /* Parse a __transaction_atomic or __transaction_relaxed statement
26632 transaction-statement:
26633 __transaction_atomic transaction-attribute[opt] compound-statement
26634 __transaction_relaxed compound-statement
26636 Note that the only valid attribute is: "outer".
26640 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
26642 unsigned int old_in
= parser
->in_transaction
;
26643 unsigned int this_in
= 1, new_in
;
26644 location_t loc
= c_parser_peek_token (parser
)->location
;
26647 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
26648 || keyword
== RID_TRANSACTION_RELAXED
)
26649 && c_parser_next_token_is_keyword (parser
, keyword
));
26650 c_parser_consume_token (parser
);
26652 if (keyword
== RID_TRANSACTION_RELAXED
)
26653 this_in
|= TM_STMT_ATTR_RELAXED
;
26656 attrs
= c_parser_transaction_attributes (parser
);
26658 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
26661 /* Keep track if we're in the lexical scope of an outer transaction. */
26662 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
26664 parser
->in_transaction
= new_in
;
26665 stmt
= c_parser_compound_statement (parser
);
26666 parser
->in_transaction
= old_in
;
26669 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
26671 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
26672 "%<__transaction_atomic%> without transactional memory support enabled"
26673 : "%<__transaction_relaxed %> "
26674 "without transactional memory support enabled"));
26679 /* Parse a __transaction_atomic or __transaction_relaxed expression
26682 transaction-expression:
26683 __transaction_atomic ( expression )
26684 __transaction_relaxed ( expression )
26687 static struct c_expr
26688 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
26691 unsigned int old_in
= parser
->in_transaction
;
26692 unsigned int this_in
= 1;
26693 location_t loc
= c_parser_peek_token (parser
)->location
;
26696 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
26697 || keyword
== RID_TRANSACTION_RELAXED
)
26698 && c_parser_next_token_is_keyword (parser
, keyword
));
26699 c_parser_consume_token (parser
);
26701 if (keyword
== RID_TRANSACTION_RELAXED
)
26702 this_in
|= TM_STMT_ATTR_RELAXED
;
26705 attrs
= c_parser_transaction_attributes (parser
);
26707 this_in
|= parse_tm_stmt_attr (attrs
, 0);
26710 parser
->in_transaction
= this_in
;
26711 matching_parens parens
;
26712 if (parens
.require_open (parser
))
26714 tree expr
= c_parser_expression (parser
).value
;
26715 ret
.original_type
= TREE_TYPE (expr
);
26716 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
26717 if (this_in
& TM_STMT_ATTR_RELAXED
)
26718 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
26719 SET_EXPR_LOCATION (ret
.value
, loc
);
26720 ret
.original_code
= TRANSACTION_EXPR
;
26722 if (!parens
.require_close (parser
))
26724 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
26732 ret
.original_code
= ERROR_MARK
;
26733 ret
.original_type
= NULL
;
26735 parser
->in_transaction
= old_in
;
26738 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
26739 "%<__transaction_atomic%> without transactional memory support enabled"
26740 : "%<__transaction_relaxed %> "
26741 "without transactional memory support enabled"));
26743 set_c_expr_source_range (&ret
, loc
, loc
);
26748 /* Parse a __transaction_cancel statement (GCC Extension).
26750 transaction-cancel-statement:
26751 __transaction_cancel transaction-attribute[opt] ;
26753 Note that the only valid attribute is "outer".
26757 c_parser_transaction_cancel (c_parser
*parser
)
26759 location_t loc
= c_parser_peek_token (parser
)->location
;
26761 bool is_outer
= false;
26763 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
26764 c_parser_consume_token (parser
);
26766 attrs
= c_parser_transaction_attributes (parser
);
26768 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
26772 error_at (loc
, "%<__transaction_cancel%> without "
26773 "transactional memory support enabled");
26776 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
26778 error_at (loc
, "%<__transaction_cancel%> within a "
26779 "%<__transaction_relaxed%>");
26784 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
26785 && !is_tm_may_cancel_outer (current_function_decl
))
26787 error_at (loc
, "outer %<__transaction_cancel%> not "
26788 "within outer %<__transaction_atomic%> or "
26789 "a %<transaction_may_cancel_outer%> function");
26793 else if (parser
->in_transaction
== 0)
26795 error_at (loc
, "%<__transaction_cancel%> not within "
26796 "%<__transaction_atomic%>");
26800 return add_stmt (build_tm_abort_call (loc
, is_outer
));
26803 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
26806 /* Parse a single source file. */
26809 c_parse_file (void)
26811 /* Use local storage to begin. If the first token is a pragma, parse it.
26812 If it is #pragma GCC pch_preprocess, then this will load a PCH file
26813 which will cause garbage collection. */
26816 memset (&tparser
, 0, sizeof tparser
);
26817 tparser
.translate_strings_p
= true;
26818 tparser
.tokens
= &tparser
.tokens_buf
[0];
26819 the_parser
= &tparser
;
26821 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
26822 c_parser_pragma_pch_preprocess (&tparser
);
26824 c_common_no_more_pch ();
26826 the_parser
= ggc_alloc
<c_parser
> ();
26827 *the_parser
= tparser
;
26828 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
26829 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
26831 /* Initialize EH, if we've been told to do so. */
26832 if (flag_exceptions
)
26833 using_eh_for_cleanups ();
26835 c_parser_translation_unit (the_parser
);
26840 c_init_preprocess (void)
26842 /* Create a parser for use by pragma_lex during preprocessing. */
26843 the_parser
= ggc_alloc
<c_parser
> ();
26844 memset (the_parser
, 0, sizeof (c_parser
));
26845 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
26848 /* Parse the body of a function declaration marked with "__RTL".
26850 The RTL parser works on the level of characters read from a
26851 FILE *, whereas c_parser works at the level of tokens.
26852 Square this circle by consuming all of the tokens up to and
26853 including the closing brace, recording the start/end of the RTL
26854 fragment, and reopening the file and re-reading the relevant
26855 lines within the RTL parser.
26857 This requires the opening and closing braces of the C function
26858 to be on separate lines from the RTL they wrap.
26860 Take ownership of START_WITH_PASS, if non-NULL. */
26863 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
26865 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
26867 free (start_with_pass
);
26868 return c_parser_peek_token (parser
)->location
;
26871 location_t start_loc
= c_parser_peek_token (parser
)->location
;
26873 /* Consume all tokens, up to the closing brace, handling
26874 matching pairs of braces in the rtl dump. */
26875 int num_open_braces
= 1;
26878 switch (c_parser_peek_token (parser
)->type
)
26880 case CPP_OPEN_BRACE
:
26883 case CPP_CLOSE_BRACE
:
26884 if (--num_open_braces
== 0)
26885 goto found_closing_brace
;
26888 error_at (start_loc
, "no closing brace");
26889 free (start_with_pass
);
26890 return c_parser_peek_token (parser
)->location
;
26894 c_parser_consume_token (parser
);
26897 found_closing_brace
:
26898 /* At the closing brace; record its location. */
26899 location_t end_loc
= c_parser_peek_token (parser
)->location
;
26901 /* Consume the closing brace. */
26902 c_parser_consume_token (parser
);
26904 /* Invoke the RTL parser. */
26905 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
26907 free (start_with_pass
);
26911 /* Run the backend on the cfun created above, transferring ownership of
26912 START_WITH_PASS. */
26913 run_rtl_passes (start_with_pass
);
26917 #include "gt-c-c-parser.h"