1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2023 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 tree std_attrs
= NULL_TREE
;
3672 tree ident
= NULL_TREE
;
3673 tree fixed_underlying_type
= NULL_TREE
;
3674 location_t enum_loc
;
3675 location_t ident_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3676 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ENUM
));
3677 c_parser_consume_token (parser
);
3678 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3680 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3681 attrs
= c_parser_gnu_attributes (parser
);
3682 enum_loc
= c_parser_peek_token (parser
)->location
;
3683 /* Set the location in case we create a decl now. */
3684 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3685 if (c_parser_next_token_is (parser
, CPP_NAME
))
3687 ident
= c_parser_peek_token (parser
)->value
;
3688 ident_loc
= c_parser_peek_token (parser
)->location
;
3689 enum_loc
= ident_loc
;
3690 c_parser_consume_token (parser
);
3692 if (c_parser_next_token_is (parser
, CPP_COLON
)
3693 /* Distinguish an enum-type-specifier from a bit-field
3694 declaration of the form "enum e : constant-expression;". */
3695 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
3697 pedwarn_c11 (enum_loc
, OPT_Wpedantic
,
3698 "ISO C does not support specifying %<enum%> underlying "
3699 "types before C23");
3702 /* The tag is in scope during the enum-type-specifier (which
3703 may refer to the tag inside typeof). */
3704 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
,
3705 have_std_attrs
, std_attrs
, true);
3706 if (!ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
))
3707 error_at (enum_loc
, "%<enum%> declared both with and without "
3708 "fixed underlying type");
3712 /* There must be an enum definition, so this initialization
3713 (to avoid possible warnings about uninitialized data)
3714 will be replaced later (either with the results of that
3715 definition, or with the results of error handling for the
3716 case of no tag and no definition). */
3717 ret
.spec
= NULL_TREE
;
3718 ret
.kind
= ctsk_tagdef
;
3719 ret
.expr
= NULL_TREE
;
3720 ret
.expr_const_operands
= true;
3721 ret
.has_enum_type_specifier
= true;
3723 c_parser_consume_token (parser
);
3724 struct c_declspecs
*specs
= build_null_declspecs ();
3725 c_parser_declspecs (parser
, specs
, false, true, false, false, false,
3726 false, true, cla_prefer_id
);
3727 finish_declspecs (specs
);
3728 if (specs
->default_int_p
)
3729 error_at (enum_loc
, "no %<enum%> underlying type specified");
3730 else if (TREE_CODE (specs
->type
) != INTEGER_TYPE
3731 && TREE_CODE (specs
->type
) != BOOLEAN_TYPE
)
3733 error_at (enum_loc
, "invalid %<enum%> underlying type");
3734 specs
->type
= integer_type_node
;
3736 else if (specs
->restrict_p
)
3737 error_at (enum_loc
, "invalid use of %<restrict%>");
3738 fixed_underlying_type
= TYPE_MAIN_VARIANT (specs
->type
);
3741 /* The type specified must be consistent with any previously
3742 specified underlying type. If this is a newly declared
3743 type, it is now a complete type. */
3744 if (ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
)
3745 && ENUM_UNDERLYING_TYPE (ret
.spec
) == NULL_TREE
)
3747 TYPE_MIN_VALUE (ret
.spec
) =
3748 TYPE_MIN_VALUE (fixed_underlying_type
);
3749 TYPE_MAX_VALUE (ret
.spec
) =
3750 TYPE_MAX_VALUE (fixed_underlying_type
);
3751 TYPE_UNSIGNED (ret
.spec
) = TYPE_UNSIGNED (fixed_underlying_type
);
3752 SET_TYPE_ALIGN (ret
.spec
, TYPE_ALIGN (fixed_underlying_type
));
3753 TYPE_SIZE (ret
.spec
) = NULL_TREE
;
3754 TYPE_PRECISION (ret
.spec
) =
3755 TYPE_PRECISION (fixed_underlying_type
);
3756 ENUM_UNDERLYING_TYPE (ret
.spec
) = fixed_underlying_type
;
3757 layout_type (ret
.spec
);
3759 else if (ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
)
3760 && !comptypes (fixed_underlying_type
,
3761 ENUM_UNDERLYING_TYPE (ret
.spec
)))
3763 error_at (enum_loc
, "%<enum%> underlying type incompatible with "
3764 "previous declaration");
3765 fixed_underlying_type
= ENUM_UNDERLYING_TYPE (ret
.spec
);
3769 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3771 /* Parse an enum definition. */
3772 struct c_enum_contents the_enum
;
3775 /* We chain the enumerators in reverse order, then put them in
3776 forward order at the end. */
3778 timevar_push (TV_PARSE_ENUM
);
3779 type
= start_enum (enum_loc
, &the_enum
, ident
, fixed_underlying_type
);
3781 c_parser_consume_token (parser
);
3789 location_t comma_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3790 location_t decl_loc
, value_loc
;
3791 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
3793 /* Give a nicer error for "enum {}". */
3794 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3797 error_at (c_parser_peek_token (parser
)->location
,
3798 "empty enum is invalid");
3799 parser
->error
= true;
3802 c_parser_error (parser
, "expected identifier");
3803 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3804 values
= error_mark_node
;
3807 token
= c_parser_peek_token (parser
);
3808 enum_id
= token
->value
;
3809 /* Set the location in case we create a decl now. */
3810 c_parser_set_source_position_from_token (token
);
3811 decl_loc
= value_loc
= token
->location
;
3812 c_parser_consume_token (parser
);
3813 /* Parse any specified attributes. */
3814 tree std_attrs
= NULL_TREE
;
3815 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3816 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3817 tree enum_attrs
= chainon (std_attrs
,
3818 c_parser_gnu_attributes (parser
));
3819 if (c_parser_next_token_is (parser
, CPP_EQ
))
3821 c_parser_consume_token (parser
);
3822 value_loc
= c_parser_peek_token (parser
)->location
;
3823 enum_value
= convert_lvalue_to_rvalue (value_loc
,
3824 (c_parser_expr_no_commas
3829 enum_value
= NULL_TREE
;
3830 enum_decl
= build_enumerator (decl_loc
, value_loc
,
3831 &the_enum
, enum_id
, enum_value
);
3833 decl_attributes (&TREE_PURPOSE (enum_decl
), enum_attrs
, 0);
3834 TREE_CHAIN (enum_decl
) = values
;
3837 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3839 comma_loc
= c_parser_peek_token (parser
)->location
;
3841 c_parser_consume_token (parser
);
3843 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3846 pedwarn_c90 (comma_loc
, OPT_Wpedantic
,
3847 "comma at end of enumerator list");
3848 c_parser_consume_token (parser
);
3853 c_parser_error (parser
, "expected %<,%> or %<}%>");
3854 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3855 values
= error_mark_node
;
3859 postfix_attrs
= c_parser_gnu_attributes (parser
);
3860 ret
.spec
= finish_enum (type
, nreverse (values
),
3862 chainon (attrs
, postfix_attrs
)));
3863 ret
.kind
= ctsk_tagdef
;
3864 ret
.expr
= NULL_TREE
;
3865 ret
.expr_const_operands
= true;
3866 ret
.has_enum_type_specifier
= fixed_underlying_type
!= NULL_TREE
;
3867 timevar_pop (TV_PARSE_ENUM
);
3872 c_parser_error (parser
, "expected %<{%>");
3873 ret
.spec
= error_mark_node
;
3874 ret
.kind
= ctsk_tagref
;
3875 ret
.expr
= NULL_TREE
;
3876 ret
.expr_const_operands
= true;
3877 ret
.has_enum_type_specifier
= false;
3880 /* Attributes may only appear when the members are defined or in
3881 certain forward declarations (treat enum forward declarations in
3882 GNU C analogously to struct and union forward declarations in
3884 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3885 c_parser_error (parser
, "expected %<;%>");
3886 if (fixed_underlying_type
== NULL_TREE
)
3888 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
, have_std_attrs
,
3890 /* In ISO C, enumerated types without a fixed underlying type
3891 can be referred to only if already defined. */
3892 if (pedantic
&& !COMPLETE_TYPE_P (ret
.spec
))
3895 pedwarn (enum_loc
, OPT_Wpedantic
,
3896 "ISO C forbids forward references to %<enum%> types");
3902 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3904 struct-or-union-specifier:
3905 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3906 identifier[opt] { struct-contents } gnu-attributes[opt]
3907 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3911 struct-declaration-list
3913 struct-declaration-list:
3914 struct-declaration ;
3915 struct-declaration-list struct-declaration ;
3922 struct-declaration-list struct-declaration
3924 struct-declaration-list:
3925 struct-declaration-list ;
3928 (Note that in the syntax here, unlike that in ISO C, the semicolons
3929 are included here rather than in struct-declaration, in order to
3930 describe the syntax with extra semicolons and missing semicolon at
3935 struct-declaration-list:
3936 @defs ( class-name )
3938 (Note this does not include a trailing semicolon, but can be
3939 followed by further declarations, and gets a pedwarn-if-pedantic
3940 when followed by a semicolon.) */
3942 static struct c_typespec
3943 c_parser_struct_or_union_specifier (c_parser
*parser
)
3945 struct c_typespec ret
;
3946 bool have_std_attrs
;
3947 tree std_attrs
= NULL_TREE
;
3949 tree ident
= NULL_TREE
;
3950 location_t struct_loc
;
3951 location_t ident_loc
= UNKNOWN_LOCATION
;
3952 enum tree_code code
;
3953 switch (c_parser_peek_token (parser
)->keyword
)
3964 struct_loc
= c_parser_peek_token (parser
)->location
;
3965 c_parser_consume_token (parser
);
3966 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3968 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3969 attrs
= c_parser_gnu_attributes (parser
);
3971 /* Set the location in case we create a decl now. */
3972 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3974 if (c_parser_next_token_is (parser
, CPP_NAME
))
3976 ident
= c_parser_peek_token (parser
)->value
;
3977 ident_loc
= c_parser_peek_token (parser
)->location
;
3978 struct_loc
= ident_loc
;
3979 c_parser_consume_token (parser
);
3981 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3983 /* Parse a struct or union definition. Start the scope of the
3984 tag before parsing components. */
3985 class c_struct_parse_info
*struct_info
;
3986 tree type
= start_struct (struct_loc
, code
, ident
, &struct_info
);
3988 /* We chain the components in reverse order, then put them in
3989 forward order at the end. Each struct-declaration may
3990 declare multiple components (comma-separated), so we must use
3991 chainon to join them, although when parsing each
3992 struct-declaration we can use TREE_CHAIN directly.
3994 The theory behind all this is that there will be more
3995 semicolon separated fields than comma separated fields, and
3996 so we'll be minimizing the number of node traversals required
4000 timevar_push (TV_PARSE_STRUCT
);
4001 contents
= NULL_TREE
;
4002 c_parser_consume_token (parser
);
4003 /* Handle the Objective-C @defs construct,
4004 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
4005 if (c_parser_next_token_is_keyword (parser
, RID_AT_DEFS
))
4008 gcc_assert (c_dialect_objc ());
4009 c_parser_consume_token (parser
);
4010 matching_parens parens
;
4011 if (!parens
.require_open (parser
))
4013 if (c_parser_next_token_is (parser
, CPP_NAME
)
4014 && c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
)
4016 name
= c_parser_peek_token (parser
)->value
;
4017 c_parser_consume_token (parser
);
4021 c_parser_error (parser
, "expected class name");
4022 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4025 parens
.skip_until_found_close (parser
);
4026 contents
= nreverse (objc_get_class_ivars (name
));
4029 /* Parse the struct-declarations and semicolons. Problems with
4030 semicolons are diagnosed here; empty structures are diagnosed
4035 /* Parse any stray semicolon. */
4036 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4038 location_t semicolon_loc
4039 = c_parser_peek_token (parser
)->location
;
4040 gcc_rich_location
richloc (semicolon_loc
);
4041 richloc
.add_fixit_remove ();
4042 pedwarn (&richloc
, OPT_Wpedantic
,
4043 "extra semicolon in struct or union specified");
4044 c_parser_consume_token (parser
);
4047 /* Stop if at the end of the struct or union contents. */
4048 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4050 c_parser_consume_token (parser
);
4053 /* Accept #pragmas at struct scope. */
4054 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
4056 c_parser_pragma (parser
, pragma_struct
, NULL
);
4059 /* Parse some comma-separated declarations, but not the
4060 trailing semicolon if any. */
4061 decls
= c_parser_struct_declaration (parser
, &expr
);
4062 contents
= chainon (decls
, contents
);
4063 /* If no semicolon follows, either we have a parse error or
4064 are at the end of the struct or union and should
4066 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4067 c_parser_consume_token (parser
);
4070 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4071 pedwarn (c_parser_peek_token (parser
)->location
, 0,
4072 "no semicolon at end of struct or union");
4073 else if (parser
->error
4074 || !c_parser_next_token_starts_declspecs (parser
))
4076 c_parser_error (parser
, "expected %<;%>");
4077 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
4081 /* If we come here, we have already emitted an error
4082 for an expected `;', identifier or `(', and we also
4083 recovered already. Go on with the next field. */
4086 postfix_attrs
= c_parser_gnu_attributes (parser
);
4087 ret
.spec
= finish_struct (struct_loc
, type
, nreverse (contents
),
4089 chainon (attrs
, postfix_attrs
)),
4091 ret
.kind
= ctsk_tagdef
;
4093 ret
.expr_const_operands
= true;
4094 ret
.has_enum_type_specifier
= false;
4095 timevar_pop (TV_PARSE_STRUCT
);
4100 c_parser_error (parser
, "expected %<{%>");
4101 ret
.spec
= error_mark_node
;
4102 ret
.kind
= ctsk_tagref
;
4103 ret
.expr
= NULL_TREE
;
4104 ret
.expr_const_operands
= true;
4105 ret
.has_enum_type_specifier
= false;
4108 /* Attributes may only appear when the members are defined or in
4109 certain forward declarations. */
4110 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
4111 c_parser_error (parser
, "expected %<;%>");
4112 /* ??? Existing practice is that GNU attributes are ignored after
4113 the struct or union keyword when not defining the members. */
4114 ret
= parser_xref_tag (ident_loc
, code
, ident
, have_std_attrs
, std_attrs
,
4119 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
4120 *without* the trailing semicolon.
4123 attribute-specifier-sequence[opt] specifier-qualifier-list
4124 attribute-specifier-sequence[opt] struct-declarator-list
4125 static_assert-declaration-no-semi
4127 specifier-qualifier-list:
4128 type-specifier specifier-qualifier-list[opt]
4129 type-qualifier specifier-qualifier-list[opt]
4130 alignment-specifier specifier-qualifier-list[opt]
4131 gnu-attributes specifier-qualifier-list[opt]
4133 struct-declarator-list:
4135 struct-declarator-list , gnu-attributes[opt] struct-declarator
4138 declarator gnu-attributes[opt]
4139 declarator[opt] : constant-expression gnu-attributes[opt]
4144 __extension__ struct-declaration
4145 specifier-qualifier-list
4147 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
4148 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
4149 any expression without commas in the syntax (assignment
4150 expressions, not just conditional expressions); assignment
4151 expressions will be diagnosed as non-constant. */
4154 c_parser_struct_declaration (c_parser
*parser
, tree
*expr
)
4156 struct c_declspecs
*specs
;
4158 tree all_prefix_attrs
;
4160 location_t decl_loc
;
4161 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
4165 ext
= disable_extension_diagnostics ();
4166 c_parser_consume_token (parser
);
4167 decl
= c_parser_struct_declaration (parser
, expr
);
4168 restore_extension_diagnostics (ext
);
4171 if (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
4173 c_parser_static_assert_declaration_no_semi (parser
);
4176 specs
= build_null_declspecs ();
4177 decl_loc
= c_parser_peek_token (parser
)->location
;
4178 /* Strictly by the standard, we shouldn't allow _Alignas here,
4179 but it appears to have been intended to allow it there, so
4180 we're keeping it as it is until WG14 reaches a conclusion
4182 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
4183 c_parser_declspecs (parser
, specs
, false, true, true,
4184 true, false, true, true, cla_nonabstract_decl
);
4187 if (!specs
->declspecs_seen_p
)
4189 c_parser_error (parser
, "expected specifier-qualifier-list");
4192 finish_declspecs (specs
);
4193 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
4194 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4197 if (specs
->typespec_kind
== ctsk_none
)
4199 pedwarn (decl_loc
, OPT_Wpedantic
,
4200 "ISO C forbids member declarations with no members");
4201 shadow_tag_warned (specs
, pedantic
);
4206 /* Support for unnamed structs or unions as members of
4207 structs or unions (which is [a] useful and [b] supports
4211 ret
= grokfield (c_parser_peek_token (parser
)->location
,
4212 build_id_declarator (NULL_TREE
), specs
,
4213 NULL_TREE
, &attrs
, expr
);
4215 decl_attributes (&ret
, attrs
, 0);
4220 /* Provide better error recovery. Note that a type name here is valid,
4221 and will be treated as a field name. */
4222 if (specs
->typespec_kind
== ctsk_tagdef
4223 && TREE_CODE (specs
->type
) != ENUMERAL_TYPE
4224 && c_parser_next_token_starts_declspecs (parser
)
4225 && !c_parser_next_token_is (parser
, CPP_NAME
))
4227 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
4228 parser
->error
= false;
4232 pending_xref_error ();
4233 prefix_attrs
= specs
->attrs
;
4234 all_prefix_attrs
= prefix_attrs
;
4235 specs
->attrs
= NULL_TREE
;
4239 /* Declaring one or more declarators or un-named bit-fields. */
4240 struct c_declarator
*declarator
;
4242 if (c_parser_next_token_is (parser
, CPP_COLON
))
4243 declarator
= build_id_declarator (NULL_TREE
);
4245 declarator
= c_parser_declarator (parser
,
4246 specs
->typespec_kind
!= ctsk_none
,
4247 C_DTR_NORMAL
, &dummy
);
4248 if (declarator
== NULL
)
4250 c_parser_skip_to_end_of_block_or_statement (parser
);
4253 if (c_parser_next_token_is (parser
, CPP_COLON
)
4254 || c_parser_next_token_is (parser
, CPP_COMMA
)
4255 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
4256 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
4257 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4259 tree postfix_attrs
= NULL_TREE
;
4260 tree width
= NULL_TREE
;
4262 if (c_parser_next_token_is (parser
, CPP_COLON
))
4264 c_parser_consume_token (parser
);
4265 location_t loc
= c_parser_peek_token (parser
)->location
;
4266 width
= convert_lvalue_to_rvalue (loc
,
4267 (c_parser_expr_no_commas
4271 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4272 postfix_attrs
= c_parser_gnu_attributes (parser
);
4273 d
= grokfield (c_parser_peek_token (parser
)->location
,
4274 declarator
, specs
, width
, &all_prefix_attrs
, expr
);
4275 decl_attributes (&d
, chainon (postfix_attrs
,
4276 all_prefix_attrs
), 0);
4277 DECL_CHAIN (d
) = decls
;
4279 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4280 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
4283 all_prefix_attrs
= prefix_attrs
;
4284 if (c_parser_next_token_is (parser
, CPP_COMMA
))
4285 c_parser_consume_token (parser
);
4286 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
4287 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4289 /* Semicolon consumed in caller. */
4294 c_parser_error (parser
, "expected %<,%>, %<;%> or %<}%>");
4300 c_parser_error (parser
,
4301 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
4302 "%<__attribute__%>");
4309 /* Parse a typeof specifier (a GNU extension adopted in C23).
4312 typeof ( expression )
4313 typeof ( type-name )
4314 typeof_unqual ( expression )
4315 typeof_unqual ( type-name )
4318 static struct c_typespec
4319 c_parser_typeof_specifier (c_parser
*parser
)
4323 struct c_typespec ret
;
4324 ret
.kind
= ctsk_typeof
;
4325 ret
.spec
= error_mark_node
;
4326 ret
.expr
= NULL_TREE
;
4327 ret
.expr_const_operands
= true;
4328 ret
.has_enum_type_specifier
= false;
4329 if (c_parser_next_token_is_keyword (parser
, RID_TYPEOF
))
4332 tree spelling
= c_parser_peek_token (parser
)->value
;
4333 is_std
= (flag_isoc23
4334 && strcmp (IDENTIFIER_POINTER (spelling
), "typeof") == 0);
4338 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TYPEOF_UNQUAL
));
4340 tree spelling
= c_parser_peek_token (parser
)->value
;
4341 is_std
= strcmp (IDENTIFIER_POINTER (spelling
), "typeof_unqual") == 0;
4343 c_parser_consume_token (parser
);
4344 c_inhibit_evaluation_warnings
++;
4346 matching_parens parens
;
4347 if (!parens
.require_open (parser
))
4349 c_inhibit_evaluation_warnings
--;
4353 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
4355 struct c_type_name
*type
= c_parser_type_name (parser
);
4356 c_inhibit_evaluation_warnings
--;
4360 ret
.spec
= groktypename (type
, &ret
.expr
, &ret
.expr_const_operands
);
4361 pop_maybe_used (c_type_variably_modified_p (ret
.spec
));
4367 location_t here
= c_parser_peek_token (parser
)->location
;
4368 struct c_expr expr
= c_parser_expression (parser
);
4369 c_inhibit_evaluation_warnings
--;
4371 if (TREE_CODE (expr
.value
) == COMPONENT_REF
4372 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
4373 error_at (here
, "%<typeof%> applied to a bit-field");
4374 mark_exp_read (expr
.value
);
4375 ret
.spec
= TREE_TYPE (expr
.value
);
4376 was_vm
= c_type_variably_modified_p (ret
.spec
);
4377 /* This is returned with the type so that when the type is
4378 evaluated, this can be evaluated. */
4380 ret
.expr
= c_fully_fold (expr
.value
, false, &ret
.expr_const_operands
);
4381 pop_maybe_used (was_vm
);
4383 parens
.skip_until_found_close (parser
);
4384 if (ret
.spec
!= error_mark_node
)
4386 if (is_unqual
&& TYPE_QUALS (ret
.spec
) != TYPE_UNQUALIFIED
)
4387 ret
.spec
= TYPE_MAIN_VARIANT (ret
.spec
);
4390 /* In ISO C terms, _Noreturn is not part of the type of
4391 expressions such as &abort, but in GCC it is represented
4392 internally as a type qualifier. */
4393 if (TREE_CODE (ret
.spec
) == FUNCTION_TYPE
4394 && TYPE_QUALS (ret
.spec
) != TYPE_UNQUALIFIED
)
4395 ret
.spec
= TYPE_MAIN_VARIANT (ret
.spec
);
4396 else if (FUNCTION_POINTER_TYPE_P (ret
.spec
)
4397 && TYPE_QUALS (TREE_TYPE (ret
.spec
)) != TYPE_UNQUALIFIED
)
4399 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (ret
.spec
)));
4405 /* Parse an alignment-specifier.
4409 alignment-specifier:
4410 _Alignas ( type-name )
4411 _Alignas ( constant-expression )
4415 c_parser_alignas_specifier (c_parser
* parser
)
4417 tree ret
= error_mark_node
;
4418 location_t loc
= c_parser_peek_token (parser
)->location
;
4419 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
));
4420 tree spelling
= c_parser_peek_token (parser
)->value
;
4421 c_parser_consume_token (parser
);
4423 pedwarn_c99 (loc
, OPT_Wpedantic
,
4424 "ISO C99 does not support %qE", spelling
);
4426 pedwarn_c99 (loc
, OPT_Wpedantic
,
4427 "ISO C90 does not support %qE", spelling
);
4428 matching_parens parens
;
4429 if (!parens
.require_open (parser
))
4431 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
4433 struct c_type_name
*type
= c_parser_type_name (parser
);
4435 ret
= c_sizeof_or_alignof_type (loc
, groktypename (type
, NULL
, NULL
),
4439 ret
= convert_lvalue_to_rvalue (loc
,
4440 c_parser_expr_no_commas (parser
, NULL
),
4442 parens
.skip_until_found_close (parser
);
4446 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
4447 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
4448 a typedef name may be redeclared; otherwise it may not. KIND
4449 indicates which kind of declarator is wanted. Returns a valid
4450 declarator except in the case of a syntax error in which case NULL is
4451 returned. *SEEN_ID is set to true if an identifier being declared is
4452 seen; this is used to diagnose bad forms of abstract array declarators
4453 and to determine whether an identifier list is syntactically permitted.
4456 pointer[opt] direct-declarator
4460 ( gnu-attributes[opt] declarator )
4461 direct-declarator array-declarator
4462 direct-declarator ( parameter-type-list )
4463 direct-declarator ( identifier-list[opt] )
4466 * type-qualifier-list[opt]
4467 * type-qualifier-list[opt] pointer
4469 type-qualifier-list:
4472 type-qualifier-list type-qualifier
4473 type-qualifier-list gnu-attributes
4476 [ type-qualifier-list[opt] assignment-expression[opt] ]
4477 [ static type-qualifier-list[opt] assignment-expression ]
4478 [ type-qualifier-list static assignment-expression ]
4479 [ type-qualifier-list[opt] * ]
4481 parameter-type-list:
4483 parameter-list , ...
4486 parameter-declaration
4487 parameter-list , parameter-declaration
4489 parameter-declaration:
4490 declaration-specifiers declarator gnu-attributes[opt]
4491 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
4495 identifier-list , identifier
4497 abstract-declarator:
4499 pointer[opt] direct-abstract-declarator
4501 direct-abstract-declarator:
4502 ( gnu-attributes[opt] abstract-declarator )
4503 direct-abstract-declarator[opt] array-declarator
4504 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
4509 direct-declarator ( parameter-forward-declarations
4510 parameter-type-list[opt] )
4512 direct-abstract-declarator:
4513 direct-abstract-declarator[opt] ( parameter-forward-declarations
4514 parameter-type-list[opt] )
4516 parameter-forward-declarations:
4518 parameter-forward-declarations parameter-list ;
4520 The uses of gnu-attributes shown above are GNU extensions.
4522 Some forms of array declarator are not included in C99 in the
4523 syntax for abstract declarators; these are disallowed elsewhere.
4524 This may be a defect (DR#289).
4526 This function also accepts an omitted abstract declarator as being
4527 an abstract declarator, although not part of the formal syntax. */
4529 struct c_declarator
*
4530 c_parser_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
4533 /* Parse any initial pointer part. */
4534 if (c_parser_next_token_is (parser
, CPP_MULT
))
4536 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4537 struct c_declarator
*inner
;
4538 c_parser_consume_token (parser
);
4539 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4540 false, false, true, false, cla_prefer_id
);
4541 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4545 return make_pointer_declarator (quals_attrs
, inner
);
4547 /* Now we have a direct declarator, direct abstract declarator or
4548 nothing (which counts as a direct abstract declarator here). */
4549 return c_parser_direct_declarator (parser
, type_seen_p
, kind
, seen_id
);
4552 /* Parse a direct declarator or direct abstract declarator; arguments
4553 as c_parser_declarator. */
4555 static struct c_declarator
*
4556 c_parser_direct_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
4559 /* The direct declarator must start with an identifier (possibly
4560 omitted) or a parenthesized declarator (possibly abstract). In
4561 an ordinary declarator, initial parentheses must start a
4562 parenthesized declarator. In an abstract declarator or parameter
4563 declarator, they could start a parenthesized declarator or a
4564 parameter list. To tell which, the open parenthesis and any
4565 following gnu-attributes must be read. If a declaration
4566 specifier or standard attributes follow, then it is a parameter
4567 list; if the specifier is a typedef name, there might be an
4568 ambiguity about redeclaring it, which is resolved in the
4569 direction of treating it as a typedef name. If a close
4570 parenthesis follows, it is also an empty parameter list, as the
4571 syntax does not permit empty abstract declarators. Otherwise, it
4572 is a parenthesized declarator (in which case the analysis may be
4573 repeated inside it, recursively).
4575 ??? There is an ambiguity in a parameter declaration "int
4576 (__attribute__((foo)) x)", where x is not a typedef name: it
4577 could be an abstract declarator for a function, or declare x with
4578 parentheses. The proper resolution of this ambiguity needs
4579 documenting. At present we follow an accident of the old
4580 parser's implementation, whereby the first parameter must have
4581 some declaration specifiers other than just gnu-attributes. Thus as
4582 a parameter declaration it is treated as a parenthesized
4583 parameter named x, and as an abstract declarator it is
4586 ??? Also following the old parser, gnu-attributes inside an empty
4587 parameter list are ignored, making it a list not yielding a
4588 prototype, rather than giving an error or making it have one
4589 parameter with implicit type int.
4591 ??? Also following the old parser, typedef names may be
4592 redeclared in declarators, but not Objective-C class names. */
4594 if (kind
!= C_DTR_ABSTRACT
4595 && c_parser_next_token_is (parser
, CPP_NAME
)
4597 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
4598 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
4599 || c_parser_peek_token (parser
)->id_kind
== C_ID_ID
))
4601 struct c_declarator
*inner
4602 = build_id_declarator (c_parser_peek_token (parser
)->value
);
4604 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
4605 c_parser_consume_token (parser
);
4606 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4607 inner
->u
.id
.attrs
= c_parser_std_attribute_specifier_sequence (parser
);
4608 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4611 if (kind
!= C_DTR_NORMAL
4612 && c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4613 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4615 struct c_declarator
*inner
= build_id_declarator (NULL_TREE
);
4616 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
4617 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4620 /* Either we are at the end of an abstract declarator, or we have
4623 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4626 struct c_declarator
*inner
;
4627 c_parser_consume_token (parser
);
4628 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4630 attrs
= c_parser_gnu_attributes (parser
);
4631 if (kind
!= C_DTR_NORMAL
4632 && (c_parser_next_token_starts_declspecs (parser
)
4634 && (c_parser_nth_token_starts_std_attributes (parser
, 1)
4635 || c_parser_next_token_is (parser
, CPP_ELLIPSIS
)))
4636 || c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
)))
4638 struct c_arg_info
*args
4639 = c_parser_parms_declarator (parser
, kind
== C_DTR_NORMAL
,
4640 attrs
, have_gnu_attrs
);
4645 inner
= build_id_declarator (NULL_TREE
);
4647 && args
->types
!= error_mark_node
4648 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4649 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4652 = c_parser_std_attribute_specifier_sequence (parser
);
4654 inner
= build_attrs_declarator (std_attrs
, inner
);
4656 inner
= build_function_declarator (args
, inner
);
4657 return c_parser_direct_declarator_inner (parser
, *seen_id
,
4661 /* A parenthesized declarator. */
4662 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4663 if (inner
!= NULL
&& attrs
!= NULL
)
4664 inner
= build_attrs_declarator (attrs
, inner
);
4665 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4667 c_parser_consume_token (parser
);
4671 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4675 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4682 if (kind
== C_DTR_NORMAL
)
4684 c_parser_error (parser
, "expected identifier or %<(%>");
4688 return build_id_declarator (NULL_TREE
);
4692 /* Parse part of a direct declarator or direct abstract declarator,
4693 given that some (in INNER) has already been parsed; ID_PRESENT is
4694 true if an identifier is present, false for an abstract
4697 static struct c_declarator
*
4698 c_parser_direct_declarator_inner (c_parser
*parser
, bool id_present
,
4699 struct c_declarator
*inner
)
4701 /* Parse a sequence of array declarators and parameter lists. */
4702 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4703 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4705 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
4706 struct c_declarator
*declarator
;
4707 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4710 struct c_expr dimen
;
4711 dimen
.value
= NULL_TREE
;
4712 dimen
.original_code
= ERROR_MARK
;
4713 dimen
.original_type
= NULL_TREE
;
4714 c_parser_consume_token (parser
);
4715 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4716 false, false, false, false, cla_prefer_id
);
4717 static_seen
= c_parser_next_token_is_keyword (parser
, RID_STATIC
);
4719 c_parser_consume_token (parser
);
4720 if (static_seen
&& !quals_attrs
->declspecs_seen_p
)
4721 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4722 false, false, false, false, cla_prefer_id
);
4723 if (!quals_attrs
->declspecs_seen_p
)
4725 /* If "static" is present, there must be an array dimension.
4726 Otherwise, there may be a dimension, "*", or no
4731 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4735 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4737 dimen
.value
= NULL_TREE
;
4740 else if (c_parser_next_token_is (parser
, CPP_MULT
))
4742 if (c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_SQUARE
)
4744 dimen
.value
= NULL_TREE
;
4746 c_parser_consume_token (parser
);
4751 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4757 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4760 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4761 c_parser_consume_token (parser
);
4764 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4769 dimen
= convert_lvalue_to_rvalue (brace_loc
, dimen
, true, true);
4770 declarator
= build_array_declarator (brace_loc
, dimen
.value
, quals_attrs
,
4771 static_seen
, star_seen
);
4772 if (declarator
== NULL
)
4774 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4777 = c_parser_std_attribute_specifier_sequence (parser
);
4779 inner
= build_attrs_declarator (std_attrs
, inner
);
4781 inner
= set_array_declarator_inner (declarator
, inner
);
4782 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4784 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4787 struct c_arg_info
*args
;
4788 c_parser_consume_token (parser
);
4789 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4791 attrs
= c_parser_gnu_attributes (parser
);
4792 args
= c_parser_parms_declarator (parser
, id_present
, attrs
,
4799 && args
->types
!= error_mark_node
4800 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4801 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4804 = c_parser_std_attribute_specifier_sequence (parser
);
4806 inner
= build_attrs_declarator (std_attrs
, inner
);
4808 inner
= build_function_declarator (args
, inner
);
4809 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4815 /* Parse a parameter list or identifier list, including the closing
4816 parenthesis but not the opening one. ATTRS are the gnu-attributes
4817 at the start of the list. ID_LIST_OK is true if an identifier list
4818 is acceptable; such a list must not have attributes at the start.
4819 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4820 attributes) were present (in which case standard attributes cannot
4823 static struct c_arg_info
*
4824 c_parser_parms_declarator (c_parser
*parser
, bool id_list_ok
, tree attrs
,
4825 bool have_gnu_attrs
)
4828 declare_parm_level ();
4829 /* If the list starts with an identifier, it is an identifier list.
4830 Otherwise, it is either a prototype list or an empty list. */
4833 && c_parser_next_token_is (parser
, CPP_NAME
)
4834 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4836 /* Look ahead to detect typos in type names. */
4837 && c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
4838 && c_parser_peek_2nd_token (parser
)->type
!= CPP_MULT
4839 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
4840 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_SQUARE
4841 && c_parser_peek_2nd_token (parser
)->type
!= CPP_KEYWORD
)
4843 tree list
= NULL_TREE
, *nextp
= &list
;
4844 while (c_parser_next_token_is (parser
, CPP_NAME
)
4845 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
4847 *nextp
= build_tree_list (NULL_TREE
,
4848 c_parser_peek_token (parser
)->value
);
4849 nextp
= & TREE_CHAIN (*nextp
);
4850 c_parser_consume_token (parser
);
4851 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
4853 c_parser_consume_token (parser
);
4854 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4856 c_parser_error (parser
, "expected identifier");
4860 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4862 struct c_arg_info
*ret
= build_arg_info ();
4864 c_parser_consume_token (parser
);
4870 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4878 struct c_arg_info
*ret
4879 = c_parser_parms_list_declarator (parser
, attrs
, NULL
, have_gnu_attrs
);
4885 /* Parse a parameter list (possibly empty), including the closing
4886 parenthesis but not the opening one. ATTRS are the gnu-attributes
4887 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4888 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4889 which means standard attributes cannot start the list. EXPR is
4890 NULL or an expression that needs to be evaluated for the side
4891 effects of array size expressions in the parameters. */
4893 static struct c_arg_info
*
4894 c_parser_parms_list_declarator (c_parser
*parser
, tree attrs
, tree expr
,
4895 bool have_gnu_attrs
)
4897 bool bad_parm
= false;
4899 /* ??? Following the old parser, forward parameter declarations may
4900 use abstract declarators, and if no real parameter declarations
4901 follow the forward declarations then this is not diagnosed. Also
4902 note as above that gnu-attributes are ignored as the only contents of
4903 the parentheses, or as the only contents after forward
4905 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4907 struct c_arg_info
*ret
= build_arg_info ();
4908 c_parser_consume_token (parser
);
4911 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
) && !have_gnu_attrs
)
4913 struct c_arg_info
*ret
= build_arg_info ();
4915 ret
->types
= NULL_TREE
;
4916 pedwarn_c11 (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
4917 "ISO C requires a named argument before %<...%> "
4919 c_parser_consume_token (parser
);
4920 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4922 ret
->no_named_args_stdarg_p
= true;
4923 c_parser_consume_token (parser
);
4928 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4933 /* Nonempty list of parameters, either terminated with semicolon
4934 (forward declarations; recurse) or with close parenthesis (normal
4935 function) or with ", ... )" (variadic function). */
4938 /* Parse a parameter. */
4939 struct c_parm
*parm
= c_parser_parameter_declaration (parser
, attrs
,
4942 have_gnu_attrs
= false;
4946 push_parm_decl (parm
, &expr
);
4947 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4950 c_parser_consume_token (parser
);
4951 mark_forward_parm_decls ();
4952 bool new_have_gnu_attrs
4953 = c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
);
4954 new_attrs
= c_parser_gnu_attributes (parser
);
4955 return c_parser_parms_list_declarator (parser
, new_attrs
, expr
,
4956 new_have_gnu_attrs
);
4958 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4960 c_parser_consume_token (parser
);
4964 return get_parm_info (false, expr
);
4966 if (!c_parser_require (parser
, CPP_COMMA
,
4967 "expected %<;%>, %<,%> or %<)%>",
4968 UNKNOWN_LOCATION
, false))
4970 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4973 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4975 c_parser_consume_token (parser
);
4976 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4978 c_parser_consume_token (parser
);
4982 return get_parm_info (true, expr
);
4986 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4994 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4995 start of the declaration if it is the first parameter;
4996 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4999 static struct c_parm
*
5000 c_parser_parameter_declaration (c_parser
*parser
, tree attrs
,
5001 bool have_gnu_attrs
)
5003 struct c_declspecs
*specs
;
5004 struct c_declarator
*declarator
;
5006 tree postfix_attrs
= NULL_TREE
;
5009 /* Accept #pragmas between parameter declarations. */
5010 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
5011 c_parser_pragma (parser
, pragma_param
, NULL
);
5013 if (!c_parser_next_token_starts_declspecs (parser
)
5014 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
5016 c_token
*token
= c_parser_peek_token (parser
);
5019 c_parser_set_source_position_from_token (token
);
5020 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
5022 auto_diagnostic_group d
;
5023 name_hint hint
= lookup_name_fuzzy (token
->value
,
5024 FUZZY_LOOKUP_TYPENAME
,
5026 if (const char *suggestion
= hint
.suggestion ())
5028 gcc_rich_location
richloc (token
->location
);
5029 richloc
.add_fixit_replace (suggestion
);
5031 "unknown type name %qE; did you mean %qs?",
5032 token
->value
, suggestion
);
5035 error_at (token
->location
, "unknown type name %qE", token
->value
);
5036 parser
->error
= true;
5038 /* ??? In some Objective-C cases '...' isn't applicable so there
5039 should be a different message. */
5041 c_parser_error (parser
,
5042 "expected declaration specifiers or %<...%>");
5043 c_parser_skip_to_end_of_parameter (parser
);
5047 location_t start_loc
= c_parser_peek_token (parser
)->location
;
5049 specs
= build_null_declspecs ();
5052 declspecs_add_attrs (input_location
, specs
, attrs
);
5055 c_parser_declspecs (parser
, specs
, true, true, true, true, false,
5056 !have_gnu_attrs
, true, cla_nonabstract_decl
);
5057 finish_declspecs (specs
);
5058 pending_xref_error ();
5059 prefix_attrs
= specs
->attrs
;
5060 specs
->attrs
= NULL_TREE
;
5061 declarator
= c_parser_declarator (parser
,
5062 specs
->typespec_kind
!= ctsk_none
,
5063 C_DTR_PARM
, &dummy
);
5064 if (declarator
== NULL
)
5066 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5069 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
5070 postfix_attrs
= c_parser_gnu_attributes (parser
);
5072 /* Generate a location for the parameter, ranging from the start of the
5073 initial token to the end of the final token.
5075 If we have a identifier, then use it for the caret location, e.g.
5077 extern int callee (int one, int (*two)(int, int), float three);
5078 ~~~~~~^~~~~~~~~~~~~~
5080 otherwise, reuse the start location for the caret location e.g.:
5082 extern int callee (int one, int (*)(int, int), float three);
5085 location_t end_loc
= parser
->last_token_location
;
5087 /* Find any cdk_id declarator; determine if we have an identifier. */
5088 c_declarator
*id_declarator
= declarator
;
5089 while (id_declarator
&& id_declarator
->kind
!= cdk_id
)
5090 id_declarator
= id_declarator
->declarator
;
5091 location_t caret_loc
= (id_declarator
->u
.id
.id
5092 ? id_declarator
->id_loc
5094 location_t param_loc
= make_location (caret_loc
, start_loc
, end_loc
);
5096 return build_c_parm (specs
, chainon (postfix_attrs
, prefix_attrs
),
5097 declarator
, param_loc
);
5100 /* Parse a string literal in an asm expression. It should not be
5101 translated, and wide string literals are an error although
5102 permitted by the syntax. This is a GNU extension.
5109 c_parser_asm_string_literal (c_parser
*parser
)
5112 int save_flag
= warn_overlength_strings
;
5113 warn_overlength_strings
= 0;
5114 str
= c_parser_string_literal (parser
, false, false).value
;
5115 warn_overlength_strings
= save_flag
;
5119 /* Parse a simple asm expression. This is used in restricted
5120 contexts, where a full expression with inputs and outputs does not
5121 make sense. This is a GNU extension.
5124 asm ( asm-string-literal )
5128 c_parser_simple_asm_expr (c_parser
*parser
)
5131 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
5132 c_parser_consume_token (parser
);
5133 matching_parens parens
;
5134 if (!parens
.require_open (parser
))
5136 str
= c_parser_asm_string_literal (parser
);
5137 if (!parens
.require_close (parser
))
5139 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
5146 c_parser_gnu_attribute_any_word (c_parser
*parser
)
5148 tree attr_name
= NULL_TREE
;
5150 if (c_parser_next_token_is (parser
, CPP_KEYWORD
))
5152 /* ??? See comment above about what keywords are accepted here. */
5154 switch (c_parser_peek_token (parser
)->keyword
)
5186 case RID_TRANSACTION_ATOMIC
:
5187 case RID_TRANSACTION_CANCEL
:
5204 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
5205 attr_name
= ridpointers
[(int) c_parser_peek_token (parser
)->keyword
];
5207 else if (c_parser_next_token_is (parser
, CPP_NAME
))
5208 attr_name
= c_parser_peek_token (parser
)->value
;
5213 /* Parse attribute arguments. This is a common form of syntax
5214 covering all currently valid GNU and standard attributes.
5216 gnu-attribute-arguments:
5218 identifier , nonempty-expr-list
5221 where the "identifier" must not be declared as a type. ??? Why not
5222 allow identifiers declared as types to start the arguments? */
5225 c_parser_attribute_arguments (c_parser
*parser
, bool takes_identifier
,
5226 bool require_string
, bool assume_attr
,
5227 bool allow_empty_args
)
5229 vec
<tree
, va_gc
> *expr_list
;
5231 /* Parse the attribute contents. If they start with an
5232 identifier which is followed by a comma or close
5233 parenthesis, then the arguments start with that
5234 identifier; otherwise they are an expression list.
5235 In objective-c the identifier may be a classname. */
5236 if (c_parser_next_token_is (parser
, CPP_NAME
)
5237 && (c_parser_peek_token (parser
)->id_kind
== C_ID_ID
5238 || (c_dialect_objc ()
5239 && c_parser_peek_token (parser
)->id_kind
5241 && ((c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
5242 || (c_parser_peek_2nd_token (parser
)->type
5243 == CPP_CLOSE_PAREN
))
5244 && (takes_identifier
5245 || (c_dialect_objc ()
5247 && c_parser_peek_token (parser
)->id_kind
5248 == C_ID_CLASSNAME
)))
5250 tree arg1
= c_parser_peek_token (parser
)->value
;
5251 c_parser_consume_token (parser
);
5252 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5253 attr_args
= build_tree_list (NULL_TREE
, arg1
);
5257 c_parser_consume_token (parser
);
5258 expr_list
= c_parser_expr_list (parser
, false, true,
5259 NULL
, NULL
, NULL
, NULL
);
5260 tree_list
= build_tree_list_vec (expr_list
);
5261 attr_args
= tree_cons (NULL_TREE
, arg1
, tree_list
);
5262 release_tree_vector (expr_list
);
5267 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5269 if (!allow_empty_args
)
5270 error_at (c_parser_peek_token (parser
)->location
,
5271 "parentheses must be omitted if "
5272 "attribute argument list is empty");
5273 attr_args
= NULL_TREE
;
5275 else if (require_string
)
5277 /* The only valid argument for this attribute is a string
5278 literal. Handle this specially here to avoid accepting
5279 string literals with excess parentheses. */
5280 tree string
= c_parser_string_literal (parser
, false, true).value
;
5281 attr_args
= build_tree_list (NULL_TREE
, string
);
5283 else if (assume_attr
)
5286 = c_parser_conditional_expression (parser
, NULL
, NULL_TREE
).value
;
5287 if (!c_parser_next_token_is (parser
, CPP_COMMA
))
5288 attr_args
= build_tree_list (NULL_TREE
, cond
);
5292 c_parser_consume_token (parser
);
5293 expr_list
= c_parser_expr_list (parser
, false, true,
5294 NULL
, NULL
, NULL
, NULL
);
5295 tree_list
= build_tree_list_vec (expr_list
);
5296 attr_args
= tree_cons (NULL_TREE
, cond
, tree_list
);
5297 release_tree_vector (expr_list
);
5302 expr_list
= c_parser_expr_list (parser
, false, true,
5303 NULL
, NULL
, NULL
, NULL
);
5304 attr_args
= build_tree_list_vec (expr_list
);
5305 release_tree_vector (expr_list
);
5311 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
5315 gnu-attributes gnu-attribute
5318 __attribute__ ( ( gnu-attribute-list ) )
5322 gnu-attribute_list , gnu-attrib
5327 any-word ( gnu-attribute-arguments )
5329 where "any-word" may be any identifier (including one declared as a
5330 type), a reserved word storage class specifier, type specifier or
5331 type qualifier. ??? This still leaves out most reserved keywords
5332 (following the old parser), shouldn't we include them?
5333 When EXPECT_COMMA is true, expect the attribute to be preceded
5334 by a comma and fail if it isn't.
5335 When EMPTY_OK is true, allow and consume any number of consecutive
5336 commas with no attributes in between. */
5339 c_parser_gnu_attribute (c_parser
*parser
, tree attrs
,
5340 bool expect_comma
= false, bool empty_ok
= true)
5342 bool comma_first
= c_parser_next_token_is (parser
, CPP_COMMA
);
5344 && !c_parser_next_token_is (parser
, CPP_NAME
)
5345 && !c_parser_next_token_is (parser
, CPP_KEYWORD
))
5348 while (c_parser_next_token_is (parser
, CPP_COMMA
))
5350 c_parser_consume_token (parser
);
5355 tree attr_name
= c_parser_gnu_attribute_any_word (parser
);
5356 if (attr_name
== NULL_TREE
)
5359 attr_name
= canonicalize_attr_name (attr_name
);
5360 c_parser_consume_token (parser
);
5363 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
5365 if (expect_comma
&& !comma_first
)
5367 /* A comma is missing between the last attribute on the chain
5369 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5371 return error_mark_node
;
5373 attr
= build_tree_list (attr_name
, NULL_TREE
);
5374 /* Add this attribute to the list. */
5375 attrs
= chainon (attrs
, attr
);
5378 c_parser_consume_token (parser
);
5381 = c_parser_attribute_arguments (parser
,
5382 attribute_takes_identifier_p (attr_name
),
5384 is_attribute_p ("assume", attr_name
),
5387 attr
= build_tree_list (attr_name
, attr_args
);
5388 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5389 c_parser_consume_token (parser
);
5392 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5394 return error_mark_node
;
5397 if (expect_comma
&& !comma_first
)
5399 /* A comma is missing between the last attribute on the chain
5401 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5403 return error_mark_node
;
5406 /* Add this attribute to the list. */
5407 attrs
= chainon (attrs
, attr
);
5412 c_parser_gnu_attributes (c_parser
*parser
)
5414 tree attrs
= NULL_TREE
;
5415 while (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
5417 bool save_translate_strings_p
= parser
->translate_strings_p
;
5418 parser
->translate_strings_p
= false;
5419 /* Consume the `__attribute__' keyword. */
5420 c_parser_consume_token (parser
);
5421 /* Look for the two `(' tokens. */
5422 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
5424 parser
->translate_strings_p
= save_translate_strings_p
;
5427 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
5429 parser
->translate_strings_p
= save_translate_strings_p
;
5430 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
5433 /* Parse the attribute list. Require a comma between successive
5434 (possibly empty) attributes. */
5435 for (bool expect_comma
= false; ; expect_comma
= true)
5437 /* Parse a single attribute. */
5438 tree attr
= c_parser_gnu_attribute (parser
, attrs
, expect_comma
);
5439 if (attr
== error_mark_node
)
5446 /* Look for the two `)' tokens. */
5447 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5448 c_parser_consume_token (parser
);
5451 parser
->translate_strings_p
= save_translate_strings_p
;
5452 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5456 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5457 c_parser_consume_token (parser
);
5460 parser
->translate_strings_p
= save_translate_strings_p
;
5461 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5465 parser
->translate_strings_p
= save_translate_strings_p
;
5471 /* Parse an optional balanced token sequence.
5473 balanced-token-sequence:
5475 balanced-token-sequence balanced-token
5478 ( balanced-token-sequence[opt] )
5479 [ balanced-token-sequence[opt] ]
5480 { balanced-token-sequence[opt] }
5481 any token other than ()[]{}
5485 c_parser_balanced_token_sequence (c_parser
*parser
)
5489 c_token
*token
= c_parser_peek_token (parser
);
5490 switch (token
->type
)
5492 case CPP_OPEN_BRACE
:
5494 matching_braces braces
;
5495 braces
.consume_open (parser
);
5496 c_parser_balanced_token_sequence (parser
);
5497 braces
.require_close (parser
);
5501 case CPP_OPEN_PAREN
:
5503 matching_parens parens
;
5504 parens
.consume_open (parser
);
5505 c_parser_balanced_token_sequence (parser
);
5506 parens
.require_close (parser
);
5510 case CPP_OPEN_SQUARE
:
5511 c_parser_consume_token (parser
);
5512 c_parser_balanced_token_sequence (parser
);
5513 c_parser_require (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5516 case CPP_CLOSE_BRACE
:
5517 case CPP_CLOSE_PAREN
:
5518 case CPP_CLOSE_SQUARE
:
5523 c_parser_consume_pragma (parser
);
5524 c_parser_skip_to_pragma_eol (parser
, false);
5528 c_parser_consume_token (parser
);
5534 static bool c_parser_check_balanced_raw_token_sequence (c_parser
*,
5537 /* Parse arguments of omp::directive or omp::decl attribute.
5539 directive-name ,[opt] clause-list[opt]
5541 For directive just remember the tokens in a vector for subsequent
5545 c_parser_omp_directive_args (c_parser
*parser
, tree attribute
, bool decl_p
)
5548 c_token
*first
= c_parser_peek_token (parser
);
5549 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
)
5550 || (c_parser_peek_nth_token_raw (parser
, n
)->type
5551 != CPP_CLOSE_PAREN
))
5553 c_parser_balanced_token_sequence (parser
);
5554 TREE_VALUE (attribute
) = NULL_TREE
;
5559 error_at (first
->location
, "expected OpenMP directive name");
5560 TREE_VALUE (attribute
) = NULL_TREE
;
5563 vec
<c_token
, va_gc
> *v
;
5564 vec_alloc (v
, n
- 1);
5567 c_token
*tok
= c_parser_peek_token (parser
);
5568 v
->quick_push (*tok
);
5569 c_parser_consume_token (parser
);
5571 tree arg
= make_node (C_TOKEN_VEC
);
5572 C_TOKEN_VEC_TOKENS (arg
) = v
;
5574 TREE_PUBLIC (arg
) = 1;
5575 TREE_VALUE (attribute
) = tree_cons (NULL_TREE
, arg
, TREE_VALUE (attribute
));
5578 /* Parse arguments of omp::sequence attribute.
5580 omp::[opt] directive-attr [ , omp::[opt] directive-attr ]... */
5583 c_parser_omp_sequence_args (c_parser
*parser
, tree attribute
)
5587 c_token
*token
= c_parser_peek_token (parser
);
5588 if (token
->type
== CPP_NAME
5589 && strcmp (IDENTIFIER_POINTER (token
->value
), "omp") == 0
5590 && c_parser_peek_2nd_token (parser
)->type
== CPP_SCOPE
)
5592 c_parser_consume_token (parser
);
5593 c_parser_consume_token (parser
);
5594 token
= c_parser_peek_token (parser
);
5596 bool directive
= false;
5598 if (token
->type
!= CPP_NAME
)
5601 p
= IDENTIFIER_POINTER (token
->value
);
5602 if (strcmp (p
, "directive") == 0)
5604 else if (strcmp (p
, "sequence") != 0)
5606 error_at (token
->location
, "expected %<directive%> or %<sequence%>");
5607 unsigned nesting_depth
= 0;
5611 /* Peek at the next token. */
5612 token
= c_parser_peek_token (parser
);
5613 /* If we've reached the token we want, consume it and stop. */
5614 if ((token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_COMMA
)
5617 /* If we've run out of tokens, stop. */
5618 if (token
->type
== CPP_EOF
)
5620 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
5622 if (token
->type
== CPP_OPEN_BRACE
5623 || token
->type
== CPP_OPEN_PAREN
5624 || token
->type
== CPP_OPEN_SQUARE
)
5626 else if (token
->type
== CPP_CLOSE_BRACE
5627 || token
->type
== CPP_CLOSE_PAREN
5628 || token
->type
== CPP_CLOSE_SQUARE
)
5630 if (nesting_depth
-- == 0)
5633 /* Consume this token. */
5634 c_parser_consume_token (parser
);
5636 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5638 c_parser_consume_token (parser
);
5641 c_parser_consume_token (parser
);
5642 matching_parens parens
;
5643 if (parens
.require_open (parser
))
5646 c_parser_omp_directive_args (parser
, attribute
, false);
5648 c_parser_omp_sequence_args (parser
, attribute
);
5649 parens
.skip_until_found_close (parser
);
5650 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5652 c_parser_consume_token (parser
);
5654 else if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5657 c_parser_consume_token (parser
);
5662 /* Parse standard (C23) attributes (including GNU attributes in the
5665 attribute-specifier-sequence:
5666 attribute-specifier-sequence[opt] attribute-specifier
5668 attribute-specifier:
5669 [ [ attribute-list ] ]
5673 attribute-list, attribute[opt]
5676 attribute-token attribute-argument-clause[opt]
5680 attribute-prefixed-token
5685 attribute-prefixed-token:
5686 attribute-prefix :: identifier
5691 attribute-argument-clause:
5692 ( balanced-token-sequence[opt] )
5694 Keywords are accepted as identifiers for this purpose.
5696 As an extension, we permit an attribute-specifier to be:
5698 [ [ __extension__ attribute-list ] ]
5700 Two colons are then accepted as a synonym for ::. No attempt is made
5701 to check whether the colons are immediately adjacent. LOOSE_SCOPE_P
5702 indicates whether this relaxation is in effect. */
5705 c_parser_std_attribute (c_parser
*parser
, bool for_tm
,
5706 bool loose_scope_p
= false)
5708 c_token
*token
= c_parser_peek_token (parser
);
5709 tree ns
, name
, attribute
;
5711 /* Parse the attribute-token. */
5712 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
5714 c_parser_error (parser
, "expected identifier");
5715 return error_mark_node
;
5717 name
= canonicalize_attr_name (token
->value
);
5718 c_parser_consume_token (parser
);
5719 if (c_parser_next_token_is (parser
, CPP_SCOPE
)
5721 && c_parser_next_token_is (parser
, CPP_COLON
)
5722 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5725 if (c_parser_next_token_is (parser
, CPP_COLON
))
5726 c_parser_consume_token (parser
);
5727 c_parser_consume_token (parser
);
5728 token
= c_parser_peek_token (parser
);
5729 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
5731 c_parser_error (parser
, "expected identifier");
5732 return error_mark_node
;
5734 name
= canonicalize_attr_name (token
->value
);
5735 c_parser_consume_token (parser
);
5739 attribute
= build_tree_list (build_tree_list (ns
, name
), NULL_TREE
);
5741 /* Parse the arguments, if any. */
5742 const attribute_spec
*as
= lookup_attribute_spec (TREE_PURPOSE (attribute
));
5743 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
5745 if ((flag_openmp
|| flag_openmp_simd
)
5747 && is_attribute_p ("omp", ns
)
5748 && (is_attribute_p ("directive", name
)
5749 || is_attribute_p ("sequence", name
)
5750 || is_attribute_p ("decl", name
)))
5752 error ("%<omp::%E%> attribute requires argument", name
);
5753 return error_mark_node
;
5758 location_t open_loc
= c_parser_peek_token (parser
)->location
;
5759 matching_parens parens
;
5760 parens
.consume_open (parser
);
5761 if ((as
&& as
->max_length
== 0)
5762 /* Special-case the transactional-memory attribute "outer",
5763 which is specially handled but not registered as an
5764 attribute, to avoid allowing arbitrary balanced token
5765 sequences as arguments. */
5766 || is_attribute_p ("outer", name
))
5768 error_at (open_loc
, "%qE attribute does not take any arguments", name
);
5769 parens
.skip_until_found_close (parser
);
5770 return error_mark_node
;
5772 /* If this is a fake attribute created to handle -Wno-attributes,
5773 we must skip parsing the arguments. */
5774 if (as
&& !attribute_ignored_p (as
))
5776 bool takes_identifier
5778 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
5779 && attribute_takes_identifier_p (name
));
5782 && (strcmp (IDENTIFIER_POINTER (name
), "deprecated") == 0
5783 || strcmp (IDENTIFIER_POINTER (name
), "nodiscard") == 0));
5786 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
5787 && strcmp (IDENTIFIER_POINTER (name
), "assume") == 0);
5788 TREE_VALUE (attribute
)
5789 = c_parser_attribute_arguments (parser
, takes_identifier
,
5790 require_string
, assume_attr
, false);
5794 if ((flag_openmp
|| flag_openmp_simd
)
5796 && is_attribute_p ("omp", ns
))
5798 if (is_attribute_p ("directive", name
))
5800 c_parser_omp_directive_args (parser
, attribute
, false);
5801 parens
.skip_until_found_close (parser
);
5804 else if (is_attribute_p ("decl", name
))
5806 TREE_VALUE (TREE_PURPOSE (attribute
))
5807 = get_identifier ("directive");
5808 c_parser_omp_directive_args (parser
, attribute
, true);
5809 parens
.skip_until_found_close (parser
);
5812 else if (is_attribute_p ("sequence", name
))
5814 TREE_VALUE (TREE_PURPOSE (attribute
))
5815 = get_identifier ("directive");
5816 c_parser_omp_sequence_args (parser
, attribute
);
5817 parens
.skip_until_found_close (parser
);
5818 TREE_VALUE (attribute
) = nreverse (TREE_VALUE (attribute
));
5822 c_parser_balanced_token_sequence (parser
);
5824 parens
.require_close (parser
);
5827 if (ns
== NULL_TREE
&& !for_tm
&& !as
)
5829 /* An attribute with standard syntax and no namespace specified
5830 is a constraint violation if it is not one of the known
5831 standard attributes. Diagnose it here with a pedwarn and
5832 then discard it to prevent a duplicate warning later. */
5833 pedwarn (input_location
, OPT_Wattributes
, "%qE attribute ignored",
5835 return error_mark_node
;
5841 c_parser_std_attribute_list (c_parser
*parser
, bool for_tm
,
5842 bool loose_scope_p
= false)
5844 tree attributes
= NULL_TREE
;
5847 c_token
*token
= c_parser_peek_token (parser
);
5848 if (token
->type
== CPP_CLOSE_SQUARE
)
5850 if (token
->type
== CPP_COMMA
)
5852 c_parser_consume_token (parser
);
5855 tree attribute
= c_parser_std_attribute (parser
, for_tm
, loose_scope_p
);
5856 if (attribute
!= error_mark_node
)
5858 TREE_CHAIN (attribute
) = attributes
;
5859 attributes
= attribute
;
5861 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5868 c_parser_std_attribute_specifier (c_parser
*parser
, bool for_tm
)
5870 location_t loc
= c_parser_peek_token (parser
)->location
;
5871 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
5873 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
5875 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5879 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
5881 auto ext
= disable_extension_diagnostics ();
5882 c_parser_consume_token (parser
);
5883 attributes
= c_parser_std_attribute_list (parser
, for_tm
, true);
5884 restore_extension_diagnostics (ext
);
5889 pedwarn_c11 (loc
, OPT_Wpedantic
,
5890 "ISO C does not support %<[[]]%> attributes before C23");
5891 attributes
= c_parser_std_attribute_list (parser
, for_tm
);
5893 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5894 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5895 return nreverse (attributes
);
5898 /* Look past an optional balanced token sequence of raw look-ahead
5899 tokens starting with the *Nth token. *N is updated to point to the
5900 following token. Return true if such a sequence was found, false
5901 if the tokens parsed were not balanced. */
5904 c_parser_check_balanced_raw_token_sequence (c_parser
*parser
, unsigned int *n
)
5908 c_token
*token
= c_parser_peek_nth_token_raw (parser
, *n
);
5909 switch (token
->type
)
5911 case CPP_OPEN_BRACE
:
5914 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5916 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5917 if (token
->type
== CPP_CLOSE_BRACE
)
5927 case CPP_OPEN_PAREN
:
5930 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5932 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5933 if (token
->type
== CPP_CLOSE_PAREN
)
5943 case CPP_OPEN_SQUARE
:
5946 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5948 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5949 if (token
->type
== CPP_CLOSE_SQUARE
)
5959 case CPP_CLOSE_BRACE
:
5960 case CPP_CLOSE_PAREN
:
5961 case CPP_CLOSE_SQUARE
:
5972 /* Return whether standard attributes start with the Nth token. */
5975 c_parser_nth_token_starts_std_attributes (c_parser
*parser
, unsigned int n
)
5977 if (!(c_parser_peek_nth_token (parser
, n
)->type
== CPP_OPEN_SQUARE
5978 && c_parser_peek_nth_token (parser
, n
+ 1)->type
== CPP_OPEN_SQUARE
))
5980 /* In C, '[[' must start attributes. In Objective-C, we need to
5981 check whether '[[' is matched by ']]'. */
5982 if (!c_dialect_objc ())
5985 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
5987 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
5988 if (token
->type
!= CPP_CLOSE_SQUARE
)
5990 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
5991 return token
->type
== CPP_CLOSE_SQUARE
;
5995 c_parser_std_attribute_specifier_sequence (c_parser
*parser
)
5997 tree attributes
= NULL_TREE
;
6000 tree attrs
= c_parser_std_attribute_specifier (parser
, false);
6001 attributes
= chainon (attributes
, attrs
);
6003 while (c_parser_nth_token_starts_std_attributes (parser
, 1));
6007 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
6008 says whether alignment specifiers are OK (only in cases that might
6009 be the type name of a compound literal).
6012 specifier-qualifier-list abstract-declarator[opt]
6015 struct c_type_name
*
6016 c_parser_type_name (c_parser
*parser
, bool alignas_ok
)
6018 struct c_declspecs
*specs
= build_null_declspecs ();
6019 struct c_declarator
*declarator
;
6020 struct c_type_name
*ret
;
6022 c_parser_declspecs (parser
, specs
, false, true, true, alignas_ok
, false,
6023 false, true, cla_prefer_type
);
6024 if (!specs
->declspecs_seen_p
)
6026 c_parser_error (parser
, "expected specifier-qualifier-list");
6029 if (specs
->type
!= error_mark_node
)
6031 pending_xref_error ();
6032 finish_declspecs (specs
);
6034 declarator
= c_parser_declarator (parser
,
6035 specs
->typespec_kind
!= ctsk_none
,
6036 C_DTR_ABSTRACT
, &dummy
);
6037 if (declarator
== NULL
)
6039 ret
= XOBNEW (&parser_obstack
, struct c_type_name
);
6041 ret
->declarator
= declarator
;
6045 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
6048 assignment-expression
6049 { initializer-list }
6050 { initializer-list , }
6053 designation[opt] initializer
6054 initializer-list , designation[opt] initializer
6061 designator-list designator
6068 [ constant-expression ]
6080 [ constant-expression ... constant-expression ]
6082 Any expression without commas is accepted in the syntax for the
6083 constant-expressions, with non-constant expressions rejected later.
6085 DECL is the declaration we're parsing this initializer for.
6087 This function is only used for top-level initializers; for nested
6088 ones, see c_parser_initval. */
6090 static struct c_expr
6091 c_parser_initializer (c_parser
*parser
, tree decl
)
6093 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6094 return c_parser_braced_init (parser
, NULL_TREE
, false, NULL
, decl
);
6098 location_t loc
= c_parser_peek_token (parser
)->location
;
6099 ret
= c_parser_expr_no_commas (parser
, NULL
);
6100 if (decl
!= error_mark_node
&& C_DECL_VARIABLE_SIZE (decl
))
6103 "variable-sized object may not be initialized except "
6104 "with an empty initializer");
6107 /* This is handled mostly by gimplify.cc, but we have to deal with
6108 not warning about int x = x; as it is a GCC extension to turn off
6109 this warning but only if warn_init_self is zero. */
6111 && !DECL_EXTERNAL (decl
)
6112 && !TREE_STATIC (decl
)
6113 && ret
.value
== decl
6114 && !warning_enabled_at (DECL_SOURCE_LOCATION (decl
), OPT_Winit_self
))
6115 suppress_warning (decl
, OPT_Winit_self
);
6116 if (TREE_CODE (ret
.value
) != STRING_CST
6117 && (TREE_CODE (ret
.value
) != COMPOUND_LITERAL_EXPR
6118 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6120 ret
= convert_lvalue_to_rvalue (loc
, ret
, true, true, true);
6125 /* The location of the last comma within the current initializer list,
6126 or UNKNOWN_LOCATION if not within one. */
6128 location_t last_init_list_comma
;
6130 /* Parse a braced initializer list. TYPE is the type specified for a
6131 compound literal, and NULL_TREE for other initializers and for
6132 nested braced lists. NESTED_P is true for nested braced lists,
6133 false for the list of a compound literal or the list that is the
6134 top-level initializer in a declaration. DECL is the declaration for
6135 the top-level initializer for a declaration, otherwise NULL_TREE. */
6137 static struct c_expr
6138 c_parser_braced_init (c_parser
*parser
, tree type
, bool nested_p
,
6139 struct obstack
*outer_obstack
, tree decl
)
6142 struct obstack braced_init_obstack
;
6143 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
6144 gcc_obstack_init (&braced_init_obstack
);
6145 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
6146 matching_braces braces
;
6147 braces
.consume_open (parser
);
6150 finish_implicit_inits (brace_loc
, outer_obstack
);
6151 push_init_level (brace_loc
, 0, &braced_init_obstack
);
6154 really_start_incremental_init (type
);
6155 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
6157 pedwarn_c11 (brace_loc
, OPT_Wpedantic
,
6158 "ISO C forbids empty initializer braces before C23");
6162 if (decl
&& decl
!= error_mark_node
&& C_DECL_VARIABLE_SIZE (decl
))
6163 error_at (brace_loc
,
6164 "variable-sized object may not be initialized except "
6165 "with an empty initializer");
6166 /* Parse a non-empty initializer list, possibly with a trailing
6170 c_parser_initelt (parser
, &braced_init_obstack
);
6173 if (c_parser_next_token_is (parser
, CPP_COMMA
))
6175 last_init_list_comma
= c_parser_peek_token (parser
)->location
;
6176 c_parser_consume_token (parser
);
6180 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
6184 c_token
*next_tok
= c_parser_peek_token (parser
);
6185 if (next_tok
->type
!= CPP_CLOSE_BRACE
)
6188 ret
.original_code
= ERROR_MARK
;
6189 ret
.original_type
= NULL
;
6190 braces
.skip_until_found_close (parser
);
6191 pop_init_level (brace_loc
, 0, &braced_init_obstack
, last_init_list_comma
);
6192 obstack_free (&braced_init_obstack
, NULL
);
6195 location_t close_loc
= next_tok
->location
;
6196 c_parser_consume_token (parser
);
6197 ret
= pop_init_level (brace_loc
, 0, &braced_init_obstack
, close_loc
);
6198 obstack_free (&braced_init_obstack
, NULL
);
6199 set_c_expr_source_range (&ret
, brace_loc
, close_loc
);
6203 /* Parse a nested initializer, including designators. */
6206 c_parser_initelt (c_parser
*parser
, struct obstack
* braced_init_obstack
)
6208 /* Parse any designator or designator list. A single array
6209 designator may have the subsequent "=" omitted in GNU C, but a
6210 longer list or a structure member designator may not. */
6211 if (c_parser_next_token_is (parser
, CPP_NAME
)
6212 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
6214 /* Old-style structure member designator. */
6215 set_init_label (c_parser_peek_token (parser
)->location
,
6216 c_parser_peek_token (parser
)->value
,
6217 c_parser_peek_token (parser
)->location
,
6218 braced_init_obstack
);
6219 /* Use the colon as the error location. */
6220 pedwarn (c_parser_peek_2nd_token (parser
)->location
, OPT_Wpedantic
,
6221 "obsolete use of designated initializer with %<:%>");
6222 c_parser_consume_token (parser
);
6223 c_parser_consume_token (parser
);
6227 /* des_seen is 0 if there have been no designators, 1 if there
6228 has been a single array designator and 2 otherwise. */
6230 /* Location of a designator. */
6231 location_t des_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
6232 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
6233 || c_parser_next_token_is (parser
, CPP_DOT
))
6235 int des_prev
= des_seen
;
6237 des_loc
= c_parser_peek_token (parser
)->location
;
6240 if (c_parser_next_token_is (parser
, CPP_DOT
))
6243 c_parser_consume_token (parser
);
6244 if (c_parser_next_token_is (parser
, CPP_NAME
))
6246 set_init_label (des_loc
, c_parser_peek_token (parser
)->value
,
6247 c_parser_peek_token (parser
)->location
,
6248 braced_init_obstack
);
6249 c_parser_consume_token (parser
);
6255 init
.original_code
= ERROR_MARK
;
6256 init
.original_type
= NULL
;
6257 c_parser_error (parser
, "expected identifier");
6258 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
6259 process_init_element (input_location
, init
, false,
6260 braced_init_obstack
);
6266 struct c_expr first_expr
;
6268 location_t ellipsis_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
6269 location_t array_index_loc
= UNKNOWN_LOCATION
;
6270 /* ??? Following the old parser, [ objc-receiver
6271 objc-message-args ] is accepted as an initializer,
6272 being distinguished from a designator by what follows
6273 the first assignment expression inside the square
6274 brackets, but after a first array designator a
6275 subsequent square bracket is for Objective-C taken to
6276 start an expression, using the obsolete form of
6277 designated initializer without '=', rather than
6278 possibly being a second level of designation: in LALR
6279 terms, the '[' is shifted rather than reducing
6280 designator to designator-list. */
6281 if (des_prev
== 1 && c_dialect_objc ())
6283 des_seen
= des_prev
;
6286 if (des_prev
== 0 && c_dialect_objc ())
6288 /* This might be an array designator or an
6289 Objective-C message expression. If the former,
6290 continue parsing here; if the latter, parse the
6291 remainder of the initializer given the starting
6292 primary-expression. ??? It might make sense to
6293 distinguish when des_prev == 1 as well; see
6294 previous comment. */
6296 struct c_expr mexpr
;
6297 c_parser_consume_token (parser
);
6298 if (c_parser_peek_token (parser
)->type
== CPP_NAME
6299 && ((c_parser_peek_token (parser
)->id_kind
6301 || (c_parser_peek_token (parser
)->id_kind
6302 == C_ID_CLASSNAME
)))
6304 /* Type name receiver. */
6305 tree id
= c_parser_peek_token (parser
)->value
;
6306 c_parser_consume_token (parser
);
6307 rec
= objc_get_class_reference (id
);
6308 goto parse_message_args
;
6310 array_index_loc
= c_parser_peek_token (parser
)->location
;
6311 first_expr
= c_parser_expr_no_commas (parser
, NULL
);
6312 mark_exp_read (first_expr
.value
);
6313 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
)
6314 || c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
6315 goto array_desig_after_first
;
6316 first
= first_expr
.value
;
6317 /* Expression receiver. So far only one part
6318 without commas has been parsed; there might be
6319 more of the expression. */
6321 while (c_parser_next_token_is (parser
, CPP_COMMA
))
6324 location_t comma_loc
, exp_loc
;
6325 comma_loc
= c_parser_peek_token (parser
)->location
;
6326 c_parser_consume_token (parser
);
6327 exp_loc
= c_parser_peek_token (parser
)->location
;
6328 next
= c_parser_expr_no_commas (parser
, NULL
);
6329 next
= convert_lvalue_to_rvalue (exp_loc
, next
,
6331 rec
= build_compound_expr (comma_loc
, rec
, next
.value
);
6334 /* Now parse the objc-message-args. */
6335 args
= c_parser_objc_message_args (parser
);
6336 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
6339 = objc_build_message_expr (rec
, args
);
6340 mexpr
.original_code
= ERROR_MARK
;
6341 mexpr
.original_type
= NULL
;
6342 mexpr
.m_decimal
= 0;
6343 /* Now parse and process the remainder of the
6344 initializer, starting with this message
6345 expression as a primary-expression. */
6346 c_parser_initval (parser
, &mexpr
, braced_init_obstack
);
6349 c_parser_consume_token (parser
);
6350 array_index_loc
= c_parser_peek_token (parser
)->location
;
6351 first_expr
= c_parser_expr_no_commas (parser
, NULL
);
6352 mark_exp_read (first_expr
.value
);
6353 array_desig_after_first
:
6354 first_expr
= convert_lvalue_to_rvalue (array_index_loc
,
6357 first
= first_expr
.value
;
6358 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
6360 ellipsis_loc
= c_parser_peek_token (parser
)->location
;
6361 c_parser_consume_token (parser
);
6362 second
= convert_lvalue_to_rvalue (ellipsis_loc
,
6363 (c_parser_expr_no_commas
6366 mark_exp_read (second
);
6370 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
6372 c_parser_consume_token (parser
);
6373 set_init_index (array_index_loc
, first
, second
,
6374 braced_init_obstack
);
6376 pedwarn (ellipsis_loc
, OPT_Wpedantic
,
6377 "ISO C forbids specifying range of elements to initialize");
6380 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
6386 if (c_parser_next_token_is (parser
, CPP_EQ
))
6388 pedwarn_c90 (des_loc
, OPT_Wpedantic
,
6389 "ISO C90 forbids specifying subobject "
6391 c_parser_consume_token (parser
);
6396 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
6397 "obsolete use of designated initializer without %<=%>");
6402 init
.original_code
= ERROR_MARK
;
6403 init
.original_type
= NULL
;
6404 c_parser_error (parser
, "expected %<=%>");
6405 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
6406 process_init_element (input_location
, init
, false,
6407 braced_init_obstack
);
6413 c_parser_initval (parser
, NULL
, braced_init_obstack
);
6416 /* Parse a nested initializer; as c_parser_initializer but parses
6417 initializers within braced lists, after any designators have been
6418 applied. If AFTER is not NULL then it is an Objective-C message
6419 expression which is the primary-expression starting the
6423 c_parser_initval (c_parser
*parser
, struct c_expr
*after
,
6424 struct obstack
* braced_init_obstack
)
6427 gcc_assert (!after
|| c_dialect_objc ());
6428 location_t loc
= c_parser_peek_token (parser
)->location
;
6430 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
) && !after
)
6431 init
= c_parser_braced_init (parser
, NULL_TREE
, true,
6432 braced_init_obstack
, NULL_TREE
);
6435 init
= c_parser_expr_no_commas (parser
, after
);
6436 if (init
.value
!= NULL_TREE
6437 && TREE_CODE (init
.value
) != STRING_CST
6438 && (TREE_CODE (init
.value
) != COMPOUND_LITERAL_EXPR
6439 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6441 init
= convert_lvalue_to_rvalue (loc
, init
, true, true, true);
6443 process_init_element (loc
, init
, false, braced_init_obstack
);
6446 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
6447 C99 6.8.2, C11 6.8.2, C23 6.8.2).
6450 { block-item-list[opt] }
6451 { label-declarations block-item-list }
6455 block-item-list block-item
6468 { label-declarations block-item-list }
6471 __extension__ nested-declaration
6472 nested-function-definition
6476 label-declarations label-declaration
6479 __label__ identifier-list ;
6481 Allowing the mixing of declarations and code is new in C99. The
6482 GNU syntax also permits (not shown above) labels at the end of
6483 compound statements, which yield an error. We don't allow labels
6484 on declarations; this might seem like a natural extension, but
6485 there would be a conflict between gnu-attributes on the label and
6486 prefix gnu-attributes on the declaration. ??? The syntax follows the
6487 old parser in requiring something after label declarations.
6488 Although they are erroneous if the labels declared aren't defined,
6489 is it useful for the syntax to be this way?
6510 cancellation-point-directive */
6513 c_parser_compound_statement (c_parser
*parser
, location_t
*endlocp
)
6516 location_t brace_loc
;
6517 brace_loc
= c_parser_peek_token (parser
)->location
;
6518 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
6520 /* Ensure a scope is entered and left anyway to avoid confusion
6521 if we have just prepared to enter a function body. */
6522 stmt
= c_begin_compound_stmt (true);
6523 c_end_compound_stmt (brace_loc
, stmt
, true);
6524 return error_mark_node
;
6526 stmt
= c_begin_compound_stmt (true);
6527 location_t end_loc
= c_parser_compound_statement_nostart (parser
);
6531 return c_end_compound_stmt (brace_loc
, stmt
, true);
6534 /* Diagnose errors related to imperfectly nested loops in an OMP
6535 loop construct. This function is called when such code is seen.
6536 Only issue one such diagnostic no matter how much invalid
6537 intervening code there is in the loop.
6538 FIXME: maybe the location associated with the diagnostic should
6539 be the current parser token instead of the location of the outer loop
6543 check_omp_intervening_code (c_parser
*parser
)
6545 struct omp_for_parse_data
*omp_for_parse_state
= parser
->omp_for_parse_state
;
6546 gcc_assert (omp_for_parse_state
);
6548 if (!omp_for_parse_state
->in_intervening_code
)
6550 omp_for_parse_state
->saw_intervening_code
= true;
6552 /* Only diagnose errors related to perfect nesting once. */
6553 if (!omp_for_parse_state
->perfect_nesting_fail
)
6556 /* OpenACC does not (yet) permit intervening code, in
6557 addition to situations forbidden by the OpenMP spec. */
6558 if (omp_for_parse_state
->code
== OACC_LOOP
)
6560 error_at (omp_for_parse_state
->for_loc
,
6561 "inner loops must be perfectly nested in "
6562 "%<#pragma acc loop%>");
6563 omp_for_parse_state
->perfect_nesting_fail
= true;
6565 else if (omp_for_parse_state
->ordered
)
6567 error_at (omp_for_parse_state
->for_loc
,
6568 "inner loops must be perfectly nested with "
6569 "%<ordered%> clause");
6570 omp_for_parse_state
->perfect_nesting_fail
= true;
6572 else if (omp_for_parse_state
->inscan
)
6574 error_at (omp_for_parse_state
->for_loc
,
6575 "inner loops must be perfectly nested with "
6576 "%<reduction%> %<inscan%> clause");
6577 omp_for_parse_state
->perfect_nesting_fail
= true;
6579 /* TODO: Also reject loops with TILE directive. */
6580 if (omp_for_parse_state
->perfect_nesting_fail
)
6581 omp_for_parse_state
->fail
= true;
6585 /* Helper function for below: wrap an OMP_STRUCTURED_BLOCK around SL
6586 and add the statement to the current list. If SL is an empty statement
6587 list, do nothing. */
6589 add_structured_block_stmt (tree sl
)
6591 if (TREE_CODE (sl
) != STATEMENT_LIST
6592 || !tsi_end_p (tsi_start (sl
)))
6593 add_stmt (build1 (OMP_STRUCTURED_BLOCK
, void_type_node
, sl
));
6596 struct c_omp_attribute_data
6598 vec
<c_token
, va_gc
> *tokens
;
6599 const c_omp_directive
*dir
;
6600 c_omp_directive_kind kind
;
6603 /* Handle omp::directive and omp::sequence attributes in ATTRS
6604 (if any) at the start of a statement or in attribute-declaration. */
6607 c_parser_handle_statement_omp_attributes (c_parser
*parser
, tree
&attrs
,
6608 bool *have_std_attrs
)
6610 if (!flag_openmp
&& !flag_openmp_simd
)
6613 auto_vec
<c_omp_attribute_data
, 16> vd
;
6617 for (tree
*pa
= &attrs
; *pa
; )
6618 if (is_attribute_namespace_p ("omp", *pa
)
6619 && is_attribute_p ("directive", get_attribute_name (*pa
)))
6622 for (tree a
= TREE_VALUE (*pa
); a
; a
= TREE_CHAIN (a
))
6624 tree d
= TREE_VALUE (a
);
6625 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
6626 vec
<c_token
, va_gc
> *toks
= C_TOKEN_VEC_TOKENS (d
);
6627 c_token
*first
= toks
->address ();
6628 c_token
*last
= first
+ toks
->length ();
6629 if (parser
->omp_attrs_forbidden_p
)
6631 error_at (first
->location
,
6632 "mixing OpenMP directives with attribute and pragma "
6633 "syntax on the same statement");
6634 parser
->omp_attrs_forbidden_p
= false;
6637 else if (TREE_PUBLIC (d
))
6639 error_at (first
->location
,
6640 "OpenMP %<omp::decl%> attribute on a statement");
6643 const char *directive
[3] = {};
6644 for (int i
= 0; i
< 3; i
++)
6646 tree id
= NULL_TREE
;
6647 if (first
+ i
== last
)
6649 if (first
[i
].type
== CPP_NAME
)
6650 id
= first
[i
].value
;
6651 else if (first
[i
].type
== CPP_KEYWORD
)
6652 id
= ridpointers
[(int) first
[i
].keyword
];
6655 directive
[i
] = IDENTIFIER_POINTER (id
);
6657 const c_omp_directive
*dir
= NULL
;
6659 dir
= c_omp_categorize_directive (directive
[0], directive
[1],
6663 error_at (first
->location
,
6664 "unknown OpenMP directive name in %qs attribute "
6666 TREE_PUBLIC (d
) ? "omp::decl" : "omp::directive");
6669 c_omp_directive_kind kind
= dir
->kind
;
6670 if (dir
->id
== PRAGMA_OMP_ORDERED
)
6672 /* ordered is C_OMP_DIR_CONSTRUCT only if it doesn't contain
6673 depend/doacross clause. */
6675 && (strcmp (directive
[1], "depend") == 0
6676 || strcmp (directive
[1], "doacross") == 0))
6677 kind
= C_OMP_DIR_STANDALONE
;
6678 else if (first
+ 2 < last
6679 && first
[1].type
== CPP_COMMA
6680 && first
[2].type
== CPP_NAME
6681 && (strcmp (IDENTIFIER_POINTER (first
[2].value
),
6683 || strcmp (IDENTIFIER_POINTER (first
[2].value
),
6685 kind
= C_OMP_DIR_STANDALONE
;
6687 else if (dir
->id
== PRAGMA_OMP_ERROR
)
6689 /* error with at(execution) clause is C_OMP_DIR_STANDALONE. */
6690 int paren_depth
= 0;
6691 for (int i
= 1; first
+ i
< last
; i
++)
6692 if (first
[i
].type
== CPP_OPEN_PAREN
)
6694 else if (first
[i
].type
== CPP_CLOSE_PAREN
)
6696 else if (paren_depth
== 0
6697 && first
+ i
+ 2 < last
6698 && first
[i
].type
== CPP_NAME
6699 && first
[i
+ 1].type
== CPP_OPEN_PAREN
6700 && first
[i
+ 2].type
== CPP_NAME
6701 && !strcmp (IDENTIFIER_POINTER (first
[i
].value
),
6703 && !strcmp (IDENTIFIER_POINTER (first
[i
6707 kind
= C_OMP_DIR_STANDALONE
;
6711 c_omp_attribute_data v
= { toks
, dir
, kind
};
6713 if (flag_openmp
|| dir
->simd
)
6714 tokens
+= (last
- first
) + 1;
6716 c_omp_attribute_data v
= {};
6718 *pa
= TREE_CHAIN (*pa
);
6721 pa
= &TREE_CHAIN (*pa
);
6726 if (have_std_attrs
&& attrs
== NULL
)
6727 *have_std_attrs
= false;
6732 c_omp_attribute_data
*v
;
6733 c_omp_attribute_data
*construct_seen
= nullptr;
6734 c_omp_attribute_data
*standalone_seen
= nullptr;
6735 c_omp_attribute_data
*prev_standalone_seen
= nullptr;
6736 FOR_EACH_VEC_ELT (vd
, i
, v
)
6739 if (v
->kind
== C_OMP_DIR_CONSTRUCT
&& !construct_seen
)
6741 else if (v
->kind
== C_OMP_DIR_STANDALONE
&& !standalone_seen
)
6742 standalone_seen
= v
;
6746 if (standalone_seen
&& !prev_standalone_seen
)
6748 prev_standalone_seen
= standalone_seen
;
6749 standalone_seen
= nullptr;
6753 if (cnt
> 1 && construct_seen
)
6755 error_at ((*construct_seen
->tokens
)[0].location
,
6756 "OpenMP construct among %<omp::directive%> attributes"
6757 " requires all %<omp::directive%> attributes on the"
6758 " same statement to be in the same %<omp::sequence%>");
6761 if (cnt
> 1 && standalone_seen
&& prev_standalone_seen
)
6763 error_at ((*standalone_seen
->tokens
)[0].location
,
6764 "multiple OpenMP standalone directives among"
6765 " %<omp::directive%> attributes must be all within the"
6766 " same %<omp::sequence%>");
6770 if (prev_standalone_seen
)
6771 standalone_seen
= prev_standalone_seen
;
6773 && !c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6775 error_at (standalone_seen
->tokens
->address ()->location
,
6776 "standalone OpenMP directives in %<omp::directive%> attribute"
6777 " can only appear on an empty statement");
6780 if (cnt
&& c_parser_next_token_is (parser
, CPP_PRAGMA
))
6782 c_token
*token
= c_parser_peek_token (parser
);
6783 enum pragma_kind kind
= token
->pragma_kind
;
6784 if (kind
>= PRAGMA_OMP__START_
&& kind
<= PRAGMA_OMP__LAST_
)
6786 error_at (token
->location
,
6787 "mixing OpenMP directives with attribute and pragma "
6788 "syntax on the same statement");
6796 unsigned int tokens_avail
= parser
->tokens_avail
;
6797 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
6800 vec
<c_token
, va_gc
> *toks
= NULL
;
6801 vec_safe_reserve (toks
, tokens
, true);
6802 FOR_EACH_VEC_ELT (vd
, i
, v
)
6806 if (!flag_openmp
&& !v
->dir
->simd
)
6808 c_token
*first
= v
->tokens
->address ();
6809 c_token
*last
= first
+ v
->tokens
->length ();
6811 tok
.type
= CPP_PRAGMA
;
6812 tok
.keyword
= RID_MAX
;
6813 tok
.pragma_kind
= pragma_kind (v
->dir
->id
);
6814 tok
.location
= first
->location
;
6815 toks
->quick_push (tok
);
6816 while (++first
< last
)
6817 toks
->quick_push (*first
);
6819 tok
.type
= CPP_PRAGMA_EOL
;
6820 tok
.keyword
= RID_MAX
;
6821 tok
.location
= last
[-1].location
;
6822 toks
->quick_push (tok
);
6827 tok
.keyword
= RID_MAX
;
6828 tok
.location
= toks
->last ().location
;
6829 tok
.flags
= tokens_avail
;
6830 toks
->quick_push (tok
);
6832 parser
->tokens
= toks
->address ();
6833 parser
->tokens_avail
= tokens
;
6834 parser
->in_omp_attribute_pragma
= toks
;
6838 /* Handle omp::directive and omp::sequence attributes in ATTRS
6839 (if any) at the start or after declaration-id of a declaration. */
6842 c_parser_handle_directive_omp_attributes (tree
&attrs
,
6843 vec
<c_token
> *&pragma_clauses
,
6844 vec
<c_token
> *attr_clauses
)
6846 if (!flag_openmp
&& !flag_openmp_simd
)
6849 for (tree
*pa
= &attrs
; *pa
; )
6850 if (is_attribute_namespace_p ("omp", *pa
)
6851 && is_attribute_p ("directive", get_attribute_name (*pa
)))
6854 for (tree
*pa2
= &TREE_VALUE (*pa
); *pa2
; )
6857 tree d
= TREE_VALUE (a
);
6858 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
6859 vec
<c_token
, va_gc
> *toks
= C_TOKEN_VEC_TOKENS (d
);
6860 c_token
*first
= toks
->address ();
6861 c_token
*last
= first
+ toks
->length ();
6862 const char *directive
[3] = {};
6863 for (int i
= 0; i
< 3; i
++)
6865 tree id
= NULL_TREE
;
6866 if (first
+ i
== last
)
6868 if (first
[i
].type
== CPP_NAME
)
6869 id
= first
[i
].value
;
6870 else if (first
[i
].type
== CPP_KEYWORD
)
6871 id
= ridpointers
[(int) first
[i
].keyword
];
6874 directive
[i
] = IDENTIFIER_POINTER (id
);
6876 const c_omp_directive
*dir
= NULL
;
6878 dir
= c_omp_categorize_directive (directive
[0], directive
[1],
6882 error_at (first
->location
,
6883 "unknown OpenMP directive name in "
6884 "%qs attribute argument",
6885 TREE_PUBLIC (d
) ? "omp::decl" : "omp::directive");
6886 *pa2
= TREE_CHAIN (a
);
6888 else if (dir
->id
== PRAGMA_OMP_DECLARE
6889 && (strcmp (directive
[1], "simd") == 0
6890 || strcmp (directive
[1], "variant") == 0))
6894 error_at (first
->location
,
6895 "mixing OpenMP directives with attribute and "
6896 "pragma syntax on the same declaration");
6897 for (pa
= &attrs
; *pa
; )
6898 if (is_attribute_namespace_p ("omp", *pa
)
6899 && is_attribute_p ("directive",
6900 get_attribute_name (*pa
)))
6901 *pa
= TREE_CHAIN (*pa
);
6903 pa
= &TREE_CHAIN (*pa
);
6907 attr_clauses
->reserve (attr_clauses
->length ()
6908 + toks
->length () + 2);
6909 for (++first
; first
< last
; ++first
)
6910 attr_clauses
->quick_push (*first
);
6912 tok
.type
= CPP_PRAGMA_EOL
;
6913 tok
.keyword
= RID_MAX
;
6914 tok
.location
= last
[-1].location
;
6915 attr_clauses
->quick_push (tok
);
6916 *pa2
= TREE_CHAIN (a
);
6919 pa2
= &TREE_CHAIN (a
);
6921 if (cnt
&& TREE_VALUE (*pa
) == NULL_TREE
)
6922 *pa
= TREE_CHAIN (*pa
);
6924 pa
= &TREE_CHAIN (*pa
);
6927 pa
= &TREE_CHAIN (*pa
);
6928 if (attr_clauses
->length ())
6932 tok
.keyword
= RID_MAX
;
6933 tok
.location
= attr_clauses
->last ().location
;
6934 attr_clauses
->quick_push (tok
);
6935 attr_clauses
->quick_push (tok
);
6936 pragma_clauses
= attr_clauses
;
6940 /* Parse a compound statement except for the opening brace. This is
6941 used for parsing both compound statements and statement expressions
6942 (which follow different paths to handling the opening). */
6945 c_parser_compound_statement_nostart (c_parser
*parser
)
6947 bool last_stmt
= false;
6948 bool last_label
= false;
6949 bool save_valid_for_pragma
= valid_location_for_stdc_pragma_p ();
6950 location_t label_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
6951 struct omp_for_parse_data
*omp_for_parse_state
6952 = parser
->omp_for_parse_state
;
6953 bool in_omp_loop_block
6954 = omp_for_parse_state
? omp_for_parse_state
->want_nested_loop
: false;
6955 tree sl
= NULL_TREE
;
6957 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
6959 location_t endloc
= c_parser_peek_token (parser
)->location
;
6960 add_debug_begin_stmt (endloc
);
6961 c_parser_consume_token (parser
);
6965 /* If we're parsing a {} sequence in an OMP_FOR body, start a
6966 statement list for intervening code. */
6967 if (in_omp_loop_block
)
6968 sl
= push_stmt_list ();
6970 mark_valid_location_for_stdc_pragma (true);
6971 if (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
6973 /* Read zero or more forward-declarations for labels that nested
6974 functions can jump to. */
6975 mark_valid_location_for_stdc_pragma (false);
6976 if (in_omp_loop_block
)
6977 check_omp_intervening_code (parser
);
6978 while (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
6980 label_loc
= c_parser_peek_token (parser
)->location
;
6981 c_parser_consume_token (parser
);
6982 /* Any identifiers, including those declared as type names,
6987 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
6989 c_parser_error (parser
, "expected identifier");
6993 = declare_label (c_parser_peek_token (parser
)->value
);
6994 C_DECLARED_LABEL_FLAG (label
) = 1;
6995 add_stmt (build_stmt (label_loc
, DECL_EXPR
, label
));
6996 c_parser_consume_token (parser
);
6997 if (c_parser_next_token_is (parser
, CPP_COMMA
))
6998 c_parser_consume_token (parser
);
7002 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
7004 pedwarn (label_loc
, OPT_Wpedantic
, "ISO C forbids label declarations");
7006 /* We must now have at least one statement, label or declaration. */
7007 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
7009 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7010 c_parser_error (parser
, "expected declaration or statement");
7011 location_t endloc
= c_parser_peek_token (parser
)->location
;
7012 c_parser_consume_token (parser
);
7015 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_BRACE
))
7017 location_t loc
= c_parser_peek_token (parser
)->location
;
7018 loc
= expansion_point_location_if_in_system_header (loc
);
7020 bool want_nested_loop
= (omp_for_parse_state
7021 ? omp_for_parse_state
->want_nested_loop
7024 /* First take care of special cases for OpenMP "canonical loop
7025 nest form", that do not allow standard attributes, labels, or
7026 __extension__ before the nested statement. */
7027 if (in_omp_loop_block
&& !last_label
)
7029 if (want_nested_loop
7030 && c_parser_next_token_is_keyword (parser
, RID_FOR
))
7032 /* Found the next nested loop. If there were intervening
7033 code statements collected before now, wrap them in an
7034 OMP_STRUCTURED_BLOCK node, and start a new structured
7035 block to hold statements that may come after the FOR. */
7037 add_structured_block_stmt (pop_stmt_list (sl
));
7038 omp_for_parse_state
->depth
++;
7039 add_stmt (c_parser_omp_loop_nest (parser
, NULL
));
7040 omp_for_parse_state
->depth
--;
7041 sl
= push_stmt_list ();
7042 parser
->error
= false;
7045 else if (want_nested_loop
7046 && c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7048 /* If this nested compound statement contains the nested loop,
7049 we need to separate the other statements in the current
7050 statement into separate blocks of intervening code. If
7051 there's no nested loop, it's all part of the same
7052 chunk of intervening code. */
7053 tree pre_sl
= pop_stmt_list (sl
);
7054 tree nested_sl
= push_stmt_list ();
7055 mark_valid_location_for_stdc_pragma (false);
7056 c_parser_statement_after_labels (parser
, NULL
);
7057 nested_sl
= pop_stmt_list (nested_sl
);
7058 if (omp_for_parse_state
->want_nested_loop
)
7060 /* This block didn't contain a loop-nest, so it's
7061 all part of the same chunk of intervening code. */
7062 check_omp_intervening_code (parser
);
7063 sl
= push_stmt_list ();
7065 add_stmt (nested_sl
);
7069 /* It contains the nested loop. */
7070 add_structured_block_stmt (pre_sl
);
7071 add_stmt (nested_sl
);
7072 sl
= push_stmt_list ();
7074 parser
->error
= false;
7077 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7079 /* Prior to implementing the OpenMP 5.1 syntax for canonical
7080 loop form, GCC used to accept an empty statements that
7081 would now be flagged as intervening code. Continue to
7082 do that, as an extension. */
7083 /* FIXME: Maybe issue a warning or something here? */
7084 c_parser_consume_token (parser
);
7089 /* Standard attributes may start a label, statement or declaration. */
7091 = c_parser_nth_token_starts_std_attributes (parser
, 1);
7092 tree std_attrs
= NULL_TREE
;
7094 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
7095 if (c_parser_next_token_is_keyword (parser
, RID_CASE
)
7096 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
7097 || (c_parser_next_token_is (parser
, CPP_NAME
)
7098 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
7100 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
7101 label_loc
= c_parser_peek_2nd_token (parser
)->location
;
7103 label_loc
= c_parser_peek_token (parser
)->location
;
7106 mark_valid_location_for_stdc_pragma (false);
7107 if (in_omp_loop_block
)
7108 check_omp_intervening_code (parser
);
7109 c_parser_label (parser
, std_attrs
);
7111 else if (c_parser_next_tokens_start_declaration (parser
)
7113 && !c_parser_handle_statement_omp_attributes
7114 (parser
, std_attrs
, &have_std_attrs
)
7115 && c_parser_next_token_is (parser
, CPP_SEMICOLON
)
7116 && (have_std_attrs
= true)))
7119 pedwarn_c11 (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
7120 "a label can only be part of a statement and "
7121 "a declaration is not a statement");
7122 /* It's unlikely we'll see a nested loop in a declaration in
7123 intervening code in an OMP loop, but disallow it anyway. */
7124 if (in_omp_loop_block
)
7126 check_omp_intervening_code (parser
);
7127 omp_for_parse_state
->want_nested_loop
= false;
7129 mark_valid_location_for_stdc_pragma (false);
7130 bool fallthru_attr_p
= false;
7131 c_parser_declaration_or_fndef (parser
, true, !have_std_attrs
,
7132 true, true, true, NULL
,
7133 NULL
, have_std_attrs
, std_attrs
,
7134 NULL
, &fallthru_attr_p
);
7136 if (in_omp_loop_block
)
7137 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7138 if (last_stmt
&& !fallthru_attr_p
)
7139 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
7140 "ISO C90 forbids mixed declarations and code");
7141 last_stmt
= fallthru_attr_p
;
7144 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
7146 /* __extension__ can start a declaration, but is also an
7147 unary operator that can start an expression. Consume all
7148 but the last of a possible series of __extension__ to
7149 determine which. If standard attributes have already
7150 been seen, it must start a statement, not a declaration,
7151 but standard attributes starting a declaration may appear
7152 after __extension__. */
7153 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
7154 && (c_parser_peek_2nd_token (parser
)->keyword
7156 c_parser_consume_token (parser
);
7158 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
7159 || c_parser_nth_token_starts_std_attributes (parser
, 2)))
7162 ext
= disable_extension_diagnostics ();
7163 c_parser_consume_token (parser
);
7165 /* It's unlikely we'll see a nested loop in a declaration in
7166 intervening code in an OMP loop, but disallow it anyway. */
7167 if (in_omp_loop_block
)
7169 check_omp_intervening_code (parser
);
7170 omp_for_parse_state
->want_nested_loop
= false;
7172 mark_valid_location_for_stdc_pragma (false);
7173 c_parser_declaration_or_fndef (parser
, true, true, true, true,
7175 if (in_omp_loop_block
)
7176 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7177 /* Following the old parser, __extension__ does not
7178 disable this diagnostic. */
7179 restore_extension_diagnostics (ext
);
7181 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
7182 "ISO C90 forbids mixed declarations and code");
7188 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
7190 if (have_std_attrs
&& !parser
->in_omp_attribute_pragma
)
7191 c_parser_error (parser
, "expected declaration or statement");
7193 c_warn_unused_attributes (std_attrs
);
7194 /* External pragmas, and some omp pragmas, are not associated
7195 with regular c code, and so are not to be considered statements
7196 syntactically. This ensures that the user doesn't put them
7197 places that would turn into syntax errors if the directive
7199 if (omp_for_parse_state
)
7200 omp_for_parse_state
->want_nested_loop
= false;
7201 if (c_parser_pragma (parser
,
7202 last_label
? pragma_stmt
: pragma_compound
,
7207 if (omp_for_parse_state
)
7208 check_omp_intervening_code (parser
);
7210 if (omp_for_parse_state
)
7211 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7213 else if (c_parser_next_token_is (parser
, CPP_EOF
))
7215 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7216 c_parser_error (parser
, "expected declaration or statement");
7217 return c_parser_peek_token (parser
)->location
;
7219 else if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
7221 if (parser
->in_if_block
)
7223 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7224 error_at (loc
, "expected %<}%> before %<else%>");
7225 return c_parser_peek_token (parser
)->location
;
7229 error_at (loc
, "%<else%> without a previous %<if%>");
7230 c_parser_consume_token (parser
);
7237 c_warn_unused_attributes (std_attrs
);
7240 mark_valid_location_for_stdc_pragma (false);
7241 if (!omp_for_parse_state
)
7242 c_parser_statement_after_labels (parser
, NULL
);
7245 /* In canonical loop nest form, nested loops can only appear
7246 directly, or in a directly nested compound statement. We
7247 already took care of those cases above, so now we have
7248 something else. This statement and everything inside
7249 it must be intervening code. */
7250 omp_for_parse_state
->want_nested_loop
= false;
7251 check_omp_intervening_code (parser
);
7252 c_parser_statement_after_labels (parser
, NULL
);
7253 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7257 parser
->error
= false;
7260 pedwarn_c11 (label_loc
, OPT_Wpedantic
, "label at end of compound statement");
7261 location_t endloc
= c_parser_peek_token (parser
)->location
;
7262 c_parser_consume_token (parser
);
7264 /* Restore the value we started with. */
7265 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7267 /* Package leftover intervening code, or the whole contents of the
7268 compound statement if we were looking for a nested loop in an OMP_FOR
7269 construct and didn't find one. */
7272 sl
= pop_stmt_list (sl
);
7273 if (omp_for_parse_state
->want_nested_loop
)
7276 add_structured_block_stmt (sl
);
7281 /* Parse all consecutive labels, possibly preceded by standard
7282 attributes. In this context, a statement is required, not a
7283 declaration, so attributes must be followed by a statement that is
7284 not just a semicolon. */
7287 c_parser_all_labels (c_parser
*parser
)
7289 bool have_std_attrs
;
7290 tree std_attrs
= NULL
;
7291 if ((have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1)))
7292 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
7293 while (c_parser_next_token_is_keyword (parser
, RID_CASE
)
7294 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
7295 || (c_parser_next_token_is (parser
, CPP_NAME
)
7296 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
7298 c_parser_label (parser
, std_attrs
);
7300 if ((have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
,
7302 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
7305 && (!c_parser_handle_statement_omp_attributes (parser
, std_attrs
, &have_std_attrs
)
7308 if (have_std_attrs
&& c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7309 c_parser_error (parser
, "expected statement");
7310 c_warn_unused_attributes (std_attrs
);
7312 else if (have_std_attrs
&& c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7313 c_parser_error (parser
, "expected statement");
7316 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
7319 identifier : gnu-attributes[opt]
7320 case constant-expression :
7326 case constant-expression ... constant-expression :
7328 The use of gnu-attributes on labels is a GNU extension. The syntax in
7329 GNU C accepts any expressions without commas, non-constant
7330 expressions being rejected later. Any standard
7331 attribute-specifier-sequence before the first label has been parsed
7332 in the caller, to distinguish statements from declarations. Any
7333 attribute-specifier-sequence after the label is parsed in this
7336 c_parser_label (c_parser
*parser
, tree std_attrs
)
7338 location_t loc1
= c_parser_peek_token (parser
)->location
;
7339 tree label
= NULL_TREE
;
7341 /* Remember whether this case or a user-defined label is allowed to fall
7343 bool fallthrough_p
= c_parser_peek_token (parser
)->flags
& PREV_FALLTHROUGH
;
7345 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
7348 c_parser_consume_token (parser
);
7349 exp1
= convert_lvalue_to_rvalue (loc1
,
7350 c_parser_expr_no_commas (parser
, NULL
),
7352 if (c_parser_next_token_is (parser
, CPP_COLON
))
7354 c_parser_consume_token (parser
);
7355 label
= do_case (loc1
, exp1
, NULL_TREE
, std_attrs
);
7357 else if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
7359 c_parser_consume_token (parser
);
7360 exp2
= convert_lvalue_to_rvalue (loc1
,
7361 c_parser_expr_no_commas (parser
,
7364 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7365 label
= do_case (loc1
, exp1
, exp2
, std_attrs
);
7368 c_parser_error (parser
, "expected %<:%> or %<...%>");
7370 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
7372 c_parser_consume_token (parser
);
7373 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7374 label
= do_case (loc1
, NULL_TREE
, NULL_TREE
, std_attrs
);
7378 tree name
= c_parser_peek_token (parser
)->value
;
7381 location_t loc2
= c_parser_peek_token (parser
)->location
;
7382 gcc_assert (c_parser_next_token_is (parser
, CPP_NAME
));
7383 c_parser_consume_token (parser
);
7384 gcc_assert (c_parser_next_token_is (parser
, CPP_COLON
));
7385 c_parser_consume_token (parser
);
7386 attrs
= c_parser_gnu_attributes (parser
);
7387 tlab
= define_label (loc2
, name
);
7390 decl_attributes (&tlab
, attrs
, 0);
7391 decl_attributes (&tlab
, std_attrs
, 0);
7392 label
= add_stmt (build_stmt (loc1
, LABEL_EXPR
, tlab
));
7395 && c_parser_next_tokens_start_declaration (parser
))
7396 warning_at (loc2
, OPT_Wattributes
, "GNU-style attribute between"
7397 " label and declaration appertains to the label");
7401 if (TREE_CODE (label
) == LABEL_EXPR
)
7402 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label
)) = fallthrough_p
;
7404 FALLTHROUGH_LABEL_P (CASE_LABEL (label
)) = fallthrough_p
;
7408 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
7412 attribute-specifier-sequence[opt] compound-statement
7413 expression-statement
7414 attribute-specifier-sequence[opt] selection-statement
7415 attribute-specifier-sequence[opt] iteration-statement
7416 attribute-specifier-sequence[opt] jump-statement
7419 attribute-specifier-sequence[opt] label statement
7421 expression-statement:
7423 attribute-specifier-sequence expression ;
7425 selection-statement:
7429 iteration-statement:
7438 return expression[opt] ;
7443 attribute-specifier-sequence[opt] asm-statement
7448 expression-statement:
7454 attribute-specifier-sequence[opt] objc-throw-statement
7455 attribute-specifier-sequence[opt] objc-try-catch-statement
7456 attribute-specifier-sequence[opt] objc-synchronized-statement
7458 objc-throw-statement:
7465 attribute-specifier-sequence[opt] openacc-construct
7474 parallel-directive structured-block
7477 kernels-directive structured-block
7480 data-directive structured-block
7483 loop-directive structured-block
7488 attribute-specifier-sequence[opt] openmp-construct
7497 parallel-for-construct
7498 parallel-for-simd-construct
7499 parallel-sections-construct
7506 parallel-directive structured-block
7509 for-directive iteration-statement
7512 simd-directive iteration-statements
7515 for-simd-directive iteration-statements
7518 sections-directive section-scope
7521 single-directive structured-block
7523 parallel-for-construct:
7524 parallel-for-directive iteration-statement
7526 parallel-for-simd-construct:
7527 parallel-for-simd-directive iteration-statement
7529 parallel-sections-construct:
7530 parallel-sections-directive section-scope
7533 master-directive structured-block
7536 critical-directive structured-block
7539 atomic-directive expression-statement
7542 ordered-directive structured-block
7544 Transactional Memory:
7547 attribute-specifier-sequence[opt] transaction-statement
7548 attribute-specifier-sequence[opt] transaction-cancel-statement
7550 IF_P is used to track whether there's a (possibly labeled) if statement
7551 which is not enclosed in braces and has an else clause. This is used to
7552 implement -Wparentheses. */
7555 c_parser_statement (c_parser
*parser
, bool *if_p
, location_t
*loc_after_labels
)
7557 c_parser_all_labels (parser
);
7558 if (loc_after_labels
)
7559 *loc_after_labels
= c_parser_peek_token (parser
)->location
;
7560 parser
->omp_attrs_forbidden_p
= false;
7561 c_parser_statement_after_labels (parser
, if_p
, NULL
);
7564 /* Parse a statement, other than a labeled statement. CHAIN is a vector
7565 of if-else-if conditions. All labels and standard attributes have
7566 been parsed in the caller.
7568 IF_P is used to track whether there's a (possibly labeled) if statement
7569 which is not enclosed in braces and has an else clause. This is used to
7570 implement -Wparentheses. */
7573 c_parser_statement_after_labels (c_parser
*parser
, bool *if_p
,
7576 location_t loc
= c_parser_peek_token (parser
)->location
;
7577 tree stmt
= NULL_TREE
;
7578 bool in_if_block
= parser
->in_if_block
;
7579 parser
->in_if_block
= false;
7583 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_BRACE
)
7584 add_debug_begin_stmt (loc
);
7587 switch (c_parser_peek_token (parser
)->type
)
7589 case CPP_OPEN_BRACE
:
7590 add_stmt (c_parser_compound_statement (parser
));
7593 switch (c_parser_peek_token (parser
)->keyword
)
7596 c_parser_if_statement (parser
, if_p
, chain
);
7599 c_parser_switch_statement (parser
, if_p
);
7602 c_parser_while_statement (parser
, false, 0, false, if_p
);
7605 c_parser_do_statement (parser
, false, 0, false);
7608 c_parser_for_statement (parser
, false, 0, false, if_p
);
7611 c_parser_consume_token (parser
);
7612 if (c_parser_next_token_is (parser
, CPP_NAME
))
7614 stmt
= c_finish_goto_label (loc
,
7615 c_parser_peek_token (parser
)->value
);
7616 c_parser_consume_token (parser
);
7618 else if (c_parser_next_token_is (parser
, CPP_MULT
))
7622 c_parser_consume_token (parser
);
7623 val
= c_parser_expression (parser
);
7624 val
= convert_lvalue_to_rvalue (loc
, val
, false, true);
7625 stmt
= c_finish_goto_ptr (loc
, val
);
7628 c_parser_error (parser
, "expected identifier or %<*%>");
7629 goto expect_semicolon
;
7631 c_parser_consume_token (parser
);
7632 stmt
= c_finish_bc_stmt (loc
, objc_foreach_continue_label
, false);
7633 goto expect_semicolon
;
7635 c_parser_consume_token (parser
);
7636 stmt
= c_finish_bc_stmt (loc
, objc_foreach_break_label
, true);
7637 goto expect_semicolon
;
7639 c_parser_consume_token (parser
);
7640 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7642 stmt
= c_finish_return (loc
, NULL_TREE
, NULL_TREE
);
7643 c_parser_consume_token (parser
);
7647 location_t xloc
= c_parser_peek_token (parser
)->location
;
7648 struct c_expr expr
= c_parser_expression_conv (parser
);
7649 mark_exp_read (expr
.value
);
7650 stmt
= c_finish_return (EXPR_LOC_OR_LOC (expr
.value
, xloc
),
7651 expr
.value
, expr
.original_type
);
7652 goto expect_semicolon
;
7656 stmt
= c_parser_asm_statement (parser
);
7658 case RID_TRANSACTION_ATOMIC
:
7659 case RID_TRANSACTION_RELAXED
:
7660 stmt
= c_parser_transaction (parser
,
7661 c_parser_peek_token (parser
)->keyword
);
7663 case RID_TRANSACTION_CANCEL
:
7664 stmt
= c_parser_transaction_cancel (parser
);
7665 goto expect_semicolon
;
7667 gcc_assert (c_dialect_objc ());
7668 c_parser_consume_token (parser
);
7669 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7671 stmt
= objc_build_throw_stmt (loc
, NULL_TREE
);
7672 c_parser_consume_token (parser
);
7676 struct c_expr expr
= c_parser_expression (parser
);
7677 expr
= convert_lvalue_to_rvalue (loc
, expr
, false, false);
7678 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
7679 stmt
= objc_build_throw_stmt (loc
, expr
.value
);
7680 goto expect_semicolon
;
7684 gcc_assert (c_dialect_objc ());
7685 c_parser_objc_try_catch_finally_statement (parser
);
7687 case RID_AT_SYNCHRONIZED
:
7688 gcc_assert (c_dialect_objc ());
7689 c_parser_objc_synchronized_statement (parser
);
7693 /* Allow '__attribute__((fallthrough));' or
7694 '__attribute__((assume(cond)));'. */
7695 tree attrs
= c_parser_gnu_attributes (parser
);
7696 bool has_assume
= lookup_attribute ("assume", attrs
);
7699 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7700 attrs
= handle_assume_attribute (loc
, attrs
, true);
7703 warning_at (loc
, OPT_Wattributes
,
7704 "%<assume%> attribute not followed by %<;%>");
7708 if (attribute_fallthrough_p (attrs
))
7710 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7712 tree fn
= build_call_expr_internal_loc (loc
,
7717 c_parser_consume_token (parser
);
7720 warning_at (loc
, OPT_Wattributes
,
7721 "%<fallthrough%> attribute not followed "
7724 else if (has_assume
)
7726 c_parser_consume_token (parser
);
7727 else if (attrs
!= NULL_TREE
)
7728 warning_at (loc
, OPT_Wattributes
,
7729 "only attribute %<fallthrough%> or %<assume%> can "
7730 "be applied to a null statement");
7738 c_parser_consume_token (parser
);
7740 case CPP_CLOSE_PAREN
:
7741 case CPP_CLOSE_SQUARE
:
7742 /* Avoid infinite loop in error recovery:
7743 c_parser_skip_until_found stops at a closing nesting
7744 delimiter without consuming it, but here we need to consume
7745 it to proceed further. */
7746 c_parser_error (parser
, "expected statement");
7747 c_parser_consume_token (parser
);
7750 if (!c_parser_pragma (parser
, pragma_stmt
, if_p
))
7755 stmt
= c_finish_expr_stmt (loc
, c_parser_expression_conv (parser
).value
);
7757 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
7760 /* Two cases cannot and do not have line numbers associated: If stmt
7761 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
7762 cannot hold line numbers. But that's OK because the statement
7763 will either be changed to a MODIFY_EXPR during gimplification of
7764 the statement expr, or discarded. If stmt was compound, but
7765 without new variables, we will have skipped the creation of a
7766 BIND and will have a bare STATEMENT_LIST. But that's OK because
7767 (recursively) all of the component statements should already have
7768 line numbers assigned. ??? Can we discard no-op statements
7770 if (EXPR_LOCATION (stmt
) == UNKNOWN_LOCATION
)
7771 protected_set_expr_location (stmt
, loc
);
7773 parser
->in_if_block
= in_if_block
;
7776 /* Parse the condition from an if, do, while or for statements. */
7779 c_parser_condition (c_parser
*parser
)
7781 location_t loc
= c_parser_peek_token (parser
)->location
;
7783 cond
= c_parser_expression_conv (parser
).value
;
7784 cond
= c_objc_common_truthvalue_conversion (loc
, cond
);
7785 cond
= c_fully_fold (cond
, false, NULL
);
7786 if (warn_sequence_point
)
7787 verify_sequence_points (cond
);
7791 /* Parse a parenthesized condition from an if, do or while statement.
7797 c_parser_paren_condition (c_parser
*parser
)
7800 matching_parens parens
;
7801 if (!parens
.require_open (parser
))
7802 return error_mark_node
;
7803 cond
= c_parser_condition (parser
);
7804 parens
.skip_until_found_close (parser
);
7808 /* Parse a statement which is a block in C99.
7810 IF_P is used to track whether there's a (possibly labeled) if statement
7811 which is not enclosed in braces and has an else clause. This is used to
7812 implement -Wparentheses. */
7815 c_parser_c99_block_statement (c_parser
*parser
, bool *if_p
,
7816 location_t
*loc_after_labels
)
7818 tree block
= c_begin_compound_stmt (flag_isoc99
);
7819 location_t loc
= c_parser_peek_token (parser
)->location
;
7820 c_parser_statement (parser
, if_p
, loc_after_labels
);
7821 return c_end_compound_stmt (loc
, block
, flag_isoc99
);
7824 /* Parse the body of an if statement. This is just parsing a
7825 statement but (a) it is a block in C99, (b) we track whether the
7826 body is an if statement for the sake of -Wparentheses warnings, (c)
7827 we handle an empty body specially for the sake of -Wempty-body
7828 warnings, and (d) we call parser_compound_statement directly
7829 because c_parser_statement_after_labels resets
7830 parser->in_if_block.
7832 IF_P is used to track whether there's a (possibly labeled) if statement
7833 which is not enclosed in braces and has an else clause. This is used to
7834 implement -Wparentheses. */
7837 c_parser_if_body (c_parser
*parser
, bool *if_p
,
7838 const token_indent_info
&if_tinfo
)
7840 tree block
= c_begin_compound_stmt (flag_isoc99
);
7841 location_t body_loc
= c_parser_peek_token (parser
)->location
;
7842 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
7843 token_indent_info body_tinfo
7844 = get_token_indent_info (c_parser_peek_token (parser
));
7846 c_parser_all_labels (parser
);
7847 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7849 location_t loc
= c_parser_peek_token (parser
)->location
;
7850 add_stmt (build_empty_stmt (loc
));
7851 c_parser_consume_token (parser
);
7852 if (!c_parser_next_token_is_keyword (parser
, RID_ELSE
))
7853 warning_at (loc
, OPT_Wempty_body
,
7854 "suggest braces around empty body in an %<if%> statement");
7856 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7857 add_stmt (c_parser_compound_statement (parser
));
7860 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
7861 c_parser_statement_after_labels (parser
, if_p
);
7864 token_indent_info next_tinfo
7865 = get_token_indent_info (c_parser_peek_token (parser
));
7866 warn_for_misleading_indentation (if_tinfo
, body_tinfo
, next_tinfo
);
7867 if (body_loc_after_labels
!= UNKNOWN_LOCATION
7868 && next_tinfo
.type
!= CPP_SEMICOLON
)
7869 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
7870 if_tinfo
.location
, RID_IF
);
7872 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
7875 /* Parse the else body of an if statement. This is just parsing a
7876 statement but (a) it is a block in C99, (b) we handle an empty body
7877 specially for the sake of -Wempty-body warnings. CHAIN is a vector
7878 of if-else-if conditions. */
7881 c_parser_else_body (c_parser
*parser
, const token_indent_info
&else_tinfo
,
7884 location_t body_loc
= c_parser_peek_token (parser
)->location
;
7885 tree block
= c_begin_compound_stmt (flag_isoc99
);
7886 token_indent_info body_tinfo
7887 = get_token_indent_info (c_parser_peek_token (parser
));
7888 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
7890 c_parser_all_labels (parser
);
7891 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7893 location_t loc
= c_parser_peek_token (parser
)->location
;
7896 "suggest braces around empty body in an %<else%> statement");
7897 add_stmt (build_empty_stmt (loc
));
7898 c_parser_consume_token (parser
);
7902 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7903 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
7904 c_parser_statement_after_labels (parser
, NULL
, chain
);
7907 token_indent_info next_tinfo
7908 = get_token_indent_info (c_parser_peek_token (parser
));
7909 warn_for_misleading_indentation (else_tinfo
, body_tinfo
, next_tinfo
);
7910 if (body_loc_after_labels
!= UNKNOWN_LOCATION
7911 && next_tinfo
.type
!= CPP_SEMICOLON
)
7912 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
7913 else_tinfo
.location
, RID_ELSE
);
7915 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
7918 /* We might need to reclassify any previously-lexed identifier, e.g.
7919 when we've left a for loop with an if-statement without else in the
7920 body - we might have used a wrong scope for the token. See PR67784. */
7923 c_parser_maybe_reclassify_token (c_parser
*parser
)
7925 if (c_parser_next_token_is (parser
, CPP_NAME
))
7927 c_token
*token
= c_parser_peek_token (parser
);
7929 if (token
->id_kind
!= C_ID_CLASSNAME
)
7931 tree decl
= lookup_name (token
->value
);
7933 token
->id_kind
= C_ID_ID
;
7936 if (TREE_CODE (decl
) == TYPE_DECL
)
7937 token
->id_kind
= C_ID_TYPENAME
;
7939 else if (c_dialect_objc ())
7941 tree objc_interface_decl
= objc_is_class_name (token
->value
);
7942 /* Objective-C class names are in the same namespace as
7943 variables and typedefs, and hence are shadowed by local
7945 if (objc_interface_decl
)
7947 token
->value
= objc_interface_decl
;
7948 token
->id_kind
= C_ID_CLASSNAME
;
7955 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
7958 if ( expression ) statement
7959 if ( expression ) statement else statement
7961 CHAIN is a vector of if-else-if conditions.
7962 IF_P is used to track whether there's a (possibly labeled) if statement
7963 which is not enclosed in braces and has an else clause. This is used to
7964 implement -Wparentheses. */
7967 c_parser_if_statement (c_parser
*parser
, bool *if_p
, vec
<tree
> *chain
)
7972 bool nested_if
= false;
7973 tree first_body
, second_body
;
7976 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_IF
));
7977 token_indent_info if_tinfo
7978 = get_token_indent_info (c_parser_peek_token (parser
));
7979 c_parser_consume_token (parser
);
7980 block
= c_begin_compound_stmt (flag_isoc99
);
7981 loc
= c_parser_peek_token (parser
)->location
;
7982 cond
= c_parser_paren_condition (parser
);
7983 in_if_block
= parser
->in_if_block
;
7984 parser
->in_if_block
= true;
7985 first_body
= c_parser_if_body (parser
, &nested_if
, if_tinfo
);
7986 parser
->in_if_block
= in_if_block
;
7988 if (warn_duplicated_cond
)
7989 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond
), cond
, &chain
);
7991 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
7993 token_indent_info else_tinfo
7994 = get_token_indent_info (c_parser_peek_token (parser
));
7995 c_parser_consume_token (parser
);
7996 if (warn_duplicated_cond
)
7998 if (c_parser_next_token_is_keyword (parser
, RID_IF
)
8001 /* We've got "if (COND) else if (COND2)". Start the
8002 condition chain and add COND as the first element. */
8003 chain
= new vec
<tree
> ();
8004 if (!CONSTANT_CLASS_P (cond
) && !TREE_SIDE_EFFECTS (cond
))
8005 chain
->safe_push (cond
);
8007 else if (!c_parser_next_token_is_keyword (parser
, RID_IF
))
8008 /* This is if-else without subsequent if. Zap the condition
8009 chain; we would have already warned at this point. */
8012 second_body
= c_parser_else_body (parser
, else_tinfo
, chain
);
8013 /* Set IF_P to true to indicate that this if statement has an
8014 else clause. This may trigger the Wparentheses warning
8015 below when we get back up to the parent if statement. */
8021 second_body
= NULL_TREE
;
8023 /* Diagnose an ambiguous else if if-then-else is nested inside
8026 warning_at (loc
, OPT_Wdangling_else
,
8027 "suggest explicit braces to avoid ambiguous %<else%>");
8029 if (warn_duplicated_cond
)
8030 /* This if statement does not have an else clause. We don't
8031 need the condition chain anymore. */
8034 c_finish_if_stmt (loc
, cond
, first_body
, second_body
);
8035 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
8037 c_parser_maybe_reclassify_token (parser
);
8040 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
8043 switch (expression) statement
8047 c_parser_switch_statement (c_parser
*parser
, bool *if_p
)
8050 tree block
, expr
, body
;
8051 unsigned char save_in_statement
;
8052 location_t switch_loc
= c_parser_peek_token (parser
)->location
;
8053 location_t switch_cond_loc
;
8054 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SWITCH
));
8055 c_parser_consume_token (parser
);
8056 block
= c_begin_compound_stmt (flag_isoc99
);
8057 bool explicit_cast_p
= false;
8058 matching_parens parens
;
8059 if (parens
.require_open (parser
))
8061 switch_cond_loc
= c_parser_peek_token (parser
)->location
;
8062 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8063 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8064 explicit_cast_p
= true;
8065 ce
= c_parser_expression (parser
);
8066 ce
= convert_lvalue_to_rvalue (switch_cond_loc
, ce
, true, true);
8068 /* ??? expr has no valid location? */
8069 parens
.skip_until_found_close (parser
);
8073 switch_cond_loc
= UNKNOWN_LOCATION
;
8074 expr
= error_mark_node
;
8075 ce
.original_type
= error_mark_node
;
8077 c_start_switch (switch_loc
, switch_cond_loc
, expr
, explicit_cast_p
);
8078 save_in_statement
= in_statement
;
8079 in_statement
|= IN_SWITCH_STMT
;
8080 location_t loc_after_labels
;
8081 bool open_brace_p
= c_parser_peek_token (parser
)->type
== CPP_OPEN_BRACE
;
8082 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
8083 location_t next_loc
= c_parser_peek_token (parser
)->location
;
8084 if (!open_brace_p
&& c_parser_peek_token (parser
)->type
!= CPP_SEMICOLON
)
8085 warn_for_multistatement_macros (loc_after_labels
, next_loc
, switch_loc
,
8087 c_finish_switch (body
, ce
.original_type
);
8088 in_statement
= save_in_statement
;
8089 add_stmt (c_end_compound_stmt (switch_loc
, block
, flag_isoc99
));
8090 c_parser_maybe_reclassify_token (parser
);
8093 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8096 while (expression) statement
8098 IF_P is used to track whether there's a (possibly labeled) if statement
8099 which is not enclosed in braces and has an else clause. This is used to
8100 implement -Wparentheses. */
8103 c_parser_while_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
8104 bool novector
, bool *if_p
)
8106 tree block
, cond
, body
;
8107 unsigned char save_in_statement
;
8109 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_WHILE
));
8110 token_indent_info while_tinfo
8111 = get_token_indent_info (c_parser_peek_token (parser
));
8113 if (parser
->omp_for_parse_state
)
8115 error_at (c_parser_peek_token (parser
)->location
,
8116 "loop not permitted in intervening code in OpenMP loop body");
8117 parser
->omp_for_parse_state
->fail
= true;
8120 c_parser_consume_token (parser
);
8121 block
= c_begin_compound_stmt (flag_isoc99
);
8122 loc
= c_parser_peek_token (parser
)->location
;
8123 cond
= c_parser_paren_condition (parser
);
8124 if (ivdep
&& cond
!= error_mark_node
)
8125 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8126 build_int_cst (integer_type_node
,
8127 annot_expr_ivdep_kind
),
8129 if (unroll
&& cond
!= error_mark_node
)
8130 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8131 build_int_cst (integer_type_node
,
8132 annot_expr_unroll_kind
),
8133 build_int_cst (integer_type_node
, unroll
));
8134 if (novector
&& cond
!= error_mark_node
)
8135 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8136 build_int_cst (integer_type_node
,
8137 annot_expr_no_vector_kind
),
8139 save_in_statement
= in_statement
;
8140 in_statement
= IN_ITERATION_STMT
;
8142 token_indent_info body_tinfo
8143 = get_token_indent_info (c_parser_peek_token (parser
));
8145 location_t loc_after_labels
;
8146 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
8147 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
8148 add_stmt (build_stmt (loc
, WHILE_STMT
, cond
, body
));
8149 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
8150 c_parser_maybe_reclassify_token (parser
);
8152 token_indent_info next_tinfo
8153 = get_token_indent_info (c_parser_peek_token (parser
));
8154 warn_for_misleading_indentation (while_tinfo
, body_tinfo
, next_tinfo
);
8156 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
8157 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
8158 while_tinfo
.location
, RID_WHILE
);
8160 in_statement
= save_in_statement
;
8163 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8166 do statement while ( expression ) ;
8170 c_parser_do_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
8173 tree block
, cond
, body
;
8174 unsigned char save_in_statement
;
8176 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_DO
));
8178 if (parser
->omp_for_parse_state
)
8180 error_at (c_parser_peek_token (parser
)->location
,
8181 "loop not permitted in intervening code in OpenMP loop body");
8182 parser
->omp_for_parse_state
->fail
= true;
8185 c_parser_consume_token (parser
);
8186 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
8187 warning_at (c_parser_peek_token (parser
)->location
,
8189 "suggest braces around empty body in %<do%> statement");
8190 block
= c_begin_compound_stmt (flag_isoc99
);
8191 loc
= c_parser_peek_token (parser
)->location
;
8192 save_in_statement
= in_statement
;
8193 in_statement
= IN_ITERATION_STMT
;
8194 body
= c_parser_c99_block_statement (parser
, NULL
);
8195 c_parser_require_keyword (parser
, RID_WHILE
, "expected %<while%>");
8196 in_statement
= save_in_statement
;
8197 cond
= c_parser_paren_condition (parser
);
8198 if (ivdep
&& cond
!= error_mark_node
)
8199 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8200 build_int_cst (integer_type_node
,
8201 annot_expr_ivdep_kind
),
8203 if (unroll
&& cond
!= error_mark_node
)
8204 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8205 build_int_cst (integer_type_node
,
8206 annot_expr_unroll_kind
),
8207 build_int_cst (integer_type_node
, unroll
));
8208 if (novector
&& cond
!= error_mark_node
)
8209 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8210 build_int_cst (integer_type_node
,
8211 annot_expr_no_vector_kind
),
8213 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
8214 c_parser_skip_to_end_of_block_or_statement (parser
);
8216 add_stmt (build_stmt (loc
, DO_STMT
, cond
, body
));
8217 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
8220 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8223 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
8224 for ( nested-declaration expression[opt] ; expression[opt] ) statement
8226 The form with a declaration is new in C99.
8228 ??? In accordance with the old parser, the declaration may be a
8229 nested function, which is then rejected in check_for_loop_decls,
8230 but does it make any sense for this to be included in the grammar?
8231 Note in particular that the nested function does not include a
8232 trailing ';', whereas the "declaration" production includes one.
8233 Also, can we reject bad declarations earlier and cheaper than
8234 check_for_loop_decls?
8236 In Objective-C, there are two additional variants:
8239 for ( expression in expresssion ) statement
8240 for ( declaration in expression ) statement
8242 This is inconsistent with C, because the second variant is allowed
8243 even if c99 is not enabled.
8245 The rest of the comment documents these Objective-C foreach-statement.
8247 Here is the canonical example of the first variant:
8248 for (object in array) { do something with object }
8249 we call the first expression ("object") the "object_expression" and
8250 the second expression ("array") the "collection_expression".
8251 object_expression must be an lvalue of type "id" (a generic Objective-C
8252 object) because the loop works by assigning to object_expression the
8253 various objects from the collection_expression. collection_expression
8254 must evaluate to something of type "id" which responds to the method
8255 countByEnumeratingWithState:objects:count:.
8257 The canonical example of the second variant is:
8258 for (id object in array) { do something with object }
8259 which is completely equivalent to
8262 for (object in array) { do something with object }
8264 Note that initizializing 'object' in some way (eg, "for ((object =
8265 xxx) in array) { do something with object }") is possibly
8266 technically valid, but completely pointless as 'object' will be
8267 assigned to something else as soon as the loop starts. We should
8268 most likely reject it (TODO).
8270 The beginning of the Objective-C foreach-statement looks exactly
8271 like the beginning of the for-statement, and we can tell it is a
8272 foreach-statement only because the initial declaration or
8273 expression is terminated by 'in' instead of ';'.
8275 IF_P is used to track whether there's a (possibly labeled) if statement
8276 which is not enclosed in braces and has an else clause. This is used to
8277 implement -Wparentheses. */
8280 c_parser_for_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
8281 bool novector
, bool *if_p
)
8283 tree block
, cond
, incr
, body
;
8284 unsigned char save_in_statement
;
8285 tree save_objc_foreach_break_label
, save_objc_foreach_continue_label
;
8286 /* The following are only used when parsing an ObjC foreach statement. */
8287 tree object_expression
;
8288 /* Silence the bogus uninitialized warning. */
8289 tree collection_expression
= NULL
;
8290 location_t loc
= c_parser_peek_token (parser
)->location
;
8291 location_t for_loc
= loc
;
8292 bool is_foreach_statement
= false;
8293 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
8294 token_indent_info for_tinfo
8295 = get_token_indent_info (c_parser_peek_token (parser
));
8297 if (parser
->omp_for_parse_state
)
8300 "loop not permitted in intervening code in OpenMP loop body");
8301 parser
->omp_for_parse_state
->fail
= true;
8304 c_parser_consume_token (parser
);
8305 /* Open a compound statement in Objective-C as well, just in case this is
8306 as foreach expression. */
8307 block
= c_begin_compound_stmt (flag_isoc99
|| c_dialect_objc ());
8308 cond
= error_mark_node
;
8309 incr
= error_mark_node
;
8310 matching_parens parens
;
8311 if (parens
.require_open (parser
))
8313 /* Parse the initialization declaration or expression. */
8314 object_expression
= error_mark_node
;
8315 parser
->objc_could_be_foreach_context
= c_dialect_objc ();
8316 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
8318 parser
->objc_could_be_foreach_context
= false;
8319 c_parser_consume_token (parser
);
8320 c_finish_expr_stmt (loc
, NULL_TREE
);
8322 else if (c_parser_next_tokens_start_declaration (parser
)
8323 || c_parser_nth_token_starts_std_attributes (parser
, 1))
8325 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
8326 &object_expression
);
8327 parser
->objc_could_be_foreach_context
= false;
8329 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
8331 c_parser_consume_token (parser
);
8332 is_foreach_statement
= true;
8333 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
8334 c_parser_error (parser
, "multiple iterating variables in "
8335 "fast enumeration");
8338 check_for_loop_decls (for_loc
, flag_isoc99
);
8340 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
8342 /* __extension__ can start a declaration, but is also an
8343 unary operator that can start an expression. Consume all
8344 but the last of a possible series of __extension__ to
8346 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
8347 && (c_parser_peek_2nd_token (parser
)->keyword
8349 c_parser_consume_token (parser
);
8350 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
8351 || c_parser_nth_token_starts_std_attributes (parser
, 2))
8354 ext
= disable_extension_diagnostics ();
8355 c_parser_consume_token (parser
);
8356 c_parser_declaration_or_fndef (parser
, true, true, true, true,
8357 true, &object_expression
);
8358 parser
->objc_could_be_foreach_context
= false;
8360 restore_extension_diagnostics (ext
);
8361 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
8363 c_parser_consume_token (parser
);
8364 is_foreach_statement
= true;
8365 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
8366 c_parser_error (parser
, "multiple iterating variables in "
8367 "fast enumeration");
8370 check_for_loop_decls (for_loc
, flag_isoc99
);
8380 tree init_expression
;
8381 ce
= c_parser_expression (parser
);
8382 init_expression
= ce
.value
;
8383 parser
->objc_could_be_foreach_context
= false;
8384 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
8386 c_parser_consume_token (parser
);
8387 is_foreach_statement
= true;
8388 if (! lvalue_p (init_expression
))
8389 c_parser_error (parser
, "invalid iterating variable in "
8390 "fast enumeration");
8392 = c_fully_fold (init_expression
, false, NULL
);
8396 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
8397 init_expression
= ce
.value
;
8398 c_finish_expr_stmt (loc
, init_expression
);
8399 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
8404 /* Parse the loop condition. In the case of a foreach
8405 statement, there is no loop condition. */
8406 gcc_assert (!parser
->objc_could_be_foreach_context
);
8407 if (!is_foreach_statement
)
8409 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
8413 c_parser_error (parser
, "missing loop condition in loop "
8414 "with %<GCC ivdep%> pragma");
8415 cond
= error_mark_node
;
8419 c_parser_error (parser
, "missing loop condition in loop "
8420 "with %<GCC unroll%> pragma");
8421 cond
= error_mark_node
;
8425 c_parser_consume_token (parser
);
8431 cond
= c_parser_condition (parser
);
8432 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
8435 if (ivdep
&& cond
!= error_mark_node
)
8436 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8437 build_int_cst (integer_type_node
,
8438 annot_expr_ivdep_kind
),
8440 if (unroll
&& cond
!= error_mark_node
)
8441 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8442 build_int_cst (integer_type_node
,
8443 annot_expr_unroll_kind
),
8444 build_int_cst (integer_type_node
, unroll
));
8445 if (novector
&& cond
!= error_mark_node
)
8446 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8447 build_int_cst (integer_type_node
,
8448 annot_expr_no_vector_kind
),
8451 /* Parse the increment expression (the third expression in a
8452 for-statement). In the case of a foreach-statement, this is
8453 the expression that follows the 'in'. */
8454 loc
= c_parser_peek_token (parser
)->location
;
8455 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8457 if (is_foreach_statement
)
8459 c_parser_error (parser
,
8460 "missing collection in fast enumeration");
8461 collection_expression
= error_mark_node
;
8464 incr
= c_process_expr_stmt (loc
, NULL_TREE
);
8468 if (is_foreach_statement
)
8469 collection_expression
8470 = c_fully_fold (c_parser_expression (parser
).value
, false, NULL
);
8473 struct c_expr ce
= c_parser_expression (parser
);
8474 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
8475 incr
= c_process_expr_stmt (loc
, ce
.value
);
8478 parens
.skip_until_found_close (parser
);
8480 save_in_statement
= in_statement
;
8481 if (is_foreach_statement
)
8483 in_statement
= IN_OBJC_FOREACH
;
8484 save_objc_foreach_break_label
= objc_foreach_break_label
;
8485 save_objc_foreach_continue_label
= objc_foreach_continue_label
;
8486 objc_foreach_break_label
= create_artificial_label (loc
);
8487 objc_foreach_continue_label
= create_artificial_label (loc
);
8490 in_statement
= IN_ITERATION_STMT
;
8492 token_indent_info body_tinfo
8493 = get_token_indent_info (c_parser_peek_token (parser
));
8495 location_t loc_after_labels
;
8496 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
8497 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
8499 if (is_foreach_statement
)
8500 objc_finish_foreach_loop (for_loc
, object_expression
,
8501 collection_expression
, body
,
8502 objc_foreach_break_label
,
8503 objc_foreach_continue_label
);
8505 add_stmt (build_stmt (for_loc
, FOR_STMT
, NULL_TREE
, cond
, incr
,
8507 add_stmt (c_end_compound_stmt (for_loc
, block
,
8508 flag_isoc99
|| c_dialect_objc ()));
8509 c_parser_maybe_reclassify_token (parser
);
8511 token_indent_info next_tinfo
8512 = get_token_indent_info (c_parser_peek_token (parser
));
8513 warn_for_misleading_indentation (for_tinfo
, body_tinfo
, next_tinfo
);
8515 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
8516 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
8517 for_tinfo
.location
, RID_FOR
);
8519 in_statement
= save_in_statement
;
8520 if (is_foreach_statement
)
8522 objc_foreach_break_label
= save_objc_foreach_break_label
;
8523 objc_foreach_continue_label
= save_objc_foreach_continue_label
;
8527 /* Parse an asm statement, a GNU extension. This is a full-blown asm
8528 statement with inputs, outputs, clobbers, and volatile, inline, and goto
8537 asm-qualifier-list asm-qualifier
8541 asm asm-qualifier-list[opt] ( asm-argument ) ;
8545 asm-string-literal : asm-operands[opt]
8546 asm-string-literal : asm-operands[opt] : asm-operands[opt]
8547 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
8549 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
8552 The form with asm-goto-operands is valid if and only if the
8553 asm-qualifier-list contains goto, and is the only allowed form in that case.
8554 Duplicate asm-qualifiers are not allowed.
8556 The :: token is considered equivalent to two consecutive : tokens. */
8559 c_parser_asm_statement (c_parser
*parser
)
8561 tree str
, outputs
, inputs
, clobbers
, labels
, ret
;
8563 location_t asm_loc
= c_parser_peek_token (parser
)->location
;
8564 int section
, nsections
;
8566 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
8567 c_parser_consume_token (parser
);
8569 /* Handle the asm-qualifier-list. */
8570 location_t volatile_loc
= UNKNOWN_LOCATION
;
8571 location_t inline_loc
= UNKNOWN_LOCATION
;
8572 location_t goto_loc
= UNKNOWN_LOCATION
;
8575 c_token
*token
= c_parser_peek_token (parser
);
8576 location_t loc
= token
->location
;
8577 switch (token
->keyword
)
8582 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
8583 inform (volatile_loc
, "first seen here");
8587 c_parser_consume_token (parser
);
8593 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
8594 inform (inline_loc
, "first seen here");
8598 c_parser_consume_token (parser
);
8604 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
8605 inform (goto_loc
, "first seen here");
8609 c_parser_consume_token (parser
);
8614 error_at (loc
, "%qE is not a valid %<asm%> qualifier", token
->value
);
8615 c_parser_consume_token (parser
);
8624 bool is_volatile
= (volatile_loc
!= UNKNOWN_LOCATION
);
8625 bool is_inline
= (inline_loc
!= UNKNOWN_LOCATION
);
8626 bool is_goto
= (goto_loc
!= UNKNOWN_LOCATION
);
8630 matching_parens parens
;
8631 if (!parens
.require_open (parser
))
8634 str
= c_parser_asm_string_literal (parser
);
8635 if (str
== NULL_TREE
)
8636 goto error_close_paren
;
8639 outputs
= NULL_TREE
;
8641 clobbers
= NULL_TREE
;
8644 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
8647 /* Parse each colon-delimited section of operands. */
8648 nsections
= 3 + is_goto
;
8649 for (section
= 0; section
< nsections
; ++section
)
8651 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
8654 if (section
== nsections
)
8656 c_parser_error (parser
, "expected %<)%>");
8657 goto error_close_paren
;
8659 c_parser_consume_token (parser
);
8661 else if (!c_parser_require (parser
, CPP_COLON
,
8663 ? G_("expected %<:%>")
8664 : G_("expected %<:%> or %<)%>"),
8665 UNKNOWN_LOCATION
, is_goto
))
8666 goto error_close_paren
;
8668 /* Once past any colon, we're no longer a simple asm. */
8671 if ((!c_parser_next_token_is (parser
, CPP_COLON
)
8672 && !c_parser_next_token_is (parser
, CPP_SCOPE
)
8673 && !c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8678 outputs
= c_parser_asm_operands (parser
);
8681 inputs
= c_parser_asm_operands (parser
);
8684 clobbers
= c_parser_asm_clobbers (parser
);
8687 labels
= c_parser_asm_goto_operands (parser
);
8693 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
8698 if (!parens
.require_close (parser
))
8700 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8704 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
8705 c_parser_skip_to_end_of_block_or_statement (parser
);
8707 ret
= build_asm_stmt (is_volatile
,
8708 build_asm_expr (asm_loc
, str
, outputs
, inputs
,
8709 clobbers
, labels
, simple
, is_inline
));
8715 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8719 /* Parse asm operands, a GNU extension.
8723 asm-operands , asm-operand
8726 asm-string-literal ( expression )
8727 [ identifier ] asm-string-literal ( expression )
8731 c_parser_asm_operands (c_parser
*parser
)
8733 tree list
= NULL_TREE
;
8738 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
8740 c_parser_consume_token (parser
);
8741 if (c_parser_next_token_is (parser
, CPP_NAME
))
8743 tree id
= c_parser_peek_token (parser
)->value
;
8744 c_parser_consume_token (parser
);
8745 name
= build_string (IDENTIFIER_LENGTH (id
),
8746 IDENTIFIER_POINTER (id
));
8750 c_parser_error (parser
, "expected identifier");
8751 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
8754 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
8759 str
= c_parser_asm_string_literal (parser
);
8760 if (str
== NULL_TREE
)
8762 matching_parens parens
;
8763 if (!parens
.require_open (parser
))
8765 expr
= c_parser_expression (parser
);
8766 mark_exp_read (expr
.value
);
8767 if (!parens
.require_close (parser
))
8769 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8772 list
= chainon (list
, build_tree_list (build_tree_list (name
, str
),
8774 if (c_parser_next_token_is (parser
, CPP_COMMA
))
8775 c_parser_consume_token (parser
);
8782 /* Parse asm clobbers, a GNU extension.
8786 asm-clobbers , asm-string-literal
8790 c_parser_asm_clobbers (c_parser
*parser
)
8792 tree list
= NULL_TREE
;
8795 tree str
= c_parser_asm_string_literal (parser
);
8797 list
= tree_cons (NULL_TREE
, str
, list
);
8800 if (c_parser_next_token_is (parser
, CPP_COMMA
))
8801 c_parser_consume_token (parser
);
8808 /* Parse asm goto labels, a GNU extension.
8812 asm-goto-operands , identifier
8816 c_parser_asm_goto_operands (c_parser
*parser
)
8818 tree list
= NULL_TREE
;
8823 if (c_parser_next_token_is (parser
, CPP_NAME
))
8825 c_token
*tok
= c_parser_peek_token (parser
);
8827 label
= lookup_label_for_goto (tok
->location
, name
);
8828 c_parser_consume_token (parser
);
8829 TREE_USED (label
) = 1;
8833 c_parser_error (parser
, "expected identifier");
8837 name
= build_string (IDENTIFIER_LENGTH (name
),
8838 IDENTIFIER_POINTER (name
));
8839 list
= tree_cons (name
, label
, list
);
8840 if (c_parser_next_token_is (parser
, CPP_COMMA
))
8841 c_parser_consume_token (parser
);
8843 return nreverse (list
);
8847 /* Parse a possibly concatenated sequence of string literals.
8848 TRANSLATE says whether to translate them to the execution character
8849 set; WIDE_OK says whether any kind of prefixed string literal is
8850 permitted in this context. This code is based on that in
8854 c_parser_string_literal (c_parser
*parser
, bool translate
, bool wide_ok
)
8858 struct obstack str_ob
;
8859 struct obstack loc_ob
;
8860 cpp_string str
, istr
, *strs
;
8862 location_t loc
, last_tok_loc
;
8863 enum cpp_ttype type
;
8864 tree value
, string_tree
;
8866 tok
= c_parser_peek_token (parser
);
8867 loc
= tok
->location
;
8868 last_tok_loc
= linemap_resolve_location (line_table
, loc
,
8869 LRK_MACRO_DEFINITION_LOCATION
,
8878 case CPP_UTF8STRING
:
8879 string_tree
= tok
->value
;
8883 c_parser_error (parser
, "expected string literal");
8885 ret
.value
= NULL_TREE
;
8886 ret
.original_code
= ERROR_MARK
;
8887 ret
.original_type
= NULL_TREE
;
8891 /* Try to avoid the overhead of creating and destroying an obstack
8892 for the common case of just one string. */
8893 switch (c_parser_peek_2nd_token (parser
)->type
)
8896 c_parser_consume_token (parser
);
8897 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
8898 str
.len
= TREE_STRING_LENGTH (string_tree
);
8907 case CPP_UTF8STRING
:
8908 gcc_obstack_init (&str_ob
);
8909 gcc_obstack_init (&loc_ob
);
8913 c_parser_consume_token (parser
);
8915 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
8916 str
.len
= TREE_STRING_LENGTH (string_tree
);
8917 if (type
!= tok
->type
)
8919 if (type
== CPP_STRING
)
8921 else if (tok
->type
!= CPP_STRING
)
8922 error ("unsupported non-standard concatenation "
8923 "of string literals");
8925 obstack_grow (&str_ob
, &str
, sizeof (cpp_string
));
8926 obstack_grow (&loc_ob
, &last_tok_loc
, sizeof (location_t
));
8927 tok
= c_parser_peek_token (parser
);
8928 string_tree
= tok
->value
;
8930 = linemap_resolve_location (line_table
, tok
->location
,
8931 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
8933 while (tok
->type
== CPP_STRING
8934 || tok
->type
== CPP_WSTRING
8935 || tok
->type
== CPP_STRING16
8936 || tok
->type
== CPP_STRING32
8937 || tok
->type
== CPP_UTF8STRING
);
8938 strs
= (cpp_string
*) obstack_finish (&str_ob
);
8941 if (count
> 1 && !in_system_header_at (input_location
))
8942 warning (OPT_Wtraditional
,
8943 "traditional C rejects string constant concatenation");
8945 if ((type
== CPP_STRING
|| wide_ok
)
8947 ? cpp_interpret_string
: cpp_interpret_string_notranslate
)
8948 (parse_in
, strs
, count
, &istr
, type
)))
8950 value
= build_string (istr
.len
, (const char *) istr
.text
);
8951 free (CONST_CAST (unsigned char *, istr
.text
));
8954 location_t
*locs
= (location_t
*) obstack_finish (&loc_ob
);
8955 gcc_assert (g_string_concat_db
);
8956 g_string_concat_db
->record_string_concatenation (count
, locs
);
8961 if (type
!= CPP_STRING
&& !wide_ok
)
8963 error_at (loc
, "a wide string is invalid in this context");
8966 /* Callers cannot generally handle error_mark_node in this
8967 context, so return the empty string instead. An error has
8968 been issued, either above or from cpp_interpret_string. */
8973 case CPP_UTF8STRING
:
8974 if (type
== CPP_UTF8STRING
&& flag_char8_t
)
8976 value
= build_string (TYPE_PRECISION (char8_type_node
)
8977 / TYPE_PRECISION (char_type_node
),
8978 ""); /* char8_t is 8 bits */
8981 value
= build_string (1, "");
8984 value
= build_string (TYPE_PRECISION (char16_type_node
)
8985 / TYPE_PRECISION (char_type_node
),
8986 "\0"); /* char16_t is 16 bits */
8989 value
= build_string (TYPE_PRECISION (char32_type_node
)
8990 / TYPE_PRECISION (char_type_node
),
8991 "\0\0\0"); /* char32_t is 32 bits */
8994 value
= build_string (TYPE_PRECISION (wchar_type_node
)
8995 / TYPE_PRECISION (char_type_node
),
8996 "\0\0\0"); /* widest supported wchar_t
9006 TREE_TYPE (value
) = char_array_type_node
;
9008 case CPP_UTF8STRING
:
9010 TREE_TYPE (value
) = char8_array_type_node
;
9012 TREE_TYPE (value
) = char_array_type_node
;
9015 TREE_TYPE (value
) = char16_array_type_node
;
9018 TREE_TYPE (value
) = char32_array_type_node
;
9021 TREE_TYPE (value
) = wchar_array_type_node
;
9023 value
= fix_string_type (value
);
9027 obstack_free (&str_ob
, 0);
9028 obstack_free (&loc_ob
, 0);
9032 ret
.original_code
= STRING_CST
;
9033 ret
.original_type
= NULL_TREE
;
9034 set_c_expr_source_range (&ret
, get_range_from_loc (line_table
, loc
));
9036 parser
->seen_string_literal
= true;
9040 /* Parse an expression other than a compound expression; that is, an
9041 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
9042 AFTER is not NULL then it is an Objective-C message expression which
9043 is the primary-expression starting the expression as an initializer.
9045 assignment-expression:
9046 conditional-expression
9047 unary-expression assignment-operator assignment-expression
9049 assignment-operator: one of
9050 = *= /= %= += -= <<= >>= &= ^= |=
9052 In GNU C we accept any conditional expression on the LHS and
9053 diagnose the invalid lvalue rather than producing a syntax
9056 static struct c_expr
9057 c_parser_expr_no_commas (c_parser
*parser
, struct c_expr
*after
,
9058 tree omp_atomic_lhs
)
9060 struct c_expr lhs
, rhs
, ret
;
9061 enum tree_code code
;
9062 location_t op_location
, exp_location
;
9063 bool save_in_omp_for
= c_in_omp_for
;
9064 c_in_omp_for
= false;
9065 gcc_assert (!after
|| c_dialect_objc ());
9066 lhs
= c_parser_conditional_expression (parser
, after
, omp_atomic_lhs
);
9067 op_location
= c_parser_peek_token (parser
)->location
;
9068 switch (c_parser_peek_token (parser
)->type
)
9077 code
= TRUNC_DIV_EXPR
;
9080 code
= TRUNC_MOD_EXPR
;
9095 code
= BIT_AND_EXPR
;
9098 code
= BIT_XOR_EXPR
;
9101 code
= BIT_IOR_EXPR
;
9104 c_in_omp_for
= save_in_omp_for
;
9107 c_parser_consume_token (parser
);
9108 exp_location
= c_parser_peek_token (parser
)->location
;
9109 rhs
= c_parser_expr_no_commas (parser
, NULL
);
9110 rhs
= convert_lvalue_to_rvalue (exp_location
, rhs
, true, true);
9112 ret
.value
= build_modify_expr (op_location
, lhs
.value
, lhs
.original_type
,
9113 code
, exp_location
, rhs
.value
,
9116 set_c_expr_source_range (&ret
, lhs
.get_start (), rhs
.get_finish ());
9117 if (code
== NOP_EXPR
)
9118 ret
.original_code
= MODIFY_EXPR
;
9121 suppress_warning (ret
.value
, OPT_Wparentheses
);
9122 ret
.original_code
= ERROR_MARK
;
9124 ret
.original_type
= NULL
;
9125 c_in_omp_for
= save_in_omp_for
;
9129 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
9130 AFTER is not NULL then it is an Objective-C message expression which is
9131 the primary-expression starting the expression as an initializer.
9133 conditional-expression:
9134 logical-OR-expression
9135 logical-OR-expression ? expression : conditional-expression
9139 conditional-expression:
9140 logical-OR-expression ? : conditional-expression
9143 static struct c_expr
9144 c_parser_conditional_expression (c_parser
*parser
, struct c_expr
*after
,
9145 tree omp_atomic_lhs
)
9147 struct c_expr cond
, exp1
, exp2
, ret
;
9148 location_t start
, cond_loc
, colon_loc
;
9150 gcc_assert (!after
|| c_dialect_objc ());
9152 cond
= c_parser_binary_expression (parser
, after
, omp_atomic_lhs
);
9154 if (c_parser_next_token_is_not (parser
, CPP_QUERY
))
9156 if (cond
.value
!= error_mark_node
)
9157 start
= cond
.get_start ();
9159 start
= UNKNOWN_LOCATION
;
9160 cond_loc
= c_parser_peek_token (parser
)->location
;
9161 cond
= convert_lvalue_to_rvalue (cond_loc
, cond
, true, true);
9162 c_parser_consume_token (parser
);
9163 if (c_parser_next_token_is (parser
, CPP_COLON
))
9165 tree eptype
= NULL_TREE
;
9167 location_t middle_loc
= c_parser_peek_token (parser
)->location
;
9168 pedwarn (middle_loc
, OPT_Wpedantic
,
9169 "ISO C forbids omitting the middle term of a %<?:%> expression");
9170 if (TREE_CODE (cond
.value
) == EXCESS_PRECISION_EXPR
)
9172 eptype
= TREE_TYPE (cond
.value
);
9173 cond
.value
= TREE_OPERAND (cond
.value
, 0);
9175 tree e
= cond
.value
;
9176 while (TREE_CODE (e
) == COMPOUND_EXPR
)
9177 e
= TREE_OPERAND (e
, 1);
9178 warn_for_omitted_condop (middle_loc
, e
);
9179 /* Make sure first operand is calculated only once. */
9180 exp1
.value
= save_expr (default_conversion (cond
.value
));
9182 exp1
.value
= build1 (EXCESS_PRECISION_EXPR
, eptype
, exp1
.value
);
9183 exp1
.original_type
= NULL
;
9184 exp1
.src_range
= cond
.src_range
;
9185 cond
.value
= c_objc_common_truthvalue_conversion (cond_loc
, exp1
.value
);
9186 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_true_node
;
9191 = c_objc_common_truthvalue_conversion
9192 (cond_loc
, default_conversion (cond
.value
));
9193 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_false_node
;
9194 exp1
= c_parser_expression_conv (parser
);
9195 mark_exp_read (exp1
.value
);
9196 c_inhibit_evaluation_warnings
+=
9197 ((cond
.value
== truthvalue_true_node
)
9198 - (cond
.value
== truthvalue_false_node
));
9201 colon_loc
= c_parser_peek_token (parser
)->location
;
9202 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
9204 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
9206 ret
.original_code
= ERROR_MARK
;
9207 ret
.original_type
= NULL
;
9211 location_t exp2_loc
= c_parser_peek_token (parser
)->location
;
9212 exp2
= c_parser_conditional_expression (parser
, NULL
, NULL_TREE
);
9213 exp2
= convert_lvalue_to_rvalue (exp2_loc
, exp2
, true, true);
9215 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
9216 location_t loc1
= make_location (exp1
.get_start (), exp1
.src_range
);
9217 location_t loc2
= make_location (exp2
.get_start (), exp2
.src_range
);
9218 if (UNLIKELY (omp_atomic_lhs
!= NULL
)
9219 && (TREE_CODE (cond
.value
) == GT_EXPR
9220 || TREE_CODE (cond
.value
) == LT_EXPR
9221 || TREE_CODE (cond
.value
) == EQ_EXPR
)
9222 && c_tree_equal (exp2
.value
, omp_atomic_lhs
)
9223 && (c_tree_equal (TREE_OPERAND (cond
.value
, 0), omp_atomic_lhs
)
9224 || c_tree_equal (TREE_OPERAND (cond
.value
, 1), omp_atomic_lhs
)))
9225 ret
.value
= build3_loc (colon_loc
, COND_EXPR
, TREE_TYPE (omp_atomic_lhs
),
9226 cond
.value
, exp1
.value
, exp2
.value
);
9229 = build_conditional_expr (colon_loc
, cond
.value
,
9230 cond
.original_code
== C_MAYBE_CONST_EXPR
,
9231 exp1
.value
, exp1
.original_type
, loc1
,
9232 exp2
.value
, exp2
.original_type
, loc2
);
9233 ret
.original_code
= ERROR_MARK
;
9234 if (exp1
.value
== error_mark_node
|| exp2
.value
== error_mark_node
)
9235 ret
.original_type
= NULL
;
9240 /* If both sides are enum type, the default conversion will have
9241 made the type of the result be an integer type. We want to
9242 remember the enum types we started with. */
9243 t1
= exp1
.original_type
? exp1
.original_type
: TREE_TYPE (exp1
.value
);
9244 t2
= exp2
.original_type
? exp2
.original_type
: TREE_TYPE (exp2
.value
);
9245 ret
.original_type
= ((t1
!= error_mark_node
9246 && t2
!= error_mark_node
9247 && (TYPE_MAIN_VARIANT (t1
)
9248 == TYPE_MAIN_VARIANT (t2
)))
9252 set_c_expr_source_range (&ret
, start
, exp2
.get_finish ());
9257 /* Parse a binary expression; that is, a logical-OR-expression (C90
9258 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
9259 NULL then it is an Objective-C message expression which is the
9260 primary-expression starting the expression as an initializer.
9262 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
9263 when it should be the unfolded lhs. In a valid OpenMP source,
9264 one of the operands of the toplevel binary expression must be equal
9265 to it. In that case, just return a build2 created binary operation
9266 rather than result of parser_build_binary_op.
9268 multiplicative-expression:
9270 multiplicative-expression * cast-expression
9271 multiplicative-expression / cast-expression
9272 multiplicative-expression % cast-expression
9274 additive-expression:
9275 multiplicative-expression
9276 additive-expression + multiplicative-expression
9277 additive-expression - multiplicative-expression
9281 shift-expression << additive-expression
9282 shift-expression >> additive-expression
9284 relational-expression:
9286 relational-expression < shift-expression
9287 relational-expression > shift-expression
9288 relational-expression <= shift-expression
9289 relational-expression >= shift-expression
9291 equality-expression:
9292 relational-expression
9293 equality-expression == relational-expression
9294 equality-expression != relational-expression
9298 AND-expression & equality-expression
9300 exclusive-OR-expression:
9302 exclusive-OR-expression ^ AND-expression
9304 inclusive-OR-expression:
9305 exclusive-OR-expression
9306 inclusive-OR-expression | exclusive-OR-expression
9308 logical-AND-expression:
9309 inclusive-OR-expression
9310 logical-AND-expression && inclusive-OR-expression
9312 logical-OR-expression:
9313 logical-AND-expression
9314 logical-OR-expression || logical-AND-expression
9317 static struct c_expr
9318 c_parser_binary_expression (c_parser
*parser
, struct c_expr
*after
,
9319 tree omp_atomic_lhs
)
9321 /* A binary expression is parsed using operator-precedence parsing,
9322 with the operands being cast expressions. All the binary
9323 operators are left-associative. Thus a binary expression is of
9326 E0 op1 E1 op2 E2 ...
9328 which we represent on a stack. On the stack, the precedence
9329 levels are strictly increasing. When a new operator is
9330 encountered of higher precedence than that at the top of the
9331 stack, it is pushed; its LHS is the top expression, and its RHS
9332 is everything parsed until it is popped. When a new operator is
9333 encountered with precedence less than or equal to that at the top
9334 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
9335 by the result of the operation until the operator at the top of
9336 the stack has lower precedence than the new operator or there is
9337 only one element on the stack; then the top expression is the LHS
9338 of the new operator. In the case of logical AND and OR
9339 expressions, we also need to adjust c_inhibit_evaluation_warnings
9340 as appropriate when the operators are pushed and popped. */
9343 /* The expression at this stack level. */
9345 /* The precedence of the operator on its left, PREC_NONE at the
9346 bottom of the stack. */
9347 enum c_parser_prec prec
;
9348 /* The operation on its left. */
9350 /* The source location of this operation. */
9352 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
9356 /* Location of the binary operator. */
9357 location_t binary_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
9360 switch (stack[sp].op) \
9362 case TRUTH_ANDIF_EXPR: \
9363 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9364 == truthvalue_false_node); \
9366 case TRUTH_ORIF_EXPR: \
9367 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9368 == truthvalue_true_node); \
9370 case TRUNC_DIV_EXPR: \
9371 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
9372 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
9373 && (stack[sp].expr.original_code == SIZEOF_EXPR \
9374 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
9376 tree type0 = stack[sp - 1].sizeof_arg; \
9377 tree type1 = stack[sp].sizeof_arg; \
9378 tree first_arg = type0; \
9379 if (!TYPE_P (type0)) \
9380 type0 = TREE_TYPE (type0); \
9381 if (!TYPE_P (type1)) \
9382 type1 = TREE_TYPE (type1); \
9383 if (POINTER_TYPE_P (type0) \
9384 && comptypes (TREE_TYPE (type0), type1) \
9385 && !(TREE_CODE (first_arg) == PARM_DECL \
9386 && C_ARRAY_PARAMETER (first_arg) \
9387 && warn_sizeof_array_argument)) \
9389 auto_diagnostic_group d; \
9390 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
9391 "division %<sizeof (%T) / sizeof (%T)%> " \
9392 "does not compute the number of array " \
9395 if (DECL_P (first_arg)) \
9396 inform (DECL_SOURCE_LOCATION (first_arg), \
9397 "first %<sizeof%> operand was declared here"); \
9399 else if (TREE_CODE (type0) == ARRAY_TYPE \
9400 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
9401 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
9402 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
9403 stack[sp].sizeof_arg, type1); \
9409 stack[sp - 1].expr \
9410 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
9411 stack[sp - 1].expr, true, true); \
9413 = convert_lvalue_to_rvalue (stack[sp].loc, \
9414 stack[sp].expr, true, true); \
9415 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
9416 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
9417 && ((1 << stack[sp].prec) \
9418 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
9419 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
9420 | (1 << PREC_ADD) | (1 << PREC_MULT) \
9421 | (1 << PREC_EQ)))) \
9422 || ((c_parser_next_token_is (parser, CPP_QUERY) \
9423 || (omp_atomic_lhs == void_list_node \
9424 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
9425 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
9426 && stack[sp].op != TRUNC_MOD_EXPR \
9427 && stack[sp].op != GE_EXPR \
9428 && stack[sp].op != LE_EXPR \
9429 && stack[sp].op != NE_EXPR \
9430 && stack[0].expr.value != error_mark_node \
9431 && stack[1].expr.value != error_mark_node \
9432 && (omp_atomic_lhs == void_list_node \
9433 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
9434 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
9435 || (stack[sp].op == EQ_EXPR \
9436 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
9438 tree t = make_node (stack[1].op); \
9439 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
9440 TREE_OPERAND (t, 0) = stack[0].expr.value; \
9441 TREE_OPERAND (t, 1) = stack[1].expr.value; \
9442 stack[0].expr.value = t; \
9443 stack[0].expr.m_decimal = 0; \
9446 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
9448 stack[sp - 1].expr, \
9452 gcc_assert (!after
|| c_dialect_objc ());
9453 stack
[0].loc
= c_parser_peek_token (parser
)->location
;
9454 stack
[0].expr
= c_parser_cast_expression (parser
, after
);
9455 stack
[0].prec
= PREC_NONE
;
9456 stack
[0].sizeof_arg
= c_last_sizeof_arg
;
9460 enum c_parser_prec oprec
;
9461 enum tree_code ocode
;
9462 source_range src_range
;
9465 switch (c_parser_peek_token (parser
)->type
)
9473 ocode
= TRUNC_DIV_EXPR
;
9477 ocode
= TRUNC_MOD_EXPR
;
9489 ocode
= LSHIFT_EXPR
;
9493 ocode
= RSHIFT_EXPR
;
9507 case CPP_GREATER_EQ
:
9520 oprec
= PREC_BITAND
;
9521 ocode
= BIT_AND_EXPR
;
9524 oprec
= PREC_BITXOR
;
9525 ocode
= BIT_XOR_EXPR
;
9529 ocode
= BIT_IOR_EXPR
;
9532 oprec
= PREC_LOGAND
;
9533 ocode
= TRUTH_ANDIF_EXPR
;
9537 ocode
= TRUTH_ORIF_EXPR
;
9540 /* Not a binary operator, so end of the binary
9544 binary_loc
= c_parser_peek_token (parser
)->location
;
9545 while (oprec
<= stack
[sp
].prec
)
9547 c_parser_consume_token (parser
);
9550 case TRUTH_ANDIF_EXPR
:
9551 src_range
= stack
[sp
].expr
.src_range
;
9553 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
9554 stack
[sp
].expr
, true, true);
9555 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
9556 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
9557 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
9558 == truthvalue_false_node
);
9559 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
9561 case TRUTH_ORIF_EXPR
:
9562 src_range
= stack
[sp
].expr
.src_range
;
9564 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
9565 stack
[sp
].expr
, true, true);
9566 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
9567 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
9568 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
9569 == truthvalue_true_node
);
9570 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
9576 stack
[sp
].loc
= binary_loc
;
9577 stack
[sp
].expr
= c_parser_cast_expression (parser
, NULL
);
9578 stack
[sp
].prec
= oprec
;
9579 stack
[sp
].op
= ocode
;
9580 stack
[sp
].sizeof_arg
= c_last_sizeof_arg
;
9585 return stack
[0].expr
;
9589 /* Parse any storage class specifiers after an open parenthesis in a
9590 context where a compound literal is permitted. */
9592 static struct c_declspecs
*
9593 c_parser_compound_literal_scspecs (c_parser
*parser
)
9595 bool seen_scspec
= false;
9596 struct c_declspecs
*specs
= build_null_declspecs ();
9597 while (c_parser_next_token_is (parser
, CPP_KEYWORD
))
9599 switch (c_parser_peek_token (parser
)->keyword
)
9606 declspecs_add_scspec (c_parser_peek_token (parser
)->location
,
9607 specs
, c_parser_peek_token (parser
)->value
);
9608 c_parser_consume_token (parser
);
9615 return seen_scspec
? specs
: NULL
;
9618 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
9619 is not NULL then it is an Objective-C message expression which is the
9620 primary-expression starting the expression as an initializer.
9624 ( type-name ) unary-expression
9627 static struct c_expr
9628 c_parser_cast_expression (c_parser
*parser
, struct c_expr
*after
)
9630 location_t cast_loc
= c_parser_peek_token (parser
)->location
;
9631 gcc_assert (!after
|| c_dialect_objc ());
9633 return c_parser_postfix_expression_after_primary (parser
,
9635 /* If the expression begins with a parenthesized type name, it may
9636 be either a cast or a compound literal; we need to see whether
9637 the next character is '{' to tell the difference. If not, it is
9638 an unary expression. Full detection of unknown typenames here
9639 would require a 3-token lookahead. */
9640 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
9641 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
9643 struct c_declspecs
*scspecs
;
9644 struct c_type_name
*type_name
;
9647 matching_parens parens
;
9648 parens
.consume_open (parser
);
9649 scspecs
= c_parser_compound_literal_scspecs (parser
);
9650 type_name
= c_parser_type_name (parser
, true);
9651 parens
.skip_until_found_close (parser
);
9652 if (type_name
== NULL
)
9655 ret
.original_code
= ERROR_MARK
;
9656 ret
.original_type
= NULL
;
9660 /* Save casted types in the function's used types hash table. */
9661 used_types_insert (type_name
->specs
->type
);
9663 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
9664 return c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
9668 error_at (cast_loc
, "storage class specifier in cast");
9669 if (type_name
->specs
->alignas_p
)
9670 error_at (type_name
->specs
->locations
[cdw_alignas
],
9671 "alignment specified for type name in cast");
9673 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
9674 expr
= c_parser_cast_expression (parser
, NULL
);
9675 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
9677 ret
.value
= c_cast_expr (cast_loc
, type_name
, expr
.value
);
9678 if (ret
.value
&& expr
.value
)
9679 set_c_expr_source_range (&ret
, cast_loc
, expr
.get_finish ());
9680 ret
.original_code
= ERROR_MARK
;
9681 ret
.original_type
= NULL
;
9686 return c_parser_unary_expression (parser
);
9689 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
9695 unary-operator cast-expression
9696 sizeof unary-expression
9697 sizeof ( type-name )
9699 unary-operator: one of
9705 __alignof__ unary-expression
9706 __alignof__ ( type-name )
9709 (C11 permits _Alignof with type names only.)
9711 unary-operator: one of
9712 __extension__ __real__ __imag__
9714 Transactional Memory:
9717 transaction-expression
9719 In addition, the GNU syntax treats ++ and -- as unary operators, so
9720 they may be applied to cast expressions with errors for non-lvalues
9723 static struct c_expr
9724 c_parser_unary_expression (c_parser
*parser
)
9727 struct c_expr ret
, op
;
9728 location_t op_loc
= c_parser_peek_token (parser
)->location
;
9731 ret
.original_code
= ERROR_MARK
;
9732 ret
.original_type
= NULL
;
9733 switch (c_parser_peek_token (parser
)->type
)
9736 c_parser_consume_token (parser
);
9737 exp_loc
= c_parser_peek_token (parser
)->location
;
9738 op
= c_parser_cast_expression (parser
, NULL
);
9740 op
= default_function_array_read_conversion (exp_loc
, op
);
9741 return parser_build_unary_op (op_loc
, PREINCREMENT_EXPR
, op
);
9742 case CPP_MINUS_MINUS
:
9743 c_parser_consume_token (parser
);
9744 exp_loc
= c_parser_peek_token (parser
)->location
;
9745 op
= c_parser_cast_expression (parser
, NULL
);
9747 op
= default_function_array_read_conversion (exp_loc
, op
);
9748 return parser_build_unary_op (op_loc
, PREDECREMENT_EXPR
, op
);
9750 c_parser_consume_token (parser
);
9751 op
= c_parser_cast_expression (parser
, NULL
);
9752 mark_exp_read (op
.value
);
9753 return parser_build_unary_op (op_loc
, ADDR_EXPR
, op
);
9756 c_parser_consume_token (parser
);
9757 exp_loc
= c_parser_peek_token (parser
)->location
;
9758 op
= c_parser_cast_expression (parser
, NULL
);
9759 finish
= op
.get_finish ();
9760 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9761 location_t combined_loc
= make_location (op_loc
, op_loc
, finish
);
9762 ret
.value
= build_indirect_ref (combined_loc
, op
.value
, RO_UNARY_STAR
);
9763 ret
.src_range
.m_start
= op_loc
;
9764 ret
.src_range
.m_finish
= finish
;
9769 if (!c_dialect_objc () && !in_system_header_at (input_location
))
9772 "traditional C rejects the unary plus operator");
9773 c_parser_consume_token (parser
);
9774 exp_loc
= c_parser_peek_token (parser
)->location
;
9775 op
= c_parser_cast_expression (parser
, NULL
);
9776 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9777 return parser_build_unary_op (op_loc
, CONVERT_EXPR
, op
);
9779 c_parser_consume_token (parser
);
9780 exp_loc
= c_parser_peek_token (parser
)->location
;
9781 op
= c_parser_cast_expression (parser
, NULL
);
9782 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9783 return parser_build_unary_op (op_loc
, NEGATE_EXPR
, op
);
9785 c_parser_consume_token (parser
);
9786 exp_loc
= c_parser_peek_token (parser
)->location
;
9787 op
= c_parser_cast_expression (parser
, NULL
);
9788 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9789 return parser_build_unary_op (op_loc
, BIT_NOT_EXPR
, op
);
9791 c_parser_consume_token (parser
);
9792 exp_loc
= c_parser_peek_token (parser
)->location
;
9793 op
= c_parser_cast_expression (parser
, NULL
);
9794 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9795 return parser_build_unary_op (op_loc
, TRUTH_NOT_EXPR
, op
);
9797 /* Refer to the address of a label as a pointer. */
9798 c_parser_consume_token (parser
);
9799 if (c_parser_next_token_is (parser
, CPP_NAME
))
9801 ret
.value
= finish_label_address_expr
9802 (c_parser_peek_token (parser
)->value
, op_loc
);
9803 set_c_expr_source_range (&ret
, op_loc
,
9804 c_parser_peek_token (parser
)->get_finish ());
9805 c_parser_consume_token (parser
);
9809 c_parser_error (parser
, "expected identifier");
9814 switch (c_parser_peek_token (parser
)->keyword
)
9817 return c_parser_sizeof_expression (parser
);
9819 return c_parser_alignof_expression (parser
);
9820 case RID_BUILTIN_HAS_ATTRIBUTE
:
9821 return c_parser_has_attribute_expression (parser
);
9823 c_parser_consume_token (parser
);
9824 ext
= disable_extension_diagnostics ();
9825 ret
= c_parser_cast_expression (parser
, NULL
);
9826 restore_extension_diagnostics (ext
);
9829 c_parser_consume_token (parser
);
9830 exp_loc
= c_parser_peek_token (parser
)->location
;
9831 op
= c_parser_cast_expression (parser
, NULL
);
9832 op
= default_function_array_conversion (exp_loc
, op
);
9833 return parser_build_unary_op (op_loc
, REALPART_EXPR
, op
);
9835 c_parser_consume_token (parser
);
9836 exp_loc
= c_parser_peek_token (parser
)->location
;
9837 op
= c_parser_cast_expression (parser
, NULL
);
9838 op
= default_function_array_conversion (exp_loc
, op
);
9839 return parser_build_unary_op (op_loc
, IMAGPART_EXPR
, op
);
9840 case RID_TRANSACTION_ATOMIC
:
9841 case RID_TRANSACTION_RELAXED
:
9842 return c_parser_transaction_expression (parser
,
9843 c_parser_peek_token (parser
)->keyword
);
9845 return c_parser_postfix_expression (parser
);
9848 return c_parser_postfix_expression (parser
);
9852 /* Parse a sizeof expression. */
9854 static struct c_expr
9855 c_parser_sizeof_expression (c_parser
*parser
)
9858 struct c_expr result
;
9859 location_t expr_loc
;
9860 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SIZEOF
));
9863 location_t finish
= UNKNOWN_LOCATION
;
9865 start
= c_parser_peek_token (parser
)->location
;
9867 c_parser_consume_token (parser
);
9868 c_inhibit_evaluation_warnings
++;
9870 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
9871 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
9873 /* Either sizeof ( type-name ) or sizeof unary-expression
9874 starting with a compound literal. */
9875 struct c_declspecs
*scspecs
;
9876 struct c_type_name
*type_name
;
9877 matching_parens parens
;
9878 parens
.consume_open (parser
);
9879 expr_loc
= c_parser_peek_token (parser
)->location
;
9880 scspecs
= c_parser_compound_literal_scspecs (parser
);
9881 type_name
= c_parser_type_name (parser
, true);
9882 parens
.skip_until_found_close (parser
);
9883 finish
= parser
->tokens_buf
[0].location
;
9884 if (type_name
== NULL
)
9887 c_inhibit_evaluation_warnings
--;
9890 ret
.original_code
= ERROR_MARK
;
9891 ret
.original_type
= NULL
;
9894 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
9896 expr
= c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
9899 finish
= expr
.get_finish ();
9902 /* sizeof ( type-name ). */
9904 error_at (expr_loc
, "storage class specifier in %<sizeof%>");
9905 if (type_name
->specs
->alignas_p
)
9906 error_at (type_name
->specs
->locations
[cdw_alignas
],
9907 "alignment specified for type name in %<sizeof%>");
9908 c_inhibit_evaluation_warnings
--;
9910 result
= c_expr_sizeof_type (expr_loc
, type_name
);
9914 expr_loc
= c_parser_peek_token (parser
)->location
;
9915 expr
= c_parser_unary_expression (parser
);
9916 finish
= expr
.get_finish ();
9918 c_inhibit_evaluation_warnings
--;
9920 mark_exp_read (expr
.value
);
9921 if (TREE_CODE (expr
.value
) == COMPONENT_REF
9922 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
9923 error_at (expr_loc
, "%<sizeof%> applied to a bit-field");
9924 result
= c_expr_sizeof_expr (expr_loc
, expr
);
9926 if (finish
== UNKNOWN_LOCATION
)
9928 set_c_expr_source_range (&result
, start
, finish
);
9932 /* Parse an alignof expression. */
9934 static struct c_expr
9935 c_parser_alignof_expression (c_parser
*parser
)
9938 location_t start_loc
= c_parser_peek_token (parser
)->location
;
9940 tree alignof_spelling
= c_parser_peek_token (parser
)->value
;
9941 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNOF
));
9942 bool is_c11_alignof
= (strcmp (IDENTIFIER_POINTER (alignof_spelling
),
9944 || strcmp (IDENTIFIER_POINTER (alignof_spelling
),
9946 /* A diagnostic is not required for the use of this identifier in
9947 the implementation namespace; only diagnose it for the C11 or C23
9948 spelling because of existing code using the other spellings. */
9952 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C99 does not support %qE",
9955 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C90 does not support %qE",
9958 c_parser_consume_token (parser
);
9959 c_inhibit_evaluation_warnings
++;
9961 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
9962 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
9964 /* Either __alignof__ ( type-name ) or __alignof__
9965 unary-expression starting with a compound literal. */
9967 struct c_declspecs
*scspecs
;
9968 struct c_type_name
*type_name
;
9970 matching_parens parens
;
9971 parens
.consume_open (parser
);
9972 loc
= c_parser_peek_token (parser
)->location
;
9973 scspecs
= c_parser_compound_literal_scspecs (parser
);
9974 type_name
= c_parser_type_name (parser
, true);
9975 end_loc
= c_parser_peek_token (parser
)->location
;
9976 parens
.skip_until_found_close (parser
);
9977 if (type_name
== NULL
)
9980 c_inhibit_evaluation_warnings
--;
9983 ret
.original_code
= ERROR_MARK
;
9984 ret
.original_type
= NULL
;
9987 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
9989 expr
= c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
9994 /* alignof ( type-name ). */
9996 error_at (loc
, "storage class specifier in %qE", alignof_spelling
);
9997 if (type_name
->specs
->alignas_p
)
9998 error_at (type_name
->specs
->locations
[cdw_alignas
],
9999 "alignment specified for type name in %qE",
10001 c_inhibit_evaluation_warnings
--;
10003 ret
.value
= c_sizeof_or_alignof_type (loc
, groktypename (type_name
,
10005 false, is_c11_alignof
, 1);
10006 ret
.original_code
= ERROR_MARK
;
10007 ret
.original_type
= NULL
;
10008 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
10015 expr
= c_parser_unary_expression (parser
);
10016 end_loc
= expr
.src_range
.m_finish
;
10018 mark_exp_read (expr
.value
);
10019 c_inhibit_evaluation_warnings
--;
10021 if (is_c11_alignof
)
10022 pedwarn (start_loc
,
10023 OPT_Wpedantic
, "ISO C does not allow %<%E (expression)%>",
10025 ret
.value
= c_alignof_expr (start_loc
, expr
.value
);
10026 ret
.original_code
= ERROR_MARK
;
10027 ret
.original_type
= NULL
;
10028 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
10034 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
10037 static struct c_expr
10038 c_parser_has_attribute_expression (c_parser
*parser
)
10040 gcc_assert (c_parser_next_token_is_keyword (parser
,
10041 RID_BUILTIN_HAS_ATTRIBUTE
));
10042 location_t start
= c_parser_peek_token (parser
)->location
;
10043 c_parser_consume_token (parser
);
10045 c_inhibit_evaluation_warnings
++;
10047 matching_parens parens
;
10048 if (!parens
.require_open (parser
))
10050 c_inhibit_evaluation_warnings
--;
10053 struct c_expr result
;
10054 result
.set_error ();
10055 result
.original_code
= ERROR_MARK
;
10056 result
.original_type
= NULL
;
10060 /* Treat the type argument the same way as in typeof for the purposes
10061 of warnings. FIXME: Generalize this so the warning refers to
10062 __builtin_has_attribute rather than typeof. */
10065 /* The first operand: one of DECL, EXPR, or TYPE. */
10066 tree oper
= NULL_TREE
;
10067 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
10069 struct c_type_name
*tname
= c_parser_type_name (parser
);
10073 oper
= groktypename (tname
, NULL
, NULL
);
10074 pop_maybe_used (c_type_variably_modified_p (oper
));
10079 struct c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
10080 c_inhibit_evaluation_warnings
--;
10082 if (cexpr
.value
!= error_mark_node
)
10084 mark_exp_read (cexpr
.value
);
10085 oper
= cexpr
.value
;
10086 tree etype
= TREE_TYPE (oper
);
10087 bool was_vm
= c_type_variably_modified_p (etype
);
10088 /* This is returned with the type so that when the type is
10089 evaluated, this can be evaluated. */
10091 oper
= c_fully_fold (oper
, false, NULL
);
10092 pop_maybe_used (was_vm
);
10096 struct c_expr result
;
10097 result
.original_code
= ERROR_MARK
;
10098 result
.original_type
= NULL
;
10100 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10102 /* Consume the closing parenthesis if that's the next token
10103 in the likely case the built-in was invoked with fewer
10104 than two arguments. */
10105 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10106 c_parser_consume_token (parser
);
10107 c_inhibit_evaluation_warnings
--;
10108 result
.set_error ();
10112 bool save_translate_strings_p
= parser
->translate_strings_p
;
10114 location_t atloc
= c_parser_peek_token (parser
)->location
;
10115 /* Parse a single attribute. Require no leading comma and do not
10116 allow empty attributes. */
10117 tree attr
= c_parser_gnu_attribute (parser
, NULL_TREE
, false, false);
10119 parser
->translate_strings_p
= save_translate_strings_p
;
10121 location_t finish
= c_parser_peek_token (parser
)->location
;
10122 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10123 c_parser_consume_token (parser
);
10126 c_parser_error (parser
, "expected identifier");
10127 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10129 result
.set_error ();
10135 error_at (atloc
, "expected identifier");
10136 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10138 result
.set_error ();
10142 result
.original_code
= INTEGER_CST
;
10143 result
.original_type
= boolean_type_node
;
10145 if (has_attribute (atloc
, oper
, attr
, default_conversion
))
10146 result
.value
= boolean_true_node
;
10148 result
.value
= boolean_false_node
;
10150 set_c_expr_source_range (&result
, start
, finish
);
10151 result
.m_decimal
= 0;
10155 /* Helper function to read arguments of builtins which are interfaces
10156 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
10157 others. The name of the builtin is passed using BNAME parameter.
10158 Function returns true if there were no errors while parsing and
10159 stores the arguments in CEXPR_LIST. If it returns true,
10160 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
10163 c_parser_get_builtin_args (c_parser
*parser
, const char *bname
,
10164 vec
<c_expr_t
, va_gc
> **ret_cexpr_list
,
10165 bool choose_expr_p
,
10166 location_t
*out_close_paren_loc
)
10168 location_t loc
= c_parser_peek_token (parser
)->location
;
10169 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10171 bool saved_force_folding_builtin_constant_p
;
10173 *ret_cexpr_list
= NULL
;
10174 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
10176 error_at (loc
, "cannot take address of %qs", bname
);
10180 c_parser_consume_token (parser
);
10182 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10184 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
10185 c_parser_consume_token (parser
);
10189 saved_force_folding_builtin_constant_p
10190 = force_folding_builtin_constant_p
;
10191 force_folding_builtin_constant_p
|= choose_expr_p
;
10192 expr
= c_parser_expr_no_commas (parser
, NULL
);
10193 force_folding_builtin_constant_p
10194 = saved_force_folding_builtin_constant_p
;
10195 vec_alloc (cexpr_list
, 1);
10196 vec_safe_push (cexpr_list
, expr
);
10197 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10199 c_parser_consume_token (parser
);
10200 expr
= c_parser_expr_no_commas (parser
, NULL
);
10201 vec_safe_push (cexpr_list
, expr
);
10204 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
10205 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
10208 *ret_cexpr_list
= cexpr_list
;
10212 /* This represents a single generic-association. */
10214 struct c_generic_association
10216 /* The location of the starting token of the type. */
10217 location_t type_location
;
10218 /* The association's type, or NULL_TREE for 'default'. */
10220 /* The association's expression. */
10221 struct c_expr expression
;
10224 /* Parse a generic-selection. (C11 6.5.1.1).
10227 _Generic ( assignment-expression , generic-assoc-list )
10229 generic-assoc-list:
10230 generic-association
10231 generic-assoc-list , generic-association
10233 generic-association:
10234 type-name : assignment-expression
10235 default : assignment-expression
10238 static struct c_expr
10239 c_parser_generic_selection (c_parser
*parser
)
10241 struct c_expr selector
, error_expr
;
10242 tree selector_type
;
10243 struct c_generic_association matched_assoc
;
10244 int match_found
= -1;
10245 location_t generic_loc
, selector_loc
;
10247 error_expr
.original_code
= ERROR_MARK
;
10248 error_expr
.original_type
= NULL
;
10249 error_expr
.set_error ();
10250 matched_assoc
.type_location
= UNKNOWN_LOCATION
;
10251 matched_assoc
.type
= NULL_TREE
;
10252 matched_assoc
.expression
= error_expr
;
10254 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_GENERIC
));
10255 generic_loc
= c_parser_peek_token (parser
)->location
;
10256 c_parser_consume_token (parser
);
10258 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
10259 "ISO C99 does not support %<_Generic%>");
10261 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
10262 "ISO C90 does not support %<_Generic%>");
10264 matching_parens parens
;
10265 if (!parens
.require_open (parser
))
10268 c_inhibit_evaluation_warnings
++;
10269 selector_loc
= c_parser_peek_token (parser
)->location
;
10270 selector
= c_parser_expr_no_commas (parser
, NULL
);
10271 selector
= default_function_array_conversion (selector_loc
, selector
);
10272 c_inhibit_evaluation_warnings
--;
10274 if (selector
.value
== error_mark_node
)
10276 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10279 mark_exp_read (selector
.value
);
10280 selector_type
= TREE_TYPE (selector
.value
);
10281 /* In ISO C terms, rvalues (including the controlling expression of
10282 _Generic) do not have qualified types. */
10283 if (TREE_CODE (selector_type
) != ARRAY_TYPE
)
10284 selector_type
= TYPE_MAIN_VARIANT (selector_type
);
10285 /* In ISO C terms, _Noreturn is not part of the type of expressions
10286 such as &abort, but in GCC it is represented internally as a type
10288 if (FUNCTION_POINTER_TYPE_P (selector_type
)
10289 && TYPE_QUALS (TREE_TYPE (selector_type
)) != TYPE_UNQUALIFIED
)
10291 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type
)));
10293 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10295 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10299 auto_vec
<c_generic_association
> associations
;
10302 struct c_generic_association assoc
, *iter
;
10304 c_token
*token
= c_parser_peek_token (parser
);
10306 assoc
.type_location
= token
->location
;
10307 if (token
->type
== CPP_KEYWORD
&& token
->keyword
== RID_DEFAULT
)
10309 c_parser_consume_token (parser
);
10310 assoc
.type
= NULL_TREE
;
10314 struct c_type_name
*type_name
;
10316 type_name
= c_parser_type_name (parser
);
10317 if (type_name
== NULL
)
10319 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10322 assoc
.type
= groktypename (type_name
, NULL
, NULL
);
10323 if (assoc
.type
== error_mark_node
)
10325 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10329 if (TREE_CODE (assoc
.type
) == FUNCTION_TYPE
)
10330 error_at (assoc
.type_location
,
10331 "%<_Generic%> association has function type");
10332 else if (!COMPLETE_TYPE_P (assoc
.type
))
10333 error_at (assoc
.type_location
,
10334 "%<_Generic%> association has incomplete type");
10336 if (c_type_variably_modified_p (assoc
.type
))
10337 error_at (assoc
.type_location
,
10338 "%<_Generic%> association has "
10339 "variable length type");
10342 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
10344 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10348 bool match
= assoc
.type
== NULL_TREE
10349 || comptypes (assoc
.type
, selector_type
);
10352 c_inhibit_evaluation_warnings
++;
10354 assoc
.expression
= c_parser_expr_no_commas (parser
, NULL
);
10357 c_inhibit_evaluation_warnings
--;
10359 if (assoc
.expression
.value
== error_mark_node
)
10361 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10365 for (ix
= 0; associations
.iterate (ix
, &iter
); ++ix
)
10367 if (assoc
.type
== NULL_TREE
)
10369 if (iter
->type
== NULL_TREE
)
10371 error_at (assoc
.type_location
,
10372 "duplicate %<default%> case in %<_Generic%>");
10373 inform (iter
->type_location
, "original %<default%> is here");
10376 else if (iter
->type
!= NULL_TREE
)
10378 if (comptypes (assoc
.type
, iter
->type
))
10380 error_at (assoc
.type_location
,
10381 "%<_Generic%> specifies two compatible types");
10382 inform (iter
->type_location
, "compatible type is here");
10387 if (assoc
.type
== NULL_TREE
)
10389 if (match_found
< 0)
10391 matched_assoc
= assoc
;
10392 match_found
= associations
.length ();
10397 if (match_found
< 0 || matched_assoc
.type
== NULL_TREE
)
10399 matched_assoc
= assoc
;
10400 match_found
= associations
.length ();
10404 error_at (assoc
.type_location
,
10405 "%<_Generic%> selector matches multiple associations");
10406 inform (matched_assoc
.type_location
,
10407 "other match is here");
10411 associations
.safe_push (assoc
);
10413 if (c_parser_peek_token (parser
)->type
!= CPP_COMMA
)
10415 c_parser_consume_token (parser
);
10419 struct c_generic_association
*iter
;
10420 FOR_EACH_VEC_ELT (associations
, ix
, iter
)
10421 if (ix
!= (unsigned) match_found
)
10422 mark_exp_read (iter
->expression
.value
);
10424 if (!parens
.require_close (parser
))
10426 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10430 if (match_found
< 0)
10432 error_at (selector_loc
, "%<_Generic%> selector of type %qT is not "
10433 "compatible with any association",
10438 return matched_assoc
.expression
;
10441 /* Check the validity of a function pointer argument *EXPR (argument
10442 position POS) to __builtin_tgmath. Return the number of function
10443 arguments if possibly valid; return 0 having reported an error if
10446 static unsigned int
10447 check_tgmath_function (c_expr
*expr
, unsigned int pos
)
10449 tree type
= TREE_TYPE (expr
->value
);
10450 if (!FUNCTION_POINTER_TYPE_P (type
))
10452 error_at (expr
->get_location (),
10453 "argument %u of %<__builtin_tgmath%> is not a function pointer",
10457 type
= TREE_TYPE (type
);
10458 if (!prototype_p (type
))
10460 error_at (expr
->get_location (),
10461 "argument %u of %<__builtin_tgmath%> is unprototyped", pos
);
10464 if (stdarg_p (type
))
10466 error_at (expr
->get_location (),
10467 "argument %u of %<__builtin_tgmath%> has variable arguments",
10471 unsigned int nargs
= 0;
10472 function_args_iterator iter
;
10474 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
10476 if (t
== void_type_node
)
10482 error_at (expr
->get_location (),
10483 "argument %u of %<__builtin_tgmath%> has no arguments", pos
);
10489 /* Ways in which a parameter or return value of a type-generic macro
10490 may vary between the different functions the macro may call. */
10491 enum tgmath_parm_kind
10493 tgmath_fixed
, tgmath_real
, tgmath_complex
10496 /* Helper function for c_parser_postfix_expression. Parse predefined
10499 static struct c_expr
10500 c_parser_predefined_identifier (c_parser
*parser
)
10502 location_t loc
= c_parser_peek_token (parser
)->location
;
10503 switch (c_parser_peek_token (parser
)->keyword
)
10505 case RID_FUNCTION_NAME
:
10506 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
10507 "identifier", "__FUNCTION__");
10509 case RID_PRETTY_FUNCTION_NAME
:
10510 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
10511 "identifier", "__PRETTY_FUNCTION__");
10513 case RID_C99_FUNCTION_NAME
:
10514 pedwarn_c90 (loc
, OPT_Wpedantic
, "ISO C90 does not support "
10515 "%<__func__%> predefined identifier");
10518 gcc_unreachable ();
10521 struct c_expr expr
;
10522 expr
.original_code
= ERROR_MARK
;
10523 expr
.original_type
= NULL
;
10524 expr
.value
= fname_decl (loc
, c_parser_peek_token (parser
)->keyword
,
10525 c_parser_peek_token (parser
)->value
);
10526 set_c_expr_source_range (&expr
, loc
, loc
);
10527 expr
.m_decimal
= 0;
10528 c_parser_consume_token (parser
);
10532 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
10533 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
10534 call c_parser_postfix_expression_after_paren_type on encountering them.
10536 postfix-expression:
10538 postfix-expression [ expression ]
10539 postfix-expression ( argument-expression-list[opt] )
10540 postfix-expression . identifier
10541 postfix-expression -> identifier
10542 postfix-expression ++
10543 postfix-expression --
10544 ( storage-class-specifiers[opt] type-name ) { initializer-list[opt] }
10545 ( storage-class-specifiers[opt] type-name ) { initializer-list , }
10547 argument-expression-list:
10548 argument-expression
10549 argument-expression-list , argument-expression
10551 primary-expression:
10560 primary-expression:
10562 (treated as a keyword in GNU C)
10564 __PRETTY_FUNCTION__
10565 ( compound-statement )
10566 __builtin_va_arg ( assignment-expression , type-name )
10567 __builtin_offsetof ( type-name , offsetof-member-designator )
10568 __builtin_choose_expr ( assignment-expression ,
10569 assignment-expression ,
10570 assignment-expression )
10571 __builtin_types_compatible_p ( type-name , type-name )
10572 __builtin_tgmath ( expr-list )
10573 __builtin_complex ( assignment-expression , assignment-expression )
10574 __builtin_shuffle ( assignment-expression , assignment-expression )
10575 __builtin_shuffle ( assignment-expression ,
10576 assignment-expression ,
10577 assignment-expression, )
10578 __builtin_convertvector ( assignment-expression , type-name )
10579 __builtin_assoc_barrier ( assignment-expression )
10581 offsetof-member-designator:
10583 offsetof-member-designator . identifier
10584 offsetof-member-designator [ expression ]
10588 primary-expression:
10589 [ objc-receiver objc-message-args ]
10590 @selector ( objc-selector-arg )
10591 @protocol ( identifier )
10592 @encode ( type-name )
10593 objc-string-literal
10594 Classname . identifier
10597 static struct c_expr
10598 c_parser_postfix_expression (c_parser
*parser
)
10600 struct c_expr expr
, e1
;
10601 struct c_type_name
*t1
, *t2
;
10602 location_t loc
= c_parser_peek_token (parser
)->location
;
10603 source_range tok_range
= c_parser_peek_token (parser
)->get_range ();
10604 expr
.original_code
= ERROR_MARK
;
10605 expr
.original_type
= NULL
;
10606 expr
.m_decimal
= 0;
10607 switch (c_parser_peek_token (parser
)->type
)
10610 expr
.value
= c_parser_peek_token (parser
)->value
;
10611 set_c_expr_source_range (&expr
, tok_range
);
10612 loc
= c_parser_peek_token (parser
)->location
;
10613 expr
.m_decimal
= c_parser_peek_token (parser
)->flags
& DECIMAL_INT
;
10614 c_parser_consume_token (parser
);
10615 if (TREE_CODE (expr
.value
) == FIXED_CST
10616 && !targetm
.fixed_point_supported_p ())
10618 error_at (loc
, "fixed-point types not supported for this target");
10627 expr
.value
= c_parser_peek_token (parser
)->value
;
10628 /* For the purpose of warning when a pointer is compared with
10629 a zero character constant. */
10630 expr
.original_type
= char_type_node
;
10631 set_c_expr_source_range (&expr
, tok_range
);
10632 c_parser_consume_token (parser
);
10638 case CPP_UTF8STRING
:
10639 expr
= c_parser_string_literal (parser
, parser
->translate_strings_p
,
10642 case CPP_OBJC_STRING
:
10643 gcc_assert (c_dialect_objc ());
10645 = objc_build_string_object (c_parser_peek_token (parser
)->value
);
10646 set_c_expr_source_range (&expr
, tok_range
);
10647 c_parser_consume_token (parser
);
10650 switch (c_parser_peek_token (parser
)->id_kind
)
10654 tree id
= c_parser_peek_token (parser
)->value
;
10655 c_parser_consume_token (parser
);
10656 expr
.value
= build_external_ref (loc
, id
,
10657 (c_parser_peek_token (parser
)->type
10658 == CPP_OPEN_PAREN
),
10659 &expr
.original_type
);
10660 set_c_expr_source_range (&expr
, tok_range
);
10663 case C_ID_CLASSNAME
:
10665 /* Here we parse the Objective-C 2.0 Class.name dot
10667 tree class_name
= c_parser_peek_token (parser
)->value
;
10669 c_parser_consume_token (parser
);
10670 gcc_assert (c_dialect_objc ());
10671 if (!c_parser_require (parser
, CPP_DOT
, "expected %<.%>"))
10676 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10678 c_parser_error (parser
, "expected identifier");
10682 c_token
*component_tok
= c_parser_peek_token (parser
);
10683 component
= component_tok
->value
;
10684 location_t end_loc
= component_tok
->get_finish ();
10685 c_parser_consume_token (parser
);
10686 expr
.value
= objc_build_class_component_ref (class_name
,
10688 set_c_expr_source_range (&expr
, loc
, end_loc
);
10692 c_parser_error (parser
, "expected expression");
10697 case CPP_OPEN_PAREN
:
10698 /* A parenthesized expression, statement expression or compound
10700 if (c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_BRACE
)
10702 /* A statement expression. */
10704 location_t brace_loc
;
10705 c_parser_consume_token (parser
);
10706 brace_loc
= c_parser_peek_token (parser
)->location
;
10707 c_parser_consume_token (parser
);
10708 /* If we've not yet started the current function's statement list,
10709 or we're in the parameter scope of an old-style function
10710 declaration, statement expressions are not allowed. */
10711 if (!building_stmt_list_p () || old_style_parameter_scope ())
10713 error_at (loc
, "braced-group within expression allowed "
10714 "only inside a function");
10715 parser
->error
= true;
10716 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
10717 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10721 stmt
= c_begin_stmt_expr ();
10722 c_parser_compound_statement_nostart (parser
);
10723 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10724 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10726 pedwarn (loc
, OPT_Wpedantic
,
10727 "ISO C forbids braced-groups within expressions");
10728 expr
.value
= c_finish_stmt_expr (brace_loc
, stmt
);
10729 set_c_expr_source_range (&expr
, loc
, close_loc
);
10730 mark_exp_read (expr
.value
);
10734 /* A parenthesized expression. */
10735 location_t loc_open_paren
= c_parser_peek_token (parser
)->location
;
10736 c_parser_consume_token (parser
);
10737 expr
= c_parser_expression (parser
);
10738 if (TREE_CODE (expr
.value
) == MODIFY_EXPR
)
10739 suppress_warning (expr
.value
, OPT_Wparentheses
);
10740 if (expr
.original_code
!= C_MAYBE_CONST_EXPR
10741 && expr
.original_code
!= SIZEOF_EXPR
)
10742 expr
.original_code
= ERROR_MARK
;
10743 /* Remember that we saw ( ) around the sizeof. */
10744 if (expr
.original_code
== SIZEOF_EXPR
)
10745 expr
.original_code
= PAREN_SIZEOF_EXPR
;
10746 /* Don't change EXPR.ORIGINAL_TYPE. */
10747 location_t loc_close_paren
= c_parser_peek_token (parser
)->location
;
10748 set_c_expr_source_range (&expr
, loc_open_paren
, loc_close_paren
);
10749 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10750 "expected %<)%>", loc_open_paren
);
10754 switch (c_parser_peek_token (parser
)->keyword
)
10756 case RID_FUNCTION_NAME
:
10757 case RID_PRETTY_FUNCTION_NAME
:
10758 case RID_C99_FUNCTION_NAME
:
10759 expr
= c_parser_predefined_identifier (parser
);
10763 location_t start_loc
= loc
;
10764 c_parser_consume_token (parser
);
10765 matching_parens parens
;
10766 if (!parens
.require_open (parser
))
10771 e1
= c_parser_expr_no_commas (parser
, NULL
);
10772 mark_exp_read (e1
.value
);
10773 e1
.value
= c_fully_fold (e1
.value
, false, NULL
);
10774 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10776 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10780 loc
= c_parser_peek_token (parser
)->location
;
10781 t1
= c_parser_type_name (parser
);
10782 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10783 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10791 tree type_expr
= NULL_TREE
;
10792 expr
.value
= c_build_va_arg (start_loc
, e1
.value
, loc
,
10793 groktypename (t1
, &type_expr
, NULL
));
10796 expr
.value
= build2 (C_MAYBE_CONST_EXPR
,
10797 TREE_TYPE (expr
.value
), type_expr
,
10799 C_MAYBE_CONST_EXPR_NON_CONST (expr
.value
) = true;
10801 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10807 c_parser_consume_token (parser
);
10808 matching_parens parens
;
10809 if (!parens
.require_open (parser
))
10814 t1
= c_parser_type_name (parser
);
10816 parser
->error
= true;
10817 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10818 gcc_assert (parser
->error
);
10821 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10825 tree type
= groktypename (t1
, NULL
, NULL
);
10827 if (type
== error_mark_node
)
10828 offsetof_ref
= error_mark_node
;
10831 offsetof_ref
= build1 (INDIRECT_REF
, type
, null_pointer_node
);
10832 SET_EXPR_LOCATION (offsetof_ref
, loc
);
10834 /* Parse the second argument to __builtin_offsetof. We
10835 must have one identifier, and beyond that we want to
10836 accept sub structure and sub array references. */
10837 if (c_parser_next_token_is (parser
, CPP_NAME
))
10839 c_token
*comp_tok
= c_parser_peek_token (parser
);
10841 = build_component_ref (loc
, offsetof_ref
, comp_tok
->value
,
10842 comp_tok
->location
, UNKNOWN_LOCATION
);
10843 c_parser_consume_token (parser
);
10844 while (c_parser_next_token_is (parser
, CPP_DOT
)
10845 || c_parser_next_token_is (parser
,
10847 || c_parser_next_token_is (parser
,
10850 if (c_parser_next_token_is (parser
, CPP_DEREF
))
10852 loc
= c_parser_peek_token (parser
)->location
;
10853 offsetof_ref
= build_array_ref (loc
,
10855 integer_zero_node
);
10858 else if (c_parser_next_token_is (parser
, CPP_DOT
))
10861 c_parser_consume_token (parser
);
10862 if (c_parser_next_token_is_not (parser
,
10865 c_parser_error (parser
, "expected identifier");
10868 c_token
*comp_tok
= c_parser_peek_token (parser
);
10870 = build_component_ref (loc
, offsetof_ref
,
10872 comp_tok
->location
,
10874 c_parser_consume_token (parser
);
10880 loc
= c_parser_peek_token (parser
)->location
;
10881 c_parser_consume_token (parser
);
10882 ce
= c_parser_expression (parser
);
10883 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
10885 idx
= c_fully_fold (idx
, false, NULL
);
10886 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10888 offsetof_ref
= build_array_ref (loc
, offsetof_ref
, idx
);
10893 c_parser_error (parser
, "expected identifier");
10894 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10895 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10897 expr
.value
= fold_offsetof (offsetof_ref
);
10898 set_c_expr_source_range (&expr
, loc
, end_loc
);
10901 case RID_CHOOSE_EXPR
:
10903 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10904 c_expr_t
*e1_p
, *e2_p
, *e3_p
;
10906 location_t close_paren_loc
;
10908 c_parser_consume_token (parser
);
10909 if (!c_parser_get_builtin_args (parser
,
10910 "__builtin_choose_expr",
10918 if (vec_safe_length (cexpr_list
) != 3)
10920 error_at (loc
, "wrong number of arguments to "
10921 "%<__builtin_choose_expr%>");
10926 e1_p
= &(*cexpr_list
)[0];
10927 e2_p
= &(*cexpr_list
)[1];
10928 e3_p
= &(*cexpr_list
)[2];
10931 mark_exp_read (e2_p
->value
);
10932 mark_exp_read (e3_p
->value
);
10933 if (TREE_CODE (c
) != INTEGER_CST
10934 || !INTEGRAL_TYPE_P (TREE_TYPE (c
)))
10936 "first argument to %<__builtin_choose_expr%> not"
10938 constant_expression_warning (c
);
10939 expr
= integer_zerop (c
) ? *e3_p
: *e2_p
;
10940 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10943 case RID_TYPES_COMPATIBLE_P
:
10945 c_parser_consume_token (parser
);
10946 matching_parens parens
;
10947 if (!parens
.require_open (parser
))
10952 t1
= c_parser_type_name (parser
);
10958 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10960 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10964 t2
= c_parser_type_name (parser
);
10970 location_t close_paren_loc
= c_parser_peek_token (parser
)->location
;
10971 parens
.skip_until_found_close (parser
);
10973 e1
= groktypename (t1
, NULL
, NULL
);
10974 e2
= groktypename (t2
, NULL
, NULL
);
10975 if (e1
== error_mark_node
|| e2
== error_mark_node
)
10981 e1
= TYPE_MAIN_VARIANT (e1
);
10982 e2
= TYPE_MAIN_VARIANT (e2
);
10985 = comptypes (e1
, e2
) ? integer_one_node
: integer_zero_node
;
10986 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10989 case RID_BUILTIN_TGMATH
:
10991 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10992 location_t close_paren_loc
;
10994 c_parser_consume_token (parser
);
10995 if (!c_parser_get_builtin_args (parser
,
10996 "__builtin_tgmath",
10997 &cexpr_list
, false,
11004 if (vec_safe_length (cexpr_list
) < 3)
11006 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
11013 FOR_EACH_VEC_ELT (*cexpr_list
, i
, p
)
11014 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
11015 unsigned int nargs
= check_tgmath_function (&(*cexpr_list
)[0], 1);
11021 if (vec_safe_length (cexpr_list
) < nargs
)
11023 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
11027 unsigned int num_functions
= vec_safe_length (cexpr_list
) - nargs
;
11028 if (num_functions
< 2)
11030 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
11035 /* The first NUM_FUNCTIONS expressions are the function
11036 pointers. The remaining NARGS expressions are the
11037 arguments that are to be passed to one of those
11038 functions, chosen following <tgmath.h> rules. */
11039 for (unsigned int j
= 1; j
< num_functions
; j
++)
11041 unsigned int this_nargs
11042 = check_tgmath_function (&(*cexpr_list
)[j
], j
+ 1);
11043 if (this_nargs
== 0)
11048 if (this_nargs
!= nargs
)
11050 error_at ((*cexpr_list
)[j
].get_location (),
11051 "argument %u of %<__builtin_tgmath%> has "
11052 "wrong number of arguments", j
+ 1);
11058 /* The functions all have the same number of arguments.
11059 Determine whether arguments and return types vary in
11060 ways permitted for <tgmath.h> functions. */
11061 /* The first entry in each of these vectors is for the
11062 return type, subsequent entries for parameter
11064 auto_vec
<enum tgmath_parm_kind
> parm_kind (nargs
+ 1);
11065 auto_vec
<tree
> parm_first (nargs
+ 1);
11066 auto_vec
<bool> parm_complex (nargs
+ 1);
11067 auto_vec
<bool> parm_varies (nargs
+ 1);
11068 tree first_type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[0].value
));
11069 tree first_ret
= TYPE_MAIN_VARIANT (TREE_TYPE (first_type
));
11070 parm_first
.quick_push (first_ret
);
11071 parm_complex
.quick_push (TREE_CODE (first_ret
) == COMPLEX_TYPE
);
11072 parm_varies
.quick_push (false);
11073 function_args_iterator iter
;
11075 unsigned int argpos
;
11076 FOREACH_FUNCTION_ARGS (first_type
, t
, iter
)
11078 if (t
== void_type_node
)
11080 parm_first
.quick_push (TYPE_MAIN_VARIANT (t
));
11081 parm_complex
.quick_push (TREE_CODE (t
) == COMPLEX_TYPE
);
11082 parm_varies
.quick_push (false);
11084 for (unsigned int j
= 1; j
< num_functions
; j
++)
11086 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
11087 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
11088 if (ret
!= parm_first
[0])
11090 parm_varies
[0] = true;
11091 if (!SCALAR_FLOAT_TYPE_P (parm_first
[0])
11092 && !COMPLEX_FLOAT_TYPE_P (parm_first
[0]))
11094 error_at ((*cexpr_list
)[0].get_location (),
11095 "invalid type-generic return type for "
11096 "argument %u of %<__builtin_tgmath%>",
11101 if (!SCALAR_FLOAT_TYPE_P (ret
)
11102 && !COMPLEX_FLOAT_TYPE_P (ret
))
11104 error_at ((*cexpr_list
)[j
].get_location (),
11105 "invalid type-generic return type for "
11106 "argument %u of %<__builtin_tgmath%>",
11112 if (TREE_CODE (ret
) == COMPLEX_TYPE
)
11113 parm_complex
[0] = true;
11115 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
11117 if (t
== void_type_node
)
11119 t
= TYPE_MAIN_VARIANT (t
);
11120 if (t
!= parm_first
[argpos
])
11122 parm_varies
[argpos
] = true;
11123 if (!SCALAR_FLOAT_TYPE_P (parm_first
[argpos
])
11124 && !COMPLEX_FLOAT_TYPE_P (parm_first
[argpos
]))
11126 error_at ((*cexpr_list
)[0].get_location (),
11127 "invalid type-generic type for "
11128 "argument %u of argument %u of "
11129 "%<__builtin_tgmath%>", argpos
, 1);
11133 if (!SCALAR_FLOAT_TYPE_P (t
)
11134 && !COMPLEX_FLOAT_TYPE_P (t
))
11136 error_at ((*cexpr_list
)[j
].get_location (),
11137 "invalid type-generic type for "
11138 "argument %u of argument %u of "
11139 "%<__builtin_tgmath%>", argpos
, j
+ 1);
11144 if (TREE_CODE (t
) == COMPLEX_TYPE
)
11145 parm_complex
[argpos
] = true;
11149 enum tgmath_parm_kind max_variation
= tgmath_fixed
;
11150 for (unsigned int j
= 0; j
<= nargs
; j
++)
11152 enum tgmath_parm_kind this_kind
;
11153 if (parm_varies
[j
])
11155 if (parm_complex
[j
])
11156 max_variation
= this_kind
= tgmath_complex
;
11159 this_kind
= tgmath_real
;
11160 if (max_variation
!= tgmath_complex
)
11161 max_variation
= tgmath_real
;
11165 this_kind
= tgmath_fixed
;
11166 parm_kind
.quick_push (this_kind
);
11168 if (max_variation
== tgmath_fixed
)
11170 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
11171 "all have the same type");
11176 /* Identify a parameter (not the return type) that varies,
11177 including with complex types if any variation includes
11178 complex types; there must be at least one such
11180 unsigned int tgarg
= 0;
11181 for (unsigned int j
= 1; j
<= nargs
; j
++)
11182 if (parm_kind
[j
] == max_variation
)
11189 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
11190 "lack type-generic parameter");
11195 /* Determine the type of the relevant parameter for each
11197 auto_vec
<tree
> tg_type (num_functions
);
11198 for (unsigned int j
= 0; j
< num_functions
; j
++)
11200 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
11202 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
11204 if (argpos
== tgarg
)
11206 tg_type
.quick_push (TYPE_MAIN_VARIANT (t
));
11213 /* Verify that the corresponding types are different for
11214 all the listed functions. Also determine whether all
11215 the types are complex, whether all the types are
11216 standard or binary, and whether all the types are
11218 bool all_complex
= true;
11219 bool all_binary
= true;
11220 bool all_decimal
= true;
11221 hash_set
<tree
> tg_types
;
11222 FOR_EACH_VEC_ELT (tg_type
, i
, t
)
11224 if (TREE_CODE (t
) == COMPLEX_TYPE
)
11225 all_decimal
= false;
11228 all_complex
= false;
11229 if (DECIMAL_FLOAT_TYPE_P (t
))
11230 all_binary
= false;
11232 all_decimal
= false;
11234 if (tg_types
.add (t
))
11236 error_at ((*cexpr_list
)[i
].get_location (),
11237 "duplicate type-generic parameter type for "
11238 "function argument %u of %<__builtin_tgmath%>",
11245 /* Verify that other parameters and the return type whose
11246 types vary have their types varying in the correct
11248 for (unsigned int j
= 0; j
< num_functions
; j
++)
11250 tree exp_type
= tg_type
[j
];
11251 tree exp_real_type
= exp_type
;
11252 if (TREE_CODE (exp_type
) == COMPLEX_TYPE
)
11253 exp_real_type
= TREE_TYPE (exp_type
);
11254 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
11255 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
11256 if ((parm_kind
[0] == tgmath_complex
&& ret
!= exp_type
)
11257 || (parm_kind
[0] == tgmath_real
&& ret
!= exp_real_type
))
11259 error_at ((*cexpr_list
)[j
].get_location (),
11260 "bad return type for function argument %u "
11261 "of %<__builtin_tgmath%>", j
+ 1);
11266 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
11268 if (t
== void_type_node
)
11270 t
= TYPE_MAIN_VARIANT (t
);
11271 if ((parm_kind
[argpos
] == tgmath_complex
11273 || (parm_kind
[argpos
] == tgmath_real
11274 && t
!= exp_real_type
))
11276 error_at ((*cexpr_list
)[j
].get_location (),
11277 "bad type for argument %u of "
11278 "function argument %u of "
11279 "%<__builtin_tgmath%>", argpos
, j
+ 1);
11287 /* The functions listed are a valid set of functions for a
11288 <tgmath.h> macro to select between. Identify the
11289 matching function, if any. First, the argument types
11290 must be combined following <tgmath.h> rules. Integer
11291 types are treated as _Decimal64 if any type-generic
11292 argument is decimal, or if the only alternatives for
11293 type-generic arguments are of decimal types, and are
11294 otherwise treated as _Float32x (or _Complex _Float32x
11295 for complex integer types) if any type-generic argument
11296 has _FloatNx type, otherwise as double (or _Complex
11297 double for complex integer types). After that
11298 adjustment, types are combined following the usual
11299 arithmetic conversions. If the function only accepts
11300 complex arguments, a complex type is produced. */
11301 bool arg_complex
= all_complex
;
11302 bool arg_binary
= all_binary
;
11303 bool arg_int_decimal
= all_decimal
;
11304 bool arg_int_floatnx
= false;
11305 for (unsigned int j
= 1; j
<= nargs
; j
++)
11307 if (parm_kind
[j
] == tgmath_fixed
)
11309 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
11310 tree type
= TREE_TYPE (ce
->value
);
11311 if (!INTEGRAL_TYPE_P (type
)
11312 && !SCALAR_FLOAT_TYPE_P (type
)
11313 && TREE_CODE (type
) != COMPLEX_TYPE
)
11315 error_at (ce
->get_location (),
11316 "invalid type of argument %u of type-generic "
11321 if (DECIMAL_FLOAT_TYPE_P (type
))
11323 arg_int_decimal
= true;
11326 error_at (ce
->get_location (),
11327 "decimal floating-point argument %u to "
11328 "complex-only type-generic function", j
);
11332 else if (all_binary
)
11334 error_at (ce
->get_location (),
11335 "decimal floating-point argument %u to "
11336 "binary-only type-generic function", j
);
11340 else if (arg_complex
)
11342 error_at (ce
->get_location (),
11343 "both complex and decimal floating-point "
11344 "arguments to type-generic function");
11348 else if (arg_binary
)
11350 error_at (ce
->get_location (),
11351 "both binary and decimal floating-point "
11352 "arguments to type-generic function");
11357 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
11359 arg_complex
= true;
11360 if (COMPLEX_FLOAT_TYPE_P (type
))
11364 error_at (ce
->get_location (),
11365 "complex argument %u to "
11366 "decimal-only type-generic function", j
);
11370 else if (arg_int_decimal
)
11372 error_at (ce
->get_location (),
11373 "both complex and decimal floating-point "
11374 "arguments to type-generic function");
11379 else if (SCALAR_FLOAT_TYPE_P (type
))
11384 error_at (ce
->get_location (),
11385 "binary argument %u to "
11386 "decimal-only type-generic function", j
);
11390 else if (arg_int_decimal
)
11392 error_at (ce
->get_location (),
11393 "both binary and decimal floating-point "
11394 "arguments to type-generic function");
11399 tree rtype
= TYPE_MAIN_VARIANT (type
);
11400 if (TREE_CODE (rtype
) == COMPLEX_TYPE
)
11401 rtype
= TREE_TYPE (rtype
);
11402 if (SCALAR_FLOAT_TYPE_P (rtype
))
11403 for (unsigned int j
= 0; j
< NUM_FLOATNX_TYPES
; j
++)
11404 if (rtype
== FLOATNX_TYPE_NODE (j
))
11406 arg_int_floatnx
= true;
11410 tree arg_real
= NULL_TREE
;
11411 for (unsigned int j
= 1; j
<= nargs
; j
++)
11413 if (parm_kind
[j
] == tgmath_fixed
)
11415 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
11416 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (ce
->value
));
11417 if (TREE_CODE (type
) == COMPLEX_TYPE
)
11418 type
= TREE_TYPE (type
);
11419 if (INTEGRAL_TYPE_P (type
))
11420 type
= (arg_int_decimal
11421 ? dfloat64_type_node
11423 ? float32x_type_node
11424 : double_type_node
);
11425 if (arg_real
== NULL_TREE
)
11428 arg_real
= common_type (arg_real
, type
);
11429 if (arg_real
== error_mark_node
)
11435 tree arg_type
= (arg_complex
11436 ? build_complex_type (arg_real
)
11439 /* Look for a function to call with type-generic parameter
11441 c_expr_t
*fn
= NULL
;
11442 for (unsigned int j
= 0; j
< num_functions
; j
++)
11444 if (tg_type
[j
] == arg_type
)
11446 fn
= &(*cexpr_list
)[j
];
11451 && parm_kind
[0] == tgmath_fixed
11452 && SCALAR_FLOAT_TYPE_P (parm_first
[0]))
11454 /* Presume this is a macro that rounds its result to a
11455 narrower type, and look for the first function with
11456 at least the range and precision of the argument
11458 for (unsigned int j
= 0; j
< num_functions
; j
++)
11461 != (TREE_CODE (tg_type
[j
]) == COMPLEX_TYPE
))
11463 tree real_tg_type
= (arg_complex
11464 ? TREE_TYPE (tg_type
[j
])
11466 if (DECIMAL_FLOAT_TYPE_P (arg_real
)
11467 != DECIMAL_FLOAT_TYPE_P (real_tg_type
))
11469 scalar_float_mode arg_mode
11470 = SCALAR_FLOAT_TYPE_MODE (arg_real
);
11471 scalar_float_mode tg_mode
11472 = SCALAR_FLOAT_TYPE_MODE (real_tg_type
);
11473 const real_format
*arg_fmt
= REAL_MODE_FORMAT (arg_mode
);
11474 const real_format
*tg_fmt
= REAL_MODE_FORMAT (tg_mode
);
11475 if (arg_fmt
->b
== tg_fmt
->b
11476 && arg_fmt
->p
<= tg_fmt
->p
11477 && arg_fmt
->emax
<= tg_fmt
->emax
11478 && (arg_fmt
->emin
- arg_fmt
->p
11479 >= tg_fmt
->emin
- tg_fmt
->p
))
11481 fn
= &(*cexpr_list
)[j
];
11488 error_at (loc
, "no matching function for type-generic call");
11493 /* Construct a call to FN. */
11494 vec
<tree
, va_gc
> *args
;
11495 vec_alloc (args
, nargs
);
11496 vec
<tree
, va_gc
> *origtypes
;
11497 vec_alloc (origtypes
, nargs
);
11498 auto_vec
<location_t
> arg_loc (nargs
);
11499 for (unsigned int j
= 0; j
< nargs
; j
++)
11501 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
];
11502 args
->quick_push (ce
->value
);
11503 arg_loc
.quick_push (ce
->get_location ());
11504 origtypes
->quick_push (ce
->original_type
);
11506 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fn
->value
,
11508 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11511 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN
:
11513 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11516 location_t close_paren_loc
;
11518 c_parser_consume_token (parser
);
11519 if (!c_parser_get_builtin_args (parser
,
11520 "__builtin_call_with_static_chain",
11521 &cexpr_list
, false,
11527 if (vec_safe_length (cexpr_list
) != 2)
11529 error_at (loc
, "wrong number of arguments to "
11530 "%<__builtin_call_with_static_chain%>");
11535 expr
= (*cexpr_list
)[0];
11536 e2_p
= &(*cexpr_list
)[1];
11537 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
11538 chain_value
= e2_p
->value
;
11539 mark_exp_read (chain_value
);
11541 if (TREE_CODE (expr
.value
) != CALL_EXPR
)
11542 error_at (loc
, "first argument to "
11543 "%<__builtin_call_with_static_chain%> "
11544 "must be a call expression");
11545 else if (TREE_CODE (TREE_TYPE (chain_value
)) != POINTER_TYPE
)
11546 error_at (loc
, "second argument to "
11547 "%<__builtin_call_with_static_chain%> "
11548 "must be a pointer type");
11550 CALL_EXPR_STATIC_CHAIN (expr
.value
) = chain_value
;
11551 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11554 case RID_BUILTIN_COMPLEX
:
11556 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11557 c_expr_t
*e1_p
, *e2_p
;
11558 location_t close_paren_loc
;
11560 c_parser_consume_token (parser
);
11561 if (!c_parser_get_builtin_args (parser
,
11562 "__builtin_complex",
11563 &cexpr_list
, false,
11570 if (vec_safe_length (cexpr_list
) != 2)
11572 error_at (loc
, "wrong number of arguments to "
11573 "%<__builtin_complex%>");
11578 e1_p
= &(*cexpr_list
)[0];
11579 e2_p
= &(*cexpr_list
)[1];
11581 *e1_p
= convert_lvalue_to_rvalue (loc
, *e1_p
, true, true);
11582 if (TREE_CODE (e1_p
->value
) == EXCESS_PRECISION_EXPR
)
11583 e1_p
->value
= convert (TREE_TYPE (e1_p
->value
),
11584 TREE_OPERAND (e1_p
->value
, 0));
11585 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
11586 if (TREE_CODE (e2_p
->value
) == EXCESS_PRECISION_EXPR
)
11587 e2_p
->value
= convert (TREE_TYPE (e2_p
->value
),
11588 TREE_OPERAND (e2_p
->value
, 0));
11589 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
11590 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
11591 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
))
11592 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
)))
11594 error_at (loc
, "%<__builtin_complex%> operand "
11595 "not of real binary floating-point type");
11599 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p
->value
))
11600 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p
->value
)))
11603 "%<__builtin_complex%> operands of different types");
11607 pedwarn_c90 (loc
, OPT_Wpedantic
,
11608 "ISO C90 does not support complex types");
11609 expr
.value
= build2_loc (loc
, COMPLEX_EXPR
,
11612 (TREE_TYPE (e1_p
->value
))),
11613 e1_p
->value
, e2_p
->value
);
11614 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11617 case RID_BUILTIN_SHUFFLE
:
11619 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11622 location_t close_paren_loc
;
11624 c_parser_consume_token (parser
);
11625 if (!c_parser_get_builtin_args (parser
,
11626 "__builtin_shuffle",
11627 &cexpr_list
, false,
11634 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
11635 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
11637 if (vec_safe_length (cexpr_list
) == 2)
11638 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
11640 (*cexpr_list
)[1].value
);
11642 else if (vec_safe_length (cexpr_list
) == 3)
11643 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
11644 (*cexpr_list
)[1].value
,
11645 (*cexpr_list
)[2].value
);
11648 error_at (loc
, "wrong number of arguments to "
11649 "%<__builtin_shuffle%>");
11652 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11655 case RID_BUILTIN_SHUFFLEVECTOR
:
11657 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11660 location_t close_paren_loc
;
11662 c_parser_consume_token (parser
);
11663 if (!c_parser_get_builtin_args (parser
,
11664 "__builtin_shufflevector",
11665 &cexpr_list
, false,
11672 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
11673 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
11675 if (vec_safe_length (cexpr_list
) < 3)
11677 error_at (loc
, "wrong number of arguments to "
11678 "%<__builtin_shuffle%>");
11683 auto_vec
<tree
, 16> mask
;
11684 for (i
= 2; i
< cexpr_list
->length (); ++i
)
11685 mask
.safe_push ((*cexpr_list
)[i
].value
);
11686 expr
.value
= c_build_shufflevector (loc
, (*cexpr_list
)[0].value
,
11687 (*cexpr_list
)[1].value
,
11690 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11693 case RID_BUILTIN_CONVERTVECTOR
:
11695 location_t start_loc
= loc
;
11696 c_parser_consume_token (parser
);
11697 matching_parens parens
;
11698 if (!parens
.require_open (parser
))
11703 e1
= c_parser_expr_no_commas (parser
, NULL
);
11704 mark_exp_read (e1
.value
);
11705 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
11707 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
11711 loc
= c_parser_peek_token (parser
)->location
;
11712 t1
= c_parser_type_name (parser
);
11713 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
11714 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
11720 tree type_expr
= NULL_TREE
;
11721 expr
.value
= c_build_vec_convert (start_loc
, e1
.value
, loc
,
11722 groktypename (t1
, &type_expr
,
11724 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
11728 case RID_BUILTIN_ASSOC_BARRIER
:
11730 location_t start_loc
= loc
;
11731 c_parser_consume_token (parser
);
11732 matching_parens parens
;
11733 if (!parens
.require_open (parser
))
11738 e1
= c_parser_expr_no_commas (parser
, NULL
);
11739 mark_exp_read (e1
.value
);
11740 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
11741 parens
.skip_until_found_close (parser
);
11742 expr
= parser_build_unary_op (loc
, PAREN_EXPR
, e1
);
11743 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
11746 case RID_AT_SELECTOR
:
11748 gcc_assert (c_dialect_objc ());
11749 c_parser_consume_token (parser
);
11750 matching_parens parens
;
11751 if (!parens
.require_open (parser
))
11756 tree sel
= c_parser_objc_selector_arg (parser
);
11757 location_t close_loc
= c_parser_peek_token (parser
)->location
;
11758 parens
.skip_until_found_close (parser
);
11759 expr
.value
= objc_build_selector_expr (loc
, sel
);
11760 set_c_expr_source_range (&expr
, loc
, close_loc
);
11763 case RID_AT_PROTOCOL
:
11765 gcc_assert (c_dialect_objc ());
11766 c_parser_consume_token (parser
);
11767 matching_parens parens
;
11768 if (!parens
.require_open (parser
))
11773 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11775 c_parser_error (parser
, "expected identifier");
11776 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
11780 tree id
= c_parser_peek_token (parser
)->value
;
11781 c_parser_consume_token (parser
);
11782 location_t close_loc
= c_parser_peek_token (parser
)->location
;
11783 parens
.skip_until_found_close (parser
);
11784 expr
.value
= objc_build_protocol_expr (id
);
11785 set_c_expr_source_range (&expr
, loc
, close_loc
);
11788 case RID_AT_ENCODE
:
11790 /* Extension to support C-structures in the archiver. */
11791 gcc_assert (c_dialect_objc ());
11792 c_parser_consume_token (parser
);
11793 matching_parens parens
;
11794 if (!parens
.require_open (parser
))
11799 t1
= c_parser_type_name (parser
);
11803 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
11806 location_t close_loc
= c_parser_peek_token (parser
)->location
;
11807 parens
.skip_until_found_close (parser
);
11808 tree type
= groktypename (t1
, NULL
, NULL
);
11809 expr
.value
= objc_build_encode_expr (type
);
11810 set_c_expr_source_range (&expr
, loc
, close_loc
);
11814 expr
= c_parser_generic_selection (parser
);
11816 case RID_OMP_ALL_MEMORY
:
11817 gcc_assert (flag_openmp
);
11818 c_parser_consume_token (parser
);
11819 error_at (loc
, "%<omp_all_memory%> may only be used in OpenMP "
11820 "%<depend%> clause");
11823 /* C23 'nullptr' literal. */
11825 c_parser_consume_token (parser
);
11826 expr
.value
= nullptr_node
;
11827 set_c_expr_source_range (&expr
, tok_range
);
11828 pedwarn_c11 (loc
, OPT_Wpedantic
,
11829 "ISO C does not support %qs before C23", "nullptr");
11832 c_parser_consume_token (parser
);
11833 expr
.value
= boolean_true_node
;
11834 set_c_expr_source_range (&expr
, tok_range
);
11837 c_parser_consume_token (parser
);
11838 expr
.value
= boolean_false_node
;
11839 set_c_expr_source_range (&expr
, tok_range
);
11842 c_parser_error (parser
, "expected expression");
11847 case CPP_OPEN_SQUARE
:
11848 if (c_dialect_objc ())
11850 tree receiver
, args
;
11851 c_parser_consume_token (parser
);
11852 receiver
= c_parser_objc_receiver (parser
);
11853 args
= c_parser_objc_message_args (parser
);
11854 location_t close_loc
= c_parser_peek_token (parser
)->location
;
11855 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
11857 expr
.value
= objc_build_message_expr (receiver
, args
);
11858 set_c_expr_source_range (&expr
, loc
, close_loc
);
11861 /* Else fall through to report error. */
11864 c_parser_error (parser
, "expected expression");
11869 return c_parser_postfix_expression_after_primary
11870 (parser
, EXPR_LOC_OR_LOC (expr
.value
, loc
), expr
);
11873 /* Parse a postfix expression after a parenthesized type name: the
11874 brace-enclosed initializer of a compound literal, possibly followed
11875 by some postfix operators. This is separate because it is not
11876 possible to tell until after the type name whether a cast
11877 expression has a cast or a compound literal, or whether the operand
11878 of sizeof is a parenthesized type name or starts with a compound
11879 literal. TYPE_LOC is the location where TYPE_NAME starts--the
11880 location of the first token after the parentheses around the type
11883 static struct c_expr
11884 c_parser_postfix_expression_after_paren_type (c_parser
*parser
,
11885 struct c_declspecs
*scspecs
,
11886 struct c_type_name
*type_name
,
11887 location_t type_loc
)
11890 struct c_expr init
;
11892 struct c_expr expr
;
11893 location_t start_loc
;
11894 tree type_expr
= NULL_TREE
;
11895 bool type_expr_const
= true;
11896 bool constexpr_p
= scspecs
? scspecs
->constexpr_p
: false;
11897 unsigned int underspec_state
= 0;
11898 check_compound_literal_type (type_loc
, type_name
);
11899 rich_location
richloc (line_table
, type_loc
);
11900 start_loc
= c_parser_peek_token (parser
)->location
;
11903 underspec_state
= start_underspecified_init (start_loc
, NULL_TREE
);
11904 /* A constexpr compound literal is subject to the constraints on
11905 underspecified declarations, which may not declare tags or
11906 members or structures or unions; it is undefined behavior to
11907 declare the members of an enumeration. Where the structure,
11908 union or enumeration type is declared within the compound
11909 literal initializer, this is diagnosed elsewhere as a result
11910 of the above call to start_underspecified_init. Diagnose
11911 here the case of declaring such a type in the type specifiers
11912 of the compound literal. */
11913 switch (type_name
->specs
->typespec_kind
)
11915 case ctsk_tagfirstref
:
11916 case ctsk_tagfirstref_attrs
:
11917 error_at (type_loc
, "%qT declared in %<constexpr%> compound literal",
11918 type_name
->specs
->type
);
11922 error_at (type_loc
, "%qT defined in %<constexpr%> compound literal",
11923 type_name
->specs
->type
);
11930 start_init (NULL_TREE
, NULL
,
11931 (global_bindings_p ()
11932 || (scspecs
&& scspecs
->storage_class
== csc_static
)
11933 || constexpr_p
), constexpr_p
, &richloc
);
11934 type
= groktypename (type_name
, &type_expr
, &type_expr_const
);
11935 if (type
!= error_mark_node
&& C_TYPE_VARIABLE_SIZE (type
))
11937 error_at (type_loc
, "compound literal has variable size");
11938 type
= error_mark_node
;
11940 else if (TREE_CODE (type
) == FUNCTION_TYPE
)
11942 error_at (type_loc
, "compound literal has function type");
11943 type
= error_mark_node
;
11945 if (constexpr_p
&& type
!= error_mark_node
)
11947 tree type_no_array
= strip_array_types (type
);
11948 /* The type of a constexpr object must not be variably modified
11949 (which applies to all compound literals), volatile, atomic or
11950 restrict qualified or have a member with such a qualifier.
11951 const qualification is implicitly added. */
11952 if (TYPE_QUALS (type_no_array
)
11953 & (TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
| TYPE_QUAL_ATOMIC
))
11954 error_at (type_loc
, "invalid qualifiers for %<constexpr%> object");
11955 else if (RECORD_OR_UNION_TYPE_P (type_no_array
)
11956 && C_TYPE_FIELDS_NON_CONSTEXPR (type_no_array
))
11957 error_at (type_loc
, "invalid qualifiers for field of "
11958 "%<constexpr%> object");
11959 type
= c_build_qualified_type (type
,
11960 (TYPE_QUALS (type_no_array
)
11961 | TYPE_QUAL_CONST
));
11963 init
= c_parser_braced_init (parser
, type
, false, NULL
, NULL_TREE
);
11965 finish_underspecified_init (NULL_TREE
, underspec_state
);
11967 maybe_warn_string_init (type_loc
, type
, init
);
11969 if (type
!= error_mark_node
11970 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type
))
11971 && current_function_decl
)
11973 error ("compound literal qualified by address-space qualifier");
11974 type
= error_mark_node
;
11977 if (!pedwarn_c90 (start_loc
, OPT_Wpedantic
,
11978 "ISO C90 forbids compound literals") && scspecs
)
11979 pedwarn_c11 (start_loc
, OPT_Wpedantic
,
11980 "ISO C forbids storage class specifiers in compound literals "
11982 non_const
= ((init
.value
&& TREE_CODE (init
.value
) == CONSTRUCTOR
)
11983 ? CONSTRUCTOR_NON_CONST (init
.value
)
11984 : init
.original_code
== C_MAYBE_CONST_EXPR
);
11985 non_const
|= !type_expr_const
;
11986 unsigned int alignas_align
= 0;
11987 if (type
!= error_mark_node
11988 && type_name
->specs
->align_log
!= -1)
11990 alignas_align
= 1U << type_name
->specs
->align_log
;
11991 if (alignas_align
< min_align_of_type (type
))
11993 error_at (type_name
->specs
->locations
[cdw_alignas
],
11994 "%<_Alignas%> specifiers cannot reduce "
11995 "alignment of compound literal");
11999 expr
.value
= build_compound_literal (start_loc
, type
, init
.value
, non_const
,
12000 alignas_align
, scspecs
);
12001 set_c_expr_source_range (&expr
, init
.src_range
);
12002 expr
.m_decimal
= 0;
12003 expr
.original_code
= ERROR_MARK
;
12004 expr
.original_type
= NULL
;
12005 if (type
!= error_mark_node
12006 && expr
.value
!= error_mark_node
12009 if (TREE_CODE (expr
.value
) == C_MAYBE_CONST_EXPR
)
12011 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr
.value
) == NULL_TREE
);
12012 C_MAYBE_CONST_EXPR_PRE (expr
.value
) = type_expr
;
12016 gcc_assert (!non_const
);
12017 expr
.value
= build2 (C_MAYBE_CONST_EXPR
, type
,
12018 type_expr
, expr
.value
);
12021 return c_parser_postfix_expression_after_primary (parser
, start_loc
, expr
);
12024 /* Callback function for sizeof_pointer_memaccess_warning to compare
12028 sizeof_ptr_memacc_comptypes (tree type1
, tree type2
)
12030 return comptypes (type1
, type2
) == 1;
12033 /* Warn for patterns where abs-like function appears to be used incorrectly,
12034 gracefully ignore any non-abs-like function. The warning location should
12035 be LOC. FNDECL is the declaration of called function, it must be a
12036 BUILT_IN_NORMAL function. ARG is the first and only argument of the
12040 warn_for_abs (location_t loc
, tree fndecl
, tree arg
)
12042 /* Avoid warning in unreachable subexpressions. */
12043 if (c_inhibit_evaluation_warnings
)
12046 tree atype
= TREE_TYPE (arg
);
12048 /* Casts from pointers (and thus arrays and fndecls) will generate
12049 -Wint-conversion warnings. Most other wrong types hopefully lead to type
12050 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
12051 types and possibly other exotic types. */
12052 if (!INTEGRAL_TYPE_P (atype
)
12053 && !SCALAR_FLOAT_TYPE_P (atype
)
12054 && TREE_CODE (atype
) != COMPLEX_TYPE
)
12057 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
12062 case BUILT_IN_LABS
:
12063 case BUILT_IN_LLABS
:
12064 case BUILT_IN_IMAXABS
:
12065 if (!INTEGRAL_TYPE_P (atype
))
12067 if (SCALAR_FLOAT_TYPE_P (atype
))
12068 warning_at (loc
, OPT_Wabsolute_value
,
12069 "using integer absolute value function %qD when "
12070 "argument is of floating-point type %qT",
12072 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12073 warning_at (loc
, OPT_Wabsolute_value
,
12074 "using integer absolute value function %qD when "
12075 "argument is of complex type %qT", fndecl
, atype
);
12077 gcc_unreachable ();
12080 if (TYPE_UNSIGNED (atype
))
12081 warning_at (loc
, OPT_Wabsolute_value
,
12082 "taking the absolute value of unsigned type %qT "
12083 "has no effect", atype
);
12086 CASE_FLT_FN (BUILT_IN_FABS
):
12087 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS
):
12088 if (!SCALAR_FLOAT_TYPE_P (atype
)
12089 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype
)))
12091 if (INTEGRAL_TYPE_P (atype
))
12092 warning_at (loc
, OPT_Wabsolute_value
,
12093 "using floating-point absolute value function %qD "
12094 "when argument is of integer type %qT", fndecl
, atype
);
12095 else if (DECIMAL_FLOAT_TYPE_P (atype
))
12096 warning_at (loc
, OPT_Wabsolute_value
,
12097 "using floating-point absolute value function %qD "
12098 "when argument is of decimal floating-point type %qT",
12100 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12101 warning_at (loc
, OPT_Wabsolute_value
,
12102 "using floating-point absolute value function %qD when "
12103 "argument is of complex type %qT", fndecl
, atype
);
12105 gcc_unreachable ();
12110 CASE_FLT_FN (BUILT_IN_CABS
):
12111 if (TREE_CODE (atype
) != COMPLEX_TYPE
)
12113 if (INTEGRAL_TYPE_P (atype
))
12114 warning_at (loc
, OPT_Wabsolute_value
,
12115 "using complex absolute value function %qD when "
12116 "argument is of integer type %qT", fndecl
, atype
);
12117 else if (SCALAR_FLOAT_TYPE_P (atype
))
12118 warning_at (loc
, OPT_Wabsolute_value
,
12119 "using complex absolute value function %qD when "
12120 "argument is of floating-point type %qT",
12123 gcc_unreachable ();
12129 case BUILT_IN_FABSD32
:
12130 case BUILT_IN_FABSD64
:
12131 case BUILT_IN_FABSD128
:
12132 if (!DECIMAL_FLOAT_TYPE_P (atype
))
12134 if (INTEGRAL_TYPE_P (atype
))
12135 warning_at (loc
, OPT_Wabsolute_value
,
12136 "using decimal floating-point absolute value "
12137 "function %qD when argument is of integer type %qT",
12139 else if (SCALAR_FLOAT_TYPE_P (atype
))
12140 warning_at (loc
, OPT_Wabsolute_value
,
12141 "using decimal floating-point absolute value "
12142 "function %qD when argument is of floating-point "
12143 "type %qT", fndecl
, atype
);
12144 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12145 warning_at (loc
, OPT_Wabsolute_value
,
12146 "using decimal floating-point absolute value "
12147 "function %qD when argument is of complex type %qT",
12150 gcc_unreachable ();
12159 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl
)))
12162 tree ftype
= TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
12163 if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12165 gcc_assert (TREE_CODE (ftype
) == COMPLEX_TYPE
);
12166 atype
= TREE_TYPE (atype
);
12167 ftype
= TREE_TYPE (ftype
);
12170 if (TYPE_PRECISION (ftype
) < TYPE_PRECISION (atype
))
12171 warning_at (loc
, OPT_Wabsolute_value
,
12172 "absolute value function %qD given an argument of type %qT "
12173 "but has parameter of type %qT which may cause truncation "
12174 "of value", fndecl
, atype
, ftype
);
12178 /* Parse a postfix expression after the initial primary or compound
12179 literal; that is, parse a series of postfix operators.
12181 EXPR_LOC is the location of the primary expression. */
12183 static struct c_expr
12184 c_parser_postfix_expression_after_primary (c_parser
*parser
,
12185 location_t expr_loc
,
12186 struct c_expr expr
)
12188 struct c_expr orig_expr
;
12190 location_t sizeof_arg_loc
[3], comp_loc
;
12191 tree sizeof_arg
[3];
12192 unsigned int literal_zero_mask
;
12194 vec
<tree
, va_gc
> *exprlist
;
12195 vec
<tree
, va_gc
> *origtypes
= NULL
;
12196 vec
<location_t
> arg_loc
= vNULL
;
12202 location_t op_loc
= c_parser_peek_token (parser
)->location
;
12203 switch (c_parser_peek_token (parser
)->type
)
12205 case CPP_OPEN_SQUARE
:
12206 /* Array reference. */
12207 c_parser_consume_token (parser
);
12208 idx
= c_parser_expression (parser
).value
;
12209 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
12211 start
= expr
.get_start ();
12212 finish
= parser
->tokens_buf
[0].location
;
12213 expr
.value
= build_array_ref (op_loc
, expr
.value
, idx
);
12214 set_c_expr_source_range (&expr
, start
, finish
);
12215 expr
.original_code
= ERROR_MARK
;
12216 expr
.original_type
= NULL
;
12217 expr
.m_decimal
= 0;
12219 case CPP_OPEN_PAREN
:
12220 /* Function call. */
12222 matching_parens parens
;
12223 parens
.consume_open (parser
);
12224 for (i
= 0; i
< 3; i
++)
12226 sizeof_arg
[i
] = NULL_TREE
;
12227 sizeof_arg_loc
[i
] = UNKNOWN_LOCATION
;
12229 literal_zero_mask
= 0;
12230 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
12232 else if (TREE_CODE (expr
.value
) == FUNCTION_DECL
12233 && fndecl_built_in_p (expr
.value
, BUILT_IN_CLASSIFY_TYPE
)
12234 && c_parser_next_tokens_start_typename (parser
,
12237 /* __builtin_classify_type (type) */
12238 c_inhibit_evaluation_warnings
++;
12240 struct c_type_name
*type
= c_parser_type_name (parser
);
12241 c_inhibit_evaluation_warnings
--;
12243 struct c_typespec ret
;
12244 ret
.expr
= NULL_TREE
;
12245 ret
.spec
= error_mark_node
;
12246 ret
.expr_const_operands
= false;
12248 ret
.spec
= groktypename (type
, &ret
.expr
,
12249 &ret
.expr_const_operands
);
12250 parens
.skip_until_found_close (parser
);
12251 expr
.value
= build_int_cst (integer_type_node
,
12252 type_to_class (ret
.spec
));
12256 exprlist
= c_parser_expr_list (parser
, true, false, &origtypes
,
12257 sizeof_arg_loc
, sizeof_arg
,
12258 &arg_loc
, &literal_zero_mask
);
12259 parens
.skip_until_found_close (parser
);
12262 mark_exp_read (expr
.value
);
12263 if (warn_sizeof_pointer_memaccess
)
12264 sizeof_pointer_memaccess_warning (sizeof_arg_loc
,
12265 expr
.value
, exprlist
,
12267 sizeof_ptr_memacc_comptypes
);
12268 if (TREE_CODE (expr
.value
) == FUNCTION_DECL
)
12270 if (fndecl_built_in_p (expr
.value
, BUILT_IN_MEMSET
)
12271 && vec_safe_length (exprlist
) == 3)
12273 tree arg0
= (*exprlist
)[0];
12274 tree arg2
= (*exprlist
)[2];
12275 warn_for_memset (expr_loc
, arg0
, arg2
, literal_zero_mask
);
12277 if (warn_absolute_value
12278 && fndecl_built_in_p (expr
.value
, BUILT_IN_NORMAL
)
12279 && vec_safe_length (exprlist
) == 1)
12280 warn_for_abs (expr_loc
, expr
.value
, (*exprlist
)[0]);
12281 if (parser
->omp_for_parse_state
12282 && parser
->omp_for_parse_state
->in_intervening_code
12283 && omp_runtime_api_call (expr
.value
))
12285 error_at (expr_loc
, "calls to the OpenMP runtime API are "
12286 "not permitted in intervening code");
12287 parser
->omp_for_parse_state
->fail
= true;
12291 start
= expr
.get_start ();
12292 finish
= parser
->tokens_buf
[0].get_finish ();
12294 = c_build_function_call_vec (expr_loc
, arg_loc
, expr
.value
,
12295 exprlist
, origtypes
);
12296 set_c_expr_source_range (&expr
, start
, finish
);
12297 expr
.m_decimal
= 0;
12299 expr
.original_code
= ERROR_MARK
;
12300 if (TREE_CODE (expr
.value
) == INTEGER_CST
12301 && TREE_CODE (orig_expr
.value
) == FUNCTION_DECL
12302 && fndecl_built_in_p (orig_expr
.value
, BUILT_IN_CONSTANT_P
))
12303 expr
.original_code
= C_MAYBE_CONST_EXPR
;
12304 expr
.original_type
= NULL
;
12307 release_tree_vector (exprlist
);
12308 release_tree_vector (origtypes
);
12310 arg_loc
.release ();
12313 /* Structure element reference. */
12314 c_parser_consume_token (parser
);
12315 expr
= default_function_array_conversion (expr_loc
, expr
);
12316 if (c_parser_next_token_is (parser
, CPP_NAME
))
12318 c_token
*comp_tok
= c_parser_peek_token (parser
);
12319 ident
= comp_tok
->value
;
12320 comp_loc
= comp_tok
->location
;
12324 c_parser_error (parser
, "expected identifier");
12326 expr
.original_code
= ERROR_MARK
;
12327 expr
.original_type
= NULL
;
12330 start
= expr
.get_start ();
12331 finish
= c_parser_peek_token (parser
)->get_finish ();
12332 c_parser_consume_token (parser
);
12333 expr
.value
= build_component_ref (op_loc
, expr
.value
, ident
,
12334 comp_loc
, UNKNOWN_LOCATION
);
12335 set_c_expr_source_range (&expr
, start
, finish
);
12336 expr
.original_code
= ERROR_MARK
;
12337 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
12338 expr
.original_type
= NULL
;
12341 /* Remember the original type of a bitfield. */
12342 tree field
= TREE_OPERAND (expr
.value
, 1);
12343 if (TREE_CODE (field
) != FIELD_DECL
)
12344 expr
.original_type
= NULL
;
12346 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
12348 expr
.m_decimal
= 0;
12351 /* Structure element reference. */
12352 c_parser_consume_token (parser
);
12353 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, false);
12354 if (c_parser_next_token_is (parser
, CPP_NAME
))
12356 c_token
*comp_tok
= c_parser_peek_token (parser
);
12357 ident
= comp_tok
->value
;
12358 comp_loc
= comp_tok
->location
;
12362 c_parser_error (parser
, "expected identifier");
12364 expr
.original_code
= ERROR_MARK
;
12365 expr
.original_type
= NULL
;
12368 start
= expr
.get_start ();
12369 finish
= c_parser_peek_token (parser
)->get_finish ();
12370 c_parser_consume_token (parser
);
12371 expr
.value
= build_component_ref (op_loc
,
12372 build_indirect_ref (op_loc
,
12376 expr
.get_location ());
12377 set_c_expr_source_range (&expr
, start
, finish
);
12378 expr
.original_code
= ERROR_MARK
;
12379 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
12380 expr
.original_type
= NULL
;
12383 /* Remember the original type of a bitfield. */
12384 tree field
= TREE_OPERAND (expr
.value
, 1);
12385 if (TREE_CODE (field
) != FIELD_DECL
)
12386 expr
.original_type
= NULL
;
12388 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
12390 expr
.m_decimal
= 0;
12392 case CPP_PLUS_PLUS
:
12393 /* Postincrement. */
12394 start
= expr
.get_start ();
12395 finish
= c_parser_peek_token (parser
)->get_finish ();
12396 c_parser_consume_token (parser
);
12397 expr
= default_function_array_read_conversion (expr_loc
, expr
);
12398 expr
.value
= build_unary_op (op_loc
, POSTINCREMENT_EXPR
,
12399 expr
.value
, false);
12400 set_c_expr_source_range (&expr
, start
, finish
);
12401 expr
.original_code
= ERROR_MARK
;
12402 expr
.original_type
= NULL
;
12404 case CPP_MINUS_MINUS
:
12405 /* Postdecrement. */
12406 start
= expr
.get_start ();
12407 finish
= c_parser_peek_token (parser
)->get_finish ();
12408 c_parser_consume_token (parser
);
12409 expr
= default_function_array_read_conversion (expr_loc
, expr
);
12410 expr
.value
= build_unary_op (op_loc
, POSTDECREMENT_EXPR
,
12411 expr
.value
, false);
12412 set_c_expr_source_range (&expr
, start
, finish
);
12413 expr
.original_code
= ERROR_MARK
;
12414 expr
.original_type
= NULL
;
12422 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
12425 assignment-expression
12426 expression , assignment-expression
12429 static struct c_expr
12430 c_parser_expression (c_parser
*parser
)
12432 location_t tloc
= c_parser_peek_token (parser
)->location
;
12433 struct c_expr expr
;
12434 expr
= c_parser_expr_no_commas (parser
, NULL
);
12435 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12436 expr
= convert_lvalue_to_rvalue (tloc
, expr
, true, false);
12437 while (c_parser_next_token_is (parser
, CPP_COMMA
))
12439 struct c_expr next
;
12441 location_t loc
= c_parser_peek_token (parser
)->location
;
12442 location_t expr_loc
;
12443 c_parser_consume_token (parser
);
12444 expr_loc
= c_parser_peek_token (parser
)->location
;
12445 lhsval
= expr
.value
;
12446 while (TREE_CODE (lhsval
) == COMPOUND_EXPR
12447 || TREE_CODE (lhsval
) == NOP_EXPR
)
12449 if (TREE_CODE (lhsval
) == COMPOUND_EXPR
)
12450 lhsval
= TREE_OPERAND (lhsval
, 1);
12452 lhsval
= TREE_OPERAND (lhsval
, 0);
12454 if (DECL_P (lhsval
) || handled_component_p (lhsval
))
12455 mark_exp_read (lhsval
);
12456 next
= c_parser_expr_no_commas (parser
, NULL
);
12457 next
= convert_lvalue_to_rvalue (expr_loc
, next
, true, false);
12458 expr
.value
= build_compound_expr (loc
, expr
.value
, next
.value
);
12459 expr
.original_code
= COMPOUND_EXPR
;
12460 expr
.original_type
= next
.original_type
;
12461 expr
.m_decimal
= 0;
12466 /* Parse an expression and convert functions or arrays to pointers and
12467 lvalues to rvalues. */
12469 static struct c_expr
12470 c_parser_expression_conv (c_parser
*parser
)
12472 struct c_expr expr
;
12473 location_t loc
= c_parser_peek_token (parser
)->location
;
12474 expr
= c_parser_expression (parser
);
12475 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, false);
12479 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
12480 argument is a literal zero alone and if so, set it in literal_zero_mask. */
12483 c_parser_check_literal_zero (c_parser
*parser
, unsigned *literal_zero_mask
,
12486 if (idx
>= HOST_BITS_PER_INT
)
12489 c_token
*tok
= c_parser_peek_token (parser
);
12498 /* If a parameter is literal zero alone, remember it
12499 for -Wmemset-transposed-args warning. */
12500 if (integer_zerop (tok
->value
)
12501 && !TREE_OVERFLOW (tok
->value
)
12502 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
12503 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
12504 *literal_zero_mask
|= 1U << idx
;
12510 /* Parse a non-empty list of expressions. If CONVERT_P, convert
12511 functions and arrays to pointers and lvalues to rvalues. If
12512 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
12513 locations of function arguments into this vector.
12515 nonempty-expr-list:
12516 assignment-expression
12517 nonempty-expr-list , assignment-expression
12520 static vec
<tree
, va_gc
> *
12521 c_parser_expr_list (c_parser
*parser
, bool convert_p
, bool fold_p
,
12522 vec
<tree
, va_gc
> **p_orig_types
,
12523 location_t
*sizeof_arg_loc
, tree
*sizeof_arg
,
12524 vec
<location_t
> *locations
,
12525 unsigned int *literal_zero_mask
)
12527 vec
<tree
, va_gc
> *ret
;
12528 vec
<tree
, va_gc
> *orig_types
;
12529 struct c_expr expr
;
12530 unsigned int idx
= 0;
12532 ret
= make_tree_vector ();
12533 if (p_orig_types
== NULL
)
12536 orig_types
= make_tree_vector ();
12538 if (literal_zero_mask
)
12539 c_parser_check_literal_zero (parser
, literal_zero_mask
, 0);
12540 expr
= c_parser_expr_no_commas (parser
, NULL
);
12542 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true, true);
12544 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
12545 ret
->quick_push (expr
.value
);
12547 orig_types
->quick_push (expr
.original_type
);
12549 locations
->safe_push (expr
.get_location ());
12550 if (sizeof_arg
!= NULL
12551 && (expr
.original_code
== SIZEOF_EXPR
12552 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
12554 sizeof_arg
[0] = c_last_sizeof_arg
;
12555 sizeof_arg_loc
[0] = c_last_sizeof_loc
;
12557 while (c_parser_next_token_is (parser
, CPP_COMMA
))
12559 c_parser_consume_token (parser
);
12560 if (literal_zero_mask
)
12561 c_parser_check_literal_zero (parser
, literal_zero_mask
, idx
+ 1);
12562 expr
= c_parser_expr_no_commas (parser
, NULL
);
12564 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true,
12567 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
12568 vec_safe_push (ret
, expr
.value
);
12570 vec_safe_push (orig_types
, expr
.original_type
);
12572 locations
->safe_push (expr
.get_location ());
12574 && sizeof_arg
!= NULL
12575 && (expr
.original_code
== SIZEOF_EXPR
12576 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
12578 sizeof_arg
[idx
] = c_last_sizeof_arg
;
12579 sizeof_arg_loc
[idx
] = c_last_sizeof_loc
;
12583 *p_orig_types
= orig_types
;
12587 /* Parse Objective-C-specific constructs. */
12589 /* Parse an objc-class-definition.
12591 objc-class-definition:
12592 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
12593 objc-class-instance-variables[opt] objc-methodprotolist @end
12594 @implementation identifier objc-superclass[opt]
12595 objc-class-instance-variables[opt]
12596 @interface identifier ( identifier ) objc-protocol-refs[opt]
12597 objc-methodprotolist @end
12598 @interface identifier ( ) objc-protocol-refs[opt]
12599 objc-methodprotolist @end
12600 @implementation identifier ( identifier )
12605 "@interface identifier (" must start "@interface identifier (
12606 identifier ) ...": objc-methodprotolist in the first production may
12607 not start with a parenthesized identifier as a declarator of a data
12608 definition with no declaration specifiers if the objc-superclass,
12609 objc-protocol-refs and objc-class-instance-variables are omitted. */
12612 c_parser_objc_class_definition (c_parser
*parser
, tree attributes
)
12617 if (c_parser_next_token_is_keyword (parser
, RID_AT_INTERFACE
))
12619 else if (c_parser_next_token_is_keyword (parser
, RID_AT_IMPLEMENTATION
))
12622 gcc_unreachable ();
12624 c_parser_consume_token (parser
);
12625 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12627 c_parser_error (parser
, "expected identifier");
12630 id1
= c_parser_peek_token (parser
)->value
;
12631 location_t loc1
= c_parser_peek_token (parser
)->location
;
12632 c_parser_consume_token (parser
);
12633 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
12635 /* We have a category or class extension. */
12637 tree proto
= NULL_TREE
;
12638 matching_parens parens
;
12639 parens
.consume_open (parser
);
12640 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12642 if (iface_p
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
12644 /* We have a class extension. */
12649 c_parser_error (parser
, "expected identifier or %<)%>");
12650 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
12656 id2
= c_parser_peek_token (parser
)->value
;
12657 c_parser_consume_token (parser
);
12659 parens
.skip_until_found_close (parser
);
12662 objc_start_category_implementation (id1
, id2
);
12665 if (c_parser_next_token_is (parser
, CPP_LESS
))
12666 proto
= c_parser_objc_protocol_refs (parser
);
12667 objc_start_category_interface (id1
, id2
, proto
, attributes
);
12668 c_parser_objc_methodprotolist (parser
);
12669 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
12670 objc_finish_interface ();
12673 if (c_parser_next_token_is (parser
, CPP_COLON
))
12675 c_parser_consume_token (parser
);
12676 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12678 c_parser_error (parser
, "expected identifier");
12681 superclass
= c_parser_peek_token (parser
)->value
;
12682 c_parser_consume_token (parser
);
12685 superclass
= NULL_TREE
;
12688 tree proto
= NULL_TREE
;
12689 if (c_parser_next_token_is (parser
, CPP_LESS
))
12690 proto
= c_parser_objc_protocol_refs (parser
);
12691 objc_start_class_interface (id1
, loc1
, superclass
, proto
, attributes
);
12694 objc_start_class_implementation (id1
, superclass
);
12695 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
12696 c_parser_objc_class_instance_variables (parser
);
12699 objc_continue_interface ();
12700 c_parser_objc_methodprotolist (parser
);
12701 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
12702 objc_finish_interface ();
12706 objc_continue_implementation ();
12711 /* Parse objc-class-instance-variables.
12713 objc-class-instance-variables:
12714 { objc-instance-variable-decl-list[opt] }
12716 objc-instance-variable-decl-list:
12717 objc-visibility-spec
12718 objc-instance-variable-decl ;
12720 objc-instance-variable-decl-list objc-visibility-spec
12721 objc-instance-variable-decl-list objc-instance-variable-decl ;
12722 objc-instance-variable-decl-list ;
12724 objc-visibility-spec:
12729 objc-instance-variable-decl:
12734 c_parser_objc_class_instance_variables (c_parser
*parser
)
12736 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
12737 c_parser_consume_token (parser
);
12738 while (c_parser_next_token_is_not (parser
, CPP_EOF
))
12741 /* Parse any stray semicolon. */
12742 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
12744 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
12745 "extra semicolon");
12746 c_parser_consume_token (parser
);
12749 /* Stop if at the end of the instance variables. */
12750 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
12752 c_parser_consume_token (parser
);
12755 /* Parse any objc-visibility-spec. */
12756 if (c_parser_next_token_is_keyword (parser
, RID_AT_PRIVATE
))
12758 c_parser_consume_token (parser
);
12759 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE
);
12762 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROTECTED
))
12764 c_parser_consume_token (parser
);
12765 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED
);
12768 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PUBLIC
))
12770 c_parser_consume_token (parser
);
12771 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC
);
12774 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PACKAGE
))
12776 c_parser_consume_token (parser
);
12777 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE
);
12780 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
12782 c_parser_pragma (parser
, pragma_external
, NULL
);
12786 /* Parse some comma-separated declarations. */
12787 decls
= c_parser_struct_declaration (parser
, NULL
);
12790 /* There is a syntax error. We want to skip the offending
12791 tokens up to the next ';' (included) or '}'
12794 /* First, skip manually a ')' or ']'. This is because they
12795 reduce the nesting level, so c_parser_skip_until_found()
12796 wouldn't be able to skip past them. */
12797 c_token
*token
= c_parser_peek_token (parser
);
12798 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_CLOSE_SQUARE
)
12799 c_parser_consume_token (parser
);
12801 /* Then, do the standard skipping. */
12802 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12804 /* We hopefully recovered. Start normal parsing again. */
12805 parser
->error
= false;
12810 /* Comma-separated instance variables are chained together
12811 in reverse order; add them one by one. */
12812 tree ivar
= nreverse (decls
);
12813 for (; ivar
; ivar
= DECL_CHAIN (ivar
))
12814 objc_add_instance_variable (copy_node (ivar
));
12816 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12820 /* Parse an objc-class-declaration.
12822 objc-class-declaration:
12823 @class identifier-list ;
12827 c_parser_objc_class_declaration (c_parser
*parser
)
12829 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_CLASS
));
12830 c_parser_consume_token (parser
);
12831 /* Any identifiers, including those declared as type names, are OK
12836 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12838 c_parser_error (parser
, "expected identifier");
12839 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12840 parser
->error
= false;
12843 id
= c_parser_peek_token (parser
)->value
;
12844 objc_declare_class (id
);
12845 c_parser_consume_token (parser
);
12846 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12847 c_parser_consume_token (parser
);
12851 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12854 /* Parse an objc-alias-declaration.
12856 objc-alias-declaration:
12857 @compatibility_alias identifier identifier ;
12861 c_parser_objc_alias_declaration (c_parser
*parser
)
12864 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_ALIAS
));
12865 c_parser_consume_token (parser
);
12866 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12868 c_parser_error (parser
, "expected identifier");
12869 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12872 id1
= c_parser_peek_token (parser
)->value
;
12873 c_parser_consume_token (parser
);
12874 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12876 c_parser_error (parser
, "expected identifier");
12877 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12880 id2
= c_parser_peek_token (parser
)->value
;
12881 c_parser_consume_token (parser
);
12882 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12883 objc_declare_alias (id1
, id2
);
12886 /* Parse an objc-protocol-definition.
12888 objc-protocol-definition:
12889 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
12890 @protocol identifier-list ;
12892 "@protocol identifier ;" should be resolved as "@protocol
12893 identifier-list ;": objc-methodprotolist may not start with a
12894 semicolon in the first alternative if objc-protocol-refs are
12898 c_parser_objc_protocol_definition (c_parser
*parser
, tree attributes
)
12900 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROTOCOL
));
12902 c_parser_consume_token (parser
);
12903 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12905 c_parser_error (parser
, "expected identifier");
12908 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
12909 || c_parser_peek_2nd_token (parser
)->type
== CPP_SEMICOLON
)
12911 /* Any identifiers, including those declared as type names, are
12916 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12918 c_parser_error (parser
, "expected identifier");
12921 id
= c_parser_peek_token (parser
)->value
;
12922 objc_declare_protocol (id
, attributes
);
12923 c_parser_consume_token (parser
);
12924 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12925 c_parser_consume_token (parser
);
12929 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12933 tree id
= c_parser_peek_token (parser
)->value
;
12934 tree proto
= NULL_TREE
;
12935 c_parser_consume_token (parser
);
12936 if (c_parser_next_token_is (parser
, CPP_LESS
))
12937 proto
= c_parser_objc_protocol_refs (parser
);
12938 parser
->objc_pq_context
= true;
12939 objc_start_protocol (id
, proto
, attributes
);
12940 c_parser_objc_methodprotolist (parser
);
12941 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
12942 parser
->objc_pq_context
= false;
12943 objc_finish_interface ();
12947 /* Parse an objc-method-type.
12953 Return true if it is a class method (+) and false if it is
12954 an instance method (-).
12957 c_parser_objc_method_type (c_parser
*parser
)
12959 switch (c_parser_peek_token (parser
)->type
)
12962 c_parser_consume_token (parser
);
12965 c_parser_consume_token (parser
);
12968 gcc_unreachable ();
12972 /* Parse an objc-method-definition.
12974 objc-method-definition:
12975 objc-method-type objc-method-decl ;[opt] compound-statement
12979 c_parser_objc_method_definition (c_parser
*parser
)
12981 bool is_class_method
= c_parser_objc_method_type (parser
);
12982 tree decl
, attributes
= NULL_TREE
, expr
= NULL_TREE
;
12983 parser
->objc_pq_context
= true;
12984 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
12986 if (decl
== error_mark_node
)
12987 return; /* Bail here. */
12989 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
12991 c_parser_consume_token (parser
);
12992 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
12993 "extra semicolon in method definition specified");
12996 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
12998 c_parser_error (parser
, "expected %<{%>");
13002 parser
->objc_pq_context
= false;
13003 if (objc_start_method_definition (is_class_method
, decl
, attributes
, expr
))
13005 add_stmt (c_parser_compound_statement (parser
));
13006 objc_finish_method_definition (current_function_decl
);
13010 /* This code is executed when we find a method definition
13011 outside of an @implementation context (or invalid for other
13012 reasons). Parse the method (to keep going) but do not emit
13015 c_parser_compound_statement (parser
);
13019 /* Parse an objc-methodprotolist.
13021 objc-methodprotolist:
13023 objc-methodprotolist objc-methodproto
13024 objc-methodprotolist declaration
13025 objc-methodprotolist ;
13029 The declaration is a data definition, which may be missing
13030 declaration specifiers under the same rules and diagnostics as
13031 other data definitions outside functions, and the stray semicolon
13032 is diagnosed the same way as a stray semicolon outside a
13036 c_parser_objc_methodprotolist (c_parser
*parser
)
13040 /* The list is terminated by @end. */
13041 switch (c_parser_peek_token (parser
)->type
)
13043 case CPP_SEMICOLON
:
13044 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
13045 "ISO C does not allow extra %<;%> outside of a function");
13046 c_parser_consume_token (parser
);
13050 c_parser_objc_methodproto (parser
);
13053 c_parser_pragma (parser
, pragma_external
, NULL
);
13058 if (c_parser_next_token_is_keyword (parser
, RID_AT_END
))
13060 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
))
13061 c_parser_objc_at_property_declaration (parser
);
13062 else if (c_parser_next_token_is_keyword (parser
, RID_AT_OPTIONAL
))
13064 objc_set_method_opt (true);
13065 c_parser_consume_token (parser
);
13067 else if (c_parser_next_token_is_keyword (parser
, RID_AT_REQUIRED
))
13069 objc_set_method_opt (false);
13070 c_parser_consume_token (parser
);
13073 c_parser_declaration_or_fndef (parser
, false, false, true,
13080 /* Parse an objc-methodproto.
13083 objc-method-type objc-method-decl ;
13087 c_parser_objc_methodproto (c_parser
*parser
)
13089 bool is_class_method
= c_parser_objc_method_type (parser
);
13090 tree decl
, attributes
= NULL_TREE
;
13092 /* Remember protocol qualifiers in prototypes. */
13093 parser
->objc_pq_context
= true;
13094 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
13096 /* Forget protocol qualifiers now. */
13097 parser
->objc_pq_context
= false;
13099 /* Do not allow the presence of attributes to hide an erroneous
13100 method implementation in the interface section. */
13101 if (!c_parser_next_token_is (parser
, CPP_SEMICOLON
))
13103 c_parser_error (parser
, "expected %<;%>");
13107 if (decl
!= error_mark_node
)
13108 objc_add_method_declaration (is_class_method
, decl
, attributes
);
13110 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13113 /* If we are at a position that method attributes may be present, check that
13114 there are not any parsed already (a syntax error) and then collect any
13115 specified at the current location. Finally, if new attributes were present,
13116 check that the next token is legal ( ';' for decls and '{' for defs). */
13119 c_parser_objc_maybe_method_attributes (c_parser
* parser
, tree
* attributes
)
13124 c_parser_error (parser
,
13125 "method attributes must be specified at the end only");
13126 *attributes
= NULL_TREE
;
13130 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
13131 *attributes
= c_parser_gnu_attributes (parser
);
13133 /* If there were no attributes here, just report any earlier error. */
13134 if (*attributes
== NULL_TREE
|| bad
)
13137 /* If the attributes are followed by a ; or {, then just report any earlier
13139 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
13140 || c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
13143 /* We've got attributes, but not at the end. */
13144 c_parser_error (parser
,
13145 "expected %<;%> or %<{%> after method attribute definition");
13149 /* Parse an objc-method-decl.
13152 ( objc-type-name ) objc-selector
13154 ( objc-type-name ) objc-keyword-selector objc-optparmlist
13155 objc-keyword-selector objc-optparmlist
13158 objc-keyword-selector:
13160 objc-keyword-selector objc-keyword-decl
13163 objc-selector : ( objc-type-name ) identifier
13164 objc-selector : identifier
13165 : ( objc-type-name ) identifier
13169 objc-optparms objc-optellipsis
13173 objc-opt-parms , parameter-declaration
13181 c_parser_objc_method_decl (c_parser
*parser
, bool is_class_method
,
13182 tree
*attributes
, tree
*expr
)
13184 tree type
= NULL_TREE
;
13186 tree parms
= NULL_TREE
;
13187 bool ellipsis
= false;
13188 bool attr_err
= false;
13190 *attributes
= NULL_TREE
;
13191 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13193 matching_parens parens
;
13194 parens
.consume_open (parser
);
13195 type
= c_parser_objc_type_name (parser
);
13196 parens
.skip_until_found_close (parser
);
13198 sel
= c_parser_objc_selector (parser
);
13199 /* If there is no selector, or a colon follows, we have an
13200 objc-keyword-selector. If there is a selector, and a colon does
13201 not follow, that selector ends the objc-method-decl. */
13202 if (!sel
|| c_parser_next_token_is (parser
, CPP_COLON
))
13205 tree list
= NULL_TREE
;
13208 tree atype
= NULL_TREE
, id
, keyworddecl
;
13209 tree param_attr
= NULL_TREE
;
13210 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
13212 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13214 c_parser_consume_token (parser
);
13215 atype
= c_parser_objc_type_name (parser
);
13216 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
13219 /* New ObjC allows attributes on method parameters. */
13220 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
13221 param_attr
= c_parser_gnu_attributes (parser
);
13222 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13224 c_parser_error (parser
, "expected identifier");
13225 return error_mark_node
;
13227 id
= c_parser_peek_token (parser
)->value
;
13228 c_parser_consume_token (parser
);
13229 keyworddecl
= objc_build_keyword_decl (tsel
, atype
, id
, param_attr
);
13230 list
= chainon (list
, keyworddecl
);
13231 tsel
= c_parser_objc_selector (parser
);
13232 if (!tsel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
13236 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
13238 /* Parse the optional parameter list. Optional Objective-C
13239 method parameters follow the C syntax, and may include '...'
13240 to denote a variable number of arguments. */
13241 parms
= make_node (TREE_LIST
);
13242 while (c_parser_next_token_is (parser
, CPP_COMMA
))
13244 struct c_parm
*parm
;
13245 c_parser_consume_token (parser
);
13246 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
13249 c_parser_consume_token (parser
);
13250 attr_err
|= c_parser_objc_maybe_method_attributes
13251 (parser
, attributes
) ;
13254 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
13257 parms
= chainon (parms
,
13258 build_tree_list (NULL_TREE
, grokparm (parm
, expr
)));
13263 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
13267 c_parser_error (parser
, "objective-c method declaration is expected");
13268 return error_mark_node
;
13272 return error_mark_node
;
13274 return objc_build_method_signature (is_class_method
, type
, sel
, parms
, ellipsis
);
13277 /* Parse an objc-type-name.
13280 objc-type-qualifiers[opt] type-name
13281 objc-type-qualifiers[opt]
13283 objc-type-qualifiers:
13284 objc-type-qualifier
13285 objc-type-qualifiers objc-type-qualifier
13287 objc-type-qualifier: one of
13288 in out inout bycopy byref oneway
13292 c_parser_objc_type_name (c_parser
*parser
)
13294 tree quals
= NULL_TREE
;
13295 struct c_type_name
*type_name
= NULL
;
13296 tree type
= NULL_TREE
;
13299 c_token
*token
= c_parser_peek_token (parser
);
13300 if (token
->type
== CPP_KEYWORD
13301 && (token
->keyword
== RID_IN
13302 || token
->keyword
== RID_OUT
13303 || token
->keyword
== RID_INOUT
13304 || token
->keyword
== RID_BYCOPY
13305 || token
->keyword
== RID_BYREF
13306 || token
->keyword
== RID_ONEWAY
))
13308 quals
= chainon (build_tree_list (NULL_TREE
, token
->value
), quals
);
13309 c_parser_consume_token (parser
);
13314 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
13315 type_name
= c_parser_type_name (parser
);
13317 type
= groktypename (type_name
, NULL
, NULL
);
13319 /* If the type is unknown, and error has already been produced and
13320 we need to recover from the error. In that case, use NULL_TREE
13321 for the type, as if no type had been specified; this will use the
13322 default type ('id') which is good for error recovery. */
13323 if (type
== error_mark_node
)
13326 return build_tree_list (quals
, type
);
13329 /* Parse objc-protocol-refs.
13331 objc-protocol-refs:
13332 < identifier-list >
13336 c_parser_objc_protocol_refs (c_parser
*parser
)
13338 tree list
= NULL_TREE
;
13339 gcc_assert (c_parser_next_token_is (parser
, CPP_LESS
));
13340 c_parser_consume_token (parser
);
13341 /* Any identifiers, including those declared as type names, are OK
13346 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13348 c_parser_error (parser
, "expected identifier");
13351 id
= c_parser_peek_token (parser
)->value
;
13352 list
= chainon (list
, build_tree_list (NULL_TREE
, id
));
13353 c_parser_consume_token (parser
);
13354 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13355 c_parser_consume_token (parser
);
13359 c_parser_require (parser
, CPP_GREATER
, "expected %<>%>");
13363 /* Parse an objc-try-catch-finally-statement.
13365 objc-try-catch-finally-statement:
13366 @try compound-statement objc-catch-list[opt]
13367 @try compound-statement objc-catch-list[opt] @finally compound-statement
13370 @catch ( objc-catch-parameter-declaration ) compound-statement
13371 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
13373 objc-catch-parameter-declaration:
13374 parameter-declaration
13377 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
13379 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
13380 for C++. Keep them in sync. */
13383 c_parser_objc_try_catch_finally_statement (c_parser
*parser
)
13385 location_t location
;
13388 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_TRY
));
13389 c_parser_consume_token (parser
);
13390 location
= c_parser_peek_token (parser
)->location
;
13391 objc_maybe_warn_exceptions (location
);
13392 stmt
= c_parser_compound_statement (parser
);
13393 objc_begin_try_stmt (location
, stmt
);
13395 while (c_parser_next_token_is_keyword (parser
, RID_AT_CATCH
))
13397 struct c_parm
*parm
;
13398 tree parameter_declaration
= error_mark_node
;
13399 bool seen_open_paren
= false;
13401 c_parser_consume_token (parser
);
13402 matching_parens parens
;
13403 if (!parens
.require_open (parser
))
13404 seen_open_paren
= true;
13405 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
13407 /* We have "@catch (...)" (where the '...' are literally
13408 what is in the code). Skip the '...'.
13409 parameter_declaration is set to NULL_TREE, and
13410 objc_being_catch_clauses() knows that that means
13412 c_parser_consume_token (parser
);
13413 parameter_declaration
= NULL_TREE
;
13417 /* We have "@catch (NSException *exception)" or something
13418 like that. Parse the parameter declaration. */
13419 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
13421 parameter_declaration
= error_mark_node
;
13423 parameter_declaration
= grokparm (parm
, NULL
);
13425 if (seen_open_paren
)
13426 parens
.require_close (parser
);
13429 /* If there was no open parenthesis, we are recovering from
13430 an error, and we are trying to figure out what mistake
13431 the user has made. */
13433 /* If there is an immediate closing parenthesis, the user
13434 probably forgot the opening one (ie, they typed "@catch
13435 NSException *e)". Parse the closing parenthesis and keep
13437 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
13438 c_parser_consume_token (parser
);
13440 /* If these is no immediate closing parenthesis, the user
13441 probably doesn't know that parenthesis are required at
13442 all (ie, they typed "@catch NSException *e"). So, just
13443 forget about the closing parenthesis and keep going. */
13445 objc_begin_catch_clause (parameter_declaration
);
13446 if (c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
13447 c_parser_compound_statement_nostart (parser
);
13448 objc_finish_catch_clause ();
13450 if (c_parser_next_token_is_keyword (parser
, RID_AT_FINALLY
))
13452 c_parser_consume_token (parser
);
13453 location
= c_parser_peek_token (parser
)->location
;
13454 stmt
= c_parser_compound_statement (parser
);
13455 objc_build_finally_clause (location
, stmt
);
13457 objc_finish_try_stmt ();
13460 /* Parse an objc-synchronized-statement.
13462 objc-synchronized-statement:
13463 @synchronized ( expression ) compound-statement
13467 c_parser_objc_synchronized_statement (c_parser
*parser
)
13471 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNCHRONIZED
));
13472 c_parser_consume_token (parser
);
13473 loc
= c_parser_peek_token (parser
)->location
;
13474 objc_maybe_warn_exceptions (loc
);
13475 matching_parens parens
;
13476 if (parens
.require_open (parser
))
13478 struct c_expr ce
= c_parser_expression (parser
);
13479 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
13481 expr
= c_fully_fold (expr
, false, NULL
);
13482 parens
.skip_until_found_close (parser
);
13485 expr
= error_mark_node
;
13486 stmt
= c_parser_compound_statement (parser
);
13487 objc_build_synchronized (loc
, expr
, stmt
);
13490 /* Parse an objc-selector; return NULL_TREE without an error if the
13491 next token is not an objc-selector.
13496 enum struct union if else while do for switch case default
13497 break continue return goto asm sizeof typeof typeof_unqual __alignof
13498 unsigned long const short volatile signed restrict _Complex
13499 in out inout bycopy byref oneway int char float double void _Bool
13502 ??? Why this selection of keywords but not, for example, storage
13503 class specifiers? */
13506 c_parser_objc_selector (c_parser
*parser
)
13508 c_token
*token
= c_parser_peek_token (parser
);
13509 tree value
= token
->value
;
13510 if (token
->type
== CPP_NAME
)
13512 c_parser_consume_token (parser
);
13515 if (token
->type
!= CPP_KEYWORD
)
13517 switch (token
->keyword
)
13537 case RID_TYPEOF_UNQUAL
:
13557 CASE_RID_FLOATN_NX
:
13561 case RID_AUTO_TYPE
:
13566 c_parser_consume_token (parser
);
13573 /* Parse an objc-selector-arg.
13577 objc-keywordname-list
13579 objc-keywordname-list:
13581 objc-keywordname-list objc-keywordname
13589 c_parser_objc_selector_arg (c_parser
*parser
)
13591 tree sel
= c_parser_objc_selector (parser
);
13592 tree list
= NULL_TREE
;
13594 && c_parser_next_token_is_not (parser
, CPP_COLON
)
13595 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
13599 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
13601 c_parser_consume_token (parser
);
13602 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
13603 list
= chainon (list
, build_tree_list (NULL_TREE
, NULL_TREE
));
13607 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
13609 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
13611 sel
= c_parser_objc_selector (parser
);
13613 && c_parser_next_token_is_not (parser
, CPP_COLON
)
13614 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
13620 /* Parse an objc-receiver.
13629 c_parser_objc_receiver (c_parser
*parser
)
13631 location_t loc
= c_parser_peek_token (parser
)->location
;
13633 if (c_parser_peek_token (parser
)->type
== CPP_NAME
13634 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
13635 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
13637 tree id
= c_parser_peek_token (parser
)->value
;
13638 c_parser_consume_token (parser
);
13639 return objc_get_class_reference (id
);
13641 struct c_expr ce
= c_parser_expression (parser
);
13642 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
13643 return c_fully_fold (ce
.value
, false, NULL
);
13646 /* Parse objc-message-args.
13650 objc-keywordarg-list
13652 objc-keywordarg-list:
13654 objc-keywordarg-list objc-keywordarg
13657 objc-selector : objc-keywordexpr
13662 c_parser_objc_message_args (c_parser
*parser
)
13664 tree sel
= c_parser_objc_selector (parser
);
13665 tree list
= NULL_TREE
;
13666 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
13671 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
13672 return error_mark_node
;
13673 keywordexpr
= c_parser_objc_keywordexpr (parser
);
13674 list
= chainon (list
, build_tree_list (sel
, keywordexpr
));
13675 sel
= c_parser_objc_selector (parser
);
13676 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
13682 /* Parse an objc-keywordexpr.
13689 c_parser_objc_keywordexpr (c_parser
*parser
)
13692 vec
<tree
, va_gc
> *expr_list
= c_parser_expr_list (parser
, true, true,
13693 NULL
, NULL
, NULL
, NULL
);
13694 if (vec_safe_length (expr_list
) == 1)
13696 /* Just return the expression, remove a level of
13698 ret
= (*expr_list
)[0];
13702 /* We have a comma expression, we will collapse later. */
13703 ret
= build_tree_list_vec (expr_list
);
13705 release_tree_vector (expr_list
);
13709 /* A check, needed in several places, that ObjC interface, implementation or
13710 method definitions are not prefixed by incorrect items. */
13712 c_parser_objc_diagnose_bad_element_prefix (c_parser
*parser
,
13713 struct c_declspecs
*specs
)
13715 if (!specs
->declspecs_seen_p
|| specs
->non_sc_seen_p
13716 || specs
->typespec_kind
!= ctsk_none
)
13718 c_parser_error (parser
,
13719 "no type or storage class may be specified here,");
13720 c_parser_skip_to_end_of_block_or_statement (parser
);
13726 /* Parse an Objective-C @property declaration. The syntax is:
13728 objc-property-declaration:
13729 '@property' objc-property-attributes[opt] struct-declaration ;
13731 objc-property-attributes:
13732 '(' objc-property-attribute-list ')'
13734 objc-property-attribute-list:
13735 objc-property-attribute
13736 objc-property-attribute-list, objc-property-attribute
13738 objc-property-attribute
13739 'getter' = identifier
13740 'setter' = identifier
13749 @property NSString *name;
13750 @property (readonly) id object;
13751 @property (retain, nonatomic, getter=getTheName) id name;
13752 @property int a, b, c;
13754 PS: This function is identical to cp_parser_objc_at_propery_declaration
13755 for C++. Keep them in sync. */
13757 c_parser_objc_at_property_declaration (c_parser
*parser
)
13759 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
));
13760 location_t loc
= c_parser_peek_token (parser
)->location
;
13761 c_parser_consume_token (parser
); /* Eat '@property'. */
13763 /* Parse the optional attribute list.
13765 A list of parsed, but not verified, attributes. */
13766 vec
<property_attribute_info
*> prop_attr_list
= vNULL
;
13768 bool syntax_error
= false;
13769 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13771 matching_parens parens
;
13773 location_t attr_start
= c_parser_peek_token (parser
)->location
;
13775 parens
.consume_open (parser
);
13777 /* Property attribute keywords are valid now. */
13778 parser
->objc_property_attr_context
= true;
13780 /* Allow @property (), with a warning. */
13781 location_t attr_end
= c_parser_peek_token (parser
)->location
;
13783 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
13785 location_t attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
13786 warning_at (attr_comb
, OPT_Wattributes
,
13787 "empty property attribute list");
13792 c_token
*token
= c_parser_peek_token (parser
);
13793 attr_start
= token
->location
;
13794 attr_end
= get_finish (token
->location
);
13795 location_t attr_comb
= make_location (attr_start
, attr_start
,
13798 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_COMMA
)
13800 warning_at (attr_comb
, OPT_Wattributes
,
13801 "missing property attribute");
13802 if (token
->type
== CPP_CLOSE_PAREN
)
13804 c_parser_consume_token (parser
);
13808 tree attr_name
= NULL_TREE
;
13809 enum rid keyword
= RID_MAX
; /* Not a valid property attribute. */
13810 bool add_at
= false;
13811 if (token
->type
== CPP_KEYWORD
)
13813 keyword
= token
->keyword
;
13814 if (OBJC_IS_AT_KEYWORD (keyword
))
13816 /* For '@' keywords the token value has the keyword,
13817 prepend the '@' for diagnostics. */
13818 attr_name
= token
->value
;
13822 attr_name
= ridpointers
[(int)keyword
];
13824 else if (token
->type
== CPP_NAME
)
13825 attr_name
= token
->value
;
13826 c_parser_consume_token (parser
);
13828 enum objc_property_attribute_kind prop_kind
13829 = objc_prop_attr_kind_for_rid (keyword
);
13830 property_attribute_info
*prop
13831 = new property_attribute_info (attr_name
, attr_comb
, prop_kind
);
13832 prop_attr_list
.safe_push (prop
);
13835 switch (prop
->prop_kind
)
13838 case OBJC_PROPERTY_ATTR_UNKNOWN
:
13840 error_at (attr_comb
, "unknown property attribute %<%s%s%>",
13841 add_at
? "@" : "", IDENTIFIER_POINTER (attr_name
));
13843 error_at (attr_comb
, "unknown property attribute");
13844 prop
->parse_error
= syntax_error
= true;
13847 case OBJC_PROPERTY_ATTR_GETTER
:
13848 case OBJC_PROPERTY_ATTR_SETTER
:
13849 if (c_parser_next_token_is_not (parser
, CPP_EQ
))
13851 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
13852 error_at (attr_comb
, "expected %<=%> after Objective-C %qE",
13854 prop
->parse_error
= syntax_error
= true;
13857 token
= c_parser_peek_token (parser
);
13858 attr_end
= token
->location
;
13859 c_parser_consume_token (parser
); /* eat the = */
13860 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13862 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
13863 error_at (attr_comb
, "expected %qE selector name",
13865 prop
->parse_error
= syntax_error
= true;
13868 /* Get the end of the method name, and consume the name. */
13869 token
= c_parser_peek_token (parser
);
13870 attr_end
= get_finish (token
->location
);
13871 meth_name
= token
->value
;
13872 c_parser_consume_token (parser
);
13873 if (prop
->prop_kind
== OBJC_PROPERTY_ATTR_SETTER
)
13875 if (c_parser_next_token_is_not (parser
, CPP_COLON
))
13877 attr_comb
= make_location (attr_end
, attr_start
,
13879 error_at (attr_comb
, "setter method names must"
13880 " terminate with %<:%>");
13881 prop
->parse_error
= syntax_error
= true;
13885 attr_end
= get_finish (c_parser_peek_token
13886 (parser
)->location
);
13887 c_parser_consume_token (parser
);
13889 attr_comb
= make_location (attr_start
, attr_start
,
13893 attr_comb
= make_location (attr_start
, attr_start
,
13895 prop
->ident
= meth_name
;
13896 /* Updated location including all that was successfully
13898 prop
->prop_loc
= attr_comb
;
13902 /* If we see a comma here, then keep going - even if we already
13903 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
13904 this makes a more useful output and avoid spurious warnings about
13905 missing attributes that are, in fact, specified after the one with
13906 the syntax error. */
13907 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13908 c_parser_consume_token (parser
);
13912 parser
->objc_property_attr_context
= false;
13914 if (syntax_error
&& c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
13915 /* We don't really want to chew the whole of the file looking for a
13916 matching closing parenthesis, so we will try to read the decl and
13917 let the error handling for that close out the statement. */
13920 syntax_error
= false, parens
.skip_until_found_close (parser
);
13923 /* 'properties' is the list of properties that we read. Usually a
13924 single one, but maybe more (eg, in "@property int a, b, c;" there
13926 tree properties
= c_parser_struct_declaration (parser
, NULL
);
13928 if (properties
== error_mark_node
)
13929 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
13932 if (properties
== NULL_TREE
)
13933 c_parser_error (parser
, "expected identifier");
13936 /* Comma-separated properties are chained together in reverse order;
13937 add them one by one. */
13938 properties
= nreverse (properties
);
13939 for (; properties
; properties
= TREE_CHAIN (properties
))
13940 objc_add_property_declaration (loc
, copy_node (properties
),
13943 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13946 while (!prop_attr_list
.is_empty())
13947 delete prop_attr_list
.pop ();
13948 prop_attr_list
.release ();
13949 parser
->error
= false;
13952 /* Parse an Objective-C @synthesize declaration. The syntax is:
13954 objc-synthesize-declaration:
13955 @synthesize objc-synthesize-identifier-list ;
13957 objc-synthesize-identifier-list:
13958 objc-synthesize-identifier
13959 objc-synthesize-identifier-list, objc-synthesize-identifier
13961 objc-synthesize-identifier
13963 identifier = identifier
13966 @synthesize MyProperty;
13967 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
13969 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
13970 for C++. Keep them in sync.
13973 c_parser_objc_at_synthesize_declaration (c_parser
*parser
)
13975 tree list
= NULL_TREE
;
13977 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNTHESIZE
));
13978 loc
= c_parser_peek_token (parser
)->location
;
13980 c_parser_consume_token (parser
);
13983 tree property
, ivar
;
13984 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13986 c_parser_error (parser
, "expected identifier");
13987 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
13988 /* Once we find the semicolon, we can resume normal parsing.
13989 We have to reset parser->error manually because
13990 c_parser_skip_until_found() won't reset it for us if the
13991 next token is precisely a semicolon. */
13992 parser
->error
= false;
13995 property
= c_parser_peek_token (parser
)->value
;
13996 c_parser_consume_token (parser
);
13997 if (c_parser_next_token_is (parser
, CPP_EQ
))
13999 c_parser_consume_token (parser
);
14000 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14002 c_parser_error (parser
, "expected identifier");
14003 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
14004 parser
->error
= false;
14007 ivar
= c_parser_peek_token (parser
)->value
;
14008 c_parser_consume_token (parser
);
14012 list
= chainon (list
, build_tree_list (ivar
, property
));
14013 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14014 c_parser_consume_token (parser
);
14018 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
14019 objc_add_synthesize_declaration (loc
, list
);
14022 /* Parse an Objective-C @dynamic declaration. The syntax is:
14024 objc-dynamic-declaration:
14025 @dynamic identifier-list ;
14028 @dynamic MyProperty;
14029 @dynamic MyProperty, AnotherProperty;
14031 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
14032 for C++. Keep them in sync.
14035 c_parser_objc_at_dynamic_declaration (c_parser
*parser
)
14037 tree list
= NULL_TREE
;
14039 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_DYNAMIC
));
14040 loc
= c_parser_peek_token (parser
)->location
;
14042 c_parser_consume_token (parser
);
14046 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14048 c_parser_error (parser
, "expected identifier");
14049 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
14050 parser
->error
= false;
14053 property
= c_parser_peek_token (parser
)->value
;
14054 list
= chainon (list
, build_tree_list (NULL_TREE
, property
));
14055 c_parser_consume_token (parser
);
14056 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14057 c_parser_consume_token (parser
);
14061 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
14062 objc_add_dynamic_declaration (loc
, list
);
14066 /* Parse a pragma GCC ivdep. */
14069 c_parse_pragma_ivdep (c_parser
*parser
)
14071 c_parser_consume_pragma (parser
);
14072 c_parser_skip_to_pragma_eol (parser
);
14076 /* Parse a pragma GCC novector. */
14079 c_parse_pragma_novector (c_parser
*parser
)
14081 c_parser_consume_pragma (parser
);
14082 c_parser_skip_to_pragma_eol (parser
);
14086 /* Parse a pragma GCC unroll. */
14088 static unsigned short
14089 c_parser_pragma_unroll (c_parser
*parser
)
14091 unsigned short unroll
;
14092 c_parser_consume_pragma (parser
);
14093 location_t location
= c_parser_peek_token (parser
)->location
;
14094 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
14095 mark_exp_read (expr
);
14096 expr
= c_fully_fold (expr
, false, NULL
);
14097 HOST_WIDE_INT lunroll
= 0;
14098 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
14099 || TREE_CODE (expr
) != INTEGER_CST
14100 || (lunroll
= tree_to_shwi (expr
)) < 0
14101 || lunroll
>= USHRT_MAX
)
14103 error_at (location
, "%<#pragma GCC unroll%> requires an"
14104 " assignment-expression that evaluates to a non-negative"
14105 " integral constant less than %u", USHRT_MAX
);
14110 unroll
= (unsigned short)lunroll
;
14115 c_parser_skip_to_pragma_eol (parser
);
14119 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
14120 should be considered, statements. ALLOW_STMT is true if we're within
14121 the context of a function and such pragmas are to be allowed. Returns
14122 true if we actually parsed such a pragma. */
14125 c_parser_pragma (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
14128 const char *construct
= NULL
;
14130 input_location
= c_parser_peek_token (parser
)->location
;
14131 id
= c_parser_peek_token (parser
)->pragma_kind
;
14132 gcc_assert (id
!= PRAGMA_NONE
);
14133 if (parser
->omp_for_parse_state
14134 && parser
->omp_for_parse_state
->in_intervening_code
14135 && id
>= PRAGMA_OMP__START_
14136 && id
<= PRAGMA_OMP__LAST_
)
14138 error_at (input_location
,
14139 "intervening code must not contain OpenMP directives");
14140 parser
->omp_for_parse_state
->fail
= true;
14141 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14147 case PRAGMA_OACC_DECLARE
:
14148 c_parser_oacc_declare (parser
);
14151 case PRAGMA_OACC_ENTER_DATA
:
14152 if (context
!= pragma_compound
)
14154 construct
= "acc enter data";
14156 if (context
== pragma_stmt
)
14158 error_at (c_parser_peek_token (parser
)->location
,
14159 "%<#pragma %s%> may only be used in compound "
14160 "statements", construct
);
14161 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14166 c_parser_oacc_enter_exit_data (parser
, true);
14169 case PRAGMA_OACC_EXIT_DATA
:
14170 if (context
!= pragma_compound
)
14172 construct
= "acc exit data";
14175 c_parser_oacc_enter_exit_data (parser
, false);
14178 case PRAGMA_OACC_ROUTINE
:
14179 if (context
!= pragma_external
)
14181 error_at (c_parser_peek_token (parser
)->location
,
14182 "%<#pragma acc routine%> must be at file scope");
14183 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14186 c_parser_oacc_routine (parser
, context
);
14189 case PRAGMA_OACC_UPDATE
:
14190 if (context
!= pragma_compound
)
14192 construct
= "acc update";
14195 c_parser_oacc_update (parser
);
14198 case PRAGMA_OMP_BARRIER
:
14199 if (context
!= pragma_compound
)
14201 construct
= "omp barrier";
14204 c_parser_omp_barrier (parser
);
14207 case PRAGMA_OMP_DEPOBJ
:
14208 if (context
!= pragma_compound
)
14210 construct
= "omp depobj";
14213 c_parser_omp_depobj (parser
);
14216 case PRAGMA_OMP_FLUSH
:
14217 if (context
!= pragma_compound
)
14219 construct
= "omp flush";
14222 c_parser_omp_flush (parser
);
14225 case PRAGMA_OMP_TASKWAIT
:
14226 if (context
!= pragma_compound
)
14228 construct
= "omp taskwait";
14231 c_parser_omp_taskwait (parser
);
14234 case PRAGMA_OMP_TASKYIELD
:
14235 if (context
!= pragma_compound
)
14237 construct
= "omp taskyield";
14240 c_parser_omp_taskyield (parser
);
14243 case PRAGMA_OMP_CANCEL
:
14244 if (context
!= pragma_compound
)
14246 construct
= "omp cancel";
14249 c_parser_omp_cancel (parser
);
14252 case PRAGMA_OMP_CANCELLATION_POINT
:
14253 return c_parser_omp_cancellation_point (parser
, context
);
14255 case PRAGMA_OMP_THREADPRIVATE
:
14256 c_parser_omp_threadprivate (parser
);
14259 case PRAGMA_OMP_TARGET
:
14260 return c_parser_omp_target (parser
, context
, if_p
);
14262 case PRAGMA_OMP_BEGIN
:
14263 c_parser_omp_begin (parser
);
14266 case PRAGMA_OMP_END
:
14267 c_parser_omp_end (parser
);
14270 case PRAGMA_OMP_SCAN
:
14271 error_at (c_parser_peek_token (parser
)->location
,
14272 "%<#pragma omp scan%> may only be used in "
14273 "a loop construct with %<inscan%> %<reduction%> clause");
14274 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14277 case PRAGMA_OMP_SECTION
:
14278 error_at (c_parser_peek_token (parser
)->location
,
14279 "%<#pragma omp section%> may only be used in "
14280 "%<#pragma omp sections%> construct");
14281 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14284 case PRAGMA_OMP_DECLARE
:
14285 return c_parser_omp_declare (parser
, context
);
14287 case PRAGMA_OMP_REQUIRES
:
14288 if (context
!= pragma_external
)
14290 error_at (c_parser_peek_token (parser
)->location
,
14291 "%<#pragma %s%> may only be used at file scope",
14293 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14296 c_parser_omp_requires (parser
);
14299 case PRAGMA_OMP_ALLOCATE
:
14300 c_parser_omp_allocate (parser
);
14303 case PRAGMA_OMP_ASSUMES
:
14304 if (context
!= pragma_external
)
14306 error_at (c_parser_peek_token (parser
)->location
,
14307 "%<#pragma %s%> may only be used at file scope",
14309 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14312 c_parser_omp_assumes (parser
);
14315 case PRAGMA_OMP_NOTHING
:
14316 c_parser_omp_nothing (parser
);
14319 case PRAGMA_OMP_ERROR
:
14320 return c_parser_omp_error (parser
, context
);
14322 case PRAGMA_OMP_ORDERED
:
14323 return c_parser_omp_ordered (parser
, context
, if_p
);
14325 case PRAGMA_NOVECTOR
:
14326 case PRAGMA_UNROLL
:
14329 bool novector
= false;
14330 unsigned short unroll
= 0;
14331 bool ivdep
= false;
14335 case PRAGMA_NOVECTOR
:
14336 novector
= c_parse_pragma_novector (parser
);
14338 case PRAGMA_UNROLL
:
14339 unroll
= c_parser_pragma_unroll (parser
);
14342 ivdep
= c_parse_pragma_ivdep (parser
);
14345 gcc_unreachable ();
14348 c_token
*tok
= c_parser_peek_token (parser
);
14349 bool has_more
= tok
->type
== CPP_PRAGMA
;
14352 switch (tok
->pragma_kind
)
14355 ivdep
= c_parse_pragma_ivdep (parser
);
14357 case PRAGMA_UNROLL
:
14358 unroll
= c_parser_pragma_unroll (parser
);
14360 case PRAGMA_NOVECTOR
:
14361 novector
= c_parse_pragma_novector (parser
);
14367 tok
= c_parser_peek_token (parser
);
14368 has_more
= has_more
&& tok
->type
== CPP_PRAGMA
;
14370 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
14371 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
14372 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
14374 c_parser_error (parser
, "for, while or do statement expected");
14377 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
14378 c_parser_for_statement (parser
, ivdep
, unroll
, novector
, if_p
);
14379 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
14380 c_parser_while_statement (parser
, ivdep
, unroll
, novector
, if_p
);
14382 c_parser_do_statement (parser
, ivdep
, unroll
, novector
);
14386 case PRAGMA_GCC_PCH_PREPROCESS
:
14387 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
14388 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14391 case PRAGMA_OACC_WAIT
:
14392 if (context
!= pragma_compound
)
14394 construct
= "acc wait";
14397 /* FALL THROUGH. */
14400 if (id
< PRAGMA_FIRST_EXTERNAL
)
14402 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
14405 c_parser_error (parser
, "expected declaration specifiers");
14406 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14409 c_parser_omp_construct (parser
, if_p
);
14415 c_parser_consume_pragma (parser
);
14416 c_invoke_pragma_handler (id
);
14418 /* Skip to EOL, but suppress any error message. Those will have been
14419 generated by the handler routine through calling error, as opposed
14420 to calling c_parser_error. */
14421 parser
->error
= true;
14422 c_parser_skip_to_pragma_eol (parser
);
14427 /* The interface the pragma parsers have to the lexer. */
14430 pragma_lex (tree
*value
, location_t
*loc
)
14432 c_token
*tok
= c_parser_peek_token (the_parser
);
14433 enum cpp_ttype ret
= tok
->type
;
14435 *value
= tok
->value
;
14437 *loc
= tok
->location
;
14439 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
14441 else if (ret
== CPP_STRING
)
14442 *value
= c_parser_string_literal (the_parser
, false, false).value
;
14445 if (ret
== CPP_KEYWORD
)
14447 c_parser_consume_token (the_parser
);
14454 pragma_lex_discard_to_eol ()
14459 type
= c_parser_peek_token (the_parser
)->type
;
14460 gcc_assert (type
!= CPP_EOF
);
14461 c_parser_consume_token (the_parser
);
14462 } while (type
!= CPP_PRAGMA_EOL
);
14466 c_parser_pragma_pch_preprocess (c_parser
*parser
)
14470 parser
->lex_joined_string
= true;
14471 c_parser_consume_pragma (parser
);
14472 if (c_parser_next_token_is (parser
, CPP_STRING
))
14474 name
= c_parser_peek_token (parser
)->value
;
14475 c_parser_consume_token (parser
);
14478 c_parser_error (parser
, "expected string literal");
14479 c_parser_skip_to_pragma_eol (parser
);
14480 parser
->lex_joined_string
= false;
14483 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
14486 /* OpenACC and OpenMP parsing routines. */
14488 /* Returns name of the next clause.
14489 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
14490 the token is not consumed. Otherwise appropriate pragma_omp_clause is
14491 returned and the token is consumed. */
14493 static pragma_omp_clause
14494 c_parser_omp_clause_name (c_parser
*parser
)
14496 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
14498 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
14499 result
= PRAGMA_OACC_CLAUSE_AUTO
;
14500 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
14501 result
= PRAGMA_OMP_CLAUSE_IF
;
14502 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
14503 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
14504 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
14505 result
= PRAGMA_OMP_CLAUSE_FOR
;
14506 else if (c_parser_next_token_is (parser
, CPP_NAME
))
14508 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14513 if (!strcmp ("affinity", p
))
14514 result
= PRAGMA_OMP_CLAUSE_AFFINITY
;
14515 else if (!strcmp ("aligned", p
))
14516 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
14517 else if (!strcmp ("allocate", p
))
14518 result
= PRAGMA_OMP_CLAUSE_ALLOCATE
;
14519 else if (!strcmp ("async", p
))
14520 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
14521 else if (!strcmp ("attach", p
))
14522 result
= PRAGMA_OACC_CLAUSE_ATTACH
;
14525 if (!strcmp ("bind", p
))
14526 result
= PRAGMA_OMP_CLAUSE_BIND
;
14529 if (!strcmp ("collapse", p
))
14530 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
14531 else if (!strcmp ("copy", p
))
14532 result
= PRAGMA_OACC_CLAUSE_COPY
;
14533 else if (!strcmp ("copyin", p
))
14534 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
14535 else if (!strcmp ("copyout", p
))
14536 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
14537 else if (!strcmp ("copyprivate", p
))
14538 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
14539 else if (!strcmp ("create", p
))
14540 result
= PRAGMA_OACC_CLAUSE_CREATE
;
14543 if (!strcmp ("defaultmap", p
))
14544 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
14545 else if (!strcmp ("delete", p
))
14546 result
= PRAGMA_OACC_CLAUSE_DELETE
;
14547 else if (!strcmp ("depend", p
))
14548 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
14549 else if (!strcmp ("detach", p
))
14550 result
= PRAGMA_OACC_CLAUSE_DETACH
;
14551 else if (!strcmp ("device", p
))
14552 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
14553 else if (!strcmp ("deviceptr", p
))
14554 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
14555 else if (!strcmp ("device_resident", p
))
14556 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
14557 else if (!strcmp ("device_type", p
))
14558 result
= PRAGMA_OMP_CLAUSE_DEVICE_TYPE
;
14559 else if (!strcmp ("dist_schedule", p
))
14560 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
14561 else if (!strcmp ("doacross", p
))
14562 result
= PRAGMA_OMP_CLAUSE_DOACROSS
;
14565 if (!strcmp ("enter", p
))
14566 result
= PRAGMA_OMP_CLAUSE_ENTER
;
14569 if (!strcmp ("filter", p
))
14570 result
= PRAGMA_OMP_CLAUSE_FILTER
;
14571 else if (!strcmp ("final", p
))
14572 result
= PRAGMA_OMP_CLAUSE_FINAL
;
14573 else if (!strcmp ("finalize", p
))
14574 result
= PRAGMA_OACC_CLAUSE_FINALIZE
;
14575 else if (!strcmp ("firstprivate", p
))
14576 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
14577 else if (!strcmp ("from", p
))
14578 result
= PRAGMA_OMP_CLAUSE_FROM
;
14581 if (!strcmp ("gang", p
))
14582 result
= PRAGMA_OACC_CLAUSE_GANG
;
14583 else if (!strcmp ("grainsize", p
))
14584 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
14587 if (!strcmp ("has_device_addr", p
))
14588 result
= PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
;
14589 else if (!strcmp ("hint", p
))
14590 result
= PRAGMA_OMP_CLAUSE_HINT
;
14591 else if (!strcmp ("host", p
))
14592 result
= PRAGMA_OACC_CLAUSE_HOST
;
14595 if (!strcmp ("if_present", p
))
14596 result
= PRAGMA_OACC_CLAUSE_IF_PRESENT
;
14597 else if (!strcmp ("in_reduction", p
))
14598 result
= PRAGMA_OMP_CLAUSE_IN_REDUCTION
;
14599 else if (!strcmp ("inbranch", p
))
14600 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
14601 else if (!strcmp ("indirect", p
))
14602 result
= PRAGMA_OMP_CLAUSE_INDIRECT
;
14603 else if (!strcmp ("independent", p
))
14604 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
14605 else if (!strcmp ("is_device_ptr", p
))
14606 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
14609 if (!strcmp ("lastprivate", p
))
14610 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
14611 else if (!strcmp ("linear", p
))
14612 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
14613 else if (!strcmp ("link", p
))
14614 result
= PRAGMA_OMP_CLAUSE_LINK
;
14617 if (!strcmp ("map", p
))
14618 result
= PRAGMA_OMP_CLAUSE_MAP
;
14619 else if (!strcmp ("mergeable", p
))
14620 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
14623 if (!strcmp ("no_create", p
))
14624 result
= PRAGMA_OACC_CLAUSE_NO_CREATE
;
14625 else if (!strcmp ("nogroup", p
))
14626 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
14627 else if (!strcmp ("nohost", p
))
14628 result
= PRAGMA_OACC_CLAUSE_NOHOST
;
14629 else if (!strcmp ("nontemporal", p
))
14630 result
= PRAGMA_OMP_CLAUSE_NONTEMPORAL
;
14631 else if (!strcmp ("notinbranch", p
))
14632 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
14633 else if (!strcmp ("nowait", p
))
14634 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
14635 else if (!strcmp ("num_gangs", p
))
14636 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
14637 else if (!strcmp ("num_tasks", p
))
14638 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
14639 else if (!strcmp ("num_teams", p
))
14640 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
14641 else if (!strcmp ("num_threads", p
))
14642 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
14643 else if (!strcmp ("num_workers", p
))
14644 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
14647 if (!strcmp ("ordered", p
))
14648 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
14649 else if (!strcmp ("order", p
))
14650 result
= PRAGMA_OMP_CLAUSE_ORDER
;
14653 if (!strcmp ("parallel", p
))
14654 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
14655 else if (!strcmp ("present", p
))
14656 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
14657 /* As of OpenACC 2.5, these are now aliases of the non-present_or
14659 else if (!strcmp ("present_or_copy", p
)
14660 || !strcmp ("pcopy", p
))
14661 result
= PRAGMA_OACC_CLAUSE_COPY
;
14662 else if (!strcmp ("present_or_copyin", p
)
14663 || !strcmp ("pcopyin", p
))
14664 result
= PRAGMA_OACC_CLAUSE_COPYIN
;
14665 else if (!strcmp ("present_or_copyout", p
)
14666 || !strcmp ("pcopyout", p
))
14667 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
14668 else if (!strcmp ("present_or_create", p
)
14669 || !strcmp ("pcreate", p
))
14670 result
= PRAGMA_OACC_CLAUSE_CREATE
;
14671 else if (!strcmp ("priority", p
))
14672 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
14673 else if (!strcmp ("private", p
))
14674 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
14675 else if (!strcmp ("proc_bind", p
))
14676 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
14679 if (!strcmp ("reduction", p
))
14680 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
14683 if (!strcmp ("safelen", p
))
14684 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
14685 else if (!strcmp ("schedule", p
))
14686 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
14687 else if (!strcmp ("sections", p
))
14688 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
14689 else if (!strcmp ("self", p
))
14690 result
= PRAGMA_OACC_CLAUSE_SELF
;
14691 else if (!strcmp ("seq", p
))
14692 result
= PRAGMA_OACC_CLAUSE_SEQ
;
14693 else if (!strcmp ("shared", p
))
14694 result
= PRAGMA_OMP_CLAUSE_SHARED
;
14695 else if (!strcmp ("simd", p
))
14696 result
= PRAGMA_OMP_CLAUSE_SIMD
;
14697 else if (!strcmp ("simdlen", p
))
14698 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
14701 if (!strcmp ("task_reduction", p
))
14702 result
= PRAGMA_OMP_CLAUSE_TASK_REDUCTION
;
14703 else if (!strcmp ("taskgroup", p
))
14704 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
14705 else if (!strcmp ("thread_limit", p
))
14706 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
14707 else if (!strcmp ("threads", p
))
14708 result
= PRAGMA_OMP_CLAUSE_THREADS
;
14709 else if (!strcmp ("tile", p
))
14710 result
= PRAGMA_OACC_CLAUSE_TILE
;
14711 else if (!strcmp ("to", p
))
14712 result
= PRAGMA_OMP_CLAUSE_TO
;
14715 if (!strcmp ("uniform", p
))
14716 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
14717 else if (!strcmp ("untied", p
))
14718 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
14719 else if (!strcmp ("use_device", p
))
14720 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
14721 else if (!strcmp ("use_device_addr", p
))
14722 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
;
14723 else if (!strcmp ("use_device_ptr", p
))
14724 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
14727 if (!strcmp ("vector", p
))
14728 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
14729 else if (!strcmp ("vector_length", p
))
14730 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
14733 if (!strcmp ("wait", p
))
14734 result
= PRAGMA_OACC_CLAUSE_WAIT
;
14735 else if (!strcmp ("worker", p
))
14736 result
= PRAGMA_OACC_CLAUSE_WORKER
;
14741 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
14742 c_parser_consume_token (parser
);
14747 /* Validate that a clause of the given type does not already exist. */
14750 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
14753 if (tree c
= omp_find_clause (clauses
, code
))
14754 error_at (OMP_CLAUSE_LOCATION (c
), "too many %qs clauses", name
);
14758 Parse wait clause or wait directive parameters. */
14761 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
14763 vec
<tree
, va_gc
> *args
;
14766 matching_parens parens
;
14767 if (!parens
.require_open (parser
))
14770 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
14771 args_tree
= build_tree_list_vec (args
);
14773 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
14775 tree targ
= TREE_VALUE (t
);
14777 if (targ
!= error_mark_node
)
14779 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
14781 c_parser_error (parser
, "expression must be integral");
14782 targ
= error_mark_node
;
14786 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
14788 OMP_CLAUSE_DECL (c
) = targ
;
14789 OMP_CLAUSE_CHAIN (c
) = list
;
14795 release_tree_vector (args
);
14796 parens
.require_close (parser
);
14800 /* OpenACC 2.0, OpenMP 2.5:
14803 variable-list , identifier
14805 If KIND is nonzero, create the appropriate node and install the
14806 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
14807 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
14809 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
14810 return the list created.
14812 The optional ALLOW_DEREF argument is true if list items can use the deref
14817 tree low_bound
, length
;
14820 omp_dim (tree lb
, tree len
, location_t lo
, bool nc
)
14821 : low_bound (lb
), length (len
), loc (lo
), no_colon (nc
) {}
14825 c_parser_omp_variable_list (c_parser
*parser
,
14826 location_t clause_loc
,
14827 enum omp_clause_code kind
, tree list
,
14828 bool allow_deref
= false)
14830 auto_vec
<omp_dim
> dims
;
14831 bool array_section_p
;
14832 auto_vec
<c_token
> tokens
;
14833 unsigned int tokens_avail
= 0;
14834 c_token
*saved_tokens
= NULL
;
14839 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
14841 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
14842 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
14844 struct c_expr expr
;
14845 if (kind
== OMP_CLAUSE_DEPEND
14846 && c_parser_next_token_is_keyword (parser
,
14847 RID_OMP_ALL_MEMORY
)
14848 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14849 || (c_parser_peek_2nd_token (parser
)->type
14850 == CPP_CLOSE_PAREN
)))
14852 expr
.value
= ridpointers
[RID_OMP_ALL_MEMORY
];
14853 c_parser_consume_token (parser
);
14856 expr
= c_parser_expr_no_commas (parser
, NULL
);
14857 if (expr
.value
!= error_mark_node
)
14859 tree u
= build_omp_clause (clause_loc
, kind
);
14860 OMP_CLAUSE_DECL (u
) = expr
.value
;
14861 OMP_CLAUSE_CHAIN (u
) = list
;
14865 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
14868 c_parser_consume_token (parser
);
14873 tokens
.truncate (0);
14874 unsigned int nesting_depth
= 0;
14877 c_token
*token
= c_parser_peek_token (parser
);
14878 switch (token
->type
)
14881 case CPP_PRAGMA_EOL
:
14883 case CPP_OPEN_BRACE
:
14884 case CPP_OPEN_PAREN
:
14885 case CPP_OPEN_SQUARE
:
14888 case CPP_CLOSE_BRACE
:
14889 case CPP_CLOSE_PAREN
:
14890 case CPP_CLOSE_SQUARE
:
14891 if (nesting_depth
-- == 0)
14895 if (nesting_depth
== 0)
14900 tokens
.safe_push (*token
);
14901 c_parser_consume_token (parser
);
14907 /* Make sure nothing tries to read past the end of the tokens. */
14909 memset (&eof_token
, 0, sizeof (eof_token
));
14910 eof_token
.type
= CPP_EOF
;
14911 tokens
.safe_push (eof_token
);
14912 tokens
.safe_push (eof_token
);
14914 saved_tokens
= parser
->tokens
;
14915 tokens_avail
= parser
->tokens_avail
;
14916 parser
->tokens
= tokens
.address ();
14917 parser
->tokens_avail
= tokens
.length ();
14920 tree t
= NULL_TREE
;
14922 if (c_parser_next_token_is (parser
, CPP_NAME
)
14923 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
14925 t
= lookup_name (c_parser_peek_token (parser
)->value
);
14927 if (t
== NULL_TREE
)
14929 undeclared_variable (c_parser_peek_token (parser
)->location
,
14930 c_parser_peek_token (parser
)->value
);
14931 t
= error_mark_node
;
14934 c_parser_consume_token (parser
);
14936 else if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
14937 && (c_parser_peek_token (parser
)->keyword
== RID_FUNCTION_NAME
14938 || (c_parser_peek_token (parser
)->keyword
14939 == RID_PRETTY_FUNCTION_NAME
)
14940 || (c_parser_peek_token (parser
)->keyword
14941 == RID_C99_FUNCTION_NAME
)))
14942 t
= c_parser_predefined_identifier (parser
).value
;
14946 c_parser_error (parser
, "expected identifier");
14950 if (t
== error_mark_node
)
14952 else if (kind
!= 0)
14956 case OMP_CLAUSE__CACHE_
:
14957 /* The OpenACC cache directive explicitly only allows "array
14958 elements or subarrays". */
14959 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
14961 c_parser_error (parser
, "expected %<[%>");
14962 t
= error_mark_node
;
14966 case OMP_CLAUSE_MAP
:
14967 case OMP_CLAUSE_FROM
:
14968 case OMP_CLAUSE_TO
:
14969 start_component_ref
:
14970 while (c_parser_next_token_is (parser
, CPP_DOT
)
14972 && c_parser_next_token_is (parser
, CPP_DEREF
)))
14974 location_t op_loc
= c_parser_peek_token (parser
)->location
;
14975 location_t arrow_loc
= UNKNOWN_LOCATION
;
14976 if (c_parser_next_token_is (parser
, CPP_DEREF
))
14980 t_expr
.original_code
= ERROR_MARK
;
14981 t_expr
.original_type
= NULL
;
14982 set_c_expr_source_range (&t_expr
, op_loc
, op_loc
);
14983 t_expr
.m_decimal
= 0;
14984 t_expr
= convert_lvalue_to_rvalue (op_loc
, t_expr
,
14986 t
= build_indirect_ref (op_loc
, t_expr
.value
, RO_ARROW
);
14987 arrow_loc
= t_expr
.get_location ();
14989 c_parser_consume_token (parser
);
14990 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14992 c_parser_error (parser
, "expected identifier");
14993 t
= error_mark_node
;
14997 c_token
*comp_tok
= c_parser_peek_token (parser
);
14998 tree ident
= comp_tok
->value
;
14999 location_t comp_loc
= comp_tok
->location
;
15000 c_parser_consume_token (parser
);
15001 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
,
15005 case OMP_CLAUSE_AFFINITY
:
15006 case OMP_CLAUSE_DEPEND
:
15007 case OMP_CLAUSE_REDUCTION
:
15008 case OMP_CLAUSE_IN_REDUCTION
:
15009 case OMP_CLAUSE_TASK_REDUCTION
:
15010 case OMP_CLAUSE_HAS_DEVICE_ADDR
:
15011 array_section_p
= false;
15013 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
15015 location_t loc
= UNKNOWN_LOCATION
;
15016 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
15017 bool no_colon
= false;
15019 c_parser_consume_token (parser
);
15020 if (!c_parser_next_token_is (parser
, CPP_COLON
))
15022 location_t expr_loc
15023 = c_parser_peek_token (parser
)->location
;
15024 c_expr expr
= c_parser_expression (parser
);
15025 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
15027 low_bound
= expr
.value
;
15030 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
15032 length
= integer_one_node
;
15037 /* Look for `:'. */
15038 if (!c_parser_require (parser
, CPP_COLON
,
15041 t
= error_mark_node
;
15044 array_section_p
= true;
15045 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
15047 location_t expr_loc
15048 = c_parser_peek_token (parser
)->location
;
15049 c_expr expr
= c_parser_expression (parser
);
15050 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
15052 length
= expr
.value
;
15055 /* Look for the closing `]'. */
15056 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
15059 t
= error_mark_node
;
15063 dims
.safe_push (omp_dim (low_bound
, length
, loc
, no_colon
));
15066 if (t
!= error_mark_node
)
15068 if ((kind
== OMP_CLAUSE_MAP
15069 || kind
== OMP_CLAUSE_FROM
15070 || kind
== OMP_CLAUSE_TO
)
15071 && !array_section_p
15072 && (c_parser_next_token_is (parser
, CPP_DOT
)
15074 && c_parser_next_token_is (parser
,
15077 for (unsigned i
= 0; i
< dims
.length (); i
++)
15079 gcc_assert (dims
[i
].length
== integer_one_node
);
15080 t
= build_array_ref (dims
[i
].loc
,
15081 t
, dims
[i
].low_bound
);
15083 goto start_component_ref
;
15086 for (unsigned i
= 0; i
< dims
.length (); i
++)
15087 t
= tree_cons (dims
[i
].low_bound
, dims
[i
].length
, t
);
15090 if ((kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
15091 && t
!= error_mark_node
15092 && parser
->tokens_avail
!= 2)
15094 if (array_section_p
)
15096 error_at (c_parser_peek_token (parser
)->location
,
15097 "expected %<)%> or %<,%>");
15098 t
= error_mark_node
;
15102 parser
->tokens
= tokens
.address ();
15103 parser
->tokens_avail
= tokens
.length ();
15105 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
15106 if (t
!= error_mark_node
&& parser
->tokens_avail
!= 2)
15108 error_at (c_parser_peek_token (parser
)->location
,
15109 "expected %<)%> or %<,%>");
15110 t
= error_mark_node
;
15119 if (t
!= error_mark_node
)
15121 tree u
= build_omp_clause (clause_loc
, kind
);
15122 OMP_CLAUSE_DECL (u
) = t
;
15123 OMP_CLAUSE_CHAIN (u
) = list
;
15128 list
= tree_cons (t
, NULL_TREE
, list
);
15130 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
15132 parser
->tokens
= saved_tokens
;
15133 parser
->tokens_avail
= tokens_avail
;
15135 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
15138 c_parser_consume_token (parser
);
15145 /* Similarly, but expect leading and trailing parenthesis. This is a very
15146 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
15147 argument is true if list items can use the deref (->) operator. */
15150 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
15151 tree list
, bool allow_deref
= false)
15153 /* The clauses location. */
15154 location_t loc
= c_parser_peek_token (parser
)->location
;
15156 if (parser
->in_omp_decl_attribute
)
15160 tree u
= build_omp_clause (loc
, kind
);
15161 OMP_CLAUSE_DECL (u
) = parser
->in_omp_decl_attribute
;
15162 OMP_CLAUSE_CHAIN (u
) = list
;
15166 return tree_cons (parser
->in_omp_decl_attribute
, NULL_TREE
, list
);
15169 matching_parens parens
;
15170 if (parens
.require_open (parser
))
15172 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
, allow_deref
);
15173 parens
.skip_until_found_close (parser
);
15179 copy ( variable-list )
15180 copyin ( variable-list )
15181 copyout ( variable-list )
15182 create ( variable-list )
15183 delete ( variable-list )
15184 present ( variable-list )
15187 no_create ( variable-list )
15188 attach ( variable-list )
15189 detach ( variable-list ) */
15192 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
15195 enum gomp_map_kind kind
;
15198 case PRAGMA_OACC_CLAUSE_ATTACH
:
15199 kind
= GOMP_MAP_ATTACH
;
15201 case PRAGMA_OACC_CLAUSE_COPY
:
15202 kind
= GOMP_MAP_TOFROM
;
15204 case PRAGMA_OACC_CLAUSE_COPYIN
:
15205 kind
= GOMP_MAP_TO
;
15207 case PRAGMA_OACC_CLAUSE_COPYOUT
:
15208 kind
= GOMP_MAP_FROM
;
15210 case PRAGMA_OACC_CLAUSE_CREATE
:
15211 kind
= GOMP_MAP_ALLOC
;
15213 case PRAGMA_OACC_CLAUSE_DELETE
:
15214 kind
= GOMP_MAP_RELEASE
;
15216 case PRAGMA_OACC_CLAUSE_DETACH
:
15217 kind
= GOMP_MAP_DETACH
;
15219 case PRAGMA_OACC_CLAUSE_DEVICE
:
15220 kind
= GOMP_MAP_FORCE_TO
;
15222 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
15223 kind
= GOMP_MAP_DEVICE_RESIDENT
;
15225 case PRAGMA_OACC_CLAUSE_LINK
:
15226 kind
= GOMP_MAP_LINK
;
15228 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
15229 kind
= GOMP_MAP_IF_PRESENT
;
15231 case PRAGMA_OACC_CLAUSE_PRESENT
:
15232 kind
= GOMP_MAP_FORCE_PRESENT
;
15234 case PRAGMA_OACC_CLAUSE_SELF
:
15235 /* "The 'host' clause is a synonym for the 'self' clause." */
15236 case PRAGMA_OACC_CLAUSE_HOST
:
15237 kind
= GOMP_MAP_FORCE_FROM
;
15240 gcc_unreachable ();
15243 nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_MAP
, list
, true);
15245 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15246 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
15252 deviceptr ( variable-list ) */
15255 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
15257 location_t loc
= c_parser_peek_token (parser
)->location
;
15260 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
15261 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
15262 variable-list must only allow for pointer variables. */
15263 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
15264 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
15266 tree v
= TREE_PURPOSE (t
);
15268 /* FIXME diagnostics: Ideally we should keep individual
15269 locations for all the variables in the var list to make the
15270 following errors more precise. Perhaps
15271 c_parser_omp_var_list_parens() should construct a list of
15272 locations to go along with the var list. */
15274 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
15275 error_at (loc
, "%qD is not a variable", v
);
15276 else if (TREE_TYPE (v
) == error_mark_node
)
15278 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
15279 error_at (loc
, "%qD is not a pointer variable", v
);
15281 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
15282 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
15283 OMP_CLAUSE_DECL (u
) = v
;
15284 OMP_CLAUSE_CHAIN (u
) = list
;
15291 /* OpenACC 2.0, OpenMP 3.0:
15292 collapse ( constant-expression ) */
15295 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
15297 tree c
, num
= error_mark_node
;
15301 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
15302 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
15304 loc
= c_parser_peek_token (parser
)->location
;
15305 matching_parens parens
;
15306 if (parens
.require_open (parser
))
15308 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
15309 parens
.skip_until_found_close (parser
);
15311 if (num
== error_mark_node
)
15313 mark_exp_read (num
);
15314 num
= c_fully_fold (num
, false, NULL
);
15315 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
15316 || !tree_fits_shwi_p (num
)
15317 || (n
= tree_to_shwi (num
)) <= 0
15321 "collapse argument needs positive constant integer expression");
15324 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
15325 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
15326 OMP_CLAUSE_CHAIN (c
) = list
;
15331 copyin ( variable-list ) */
15334 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
15336 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
15340 copyprivate ( variable-list ) */
15343 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
15345 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
15349 default ( none | shared )
15352 default ( private | firstprivate )
15355 default ( none | present ) */
15358 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
15360 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
15361 location_t loc
= c_parser_peek_token (parser
)->location
;
15364 matching_parens parens
;
15365 if (!parens
.require_open (parser
))
15367 if (c_parser_next_token_is (parser
, CPP_NAME
))
15369 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15374 if (strcmp ("none", p
) != 0)
15376 kind
= OMP_CLAUSE_DEFAULT_NONE
;
15382 if (strcmp ("present", p
) != 0)
15384 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
15388 if (strcmp ("private", p
) != 0)
15390 kind
= OMP_CLAUSE_DEFAULT_PRIVATE
;
15395 if (strcmp ("firstprivate", p
) != 0 || is_oacc
)
15397 kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
15401 if (strcmp ("shared", p
) != 0 || is_oacc
)
15403 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
15410 c_parser_consume_token (parser
);
15416 c_parser_error (parser
, "expected %<none%> or %<present%>");
15418 c_parser_error (parser
, "expected %<none%>, %<shared%>, "
15419 "%<private%> or %<firstprivate%>");
15421 parens
.skip_until_found_close (parser
);
15423 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
15426 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
15427 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
15428 OMP_CLAUSE_CHAIN (c
) = list
;
15429 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
15435 firstprivate ( variable-list ) */
15438 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
15440 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
15444 final ( expression ) */
15447 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
15449 location_t loc
= c_parser_peek_token (parser
)->location
;
15450 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
15452 matching_parens parens
;
15454 if (!parens
.require_open (parser
))
15455 t
= error_mark_node
;
15458 location_t eloc
= c_parser_peek_token (parser
)->location
;
15459 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15460 t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
15461 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
15462 t
= c_fully_fold (t
, false, NULL
);
15463 parens
.skip_until_found_close (parser
);
15466 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
15468 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
15469 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
15470 OMP_CLAUSE_CHAIN (c
) = list
;
15474 c_parser_error (parser
, "expected %<(%>");
15480 indirect [( expression )]
15484 c_parser_omp_clause_indirect (c_parser
*parser
, tree list
)
15486 location_t location
= c_parser_peek_token (parser
)->location
;
15489 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
15491 matching_parens parens
;
15492 if (!parens
.require_open (parser
))
15495 location_t loc
= c_parser_peek_token (parser
)->location
;
15496 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15497 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
15498 t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
);
15499 t
= c_fully_fold (t
, false, NULL
);
15500 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
15501 || TREE_CODE (t
) != INTEGER_CST
)
15503 c_parser_error (parser
, "expected constant logical expression");
15506 parens
.skip_until_found_close (parser
);
15509 t
= integer_one_node
;
15511 check_no_duplicate_clause (list
, OMP_CLAUSE_INDIRECT
, "indirect");
15513 tree c
= build_omp_clause (location
, OMP_CLAUSE_INDIRECT
);
15514 OMP_CLAUSE_INDIRECT_EXPR (c
) = t
;
15515 OMP_CLAUSE_CHAIN (c
) = list
;
15520 /* OpenACC, OpenMP 2.5:
15524 if ( directive-name-modifier : expression )
15526 directive-name-modifier:
15527 parallel | task | taskloop | target data | target | target update
15528 | target enter data | target exit data
15531 directive-name-modifier:
15532 ... | simd | cancel */
15535 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
15537 location_t location
= c_parser_peek_token (parser
)->location
;
15538 enum tree_code if_modifier
= ERROR_MARK
;
15540 matching_parens parens
;
15541 if (!parens
.require_open (parser
))
15544 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
15546 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15548 if (strcmp (p
, "cancel") == 0)
15549 if_modifier
= VOID_CST
;
15550 else if (strcmp (p
, "parallel") == 0)
15551 if_modifier
= OMP_PARALLEL
;
15552 else if (strcmp (p
, "simd") == 0)
15553 if_modifier
= OMP_SIMD
;
15554 else if (strcmp (p
, "task") == 0)
15555 if_modifier
= OMP_TASK
;
15556 else if (strcmp (p
, "taskloop") == 0)
15557 if_modifier
= OMP_TASKLOOP
;
15558 else if (strcmp (p
, "target") == 0)
15560 if_modifier
= OMP_TARGET
;
15561 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
15563 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
15564 if (strcmp ("data", p
) == 0)
15565 if_modifier
= OMP_TARGET_DATA
;
15566 else if (strcmp ("update", p
) == 0)
15567 if_modifier
= OMP_TARGET_UPDATE
;
15568 else if (strcmp ("enter", p
) == 0)
15569 if_modifier
= OMP_TARGET_ENTER_DATA
;
15570 else if (strcmp ("exit", p
) == 0)
15571 if_modifier
= OMP_TARGET_EXIT_DATA
;
15572 if (if_modifier
!= OMP_TARGET
)
15575 c_parser_consume_token (parser
);
15579 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
15580 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
15582 if_modifier
= ERROR_MARK
;
15584 if (if_modifier
== OMP_TARGET_ENTER_DATA
15585 || if_modifier
== OMP_TARGET_EXIT_DATA
)
15587 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
15589 p
= IDENTIFIER_POINTER
15590 (c_parser_peek_2nd_token (parser
)->value
);
15591 if (strcmp ("data", p
) == 0)
15595 c_parser_consume_token (parser
);
15599 = c_parser_peek_2nd_token (parser
)->location
;
15600 error_at (loc
, "expected %<data%>");
15601 if_modifier
= ERROR_MARK
;
15606 if (if_modifier
!= ERROR_MARK
)
15608 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
15610 c_parser_consume_token (parser
);
15611 c_parser_consume_token (parser
);
15617 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
15618 error_at (loc
, "expected %<:%>");
15620 if_modifier
= ERROR_MARK
;
15625 location_t loc
= c_parser_peek_token (parser
)->location
;
15626 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15627 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
15628 tree t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
), c
;
15629 t
= c_fully_fold (t
, false, NULL
);
15630 parens
.skip_until_found_close (parser
);
15632 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
15633 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
15635 if (if_modifier
!= ERROR_MARK
15636 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
15638 const char *p
= NULL
;
15639 switch (if_modifier
)
15641 case VOID_CST
: p
= "cancel"; break;
15642 case OMP_PARALLEL
: p
= "parallel"; break;
15643 case OMP_SIMD
: p
= "simd"; break;
15644 case OMP_TASK
: p
= "task"; break;
15645 case OMP_TASKLOOP
: p
= "taskloop"; break;
15646 case OMP_TARGET_DATA
: p
= "target data"; break;
15647 case OMP_TARGET
: p
= "target"; break;
15648 case OMP_TARGET_UPDATE
: p
= "target update"; break;
15649 case OMP_TARGET_ENTER_DATA
: p
= "target enter data"; break;
15650 case OMP_TARGET_EXIT_DATA
: p
= "target exit data"; break;
15651 default: gcc_unreachable ();
15653 error_at (location
, "too many %<if%> clauses with %qs modifier",
15657 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
15660 error_at (location
, "too many %<if%> clauses");
15662 error_at (location
, "too many %<if%> clauses without modifier");
15665 else if (if_modifier
== ERROR_MARK
15666 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
15668 error_at (location
, "if any %<if%> clause has modifier, then all "
15669 "%<if%> clauses have to use modifier");
15674 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
15675 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
15676 OMP_CLAUSE_IF_EXPR (c
) = t
;
15677 OMP_CLAUSE_CHAIN (c
) = list
;
15682 lastprivate ( variable-list )
15685 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
15688 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
15690 /* The clauses location. */
15691 location_t loc
= c_parser_peek_token (parser
)->location
;
15693 if (c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
15695 bool conditional
= false;
15696 if (c_parser_next_token_is (parser
, CPP_NAME
)
15697 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
15700 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15701 if (strcmp (p
, "conditional") == 0)
15703 conditional
= true;
15704 c_parser_consume_token (parser
);
15705 c_parser_consume_token (parser
);
15708 tree nlist
= c_parser_omp_variable_list (parser
, loc
,
15709 OMP_CLAUSE_LASTPRIVATE
, list
);
15710 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
15712 for (tree c
= nlist
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15713 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 1;
15723 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
15727 /* FIXME: Should we allow duplicates? */
15728 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
15730 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
15731 OMP_CLAUSE_MERGEABLE
);
15732 OMP_CLAUSE_CHAIN (c
) = list
;
15741 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
15744 location_t loc
= c_parser_peek_token (parser
)->location
;
15746 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
15748 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
15749 OMP_CLAUSE_CHAIN (c
) = list
;
15754 num_threads ( expression ) */
15757 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
15759 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
15760 matching_parens parens
;
15761 if (parens
.require_open (parser
))
15763 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15764 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15765 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15766 tree c
, t
= expr
.value
;
15767 t
= c_fully_fold (t
, false, NULL
);
15769 parens
.skip_until_found_close (parser
);
15771 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15773 c_parser_error (parser
, "expected integer expression");
15777 /* Attempt to statically determine when the number isn't positive. */
15778 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
15779 build_int_cst (TREE_TYPE (t
), 0));
15780 protected_set_expr_location (c
, expr_loc
);
15781 if (c
== boolean_true_node
)
15783 warning_at (expr_loc
, 0,
15784 "%<num_threads%> value must be positive");
15785 t
= integer_one_node
;
15788 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
15790 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
15791 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
15792 OMP_CLAUSE_CHAIN (c
) = list
;
15800 num_tasks ( expression )
15803 num_tasks ( strict : expression ) */
15806 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
15808 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
15809 matching_parens parens
;
15810 if (parens
.require_open (parser
))
15812 bool strict
= false;
15813 if (c_parser_next_token_is (parser
, CPP_NAME
)
15814 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
15815 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
15819 c_parser_consume_token (parser
);
15820 c_parser_consume_token (parser
);
15823 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15824 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15825 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15826 tree c
, t
= expr
.value
;
15827 t
= c_fully_fold (t
, false, NULL
);
15829 parens
.skip_until_found_close (parser
);
15831 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15833 c_parser_error (parser
, "expected integer expression");
15837 /* Attempt to statically determine when the number isn't positive. */
15838 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
15839 build_int_cst (TREE_TYPE (t
), 0));
15840 if (CAN_HAVE_LOCATION_P (c
))
15841 SET_EXPR_LOCATION (c
, expr_loc
);
15842 if (c
== boolean_true_node
)
15844 warning_at (expr_loc
, 0, "%<num_tasks%> value must be positive");
15845 t
= integer_one_node
;
15848 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
15850 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
15851 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
15852 OMP_CLAUSE_NUM_TASKS_STRICT (c
) = strict
;
15853 OMP_CLAUSE_CHAIN (c
) = list
;
15861 grainsize ( expression )
15864 grainsize ( strict : expression ) */
15867 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
15869 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
15870 matching_parens parens
;
15871 if (parens
.require_open (parser
))
15873 bool strict
= false;
15874 if (c_parser_next_token_is (parser
, CPP_NAME
)
15875 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
15876 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
15880 c_parser_consume_token (parser
);
15881 c_parser_consume_token (parser
);
15884 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15885 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15886 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15887 tree c
, t
= expr
.value
;
15888 t
= c_fully_fold (t
, false, NULL
);
15890 parens
.skip_until_found_close (parser
);
15892 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15894 c_parser_error (parser
, "expected integer expression");
15898 /* Attempt to statically determine when the number isn't positive. */
15899 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
15900 build_int_cst (TREE_TYPE (t
), 0));
15901 if (CAN_HAVE_LOCATION_P (c
))
15902 SET_EXPR_LOCATION (c
, expr_loc
);
15903 if (c
== boolean_true_node
)
15905 warning_at (expr_loc
, 0, "%<grainsize%> value must be positive");
15906 t
= integer_one_node
;
15909 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
15911 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
15912 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
15913 OMP_CLAUSE_GRAINSIZE_STRICT (c
) = strict
;
15914 OMP_CLAUSE_CHAIN (c
) = list
;
15922 priority ( expression ) */
15925 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
15927 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
15928 matching_parens parens
;
15929 if (parens
.require_open (parser
))
15931 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15932 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15933 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15934 tree c
, t
= expr
.value
;
15935 t
= c_fully_fold (t
, false, NULL
);
15937 parens
.skip_until_found_close (parser
);
15939 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15941 c_parser_error (parser
, "expected integer expression");
15945 /* Attempt to statically determine when the number isn't
15947 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
15948 build_int_cst (TREE_TYPE (t
), 0));
15949 if (CAN_HAVE_LOCATION_P (c
))
15950 SET_EXPR_LOCATION (c
, expr_loc
);
15951 if (c
== boolean_true_node
)
15953 warning_at (expr_loc
, 0, "%<priority%> value must be non-negative");
15954 t
= integer_one_node
;
15957 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
15959 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
15960 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
15961 OMP_CLAUSE_CHAIN (c
) = list
;
15969 hint ( expression ) */
15972 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
15974 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
15975 matching_parens parens
;
15976 if (parens
.require_open (parser
))
15978 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15979 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15980 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15981 tree c
, t
= expr
.value
;
15982 t
= c_fully_fold (t
, false, NULL
);
15983 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
15984 || TREE_CODE (t
) != INTEGER_CST
15985 || tree_int_cst_sgn (t
) == -1)
15987 c_parser_error (parser
, "expected constant integer expression "
15988 "with valid sync-hint value");
15991 parens
.skip_until_found_close (parser
);
15992 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
15994 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
15995 OMP_CLAUSE_HINT_EXPR (c
) = t
;
15996 OMP_CLAUSE_CHAIN (c
) = list
;
16004 filter ( integer-expression ) */
16007 c_parser_omp_clause_filter (c_parser
*parser
, tree list
)
16009 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
16010 matching_parens parens
;
16011 if (parens
.require_open (parser
))
16013 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16014 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16015 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16016 tree c
, t
= expr
.value
;
16017 t
= c_fully_fold (t
, false, NULL
);
16018 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16020 c_parser_error (parser
, "expected integer expression");
16023 parens
.skip_until_found_close (parser
);
16024 check_no_duplicate_clause (list
, OMP_CLAUSE_FILTER
, "filter");
16026 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_FILTER
);
16027 OMP_CLAUSE_FILTER_EXPR (c
) = t
;
16028 OMP_CLAUSE_CHAIN (c
) = list
;
16036 defaultmap ( tofrom : scalar )
16039 defaultmap ( implicit-behavior [ : variable-category ] ) */
16042 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
16044 location_t loc
= c_parser_peek_token (parser
)->location
;
16047 enum omp_clause_defaultmap_kind behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
16048 enum omp_clause_defaultmap_kind category
16049 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
16051 matching_parens parens
;
16052 if (!parens
.require_open (parser
))
16054 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
16056 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
16059 c_parser_error (parser
, "expected %<alloc%>, %<to%>, %<from%>, "
16060 "%<tofrom%>, %<firstprivate%>, %<none%> "
16065 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16070 if (strcmp ("alloc", p
) == 0)
16071 behavior
= OMP_CLAUSE_DEFAULTMAP_ALLOC
;
16073 goto invalid_behavior
;
16077 if (strcmp ("default", p
) == 0)
16078 behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
16080 goto invalid_behavior
;
16084 if (strcmp ("firstprivate", p
) == 0)
16085 behavior
= OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
16086 else if (strcmp ("from", p
) == 0)
16087 behavior
= OMP_CLAUSE_DEFAULTMAP_FROM
;
16089 goto invalid_behavior
;
16093 if (strcmp ("none", p
) == 0)
16094 behavior
= OMP_CLAUSE_DEFAULTMAP_NONE
;
16096 goto invalid_behavior
;
16100 if (strcmp ("present", p
) == 0)
16101 behavior
= OMP_CLAUSE_DEFAULTMAP_PRESENT
;
16103 goto invalid_behavior
;
16107 if (strcmp ("tofrom", p
) == 0)
16108 behavior
= OMP_CLAUSE_DEFAULTMAP_TOFROM
;
16109 else if (strcmp ("to", p
) == 0)
16110 behavior
= OMP_CLAUSE_DEFAULTMAP_TO
;
16112 goto invalid_behavior
;
16116 goto invalid_behavior
;
16118 c_parser_consume_token (parser
);
16120 if (!c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
16122 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16124 if (!c_parser_next_token_is (parser
, CPP_NAME
))
16127 c_parser_error (parser
, "expected %<scalar%>, %<aggregate%>, "
16128 "%<pointer%> or %<all%>");
16131 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16135 if (strcmp ("aggregate", p
) == 0)
16136 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
;
16137 else if (strcmp ("all", p
) == 0)
16138 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
;
16140 goto invalid_category
;
16144 if (strcmp ("pointer", p
) == 0)
16145 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
;
16147 goto invalid_category
;
16151 if (strcmp ("scalar", p
) == 0)
16152 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
;
16154 goto invalid_category
;
16158 goto invalid_category
;
16161 c_parser_consume_token (parser
);
16163 parens
.skip_until_found_close (parser
);
16165 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
16166 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEFAULTMAP
16167 && (category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16168 || category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16169 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
) == category
16170 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
16171 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
16172 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
16173 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
)))
16175 enum omp_clause_defaultmap_kind cat
= category
;
16176 location_t loc
= OMP_CLAUSE_LOCATION (c
);
16177 if (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16178 || (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16179 && (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
16180 != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)))
16181 cat
= OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
);
16185 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
16188 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
:
16191 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
16194 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
16197 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
16201 gcc_unreachable ();
16204 error_at (loc
, "too many %<defaultmap%> clauses with %qs category",
16207 error_at (loc
, "too many %<defaultmap%> clauses with unspecified "
16212 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
16213 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c
, behavior
, category
);
16214 OMP_CLAUSE_CHAIN (c
) = list
;
16218 parens
.skip_until_found_close (parser
);
16223 use_device ( variable-list )
16226 use_device_ptr ( variable-list ) */
16229 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
16231 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
16236 use_device_addr ( variable-list ) */
16239 c_parser_omp_clause_use_device_addr (c_parser
*parser
, tree list
)
16241 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_ADDR
,
16246 has_device_addr ( variable-list ) */
16249 c_parser_omp_clause_has_device_addr (c_parser
*parser
, tree list
)
16251 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_HAS_DEVICE_ADDR
,
16256 is_device_ptr ( variable-list ) */
16259 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
16261 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
16265 num_gangs ( expression )
16266 num_workers ( expression )
16267 vector_length ( expression ) */
16270 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
16273 location_t loc
= c_parser_peek_token (parser
)->location
;
16275 matching_parens parens
;
16276 if (!parens
.require_open (parser
))
16279 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16280 c_expr expr
= c_parser_expression (parser
);
16281 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16282 tree c
, t
= expr
.value
;
16283 t
= c_fully_fold (t
, false, NULL
);
16285 parens
.skip_until_found_close (parser
);
16287 if (t
== error_mark_node
)
16289 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16291 error_at (expr_loc
, "%qs expression must be integral",
16292 omp_clause_code_name
[code
]);
16296 /* Attempt to statically determine when the number isn't positive. */
16297 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
16298 build_int_cst (TREE_TYPE (t
), 0));
16299 protected_set_expr_location (c
, expr_loc
);
16300 if (c
== boolean_true_node
)
16302 warning_at (expr_loc
, 0,
16303 "%qs value must be positive",
16304 omp_clause_code_name
[code
]);
16305 t
= integer_one_node
;
16308 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
16310 c
= build_omp_clause (loc
, code
);
16311 OMP_CLAUSE_OPERAND (c
, 0) = t
;
16312 OMP_CLAUSE_CHAIN (c
) = list
;
16318 gang [( gang-arg-list )]
16319 worker [( [num:] int-expr )]
16320 vector [( [length:] int-expr )]
16322 where gang-arg is one of:
16327 and size-expr may be:
16334 c_parser_oacc_shape_clause (c_parser
*parser
, location_t loc
,
16335 omp_clause_code kind
,
16336 const char *str
, tree list
)
16338 const char *id
= "num";
16339 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
16341 if (kind
== OMP_CLAUSE_VECTOR
)
16344 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
16346 c_parser_consume_token (parser
);
16350 c_token
*next
= c_parser_peek_token (parser
);
16353 /* Gang static argument. */
16354 if (kind
== OMP_CLAUSE_GANG
16355 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
16357 c_parser_consume_token (parser
);
16359 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16360 goto cleanup_error
;
16363 if (ops
[idx
] != NULL_TREE
)
16365 c_parser_error (parser
, "too many %<static%> arguments");
16366 goto cleanup_error
;
16369 /* Check for the '*' argument. */
16370 if (c_parser_next_token_is (parser
, CPP_MULT
)
16371 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
16372 || c_parser_peek_2nd_token (parser
)->type
16373 == CPP_CLOSE_PAREN
))
16375 c_parser_consume_token (parser
);
16376 ops
[idx
] = integer_minus_one_node
;
16378 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16380 c_parser_consume_token (parser
);
16387 /* Worker num: argument and vector length: arguments. */
16388 else if (c_parser_next_token_is (parser
, CPP_NAME
)
16389 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
16390 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16392 c_parser_consume_token (parser
); /* id */
16393 c_parser_consume_token (parser
); /* ':' */
16396 /* Now collect the actual argument. */
16397 if (ops
[idx
] != NULL_TREE
)
16399 c_parser_error (parser
, "unexpected argument");
16400 goto cleanup_error
;
16403 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16404 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
16405 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
16406 tree expr
= cexpr
.value
;
16407 if (expr
== error_mark_node
)
16408 goto cleanup_error
;
16410 expr
= c_fully_fold (expr
, false, NULL
);
16412 /* Attempt to statically determine when the number isn't a
16413 positive integer. */
16415 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
16417 c_parser_error (parser
, "expected integer expression");
16421 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
16422 build_int_cst (TREE_TYPE (expr
), 0));
16423 if (c
== boolean_true_node
)
16425 warning_at (loc
, 0,
16426 "%qs value must be positive", str
);
16427 expr
= integer_one_node
;
16432 if (kind
== OMP_CLAUSE_GANG
16433 && c_parser_next_token_is (parser
, CPP_COMMA
))
16435 c_parser_consume_token (parser
);
16442 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
16443 goto cleanup_error
;
16446 check_no_duplicate_clause (list
, kind
, str
);
16448 c
= build_omp_clause (loc
, kind
);
16451 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
16453 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
16454 OMP_CLAUSE_CHAIN (c
) = list
;
16459 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
16471 c_parser_oacc_simple_clause (location_t loc
, enum omp_clause_code code
,
16474 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
16476 tree c
= build_omp_clause (loc
, code
);
16477 OMP_CLAUSE_CHAIN (c
) = list
;
16483 async [( int-expr )] */
16486 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
16489 location_t loc
= c_parser_peek_token (parser
)->location
;
16491 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
16493 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
16495 c_parser_consume_token (parser
);
16497 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
16498 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16499 c_parser_error (parser
, "expected integer expression");
16500 else if (t
== error_mark_node
16501 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
16505 t
= c_fully_fold (t
, false, NULL
);
16507 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
16509 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
16510 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
16511 OMP_CLAUSE_CHAIN (c
) = list
;
16518 tile ( size-expr-list ) */
16521 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
16523 tree c
, expr
= error_mark_node
;
16525 tree tile
= NULL_TREE
;
16527 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
16528 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
16530 loc
= c_parser_peek_token (parser
)->location
;
16531 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
16536 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
16539 if (c_parser_next_token_is (parser
, CPP_MULT
)
16540 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
16541 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
16543 c_parser_consume_token (parser
);
16544 expr
= integer_zero_node
;
16548 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16549 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
16550 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
16551 expr
= cexpr
.value
;
16553 if (expr
== error_mark_node
)
16555 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
16560 expr
= c_fully_fold (expr
, false, NULL
);
16562 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
16563 || !tree_fits_shwi_p (expr
)
16564 || tree_to_shwi (expr
) <= 0)
16566 error_at (expr_loc
, "%<tile%> argument needs positive"
16567 " integral constant");
16568 expr
= integer_zero_node
;
16572 tile
= tree_cons (NULL_TREE
, expr
, tile
);
16574 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
16576 /* Consume the trailing ')'. */
16577 c_parser_consume_token (parser
);
16579 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
16580 tile
= nreverse (tile
);
16581 OMP_CLAUSE_TILE_LIST (c
) = tile
;
16582 OMP_CLAUSE_CHAIN (c
) = list
;
16587 wait [( int-expr-list )] */
16590 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
16592 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16594 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
16595 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
16598 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
16600 OMP_CLAUSE_DECL (c
) = build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
16601 OMP_CLAUSE_CHAIN (c
) = list
;
16609 self [( expression )] */
16612 c_parser_oacc_compute_clause_self (c_parser
*parser
, tree list
)
16615 location_t location
= c_parser_peek_token (parser
)->location
;
16616 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
16618 matching_parens parens
;
16619 parens
.consume_open (parser
);
16621 location_t loc
= c_parser_peek_token (parser
)->location
;
16622 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16623 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
16624 t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
);
16625 t
= c_fully_fold (t
, false, NULL
);
16626 parens
.skip_until_found_close (parser
);
16629 t
= truthvalue_true_node
;
16631 for (tree c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
16632 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SELF
)
16634 error_at (location
, "too many %<self%> clauses");
16638 tree c
= build_omp_clause (location
, OMP_CLAUSE_SELF
);
16639 OMP_CLAUSE_SELF_EXPR (c
) = t
;
16640 OMP_CLAUSE_CHAIN (c
) = list
;
16645 order ( concurrent )
16648 order ( order-modifier : concurrent )
16655 c_parser_omp_clause_order (c_parser
*parser
, tree list
)
16657 location_t loc
= c_parser_peek_token (parser
)->location
;
16660 bool unconstrained
= false;
16661 bool reproducible
= false;
16663 matching_parens parens
;
16664 if (!parens
.require_open (parser
))
16666 if (c_parser_next_token_is (parser
, CPP_NAME
)
16667 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16669 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16670 if (strcmp (p
, "unconstrained") == 0)
16671 unconstrained
= true;
16672 else if (strcmp (p
, "reproducible") == 0)
16673 reproducible
= true;
16676 c_parser_error (parser
, "expected %<reproducible%> or "
16677 "%<unconstrained%>");
16680 c_parser_consume_token (parser
);
16681 c_parser_consume_token (parser
);
16683 if (!c_parser_next_token_is (parser
, CPP_NAME
))
16685 c_parser_error (parser
, "expected %<concurrent%>");
16688 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16689 if (strcmp (p
, "concurrent") != 0)
16691 c_parser_error (parser
, "expected %<concurrent%>");
16694 c_parser_consume_token (parser
);
16695 parens
.skip_until_found_close (parser
);
16696 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDER
, "order");
16697 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDER
);
16698 OMP_CLAUSE_ORDER_UNCONSTRAINED (c
) = unconstrained
;
16699 OMP_CLAUSE_ORDER_REPRODUCIBLE (c
) = reproducible
;
16700 OMP_CLAUSE_CHAIN (c
) = list
;
16704 parens
.skip_until_found_close (parser
);
16710 bind ( teams | parallel | thread ) */
16713 c_parser_omp_clause_bind (c_parser
*parser
, tree list
)
16715 location_t loc
= c_parser_peek_token (parser
)->location
;
16718 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
16720 matching_parens parens
;
16721 if (!parens
.require_open (parser
))
16723 if (!c_parser_next_token_is (parser
, CPP_NAME
))
16726 c_parser_error (parser
,
16727 "expected %<teams%>, %<parallel%> or %<thread%>");
16728 parens
.skip_until_found_close (parser
);
16731 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16732 if (strcmp (p
, "teams") == 0)
16733 kind
= OMP_CLAUSE_BIND_TEAMS
;
16734 else if (strcmp (p
, "parallel") == 0)
16735 kind
= OMP_CLAUSE_BIND_PARALLEL
;
16736 else if (strcmp (p
, "thread") != 0)
16738 c_parser_consume_token (parser
);
16739 parens
.skip_until_found_close (parser
);
16740 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
16741 c
= build_omp_clause (loc
, OMP_CLAUSE_BIND
);
16742 OMP_CLAUSE_BIND_KIND (c
) = kind
;
16743 OMP_CLAUSE_CHAIN (c
) = list
;
16752 ordered ( constant-expression ) */
16755 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
16757 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
16759 tree c
, num
= NULL_TREE
;
16761 location_t loc
= c_parser_peek_token (parser
)->location
;
16762 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
16764 matching_parens parens
;
16765 parens
.consume_open (parser
);
16766 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
16767 parens
.skip_until_found_close (parser
);
16769 if (num
== error_mark_node
)
16773 mark_exp_read (num
);
16774 num
= c_fully_fold (num
, false, NULL
);
16775 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
16776 || !tree_fits_shwi_p (num
)
16777 || (n
= tree_to_shwi (num
)) <= 0
16780 error_at (loc
, "ordered argument needs positive "
16781 "constant integer expression");
16785 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
16786 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
16787 OMP_CLAUSE_CHAIN (c
) = list
;
16792 private ( variable-list ) */
16795 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
16797 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
16801 reduction ( reduction-operator : variable-list )
16803 reduction-operator:
16804 One of: + * - & ^ | && ||
16808 reduction-operator:
16809 One of: + * - & ^ | && || max min
16813 reduction-operator:
16814 One of: + * - & ^ | && ||
16818 reduction ( reduction-modifier, reduction-operator : variable-list )
16819 in_reduction ( reduction-operator : variable-list )
16820 task_reduction ( reduction-operator : variable-list ) */
16823 c_parser_omp_clause_reduction (c_parser
*parser
, enum omp_clause_code kind
,
16824 bool is_omp
, tree list
)
16826 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16827 matching_parens parens
;
16828 if (parens
.require_open (parser
))
16831 bool inscan
= false;
16832 enum tree_code code
= ERROR_MARK
;
16833 tree reduc_id
= NULL_TREE
;
16835 if (kind
== OMP_CLAUSE_REDUCTION
&& is_omp
)
16837 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
16838 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
16840 c_parser_consume_token (parser
);
16841 c_parser_consume_token (parser
);
16843 else if (c_parser_next_token_is (parser
, CPP_NAME
)
16844 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
16847 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16848 if (strcmp (p
, "task") == 0)
16850 else if (strcmp (p
, "inscan") == 0)
16852 if (task
|| inscan
)
16854 c_parser_consume_token (parser
);
16855 c_parser_consume_token (parser
);
16860 switch (c_parser_peek_token (parser
)->type
)
16872 code
= BIT_AND_EXPR
;
16875 code
= BIT_XOR_EXPR
;
16878 code
= BIT_IOR_EXPR
;
16881 code
= TRUTH_ANDIF_EXPR
;
16884 code
= TRUTH_ORIF_EXPR
;
16889 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16890 if (strcmp (p
, "min") == 0)
16895 if (strcmp (p
, "max") == 0)
16900 reduc_id
= c_parser_peek_token (parser
)->value
;
16904 c_parser_error (parser
,
16905 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
16906 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
16907 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
16910 c_parser_consume_token (parser
);
16911 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
16912 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16916 nl
= c_parser_omp_variable_list (parser
, clause_loc
, kind
, list
);
16917 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16919 tree d
= OMP_CLAUSE_DECL (c
), type
;
16920 if (TREE_CODE (d
) != TREE_LIST
)
16921 type
= TREE_TYPE (d
);
16926 for (t
= d
; TREE_CODE (t
) == TREE_LIST
; t
= TREE_CHAIN (t
))
16928 type
= TREE_TYPE (t
);
16931 if (TREE_CODE (type
) != POINTER_TYPE
16932 && TREE_CODE (type
) != ARRAY_TYPE
)
16934 type
= TREE_TYPE (type
);
16938 while (TREE_CODE (type
) == ARRAY_TYPE
)
16939 type
= TREE_TYPE (type
);
16940 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
16942 OMP_CLAUSE_REDUCTION_TASK (c
) = 1;
16944 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 1;
16945 if (code
== ERROR_MARK
16946 || !(INTEGRAL_TYPE_P (type
)
16947 || SCALAR_FLOAT_TYPE_P (type
)
16948 || TREE_CODE (type
) == COMPLEX_TYPE
))
16949 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
16950 = c_omp_reduction_lookup (reduc_id
,
16951 TYPE_MAIN_VARIANT (type
));
16956 parens
.skip_until_found_close (parser
);
16962 schedule ( schedule-kind )
16963 schedule ( schedule-kind , expression )
16966 static | dynamic | guided | runtime | auto
16969 schedule ( schedule-modifier : schedule-kind )
16970 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
16978 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
16981 location_t loc
= c_parser_peek_token (parser
)->location
;
16982 int modifiers
= 0, nmodifiers
= 0;
16984 matching_parens parens
;
16985 if (!parens
.require_open (parser
))
16988 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
16990 location_t comma
= UNKNOWN_LOCATION
;
16991 while (c_parser_next_token_is (parser
, CPP_NAME
))
16993 tree kind
= c_parser_peek_token (parser
)->value
;
16994 const char *p
= IDENTIFIER_POINTER (kind
);
16995 if (strcmp ("simd", p
) == 0)
16996 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
16997 else if (strcmp ("monotonic", p
) == 0)
16998 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
16999 else if (strcmp ("nonmonotonic", p
) == 0)
17000 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
17003 comma
= UNKNOWN_LOCATION
;
17004 c_parser_consume_token (parser
);
17005 if (nmodifiers
++ == 0
17006 && c_parser_next_token_is (parser
, CPP_COMMA
))
17008 comma
= c_parser_peek_token (parser
)->location
;
17009 c_parser_consume_token (parser
);
17013 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
17017 if (comma
!= UNKNOWN_LOCATION
)
17018 error_at (comma
, "expected %<:%>");
17020 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
17021 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
17022 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
17023 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
17025 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
17030 if (c_parser_next_token_is (parser
, CPP_NAME
))
17032 tree kind
= c_parser_peek_token (parser
)->value
;
17033 const char *p
= IDENTIFIER_POINTER (kind
);
17038 if (strcmp ("dynamic", p
) != 0)
17040 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
17044 if (strcmp ("guided", p
) != 0)
17046 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
17050 if (strcmp ("runtime", p
) != 0)
17052 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
17059 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
17060 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
17061 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
17062 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
17066 c_parser_consume_token (parser
);
17067 if (c_parser_next_token_is (parser
, CPP_COMMA
))
17070 c_parser_consume_token (parser
);
17072 here
= c_parser_peek_token (parser
)->location
;
17073 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17074 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
17076 t
= c_fully_fold (t
, false, NULL
);
17078 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
17079 error_at (here
, "schedule %<runtime%> does not take "
17080 "a %<chunk_size%> parameter");
17081 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
17083 "schedule %<auto%> does not take "
17084 "a %<chunk_size%> parameter");
17085 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
17086 || TREE_CODE (TREE_TYPE (t
)) == BITINT_TYPE
)
17088 /* Attempt to statically determine when the number isn't
17090 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
17091 build_int_cst (TREE_TYPE (t
), 0));
17092 protected_set_expr_location (s
, loc
);
17093 if (s
== boolean_true_node
)
17095 warning_at (loc
, 0,
17096 "chunk size value must be positive");
17097 t
= integer_one_node
;
17099 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
17102 c_parser_error (parser
, "expected integer expression");
17104 parens
.skip_until_found_close (parser
);
17107 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
17108 "expected %<,%> or %<)%>");
17110 OMP_CLAUSE_SCHEDULE_KIND (c
)
17111 = (enum omp_clause_schedule_kind
)
17112 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
17114 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
17115 OMP_CLAUSE_CHAIN (c
) = list
;
17119 c_parser_error (parser
, "invalid schedule kind");
17120 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
17125 shared ( variable-list ) */
17128 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
17130 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
17137 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
17141 /* FIXME: Should we allow duplicates? */
17142 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
17144 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
17145 OMP_CLAUSE_UNTIED
);
17146 OMP_CLAUSE_CHAIN (c
) = list
;
17156 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
17157 enum omp_clause_code code
, tree list
)
17159 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
17161 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
17162 OMP_CLAUSE_CHAIN (c
) = list
;
17174 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
17175 enum omp_clause_code code
, tree list
)
17177 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
17178 OMP_CLAUSE_CHAIN (c
) = list
;
17187 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
17189 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
17190 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
17191 OMP_CLAUSE_NOGROUP
);
17192 OMP_CLAUSE_CHAIN (c
) = list
;
17201 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
17202 enum omp_clause_code code
, tree list
)
17204 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
17205 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
17206 OMP_CLAUSE_CHAIN (c
) = list
;
17211 num_teams ( expression )
17214 num_teams ( expression : expression ) */
17217 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
17219 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
17220 matching_parens parens
;
17221 if (parens
.require_open (parser
))
17223 location_t upper_loc
= c_parser_peek_token (parser
)->location
;
17224 location_t lower_loc
= UNKNOWN_LOCATION
;
17225 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17226 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
17227 tree c
, upper
= expr
.value
, lower
= NULL_TREE
;
17228 upper
= c_fully_fold (upper
, false, NULL
);
17230 if (c_parser_next_token_is (parser
, CPP_COLON
))
17232 c_parser_consume_token (parser
);
17233 lower_loc
= upper_loc
;
17235 upper_loc
= c_parser_peek_token (parser
)->location
;
17236 expr
= c_parser_expr_no_commas (parser
, NULL
);
17237 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
17238 upper
= expr
.value
;
17239 upper
= c_fully_fold (upper
, false, NULL
);
17242 parens
.skip_until_found_close (parser
);
17244 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper
))
17245 || (lower
&& !INTEGRAL_TYPE_P (TREE_TYPE (lower
))))
17247 c_parser_error (parser
, "expected integer expression");
17251 /* Attempt to statically determine when the number isn't positive. */
17252 c
= fold_build2_loc (upper_loc
, LE_EXPR
, boolean_type_node
, upper
,
17253 build_int_cst (TREE_TYPE (upper
), 0));
17254 protected_set_expr_location (c
, upper_loc
);
17255 if (c
== boolean_true_node
)
17257 warning_at (upper_loc
, 0, "%<num_teams%> value must be positive");
17258 upper
= integer_one_node
;
17262 c
= fold_build2_loc (lower_loc
, LE_EXPR
, boolean_type_node
, lower
,
17263 build_int_cst (TREE_TYPE (lower
), 0));
17264 protected_set_expr_location (c
, lower_loc
);
17265 if (c
== boolean_true_node
)
17267 warning_at (lower_loc
, 0, "%<num_teams%> value must be positive");
17270 else if (TREE_CODE (lower
) == INTEGER_CST
17271 && TREE_CODE (upper
) == INTEGER_CST
17272 && tree_int_cst_lt (upper
, lower
))
17274 warning_at (lower_loc
, 0, "%<num_teams%> lower bound %qE bigger "
17275 "than upper bound %qE", lower
, upper
);
17280 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
17282 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
17283 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c
) = upper
;
17284 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
) = lower
;
17285 OMP_CLAUSE_CHAIN (c
) = list
;
17293 thread_limit ( expression ) */
17296 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
17298 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
17299 matching_parens parens
;
17300 if (parens
.require_open (parser
))
17302 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17303 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17304 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17305 tree c
, t
= expr
.value
;
17306 t
= c_fully_fold (t
, false, NULL
);
17308 parens
.skip_until_found_close (parser
);
17310 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
17312 c_parser_error (parser
, "expected integer expression");
17316 /* Attempt to statically determine when the number isn't positive. */
17317 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
17318 build_int_cst (TREE_TYPE (t
), 0));
17319 protected_set_expr_location (c
, expr_loc
);
17320 if (c
== boolean_true_node
)
17322 warning_at (expr_loc
, 0, "%<thread_limit%> value must be positive");
17323 t
= integer_one_node
;
17326 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
17329 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
17330 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
17331 OMP_CLAUSE_CHAIN (c
) = list
;
17339 aligned ( variable-list )
17340 aligned ( variable-list : constant-expression ) */
17343 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
17345 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17348 matching_parens parens
;
17349 if (!parens
.require_open (parser
))
17352 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
17353 OMP_CLAUSE_ALIGNED
, list
);
17355 if (c_parser_next_token_is (parser
, CPP_COLON
))
17357 c_parser_consume_token (parser
);
17358 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17359 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17360 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17361 tree alignment
= expr
.value
;
17362 alignment
= c_fully_fold (alignment
, false, NULL
);
17363 if (TREE_CODE (alignment
) != INTEGER_CST
17364 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
17365 || tree_int_cst_sgn (alignment
) != 1)
17367 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
17368 "be positive constant integer expression");
17369 alignment
= NULL_TREE
;
17372 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
17373 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
17376 parens
.skip_until_found_close (parser
);
17381 allocate ( variable-list )
17382 allocate ( expression : variable-list )
17385 allocate ( allocator-modifier : variable-list )
17386 allocate ( allocator-modifier , allocator-modifier : variable-list )
17388 allocator-modifier:
17389 allocator ( expression )
17390 align ( expression ) */
17393 c_parser_omp_clause_allocate (c_parser
*parser
, tree list
)
17395 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17397 tree allocator
= NULL_TREE
;
17398 tree align
= NULL_TREE
;
17400 matching_parens parens
;
17401 if (!parens
.require_open (parser
))
17404 if ((c_parser_next_token_is_not (parser
, CPP_NAME
)
17405 && c_parser_next_token_is_not (parser
, CPP_KEYWORD
))
17406 || (c_parser_peek_2nd_token (parser
)->type
!= CPP_COMMA
17407 && c_parser_peek_2nd_token (parser
)->type
!= CPP_CLOSE_PAREN
))
17409 bool has_modifiers
= false;
17410 tree orig_type
= NULL_TREE
;
17411 if (c_parser_next_token_is (parser
, CPP_NAME
)
17412 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
17414 unsigned int n
= 3;
17416 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17417 if ((strcmp (p
, "allocator") == 0 || strcmp (p
, "align") == 0)
17418 && c_parser_check_balanced_raw_token_sequence (parser
, &n
)
17419 && (c_parser_peek_nth_token_raw (parser
, n
)->type
17420 == CPP_CLOSE_PAREN
))
17422 if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
17424 has_modifiers
= true;
17425 else if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
17427 && (c_parser_peek_nth_token_raw (parser
, n
+ 2)->type
17429 && (c_parser_peek_nth_token_raw (parser
, n
+ 3)->type
17430 == CPP_OPEN_PAREN
))
17432 c_token
*tok
= c_parser_peek_nth_token_raw (parser
, n
+ 2);
17433 const char *q
= IDENTIFIER_POINTER (tok
->value
);
17435 if ((strcmp (q
, "allocator") == 0
17436 || strcmp (q
, "align") == 0)
17437 && c_parser_check_balanced_raw_token_sequence (parser
,
17439 && (c_parser_peek_nth_token_raw (parser
, n
)->type
17440 == CPP_CLOSE_PAREN
)
17441 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
17443 has_modifiers
= true;
17448 c_parser_consume_token (parser
);
17449 matching_parens parens2
;;
17450 parens2
.require_open (parser
);
17451 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17452 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17453 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17454 if (expr
.value
== error_mark_node
)
17456 else if (strcmp (p
, "allocator") == 0)
17458 allocator
= expr
.value
;
17459 allocator
= c_fully_fold (allocator
, false, NULL
);
17460 orig_type
= expr
.original_type
17461 ? expr
.original_type
: TREE_TYPE (allocator
);
17462 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
17466 align
= expr
.value
;
17467 align
= c_fully_fold (align
, false, NULL
);
17469 parens2
.skip_until_found_close (parser
);
17470 if (c_parser_next_token_is (parser
, CPP_COMMA
))
17472 c_parser_consume_token (parser
);
17473 c_token
*tok
= c_parser_peek_token (parser
);
17474 const char *q
= "";
17475 if (c_parser_next_token_is (parser
, CPP_NAME
))
17476 q
= IDENTIFIER_POINTER (tok
->value
);
17477 if (strcmp (q
, "allocator") != 0 && strcmp (q
, "align") != 0)
17479 c_parser_error (parser
, "expected %<allocator%> or "
17481 parens
.skip_until_found_close (parser
);
17484 else if (strcmp (p
, q
) == 0)
17486 error_at (tok
->location
, "duplicate %qs modifier", p
);
17487 parens
.skip_until_found_close (parser
);
17490 c_parser_consume_token (parser
);
17491 if (!parens2
.require_open (parser
))
17493 parens
.skip_until_found_close (parser
);
17496 expr_loc
= c_parser_peek_token (parser
)->location
;
17497 expr
= c_parser_expr_no_commas (parser
, NULL
);
17498 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
17500 if (strcmp (q
, "allocator") == 0)
17502 allocator
= expr
.value
;
17503 allocator
= c_fully_fold (allocator
, false, NULL
);
17504 orig_type
= expr
.original_type
17505 ? expr
.original_type
: TREE_TYPE (allocator
);
17506 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
17510 align
= expr
.value
;
17511 align
= c_fully_fold (align
, false, NULL
);
17513 parens2
.skip_until_found_close (parser
);
17517 if (!has_modifiers
)
17519 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17520 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17521 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17522 allocator
= expr
.value
;
17523 allocator
= c_fully_fold (allocator
, false, NULL
);
17524 orig_type
= expr
.original_type
17525 ? expr
.original_type
: TREE_TYPE (allocator
);
17526 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
17529 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
17530 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
17531 || (TYPE_NAME (orig_type
)
17532 != get_identifier ("omp_allocator_handle_t"))))
17534 error_at (clause_loc
, "%<allocate%> clause allocator expression "
17535 "has type %qT rather than "
17536 "%<omp_allocator_handle_t%>",
17537 TREE_TYPE (allocator
));
17538 allocator
= NULL_TREE
;
17541 && (!INTEGRAL_TYPE_P (TREE_TYPE (align
))
17542 || !tree_fits_uhwi_p (align
)
17543 || !integer_pow2p (align
)))
17545 error_at (clause_loc
, "%<allocate%> clause %<align%> modifier "
17546 "argument needs to be positive constant "
17547 "power of two integer expression");
17550 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
17552 parens
.skip_until_found_close (parser
);
17557 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
17558 OMP_CLAUSE_ALLOCATE
, list
);
17560 if (allocator
|| align
)
17561 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
17563 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
17564 OMP_CLAUSE_ALLOCATE_ALIGN (c
) = align
;
17567 parens
.skip_until_found_close (parser
);
17572 linear ( variable-list )
17573 linear ( variable-list : expression )
17576 linear ( modifier ( variable-list ) )
17577 linear ( modifier ( variable-list ) : expression )
17583 linear ( variable-list : modifiers-list )
17587 step ( expression ) */
17590 c_parser_omp_clause_linear (c_parser
*parser
, tree list
)
17592 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17594 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
17595 bool old_linear_modifier
= false;
17597 matching_parens parens
;
17598 if (!parens
.require_open (parser
))
17601 if (c_parser_next_token_is (parser
, CPP_NAME
))
17603 c_token
*tok
= c_parser_peek_token (parser
);
17604 const char *p
= IDENTIFIER_POINTER (tok
->value
);
17605 if (strcmp ("val", p
) == 0)
17606 kind
= OMP_CLAUSE_LINEAR_VAL
;
17607 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
17608 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
17609 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
17611 old_linear_modifier
= true;
17612 c_parser_consume_token (parser
);
17613 c_parser_consume_token (parser
);
17617 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
17618 OMP_CLAUSE_LINEAR
, list
);
17620 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
17621 parens
.skip_until_found_close (parser
);
17623 if (c_parser_next_token_is (parser
, CPP_COLON
))
17625 c_parser_consume_token (parser
);
17626 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17627 bool has_modifiers
= false;
17628 if (kind
== OMP_CLAUSE_LINEAR_DEFAULT
17629 && c_parser_next_token_is (parser
, CPP_NAME
))
17631 c_token
*tok
= c_parser_peek_token (parser
);
17632 const char *p
= IDENTIFIER_POINTER (tok
->value
);
17633 unsigned int pos
= 0;
17634 if (strcmp ("val", p
) == 0)
17636 else if (strcmp ("step", p
) == 0
17637 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
17640 if (c_parser_check_balanced_raw_token_sequence (parser
, &pos
)
17641 && (c_parser_peek_nth_token_raw (parser
, pos
)->type
17642 == CPP_CLOSE_PAREN
))
17649 tok
= c_parser_peek_nth_token_raw (parser
, pos
);
17650 if (tok
->type
== CPP_COMMA
|| tok
->type
== CPP_CLOSE_PAREN
)
17651 has_modifiers
= true;
17657 while (c_parser_next_token_is (parser
, CPP_NAME
))
17659 c_token
*tok
= c_parser_peek_token (parser
);
17660 const char *p
= IDENTIFIER_POINTER (tok
->value
);
17661 if (strcmp ("val", p
) == 0)
17663 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
17664 error_at (tok
->location
, "multiple linear modifiers");
17665 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
17666 c_parser_consume_token (parser
);
17668 else if (strcmp ("step", p
) == 0)
17670 c_parser_consume_token (parser
);
17671 matching_parens parens2
;
17672 if (parens2
.require_open (parser
))
17675 error_at (tok
->location
,
17676 "multiple %<step%> modifiers");
17677 expr_loc
= c_parser_peek_token (parser
)->location
;
17678 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17679 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
17681 step
= c_fully_fold (expr
.value
, false, NULL
);
17682 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
17684 error_at (clause_loc
, "%<linear%> clause step "
17685 "expression must be integral");
17686 step
= integer_one_node
;
17688 parens2
.skip_until_found_close (parser
);
17695 if (c_parser_next_token_is (parser
, CPP_COMMA
))
17697 c_parser_consume_token (parser
);
17703 step
= integer_one_node
;
17707 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17708 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17709 step
= c_fully_fold (expr
.value
, false, NULL
);
17710 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
17712 error_at (clause_loc
, "%<linear%> clause step expression must "
17714 step
= integer_one_node
;
17720 step
= integer_one_node
;
17722 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
17724 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
17725 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
17726 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c
) = old_linear_modifier
;
17729 parens
.skip_until_found_close (parser
);
17734 nontemporal ( variable-list ) */
17737 c_parser_omp_clause_nontemporal (c_parser
*parser
, tree list
)
17739 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_NONTEMPORAL
, list
);
17743 safelen ( constant-expression ) */
17746 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
17748 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17751 matching_parens parens
;
17752 if (!parens
.require_open (parser
))
17755 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17756 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17757 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17759 t
= c_fully_fold (t
, false, NULL
);
17760 if (TREE_CODE (t
) != INTEGER_CST
17761 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
17762 || tree_int_cst_sgn (t
) != 1)
17764 error_at (clause_loc
, "%<safelen%> clause expression must "
17765 "be positive constant integer expression");
17769 parens
.skip_until_found_close (parser
);
17770 if (t
== NULL_TREE
|| t
== error_mark_node
)
17773 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
17775 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
17776 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
17777 OMP_CLAUSE_CHAIN (c
) = list
;
17782 simdlen ( constant-expression ) */
17785 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
17787 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17790 matching_parens parens
;
17791 if (!parens
.require_open (parser
))
17794 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17795 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17796 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17798 t
= c_fully_fold (t
, false, NULL
);
17799 if (TREE_CODE (t
) != INTEGER_CST
17800 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
17801 || tree_int_cst_sgn (t
) != 1)
17803 error_at (clause_loc
, "%<simdlen%> clause expression must "
17804 "be positive constant integer expression");
17808 parens
.skip_until_found_close (parser
);
17809 if (t
== NULL_TREE
|| t
== error_mark_node
)
17812 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
17814 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
17815 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
17816 OMP_CLAUSE_CHAIN (c
) = list
;
17822 identifier [+/- integer]
17823 vec , identifier [+/- integer]
17827 c_parser_omp_clause_doacross_sink (c_parser
*parser
, location_t clause_loc
,
17828 tree list
, bool depend_p
)
17831 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
17832 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
17834 c_parser_error (parser
, "expected identifier");
17840 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17841 if (strcmp (p
, "omp_cur_iteration") == 0
17842 && c_parser_peek_2nd_token (parser
)->type
== CPP_MINUS
17843 && c_parser_peek_nth_token (parser
, 3)->type
== CPP_NUMBER
17844 && c_parser_peek_nth_token (parser
, 4)->type
== CPP_CLOSE_PAREN
)
17846 tree val
= c_parser_peek_nth_token (parser
, 3)->value
;
17847 if (integer_onep (val
))
17849 c_parser_consume_token (parser
);
17850 c_parser_consume_token (parser
);
17851 c_parser_consume_token (parser
);
17852 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
17853 OMP_CLAUSE_DOACROSS_KIND (u
) = OMP_CLAUSE_DOACROSS_SINK
;
17854 OMP_CLAUSE_CHAIN (u
) = list
;
17862 while (c_parser_next_token_is (parser
, CPP_NAME
)
17863 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
17865 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
17866 tree addend
= NULL
;
17868 if (t
== NULL_TREE
)
17870 undeclared_variable (c_parser_peek_token (parser
)->location
,
17871 c_parser_peek_token (parser
)->value
);
17872 t
= error_mark_node
;
17875 c_parser_consume_token (parser
);
17878 if (c_parser_next_token_is (parser
, CPP_MINUS
))
17880 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
17882 addend
= integer_zero_node
;
17884 goto add_to_vector
;
17886 c_parser_consume_token (parser
);
17888 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
17890 c_parser_error (parser
, "expected integer");
17894 addend
= c_parser_peek_token (parser
)->value
;
17895 if (TREE_CODE (addend
) != INTEGER_CST
)
17897 c_parser_error (parser
, "expected integer");
17900 c_parser_consume_token (parser
);
17903 if (t
!= error_mark_node
)
17905 vec
= tree_cons (addend
, t
, vec
);
17907 OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec
) = 1;
17910 if (c_parser_next_token_is_not (parser
, CPP_COMMA
)
17911 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
17912 || c_parser_peek_2nd_token (parser
)->id_kind
!= C_ID_ID
)
17915 c_parser_consume_token (parser
);
17918 if (vec
== NULL_TREE
)
17921 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
17922 OMP_CLAUSE_DOACROSS_KIND (u
) = OMP_CLAUSE_DOACROSS_SINK
;
17923 OMP_CLAUSE_DOACROSS_DEPEND (u
) = depend_p
;
17924 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
17925 OMP_CLAUSE_CHAIN (u
) = list
;
17930 iterators ( iterators-definition )
17932 iterators-definition:
17934 iterator-specifier , iterators-definition
17936 iterator-specifier:
17937 identifier = range-specification
17938 iterator-type identifier = range-specification
17940 range-specification:
17942 begin : end : step */
17945 c_parser_omp_iterators (c_parser
*parser
)
17947 tree ret
= NULL_TREE
, *last
= &ret
;
17948 c_parser_consume_token (parser
);
17952 matching_parens parens
;
17953 if (!parens
.require_open (parser
))
17954 return error_mark_node
;
17958 tree iter_type
= NULL_TREE
, type_expr
= NULL_TREE
;
17959 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
17961 struct c_type_name
*type
= c_parser_type_name (parser
);
17963 iter_type
= groktypename (type
, &type_expr
, NULL
);
17965 if (iter_type
== NULL_TREE
)
17966 iter_type
= integer_type_node
;
17968 location_t loc
= c_parser_peek_token (parser
)->location
;
17969 if (!c_parser_next_token_is (parser
, CPP_NAME
))
17971 c_parser_error (parser
, "expected identifier");
17975 tree id
= c_parser_peek_token (parser
)->value
;
17976 c_parser_consume_token (parser
);
17978 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
17981 location_t eloc
= c_parser_peek_token (parser
)->location
;
17982 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17983 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
17984 tree begin
= expr
.value
;
17986 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
17989 eloc
= c_parser_peek_token (parser
)->location
;
17990 expr
= c_parser_expr_no_commas (parser
, NULL
);
17991 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
17992 tree end
= expr
.value
;
17994 tree step
= integer_one_node
;
17995 if (c_parser_next_token_is (parser
, CPP_COLON
))
17997 c_parser_consume_token (parser
);
17998 eloc
= c_parser_peek_token (parser
)->location
;
17999 expr
= c_parser_expr_no_commas (parser
, NULL
);
18000 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
18004 tree iter_var
= build_decl (loc
, VAR_DECL
, id
, iter_type
);
18005 DECL_ARTIFICIAL (iter_var
) = 1;
18006 DECL_CONTEXT (iter_var
) = current_function_decl
;
18007 pushdecl (iter_var
);
18009 *last
= make_tree_vec (6);
18010 TREE_VEC_ELT (*last
, 0) = iter_var
;
18011 TREE_VEC_ELT (*last
, 1) = begin
;
18012 TREE_VEC_ELT (*last
, 2) = end
;
18013 TREE_VEC_ELT (*last
, 3) = step
;
18014 last
= &TREE_CHAIN (*last
);
18016 if (c_parser_next_token_is (parser
, CPP_COMMA
))
18018 c_parser_consume_token (parser
);
18025 parens
.skip_until_found_close (parser
);
18026 return ret
? ret
: error_mark_node
;
18030 affinity ( [aff-modifier :] variable-list )
18032 iterator ( iterators-definition ) */
18035 c_parser_omp_clause_affinity (c_parser
*parser
, tree list
)
18037 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18038 tree nl
, iterators
= NULL_TREE
;
18040 matching_parens parens
;
18041 if (!parens
.require_open (parser
))
18044 if (c_parser_next_token_is (parser
, CPP_NAME
))
18046 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18047 bool parse_iter
= ((strcmp ("iterator", p
) == 0)
18048 && (c_parser_peek_2nd_token (parser
)->type
18049 == CPP_OPEN_PAREN
));
18053 parse_iter
= (c_parser_check_balanced_raw_token_sequence (parser
, &n
)
18054 && (c_parser_peek_nth_token_raw (parser
, n
)->type
18055 == CPP_CLOSE_PAREN
)
18056 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
18061 iterators
= c_parser_omp_iterators (parser
);
18062 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18066 parens
.skip_until_found_close (parser
);
18071 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_AFFINITY
,
18075 tree block
= pop_scope ();
18076 if (iterators
!= error_mark_node
)
18078 TREE_VEC_ELT (iterators
, 5) = block
;
18079 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18080 OMP_CLAUSE_DECL (c
) = build_tree_list (iterators
,
18081 OMP_CLAUSE_DECL (c
));
18085 parens
.skip_until_found_close (parser
);
18091 depend ( depend-kind: variable-list )
18099 depend ( sink : vec )
18102 depend ( depend-modifier , depend-kind: variable-list )
18105 in | out | inout | mutexinoutset | depobj | inoutset
18108 iterator ( iterators-definition ) */
18111 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
18113 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18114 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_LAST
;
18115 enum omp_clause_doacross_kind dkind
= OMP_CLAUSE_DOACROSS_LAST
;
18116 tree nl
, c
, iterators
= NULL_TREE
;
18118 matching_parens parens
;
18119 if (!parens
.require_open (parser
))
18124 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
18127 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18128 if (strcmp ("iterator", p
) == 0 && iterators
== NULL_TREE
)
18130 iterators
= c_parser_omp_iterators (parser
);
18131 c_parser_require (parser
, CPP_COMMA
, "expected %<,%>");
18134 if (strcmp ("in", p
) == 0)
18135 kind
= OMP_CLAUSE_DEPEND_IN
;
18136 else if (strcmp ("inout", p
) == 0)
18137 kind
= OMP_CLAUSE_DEPEND_INOUT
;
18138 else if (strcmp ("inoutset", p
) == 0)
18139 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
18140 else if (strcmp ("mutexinoutset", p
) == 0)
18141 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
18142 else if (strcmp ("out", p
) == 0)
18143 kind
= OMP_CLAUSE_DEPEND_OUT
;
18144 else if (strcmp ("depobj", p
) == 0)
18145 kind
= OMP_CLAUSE_DEPEND_DEPOBJ
;
18146 else if (strcmp ("sink", p
) == 0)
18147 dkind
= OMP_CLAUSE_DOACROSS_SINK
;
18148 else if (strcmp ("source", p
) == 0)
18149 dkind
= OMP_CLAUSE_DOACROSS_SOURCE
;
18156 c_parser_consume_token (parser
);
18159 && (dkind
== OMP_CLAUSE_DOACROSS_SOURCE
18160 || dkind
== OMP_CLAUSE_DOACROSS_SINK
))
18163 error_at (clause_loc
, "%<iterator%> modifier incompatible with %qs",
18164 dkind
== OMP_CLAUSE_DOACROSS_SOURCE
? "source" : "sink");
18165 iterators
= NULL_TREE
;
18168 if (dkind
== OMP_CLAUSE_DOACROSS_SOURCE
)
18170 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
18171 OMP_CLAUSE_DOACROSS_KIND (c
) = dkind
;
18172 OMP_CLAUSE_DOACROSS_DEPEND (c
) = 1;
18173 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
18174 OMP_CLAUSE_CHAIN (c
) = list
;
18175 parens
.skip_until_found_close (parser
);
18179 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18182 if (dkind
== OMP_CLAUSE_DOACROSS_SINK
)
18183 nl
= c_parser_omp_clause_doacross_sink (parser
, clause_loc
, list
, true);
18186 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
18187 OMP_CLAUSE_DEPEND
, list
);
18191 tree block
= pop_scope ();
18192 if (iterators
== error_mark_node
)
18193 iterators
= NULL_TREE
;
18195 TREE_VEC_ELT (iterators
, 5) = block
;
18198 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18200 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
18202 OMP_CLAUSE_DECL (c
)
18203 = build_tree_list (iterators
, OMP_CLAUSE_DECL (c
));
18207 parens
.skip_until_found_close (parser
);
18211 c_parser_error (parser
, "invalid depend kind");
18213 parens
.skip_until_found_close (parser
);
18220 doacross ( source : )
18221 doacross ( source : omp_cur_iteration )
18223 doacross ( sink : vec )
18224 doacross ( sink : omp_cur_iteration - logical_iteration ) */
18227 c_parser_omp_clause_doacross (c_parser
*parser
, tree list
)
18229 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18230 enum omp_clause_doacross_kind kind
= OMP_CLAUSE_DOACROSS_LAST
;
18234 matching_parens parens
;
18235 if (!parens
.require_open (parser
))
18238 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
18241 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18242 if (strcmp ("sink", p
) == 0)
18243 kind
= OMP_CLAUSE_DOACROSS_SINK
;
18244 else if (strcmp ("source", p
) == 0)
18245 kind
= OMP_CLAUSE_DOACROSS_SOURCE
;
18249 c_parser_consume_token (parser
);
18251 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18254 if (kind
== OMP_CLAUSE_DOACROSS_SOURCE
)
18256 if (c_parser_next_token_is (parser
, CPP_NAME
)
18257 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
18258 "omp_cur_iteration") == 0)
18259 c_parser_consume_token (parser
);
18260 nl
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
18261 OMP_CLAUSE_DOACROSS_KIND (nl
) = OMP_CLAUSE_DOACROSS_SOURCE
;
18262 OMP_CLAUSE_DECL (nl
) = NULL_TREE
;
18263 OMP_CLAUSE_CHAIN (nl
) = list
;
18266 nl
= c_parser_omp_clause_doacross_sink (parser
, clause_loc
, list
, false);
18268 parens
.skip_until_found_close (parser
);
18272 c_parser_error (parser
, "invalid doacross kind");
18274 parens
.skip_until_found_close (parser
);
18279 map ( map-kind: variable-list )
18280 map ( variable-list )
18283 alloc | to | from | tofrom
18287 alloc | to | from | tofrom | release | delete
18289 map ( always [,] map-kind: variable-list )
18292 map ( [map-type-modifier[,] ...] map-kind: variable-list )
18298 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
18300 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18301 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
18304 matching_parens parens
;
18305 if (!parens
.require_open (parser
))
18309 int map_kind_pos
= 0;
18310 while (c_parser_peek_nth_token_raw (parser
, pos
)->type
== CPP_NAME
)
18312 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COLON
)
18314 map_kind_pos
= pos
;
18318 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COMMA
)
18323 int always_modifier
= 0;
18324 int close_modifier
= 0;
18325 int present_modifier
= 0;
18326 for (int pos
= 1; pos
< map_kind_pos
; ++pos
)
18328 c_token
*tok
= c_parser_peek_token (parser
);
18330 if (tok
->type
== CPP_COMMA
)
18332 c_parser_consume_token (parser
);
18336 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18337 if (strcmp ("always", p
) == 0)
18339 if (always_modifier
)
18341 c_parser_error (parser
, "too many %<always%> modifiers");
18342 parens
.skip_until_found_close (parser
);
18347 else if (strcmp ("close", p
) == 0)
18349 if (close_modifier
)
18351 c_parser_error (parser
, "too many %<close%> modifiers");
18352 parens
.skip_until_found_close (parser
);
18357 else if (strcmp ("present", p
) == 0)
18359 if (present_modifier
)
18361 c_parser_error (parser
, "too many %<present%> modifiers");
18362 parens
.skip_until_found_close (parser
);
18365 present_modifier
++;
18369 c_parser_error (parser
, "%<map%> clause with map-type modifier other "
18370 "than %<always%>, %<close%> or %<present%>");
18371 parens
.skip_until_found_close (parser
);
18375 c_parser_consume_token (parser
);
18378 if (c_parser_next_token_is (parser
, CPP_NAME
)
18379 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
18381 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18382 int always_present_modifier
= always_modifier
&& present_modifier
;
18384 if (strcmp ("alloc", p
) == 0)
18385 kind
= present_modifier
? GOMP_MAP_PRESENT_ALLOC
: GOMP_MAP_ALLOC
;
18386 else if (strcmp ("to", p
) == 0)
18387 kind
= (always_present_modifier
? GOMP_MAP_ALWAYS_PRESENT_TO
18388 : present_modifier
? GOMP_MAP_PRESENT_TO
18389 : always_modifier
? GOMP_MAP_ALWAYS_TO
18391 else if (strcmp ("from", p
) == 0)
18392 kind
= (always_present_modifier
? GOMP_MAP_ALWAYS_PRESENT_FROM
18393 : present_modifier
? GOMP_MAP_PRESENT_FROM
18394 : always_modifier
? GOMP_MAP_ALWAYS_FROM
18396 else if (strcmp ("tofrom", p
) == 0)
18397 kind
= (always_present_modifier
? GOMP_MAP_ALWAYS_PRESENT_TOFROM
18398 : present_modifier
? GOMP_MAP_PRESENT_TOFROM
18399 : always_modifier
? GOMP_MAP_ALWAYS_TOFROM
18400 : GOMP_MAP_TOFROM
);
18401 else if (strcmp ("release", p
) == 0)
18402 kind
= GOMP_MAP_RELEASE
;
18403 else if (strcmp ("delete", p
) == 0)
18404 kind
= GOMP_MAP_DELETE
;
18407 c_parser_error (parser
, "invalid map kind");
18408 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
18412 c_parser_consume_token (parser
);
18413 c_parser_consume_token (parser
);
18416 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
,
18419 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18420 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
18422 parens
.skip_until_found_close (parser
);
18427 device ( expression )
18430 device ( [device-modifier :] integer-expression )
18433 ancestor | device_num */
18436 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
18438 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18439 location_t expr_loc
;
18442 bool ancestor
= false;
18444 matching_parens parens
;
18445 if (!parens
.require_open (parser
))
18448 if (c_parser_next_token_is (parser
, CPP_NAME
)
18449 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
18451 c_token
*tok
= c_parser_peek_token (parser
);
18452 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18453 if (strcmp ("ancestor", p
) == 0)
18455 /* A requires directive with the reverse_offload clause must be
18457 if ((omp_requires_mask
& OMP_REQUIRES_REVERSE_OFFLOAD
) == 0)
18459 error_at (tok
->location
, "%<ancestor%> device modifier not "
18460 "preceded by %<requires%> directive "
18461 "with %<reverse_offload%> clause");
18462 parens
.skip_until_found_close (parser
);
18467 else if (strcmp ("device_num", p
) == 0)
18471 error_at (tok
->location
, "expected %<ancestor%> or %<device_num%>");
18472 parens
.skip_until_found_close (parser
);
18475 c_parser_consume_token (parser
);
18476 c_parser_consume_token (parser
);
18479 expr_loc
= c_parser_peek_token (parser
)->location
;
18480 expr
= c_parser_expr_no_commas (parser
, NULL
);
18481 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18483 t
= c_fully_fold (t
, false, NULL
);
18485 parens
.skip_until_found_close (parser
);
18487 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
18489 c_parser_error (parser
, "expected integer expression");
18492 if (ancestor
&& TREE_CODE (t
) == INTEGER_CST
&& !integer_onep (t
))
18494 error_at (expr_loc
, "the %<device%> clause expression must evaluate to "
18499 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
18501 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
18503 OMP_CLAUSE_DEVICE_ID (c
) = t
;
18504 OMP_CLAUSE_CHAIN (c
) = list
;
18505 OMP_CLAUSE_DEVICE_ANCESTOR (c
) = ancestor
;
18512 dist_schedule ( static )
18513 dist_schedule ( static , expression ) */
18516 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
18518 tree c
, t
= NULL_TREE
;
18519 location_t loc
= c_parser_peek_token (parser
)->location
;
18521 matching_parens parens
;
18522 if (!parens
.require_open (parser
))
18525 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
18527 c_parser_error (parser
, "invalid dist_schedule kind");
18528 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
18533 c_parser_consume_token (parser
);
18534 if (c_parser_next_token_is (parser
, CPP_COMMA
))
18536 c_parser_consume_token (parser
);
18538 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18539 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18540 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18542 t
= c_fully_fold (t
, false, NULL
);
18543 parens
.skip_until_found_close (parser
);
18546 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
18547 "expected %<,%> or %<)%>");
18549 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
18550 "dist_schedule"); */
18551 if (omp_find_clause (list
, OMP_CLAUSE_DIST_SCHEDULE
))
18552 warning_at (loc
, 0, "too many %qs clauses", "dist_schedule");
18553 if (t
== error_mark_node
)
18556 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
18557 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
18558 OMP_CLAUSE_CHAIN (c
) = list
;
18563 proc_bind ( proc-bind-kind )
18566 primary | master | close | spread
18567 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
18570 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
18572 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18573 enum omp_clause_proc_bind_kind kind
;
18576 matching_parens parens
;
18577 if (!parens
.require_open (parser
))
18580 if (c_parser_next_token_is (parser
, CPP_NAME
))
18582 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18583 if (strcmp ("primary", p
) == 0)
18584 kind
= OMP_CLAUSE_PROC_BIND_PRIMARY
;
18585 else if (strcmp ("master", p
) == 0)
18586 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
18587 else if (strcmp ("close", p
) == 0)
18588 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
18589 else if (strcmp ("spread", p
) == 0)
18590 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
18597 check_no_duplicate_clause (list
, OMP_CLAUSE_PROC_BIND
, "proc_bind");
18598 c_parser_consume_token (parser
);
18599 parens
.skip_until_found_close (parser
);
18600 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
18601 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
18602 OMP_CLAUSE_CHAIN (c
) = list
;
18606 c_parser_error (parser
, "invalid proc_bind kind");
18607 parens
.skip_until_found_close (parser
);
18612 device_type ( host | nohost | any ) */
18615 c_parser_omp_clause_device_type (c_parser
*parser
, tree list
)
18617 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18618 enum omp_clause_device_type_kind kind
;
18621 matching_parens parens
;
18622 if (!parens
.require_open (parser
))
18625 if (c_parser_next_token_is (parser
, CPP_NAME
))
18627 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18628 if (strcmp ("host", p
) == 0)
18629 kind
= OMP_CLAUSE_DEVICE_TYPE_HOST
;
18630 else if (strcmp ("nohost", p
) == 0)
18631 kind
= OMP_CLAUSE_DEVICE_TYPE_NOHOST
;
18632 else if (strcmp ("any", p
) == 0)
18633 kind
= OMP_CLAUSE_DEVICE_TYPE_ANY
;
18640 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE_TYPE
,
18642 c_parser_consume_token (parser
);
18643 parens
.skip_until_found_close (parser
);
18644 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE_TYPE
);
18645 OMP_CLAUSE_DEVICE_TYPE_KIND (c
) = kind
;
18646 OMP_CLAUSE_CHAIN (c
) = list
;
18650 c_parser_error (parser
, "expected %<host%>, %<nohost%> or %<any%>");
18651 parens
.skip_until_found_close (parser
);
18656 from ( variable-list )
18657 to ( variable-list )
18660 from ( [present :] variable-list )
18661 to ( [present :] variable-list ) */
18664 c_parser_omp_clause_from_to (c_parser
*parser
, enum omp_clause_code kind
,
18667 location_t loc
= c_parser_peek_token (parser
)->location
;
18668 matching_parens parens
;
18669 if (!parens
.require_open (parser
))
18672 bool present
= false;
18673 c_token
*token
= c_parser_peek_token (parser
);
18675 if (token
->type
== CPP_NAME
18676 && strcmp (IDENTIFIER_POINTER (token
->value
), "present") == 0
18677 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
18680 c_parser_consume_token (parser
);
18681 c_parser_consume_token (parser
);
18684 tree nl
= c_parser_omp_variable_list (parser
, loc
, kind
, list
);
18685 parens
.skip_until_found_close (parser
);
18688 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18689 OMP_CLAUSE_MOTION_PRESENT (c
) = 1;
18695 uniform ( variable-list ) */
18698 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
18700 /* The clauses location. */
18701 location_t loc
= c_parser_peek_token (parser
)->location
;
18703 matching_parens parens
;
18704 if (parens
.require_open (parser
))
18706 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
18708 parens
.skip_until_found_close (parser
);
18714 detach ( event-handle ) */
18717 c_parser_omp_clause_detach (c_parser
*parser
, tree list
)
18719 matching_parens parens
;
18720 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18722 if (!parens
.require_open (parser
))
18725 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
18726 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
18728 c_parser_error (parser
, "expected identifier");
18729 parens
.skip_until_found_close (parser
);
18733 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
18734 if (t
== NULL_TREE
)
18736 undeclared_variable (c_parser_peek_token (parser
)->location
,
18737 c_parser_peek_token (parser
)->value
);
18738 parens
.skip_until_found_close (parser
);
18741 c_parser_consume_token (parser
);
18743 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (t
));
18744 if (!INTEGRAL_TYPE_P (type
)
18745 || TREE_CODE (type
) != ENUMERAL_TYPE
18746 || TYPE_NAME (type
) != get_identifier ("omp_event_handle_t"))
18748 error_at (clause_loc
, "%<detach%> clause event handle "
18749 "has type %qT rather than "
18750 "%<omp_event_handle_t%>",
18752 parens
.skip_until_found_close (parser
);
18756 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DETACH
);
18757 OMP_CLAUSE_DECL (u
) = t
;
18758 OMP_CLAUSE_CHAIN (u
) = list
;
18759 parens
.skip_until_found_close (parser
);
18763 /* Parse all OpenACC clauses. The set clauses allowed by the directive
18764 is a bitmask in MASK. Return the list of clauses found. */
18767 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
18768 const char *where
, bool finish_p
= true)
18770 tree clauses
= NULL
;
18773 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
18776 pragma_omp_clause c_kind
;
18777 const char *c_name
;
18778 tree prev
= clauses
;
18780 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
18781 c_parser_consume_token (parser
);
18783 here
= c_parser_peek_token (parser
)->location
;
18784 c_kind
= c_parser_omp_clause_name (parser
);
18788 case PRAGMA_OACC_CLAUSE_ASYNC
:
18789 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
18792 case PRAGMA_OACC_CLAUSE_AUTO
:
18793 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_AUTO
,
18797 case PRAGMA_OACC_CLAUSE_ATTACH
:
18798 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
18801 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
18802 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
18803 c_name
= "collapse";
18805 case PRAGMA_OACC_CLAUSE_COPY
:
18806 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
18809 case PRAGMA_OACC_CLAUSE_COPYIN
:
18810 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
18813 case PRAGMA_OACC_CLAUSE_COPYOUT
:
18814 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
18815 c_name
= "copyout";
18817 case PRAGMA_OACC_CLAUSE_CREATE
:
18818 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
18821 case PRAGMA_OACC_CLAUSE_DELETE
:
18822 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
18825 case PRAGMA_OMP_CLAUSE_DEFAULT
:
18826 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
18827 c_name
= "default";
18829 case PRAGMA_OACC_CLAUSE_DETACH
:
18830 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
18833 case PRAGMA_OACC_CLAUSE_DEVICE
:
18834 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
18837 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
18838 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
18839 c_name
= "deviceptr";
18841 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
18842 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
18843 c_name
= "device_resident";
18845 case PRAGMA_OACC_CLAUSE_FINALIZE
:
18846 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_FINALIZE
,
18848 c_name
= "finalize";
18850 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
18851 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
18852 c_name
= "firstprivate";
18854 case PRAGMA_OACC_CLAUSE_GANG
:
18856 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_GANG
,
18859 case PRAGMA_OACC_CLAUSE_HOST
:
18860 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
18863 case PRAGMA_OACC_CLAUSE_IF
:
18864 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
18867 case PRAGMA_OACC_CLAUSE_IF_PRESENT
:
18868 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_IF_PRESENT
,
18870 c_name
= "if_present";
18872 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
18873 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_INDEPENDENT
,
18875 c_name
= "independent";
18877 case PRAGMA_OACC_CLAUSE_LINK
:
18878 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
18881 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
18882 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
18883 c_name
= "no_create";
18885 case PRAGMA_OACC_CLAUSE_NOHOST
:
18886 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_NOHOST
,
18890 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
18891 clauses
= c_parser_oacc_single_int_clause (parser
,
18892 OMP_CLAUSE_NUM_GANGS
,
18894 c_name
= "num_gangs";
18896 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
18897 clauses
= c_parser_oacc_single_int_clause (parser
,
18898 OMP_CLAUSE_NUM_WORKERS
,
18900 c_name
= "num_workers";
18902 case PRAGMA_OACC_CLAUSE_PRESENT
:
18903 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
18904 c_name
= "present";
18906 case PRAGMA_OACC_CLAUSE_PRIVATE
:
18907 clauses
= c_parser_omp_clause_private (parser
, clauses
);
18908 c_name
= "private";
18910 case PRAGMA_OACC_CLAUSE_REDUCTION
:
18912 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
18914 c_name
= "reduction";
18916 case PRAGMA_OACC_CLAUSE_SELF
:
18917 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OACC_CLAUSE_HOST
)) == 0)
18918 /* OpenACC compute construct */
18919 clauses
= c_parser_oacc_compute_clause_self (parser
, clauses
);
18921 /* OpenACC 'update' directive */
18922 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
18925 case PRAGMA_OACC_CLAUSE_SEQ
:
18926 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_SEQ
,
18930 case PRAGMA_OACC_CLAUSE_TILE
:
18931 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
18934 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
18935 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
18936 c_name
= "use_device";
18938 case PRAGMA_OACC_CLAUSE_VECTOR
:
18940 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_VECTOR
,
18943 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
18944 clauses
= c_parser_oacc_single_int_clause (parser
,
18945 OMP_CLAUSE_VECTOR_LENGTH
,
18947 c_name
= "vector_length";
18949 case PRAGMA_OACC_CLAUSE_WAIT
:
18950 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
18953 case PRAGMA_OACC_CLAUSE_WORKER
:
18955 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_WORKER
,
18959 c_parser_error (parser
, "expected an OpenACC clause");
18965 if (((mask
>> c_kind
) & 1) == 0)
18967 /* Remove the invalid clause(s) from the list to avoid
18968 confusing the rest of the compiler. */
18970 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
18975 c_parser_skip_to_pragma_eol (parser
);
18978 return c_finish_omp_clauses (clauses
, C_ORT_ACC
);
18983 /* Parse all OpenMP clauses. The set clauses allowed by the directive
18984 is a bitmask in MASK. Return the list of clauses found.
18985 FINISH_P set if c_finish_omp_clauses should be called.
18986 NESTED non-zero if clauses should be terminated by closing paren instead
18987 of end of pragma. If it is 2, additionally commas are required in between
18991 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
18992 const char *where
, bool finish_p
= true,
18995 tree clauses
= NULL
;
18998 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19001 pragma_omp_clause c_kind
;
19002 const char *c_name
;
19003 tree prev
= clauses
;
19005 if (nested
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
19008 if (!first
|| nested
!= 2)
19010 if (c_parser_next_token_is (parser
, CPP_COMMA
))
19011 c_parser_consume_token (parser
);
19012 else if (nested
== 2)
19013 error_at (c_parser_peek_token (parser
)->location
,
19014 "clauses in %<simd%> trait should be separated "
19018 here
= c_parser_peek_token (parser
)->location
;
19019 c_kind
= c_parser_omp_clause_name (parser
);
19023 case PRAGMA_OMP_CLAUSE_BIND
:
19024 clauses
= c_parser_omp_clause_bind (parser
, clauses
);
19027 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
19028 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
19029 c_name
= "collapse";
19031 case PRAGMA_OMP_CLAUSE_COPYIN
:
19032 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
19035 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
19036 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
19037 c_name
= "copyprivate";
19039 case PRAGMA_OMP_CLAUSE_DEFAULT
:
19040 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
19041 c_name
= "default";
19043 case PRAGMA_OMP_CLAUSE_DETACH
:
19044 clauses
= c_parser_omp_clause_detach (parser
, clauses
);
19047 case PRAGMA_OMP_CLAUSE_FILTER
:
19048 clauses
= c_parser_omp_clause_filter (parser
, clauses
);
19051 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
19052 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
19053 c_name
= "firstprivate";
19055 case PRAGMA_OMP_CLAUSE_FINAL
:
19056 clauses
= c_parser_omp_clause_final (parser
, clauses
);
19059 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
19060 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
19061 c_name
= "grainsize";
19063 case PRAGMA_OMP_CLAUSE_HINT
:
19064 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
19067 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
19068 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
19069 c_name
= "defaultmap";
19071 case PRAGMA_OMP_CLAUSE_IF
:
19072 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
19075 case PRAGMA_OMP_CLAUSE_IN_REDUCTION
:
19077 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_IN_REDUCTION
,
19079 c_name
= "in_reduction";
19081 case PRAGMA_OMP_CLAUSE_INDIRECT
:
19082 clauses
= c_parser_omp_clause_indirect (parser
, clauses
);
19083 c_name
= "indirect";
19085 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
19086 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
19087 c_name
= "lastprivate";
19089 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
19090 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
19091 c_name
= "mergeable";
19093 case PRAGMA_OMP_CLAUSE_NOWAIT
:
19094 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
19097 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
19098 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
19099 c_name
= "num_tasks";
19101 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
19102 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
19103 c_name
= "num_threads";
19105 case PRAGMA_OMP_CLAUSE_ORDER
:
19106 clauses
= c_parser_omp_clause_order (parser
, clauses
);
19109 case PRAGMA_OMP_CLAUSE_ORDERED
:
19110 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
19111 c_name
= "ordered";
19113 case PRAGMA_OMP_CLAUSE_PRIORITY
:
19114 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
19115 c_name
= "priority";
19117 case PRAGMA_OMP_CLAUSE_PRIVATE
:
19118 clauses
= c_parser_omp_clause_private (parser
, clauses
);
19119 c_name
= "private";
19121 case PRAGMA_OMP_CLAUSE_REDUCTION
:
19123 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
19125 c_name
= "reduction";
19127 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
19128 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
19129 c_name
= "schedule";
19131 case PRAGMA_OMP_CLAUSE_SHARED
:
19132 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
19135 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION
:
19137 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_TASK_REDUCTION
,
19139 c_name
= "task_reduction";
19141 case PRAGMA_OMP_CLAUSE_UNTIED
:
19142 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
19145 case PRAGMA_OMP_CLAUSE_INBRANCH
:
19146 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
19148 c_name
= "inbranch";
19150 case PRAGMA_OMP_CLAUSE_NONTEMPORAL
:
19151 clauses
= c_parser_omp_clause_nontemporal (parser
, clauses
);
19152 c_name
= "nontemporal";
19154 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
19155 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
19157 c_name
= "notinbranch";
19159 case PRAGMA_OMP_CLAUSE_PARALLEL
:
19161 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
19163 c_name
= "parallel";
19167 error_at (here
, "%qs must be the first clause of %qs",
19172 case PRAGMA_OMP_CLAUSE_FOR
:
19174 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
19178 goto clause_not_first
;
19180 case PRAGMA_OMP_CLAUSE_SECTIONS
:
19182 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
19184 c_name
= "sections";
19186 goto clause_not_first
;
19188 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
19190 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
19192 c_name
= "taskgroup";
19194 goto clause_not_first
;
19196 case PRAGMA_OMP_CLAUSE_LINK
:
19198 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
19201 case PRAGMA_OMP_CLAUSE_TO
:
19202 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
19204 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
19206 for (tree c
= nl
; c
!= clauses
; c
= OMP_CLAUSE_CHAIN (c
))
19207 OMP_CLAUSE_ENTER_TO (c
) = 1;
19211 clauses
= c_parser_omp_clause_from_to (parser
, OMP_CLAUSE_TO
,
19215 case PRAGMA_OMP_CLAUSE_FROM
:
19216 clauses
= c_parser_omp_clause_from_to (parser
, OMP_CLAUSE_FROM
,
19220 case PRAGMA_OMP_CLAUSE_UNIFORM
:
19221 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
19222 c_name
= "uniform";
19224 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
19225 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
19226 c_name
= "num_teams";
19228 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
19229 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
19230 c_name
= "thread_limit";
19232 case PRAGMA_OMP_CLAUSE_ALIGNED
:
19233 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
19234 c_name
= "aligned";
19236 case PRAGMA_OMP_CLAUSE_ALLOCATE
:
19237 clauses
= c_parser_omp_clause_allocate (parser
, clauses
);
19238 c_name
= "allocate";
19240 case PRAGMA_OMP_CLAUSE_LINEAR
:
19241 clauses
= c_parser_omp_clause_linear (parser
, clauses
);
19244 case PRAGMA_OMP_CLAUSE_AFFINITY
:
19245 clauses
= c_parser_omp_clause_affinity (parser
, clauses
);
19246 c_name
= "affinity";
19248 case PRAGMA_OMP_CLAUSE_DEPEND
:
19249 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
19252 case PRAGMA_OMP_CLAUSE_DOACROSS
:
19253 clauses
= c_parser_omp_clause_doacross (parser
, clauses
);
19254 c_name
= "doacross";
19256 case PRAGMA_OMP_CLAUSE_MAP
:
19257 clauses
= c_parser_omp_clause_map (parser
, clauses
);
19260 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
19261 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
19262 c_name
= "use_device_ptr";
19264 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
:
19265 clauses
= c_parser_omp_clause_use_device_addr (parser
, clauses
);
19266 c_name
= "use_device_addr";
19268 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
:
19269 clauses
= c_parser_omp_clause_has_device_addr (parser
, clauses
);
19270 c_name
= "has_device_addr";
19272 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
19273 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
19274 c_name
= "is_device_ptr";
19276 case PRAGMA_OMP_CLAUSE_DEVICE
:
19277 clauses
= c_parser_omp_clause_device (parser
, clauses
);
19280 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
19281 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
19282 c_name
= "dist_schedule";
19284 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
19285 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
19286 c_name
= "proc_bind";
19288 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE
:
19289 clauses
= c_parser_omp_clause_device_type (parser
, clauses
);
19290 c_name
= "device_type";
19292 case PRAGMA_OMP_CLAUSE_SAFELEN
:
19293 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
19294 c_name
= "safelen";
19296 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
19297 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
19298 c_name
= "simdlen";
19300 case PRAGMA_OMP_CLAUSE_NOGROUP
:
19301 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
19302 c_name
= "nogroup";
19304 case PRAGMA_OMP_CLAUSE_THREADS
:
19306 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
19308 c_name
= "threads";
19310 case PRAGMA_OMP_CLAUSE_SIMD
:
19312 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
19316 case PRAGMA_OMP_CLAUSE_ENTER
:
19318 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
19323 c_parser_error (parser
, "expected an OpenMP clause");
19329 if (((mask
>> c_kind
) & 1) == 0)
19331 /* Remove the invalid clause(s) from the list to avoid
19332 confusing the rest of the compiler. */
19334 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
19340 c_parser_skip_to_pragma_eol (parser
);
19344 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
19345 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
19346 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
19352 /* OpenACC 2.0, OpenMP 2.5:
19356 In practice, we're also interested in adding the statement to an
19357 outer node. So it is convenient if we work around the fact that
19358 c_parser_statement calls add_stmt. */
19361 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
19363 tree stmt
= push_stmt_list ();
19364 parser
->omp_attrs_forbidden_p
= true;
19365 c_parser_statement (parser
, if_p
);
19366 return pop_stmt_list (stmt
);
19370 # pragma acc cache (variable-list) new-line
19372 LOC is the location of the #pragma token.
19376 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
19378 tree stmt
, clauses
;
19380 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE__CACHE_
, NULL
);
19381 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
19383 c_parser_skip_to_pragma_eol (parser
);
19385 stmt
= make_node (OACC_CACHE
);
19386 TREE_TYPE (stmt
) = void_type_node
;
19387 OACC_CACHE_CLAUSES (stmt
) = clauses
;
19388 SET_EXPR_LOCATION (stmt
, loc
);
19395 # pragma acc data oacc-data-clause[optseq] new-line
19398 LOC is the location of the #pragma token.
19401 #define OACC_DATA_CLAUSE_MASK \
19402 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
19403 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19404 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19405 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19406 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19407 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
19408 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19409 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
19410 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
19411 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
19414 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
19416 tree stmt
, clauses
, block
;
19418 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
19419 "#pragma acc data");
19421 block
= c_begin_omp_parallel ();
19422 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19424 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
19430 # pragma acc declare oacc-data-clause[optseq] new-line
19433 #define OACC_DECLARE_CLAUSE_MASK \
19434 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19435 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19436 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19437 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19438 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19439 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
19440 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
19441 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
19444 c_parser_oacc_declare (c_parser
*parser
)
19446 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
19447 tree clauses
, stmt
, t
, decl
;
19449 bool error
= false;
19451 c_parser_consume_pragma (parser
);
19453 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
19454 "#pragma acc declare");
19457 error_at (pragma_loc
,
19458 "no valid clauses specified in %<#pragma acc declare%>");
19462 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
19464 location_t loc
= OMP_CLAUSE_LOCATION (t
);
19465 decl
= OMP_CLAUSE_DECL (t
);
19466 if (!DECL_P (decl
))
19468 error_at (loc
, "array section in %<#pragma acc declare%>");
19473 switch (OMP_CLAUSE_MAP_KIND (t
))
19475 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19476 case GOMP_MAP_ALLOC
:
19478 case GOMP_MAP_FORCE_DEVICEPTR
:
19479 case GOMP_MAP_DEVICE_RESIDENT
:
19482 case GOMP_MAP_LINK
:
19483 if (!global_bindings_p ()
19484 && (TREE_STATIC (decl
)
19485 || !DECL_EXTERNAL (decl
)))
19488 "%qD must be a global variable in "
19489 "%<#pragma acc declare link%>",
19497 if (global_bindings_p ())
19499 error_at (loc
, "invalid OpenACC clause at file scope");
19503 if (DECL_EXTERNAL (decl
))
19506 "invalid use of %<extern%> variable %qD "
19507 "in %<#pragma acc declare%>", decl
);
19511 else if (TREE_PUBLIC (decl
))
19514 "invalid use of %<global%> variable %qD "
19515 "in %<#pragma acc declare%>", decl
);
19522 if (!c_check_in_current_scope (decl
))
19525 "%qD must be a variable declared in the same scope as "
19526 "%<#pragma acc declare%>", decl
);
19531 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
19532 || lookup_attribute ("omp declare target link",
19533 DECL_ATTRIBUTES (decl
)))
19535 error_at (loc
, "variable %qD used more than once with "
19536 "%<#pragma acc declare%>", decl
);
19545 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
19546 id
= get_identifier ("omp declare target link");
19548 id
= get_identifier ("omp declare target");
19550 DECL_ATTRIBUTES (decl
)
19551 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
19553 if (global_bindings_p ())
19555 symtab_node
*node
= symtab_node::get (decl
);
19558 node
->offloadable
= 1;
19559 if (ENABLE_OFFLOADING
)
19561 g
->have_offload
= true;
19562 if (is_a
<varpool_node
*> (node
))
19563 vec_safe_push (offload_vars
, decl
);
19570 if (error
|| global_bindings_p ())
19573 stmt
= make_node (OACC_DECLARE
);
19574 TREE_TYPE (stmt
) = void_type_node
;
19575 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
19576 SET_EXPR_LOCATION (stmt
, pragma_loc
);
19584 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
19588 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
19591 LOC is the location of the #pragma token.
19594 #define OACC_ENTER_DATA_CLAUSE_MASK \
19595 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
19596 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
19597 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
19598 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19599 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19600 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
19602 #define OACC_EXIT_DATA_CLAUSE_MASK \
19603 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
19604 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
19605 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19606 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
19607 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
19608 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
19609 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
19612 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
19614 location_t loc
= c_parser_peek_token (parser
)->location
;
19615 tree clauses
, stmt
;
19616 const char *p
= "";
19618 c_parser_consume_pragma (parser
);
19620 if (c_parser_next_token_is (parser
, CPP_NAME
))
19622 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19623 c_parser_consume_token (parser
);
19626 if (strcmp (p
, "data") != 0)
19628 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
19629 enter
? "enter" : "exit");
19630 parser
->error
= true;
19631 c_parser_skip_to_pragma_eol (parser
);
19636 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
19637 "#pragma acc enter data");
19639 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
19640 "#pragma acc exit data");
19642 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
19644 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
19645 enter
? "enter" : "exit");
19649 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
19650 TREE_TYPE (stmt
) = void_type_node
;
19651 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
19652 SET_EXPR_LOCATION (stmt
, loc
);
19658 # pragma acc host_data oacc-data-clause[optseq] new-line
19662 #define OACC_HOST_DATA_CLAUSE_MASK \
19663 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
19664 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
19665 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
19668 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
19670 tree stmt
, clauses
, block
;
19672 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
19673 "#pragma acc host_data", false);
19674 if (!omp_find_clause (clauses
, OMP_CLAUSE_USE_DEVICE_PTR
))
19676 error_at (loc
, "%<host_data%> construct requires %<use_device%> clause");
19677 return error_mark_node
;
19679 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
19680 block
= c_begin_omp_parallel ();
19681 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19682 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
19689 # pragma acc loop oacc-loop-clause[optseq] new-line
19692 LOC is the location of the #pragma token.
19695 #define OACC_LOOP_CLAUSE_MASK \
19696 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
19697 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
19698 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
19699 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
19700 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
19701 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
19702 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
19703 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
19704 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
19705 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
19707 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
19708 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
19710 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
19712 strcat (p_name
, " loop");
19713 mask
|= OACC_LOOP_CLAUSE_MASK
;
19715 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
19719 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
19721 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC
);
19723 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
19726 tree block
= c_begin_compound_stmt (true);
19727 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
19729 block
= c_end_compound_stmt (loc
, block
, true);
19736 # pragma acc kernels oacc-kernels-clause[optseq] new-line
19741 # pragma acc parallel oacc-parallel-clause[optseq] new-line
19746 # pragma acc serial oacc-serial-clause[optseq] new-line
19749 LOC is the location of the #pragma token.
19752 #define OACC_KERNELS_CLAUSE_MASK \
19753 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
19754 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
19755 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19756 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19757 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19758 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19759 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
19760 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19761 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
19762 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
19763 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
19764 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
19765 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
19766 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
19767 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
19768 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
19770 #define OACC_PARALLEL_CLAUSE_MASK \
19771 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
19772 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
19773 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19774 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19775 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19776 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19777 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
19778 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19779 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
19780 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
19781 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
19782 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
19783 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
19784 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
19785 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
19786 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
19787 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
19788 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
19789 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
19791 #define OACC_SERIAL_CLAUSE_MASK \
19792 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
19793 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
19794 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19795 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19796 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19797 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19798 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
19799 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19800 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
19801 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
19802 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
19803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
19804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
19805 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
19806 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
19807 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
19810 c_parser_oacc_compute (location_t loc
, c_parser
*parser
,
19811 enum pragma_kind p_kind
, char *p_name
, bool *if_p
)
19813 omp_clause_mask mask
;
19814 enum tree_code code
;
19817 case PRAGMA_OACC_KERNELS
:
19818 strcat (p_name
, " kernels");
19819 mask
= OACC_KERNELS_CLAUSE_MASK
;
19820 code
= OACC_KERNELS
;
19822 case PRAGMA_OACC_PARALLEL
:
19823 strcat (p_name
, " parallel");
19824 mask
= OACC_PARALLEL_CLAUSE_MASK
;
19825 code
= OACC_PARALLEL
;
19827 case PRAGMA_OACC_SERIAL
:
19828 strcat (p_name
, " serial");
19829 mask
= OACC_SERIAL_CLAUSE_MASK
;
19830 code
= OACC_SERIAL
;
19833 gcc_unreachable ();
19836 if (c_parser_next_token_is (parser
, CPP_NAME
))
19838 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19839 if (strcmp (p
, "loop") == 0)
19841 c_parser_consume_token (parser
);
19842 tree block
= c_begin_omp_parallel ();
19844 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
19845 return c_finish_omp_construct (loc
, code
, block
, clauses
);
19849 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
);
19851 tree block
= c_begin_omp_parallel ();
19852 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19854 return c_finish_omp_construct (loc
, code
, block
, clauses
);
19858 # pragma acc routine oacc-routine-clause[optseq] new-line
19859 function-definition
19861 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
19864 #define OACC_ROUTINE_CLAUSE_MASK \
19865 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
19866 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
19867 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
19868 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
19869 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
19871 /* Parse an OpenACC routine directive. For named directives, we apply
19872 immediately to the named function. For unnamed ones we then parse
19873 a declaration or definition, which must be for a function. */
19876 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
19878 gcc_checking_assert (context
== pragma_external
);
19880 oacc_routine_data data
;
19881 data
.error_seen
= false;
19882 data
.fndecl_seen
= false;
19883 data
.loc
= c_parser_peek_token (parser
)->location
;
19885 c_parser_consume_pragma (parser
);
19887 /* Look for optional '( name )'. */
19888 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
19890 c_parser_consume_token (parser
); /* '(' */
19892 tree decl
= NULL_TREE
;
19893 c_token
*name_token
= c_parser_peek_token (parser
);
19894 location_t name_loc
= name_token
->location
;
19895 if (name_token
->type
== CPP_NAME
19896 && (name_token
->id_kind
== C_ID_ID
19897 || name_token
->id_kind
== C_ID_TYPENAME
))
19899 decl
= lookup_name (name_token
->value
);
19901 error_at (name_loc
,
19902 "%qE has not been declared", name_token
->value
);
19903 c_parser_consume_token (parser
);
19906 c_parser_error (parser
, "expected function name");
19909 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
19911 c_parser_skip_to_pragma_eol (parser
, false);
19916 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
19917 "#pragma acc routine");
19918 /* The clauses are in reverse order; fix that to make later diagnostic
19919 emission easier. */
19920 data
.clauses
= nreverse (data
.clauses
);
19922 if (TREE_CODE (decl
) != FUNCTION_DECL
)
19924 error_at (name_loc
, "%qD does not refer to a function", decl
);
19928 c_finish_oacc_routine (&data
, decl
, false);
19930 else /* No optional '( name )'. */
19933 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
19934 "#pragma acc routine");
19935 /* The clauses are in reverse order; fix that to make later diagnostic
19936 emission easier. */
19937 data
.clauses
= nreverse (data
.clauses
);
19939 /* Emit a helpful diagnostic if there's another pragma following this
19940 one. Also don't allow a static assertion declaration, as in the
19941 following we'll just parse a *single* "declaration or function
19942 definition", and the static assertion counts an one. */
19943 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
19944 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
19946 error_at (data
.loc
,
19947 "%<#pragma acc routine%> not immediately followed by"
19948 " function declaration or definition");
19949 /* ..., and then just keep going. */
19953 /* We only have to consider the pragma_external case here. */
19954 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19955 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
19957 int ext
= disable_extension_diagnostics ();
19959 c_parser_consume_token (parser
);
19960 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
19961 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
19962 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
19963 NULL
, NULL
, false, NULL
, &data
);
19964 restore_extension_diagnostics (ext
);
19967 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
19968 NULL
, NULL
, false, NULL
, &data
);
19972 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
19973 IS_DEFN is true if we're applying it to the definition. */
19976 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
19979 /* Keep going if we're in error reporting mode. */
19980 if (data
->error_seen
19981 || fndecl
== error_mark_node
)
19984 if (data
->fndecl_seen
)
19986 error_at (data
->loc
,
19987 "%<#pragma acc routine%> not immediately followed by"
19988 " a single function declaration or definition");
19989 data
->error_seen
= true;
19992 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
19994 error_at (data
->loc
,
19995 "%<#pragma acc routine%> not immediately followed by"
19996 " function declaration or definition");
19997 data
->error_seen
= true;
20002 = oacc_verify_routine_clauses (fndecl
, &data
->clauses
, data
->loc
,
20003 "#pragma acc routine");
20004 if (compatible
< 0)
20006 data
->error_seen
= true;
20009 if (compatible
> 0)
20014 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
20016 error_at (data
->loc
,
20018 ? G_("%<#pragma acc routine%> must be applied before use")
20019 : G_("%<#pragma acc routine%> must be applied before"
20021 data
->error_seen
= true;
20025 /* Set the routine's level of parallelism. */
20026 tree dims
= oacc_build_routine_dims (data
->clauses
);
20027 oacc_replace_fn_attrib (fndecl
, dims
);
20029 /* Add an "omp declare target" attribute. */
20030 DECL_ATTRIBUTES (fndecl
)
20031 = tree_cons (get_identifier ("omp declare target"),
20032 data
->clauses
, DECL_ATTRIBUTES (fndecl
));
20035 /* Remember that we've used this "#pragma acc routine". */
20036 data
->fndecl_seen
= true;
20040 # pragma acc update oacc-update-clause[optseq] new-line
20043 #define OACC_UPDATE_CLAUSE_MASK \
20044 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20045 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
20046 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
20047 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20048 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
20049 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20050 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20053 c_parser_oacc_update (c_parser
*parser
)
20055 location_t loc
= c_parser_peek_token (parser
)->location
;
20057 c_parser_consume_pragma (parser
);
20059 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
20060 "#pragma acc update");
20061 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
20064 "%<#pragma acc update%> must contain at least one "
20065 "%<device%> or %<host%> or %<self%> clause");
20072 tree stmt
= make_node (OACC_UPDATE
);
20073 TREE_TYPE (stmt
) = void_type_node
;
20074 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
20075 SET_EXPR_LOCATION (stmt
, loc
);
20080 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
20082 LOC is the location of the #pragma token.
20085 #define OACC_WAIT_CLAUSE_MASK \
20086 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
20089 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
20091 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
20093 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
20094 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
20096 strcpy (p_name
, " wait");
20097 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
20098 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
20104 struct c_omp_loc_tree
20110 /* Check whether the expression used in the allocator clause is declared or
20111 modified between the variable declaration and its allocate directive. */
20113 c_check_omp_allocate_allocator_r (tree
*tp
, int *, void *data
)
20115 tree var
= ((struct c_omp_loc_tree
*) data
)->var
;
20116 location_t loc
= ((struct c_omp_loc_tree
*) data
)->loc
;
20117 if (TREE_CODE (*tp
) == VAR_DECL
&& c_check_in_current_scope (*tp
))
20119 if (linemap_location_before_p (line_table
, DECL_SOURCE_LOCATION (var
),
20120 DECL_SOURCE_LOCATION (*tp
)))
20122 error_at (loc
, "variable %qD used in the %<allocator%> clause must "
20123 "be declared before %qD", *tp
, var
);
20124 inform (DECL_SOURCE_LOCATION (*tp
), "declared here");
20125 inform (DECL_SOURCE_LOCATION (var
),
20126 "to be allocated variable declared here");
20131 gcc_assert (cur_stmt_list
20132 && TREE_CODE (cur_stmt_list
) == STATEMENT_LIST
);
20134 tree_stmt_iterator l
= tsi_last (cur_stmt_list
);
20135 while (!tsi_end_p (l
))
20137 if (linemap_location_before_p (line_table
, EXPR_LOCATION (*l
),
20138 DECL_SOURCE_LOCATION (var
)))
20140 if (TREE_CODE (*l
) == MODIFY_EXPR
20141 && TREE_OPERAND (*l
, 0) == *tp
)
20144 "variable %qD used in the %<allocator%> clause "
20145 "must not be modified between declaration of %qD "
20146 "and its %<allocate%> directive", *tp
, var
);
20147 inform (EXPR_LOCATION (*l
), "modified here");
20148 inform (DECL_SOURCE_LOCATION (var
),
20149 "to be allocated variable declared here");
20160 # pragma omp allocate (list) clauses
20163 allocator (omp_allocator_handle_t expression)
20165 OpenMP 5.1 additional clause:
20166 align (constant-expression)] */
20169 c_parser_omp_allocate (c_parser
*parser
)
20171 tree alignment
= NULL_TREE
;
20172 tree allocator
= NULL_TREE
;
20173 c_parser_consume_pragma (parser
);
20174 location_t loc
= c_parser_peek_token (parser
)->location
;
20175 location_t allocator_loc
= UNKNOWN_LOCATION
;
20176 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ALLOCATE
, NULL_TREE
);
20179 if (c_parser_next_token_is (parser
, CPP_COMMA
)
20180 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
20181 c_parser_consume_token (parser
);
20182 if (!c_parser_next_token_is (parser
, CPP_NAME
))
20184 matching_parens parens
;
20185 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20186 c_parser_consume_token (parser
);
20187 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
20188 if (strcmp ("align", p
) != 0 && strcmp ("allocator", p
) != 0)
20190 error_at (c_parser_peek_token (parser
)->location
,
20191 "expected %<allocator%> or %<align%>");
20194 if (!parens
.require_open (parser
))
20197 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
20198 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
20199 expr_loc
= c_parser_peek_token (parser
)->location
;
20200 if (expr
.value
== error_mark_node
)
20202 else if (p
[2] == 'i' && alignment
)
20204 error_at (expr_loc
, "too many %qs clauses", "align");
20207 else if (p
[2] == 'i')
20209 alignment
= c_fully_fold (expr
.value
, false, NULL
);
20210 if (TREE_CODE (alignment
) != INTEGER_CST
20211 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
20212 || tree_int_cst_sgn (alignment
) != 1
20213 || !integer_pow2p (alignment
))
20215 error_at (expr_loc
, "%<align%> clause argument needs to be "
20216 "positive constant power of two integer "
20218 alignment
= NULL_TREE
;
20221 else if (allocator
)
20223 error_at (expr_loc
, "too many %qs clauses", "allocator");
20228 allocator
= c_fully_fold (expr
.value
, false, NULL
);
20229 allocator_loc
= expr_loc
;
20231 = expr
.original_type
? expr
.original_type
: TREE_TYPE (allocator
);
20232 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
20233 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
20234 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
20235 || TYPE_NAME (orig_type
)
20236 != get_identifier ("omp_allocator_handle_t"))
20238 error_at (expr_loc
,
20239 "%<allocator%> clause allocator expression has type "
20240 "%qT rather than %<omp_allocator_handle_t%>",
20241 TREE_TYPE (allocator
));
20242 allocator
= NULL_TREE
;
20245 parens
.skip_until_found_close (parser
);
20247 c_parser_skip_to_pragma_eol (parser
);
20249 c_mark_decl_jump_unsafe_in_current_scope ();
20250 for (tree c
= nl
; c
!= NULL_TREE
; c
= OMP_CLAUSE_CHAIN (c
))
20252 tree var
= OMP_CLAUSE_DECL (c
);
20253 if (TREE_CODE (var
) == PARM_DECL
)
20255 error_at (OMP_CLAUSE_LOCATION (nl
),
20256 "function parameter %qD may not appear as list item in an "
20257 "%<allocate%> directive", var
);
20260 if (!c_check_in_current_scope (var
))
20262 error_at (OMP_CLAUSE_LOCATION (nl
),
20263 "%<allocate%> directive must be in the same scope as %qD",
20265 inform (DECL_SOURCE_LOCATION (var
), "declared here");
20268 if (lookup_attribute ("omp allocate", DECL_ATTRIBUTES (var
)))
20270 error_at (OMP_CLAUSE_LOCATION (nl
),
20271 "%qD already appeared as list item in an "
20272 "%<allocate%> directive", var
);
20275 if (TREE_STATIC (var
))
20277 if (allocator
== NULL_TREE
&& allocator_loc
== UNKNOWN_LOCATION
)
20278 error_at (loc
, "%<allocator%> clause required for "
20279 "static variable %qD", var
);
20281 && (wi::to_widest (allocator
) < 1
20282 || wi::to_widest (allocator
) > 8))
20283 /* 8 = largest predefined memory allocator. */
20284 error_at (allocator_loc
,
20285 "%<allocator%> clause requires a predefined allocator as "
20286 "%qD is static", var
);
20288 sorry_at (OMP_CLAUSE_LOCATION (nl
),
20289 "%<#pragma omp allocate%> for static variables like "
20290 "%qD not yet supported", var
);
20295 struct c_omp_loc_tree data
20296 = {EXPR_LOC_OR_LOC (allocator
, OMP_CLAUSE_LOCATION (nl
)), var
};
20297 walk_tree (&allocator
, c_check_omp_allocate_allocator_r
, &data
, NULL
);
20299 DECL_ATTRIBUTES (var
) = tree_cons (get_identifier ("omp allocate"),
20300 build_tree_list (allocator
, alignment
),
20301 DECL_ATTRIBUTES (var
));
20306 # pragma omp atomic new-line
20310 x binop= expr | x++ | ++x | x-- | --x
20312 +, *, -, /, &, ^, |, <<, >>
20314 where x is an lvalue expression with scalar type.
20317 # pragma omp atomic new-line
20320 # pragma omp atomic read new-line
20323 # pragma omp atomic write new-line
20326 # pragma omp atomic update new-line
20329 # pragma omp atomic capture new-line
20332 # pragma omp atomic capture new-line
20340 expression-stmt | x = x binop expr
20342 v = expression-stmt
20344 { v = x; update-stmt; } | { update-stmt; v = x; }
20348 expression-stmt | x = x binop expr | x = expr binop x
20352 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
20355 # pragma omp atomic compare new-line
20356 conditional-update-atomic
20358 # pragma omp atomic compare capture new-line
20359 conditional-update-capture-atomic
20361 conditional-update-atomic:
20362 cond-expr-stmt | cond-update-stmt
20364 x = expr ordop x ? expr : x;
20365 x = x ordop expr ? expr : x;
20366 x = x == e ? d : x;
20368 if (expr ordop x) { x = expr; }
20369 if (x ordop expr) { x = expr; }
20370 if (x == e) { x = d; }
20373 conditional-update-capture-atomic:
20375 { v = x; cond-expr-stmt }
20376 { cond-expr-stmt v = x; }
20377 { v = x; cond-update-stmt }
20378 { cond-update-stmt v = x; }
20379 if (x == e) { x = d; } else { v = x; }
20380 { r = x == e; if (r) { x = d; } }
20381 { r = x == e; if (r) { x = d; } else { v = x; } }
20383 where x, r and v are lvalue expressions with scalar type,
20384 expr, e and d are expressions with scalar type and e might be
20387 LOC is the location of the #pragma token. */
20390 c_parser_omp_atomic (location_t loc
, c_parser
*parser
, bool openacc
)
20392 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
, r
= NULL_TREE
;
20393 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
20394 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
20395 enum tree_code code
= ERROR_MARK
, opcode
= NOP_EXPR
;
20396 enum omp_memory_order memory_order
= OMP_MEMORY_ORDER_UNSPECIFIED
;
20397 struct c_expr expr
;
20399 bool structured_block
= false;
20400 bool swapped
= false;
20402 tree clauses
= NULL_TREE
;
20403 bool capture
= false;
20404 bool compare
= false;
20406 enum omp_memory_order fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
20407 bool no_semicolon
= false;
20408 bool extra_scope
= false;
20410 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
20412 if (c_parser_next_token_is (parser
, CPP_COMMA
)
20413 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
20414 c_parser_consume_token (parser
);
20416 if (c_parser_next_token_is (parser
, CPP_NAME
))
20419 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20420 location_t cloc
= c_parser_peek_token (parser
)->location
;
20421 enum tree_code new_code
= ERROR_MARK
;
20422 enum omp_memory_order new_memory_order
20423 = OMP_MEMORY_ORDER_UNSPECIFIED
;
20424 bool new_capture
= false;
20425 bool new_compare
= false;
20426 bool new_weak
= false;
20427 enum omp_memory_order new_fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
20429 if (!strcmp (p
, "read"))
20430 new_code
= OMP_ATOMIC_READ
;
20431 else if (!strcmp (p
, "write"))
20432 new_code
= NOP_EXPR
;
20433 else if (!strcmp (p
, "update"))
20434 new_code
= OMP_ATOMIC
;
20435 else if (openacc
&& !strcmp (p
, "capture"))
20436 new_code
= OMP_ATOMIC_CAPTURE_NEW
;
20440 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
20441 "or %<capture%> clause");
20443 else if (!strcmp (p
, "capture"))
20444 new_capture
= true;
20445 else if (!strcmp (p
, "compare"))
20446 new_compare
= true;
20447 else if (!strcmp (p
, "weak"))
20449 else if (!strcmp (p
, "fail"))
20451 matching_parens parens
;
20453 c_parser_consume_token (parser
);
20454 if (!parens
.require_open (parser
))
20457 if (c_parser_next_token_is (parser
, CPP_NAME
))
20460 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20462 if (!strcmp (q
, "seq_cst"))
20463 new_fail
= OMP_MEMORY_ORDER_SEQ_CST
;
20464 else if (!strcmp (q
, "acquire"))
20465 new_fail
= OMP_MEMORY_ORDER_ACQUIRE
;
20466 else if (!strcmp (q
, "relaxed"))
20467 new_fail
= OMP_MEMORY_ORDER_RELAXED
;
20470 if (new_fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
20472 c_parser_consume_token (parser
);
20473 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
20474 error_at (cloc
, "too many %qs clauses", "fail");
20479 c_parser_error (parser
, "expected %<seq_cst%>, %<acquire%> "
20481 parens
.skip_until_found_close (parser
);
20484 else if (!strcmp (p
, "seq_cst"))
20485 new_memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
20486 else if (!strcmp (p
, "acq_rel"))
20487 new_memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
20488 else if (!strcmp (p
, "release"))
20489 new_memory_order
= OMP_MEMORY_ORDER_RELEASE
;
20490 else if (!strcmp (p
, "acquire"))
20491 new_memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
20492 else if (!strcmp (p
, "relaxed"))
20493 new_memory_order
= OMP_MEMORY_ORDER_RELAXED
;
20494 else if (!strcmp (p
, "hint"))
20496 c_parser_consume_token (parser
);
20497 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
20503 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
20504 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
20505 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
20506 "%<relaxed%> or %<hint%> clause");
20510 if (new_code
!= ERROR_MARK
)
20512 /* OpenACC permits 'update capture'. */
20514 && code
== OMP_ATOMIC
20515 && new_code
== OMP_ATOMIC_CAPTURE_NEW
)
20517 else if (code
!= ERROR_MARK
)
20518 error_at (cloc
, "too many atomic clauses");
20522 else if (new_memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
20524 if (memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
20525 error_at (cloc
, "too many memory order clauses");
20527 memory_order
= new_memory_order
;
20529 else if (new_capture
)
20532 error_at (cloc
, "too many %qs clauses", "capture");
20536 else if (new_compare
)
20539 error_at (cloc
, "too many %qs clauses", "compare");
20546 error_at (cloc
, "too many %qs clauses", "weak");
20550 c_parser_consume_token (parser
);
20556 c_parser_skip_to_pragma_eol (parser
);
20558 if (code
== ERROR_MARK
)
20562 if (code
!= OMP_ATOMIC
)
20563 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
20564 "clauses", "capture");
20566 code
= OMP_ATOMIC_CAPTURE_NEW
;
20568 if (compare
&& code
!= OMP_ATOMIC
&& code
!= OMP_ATOMIC_CAPTURE_NEW
)
20570 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
20571 "clauses", "compare");
20574 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
&& !compare
)
20576 error_at (loc
, "%qs clause requires %qs clause", "fail", "compare");
20577 fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
20579 if (weak
&& !compare
)
20581 error_at (loc
, "%qs clause requires %qs clause", "weak", "compare");
20585 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
20586 else if (memory_order
== OMP_MEMORY_ORDER_UNSPECIFIED
)
20589 = (enum omp_requires
) (omp_requires_mask
20590 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
);
20591 switch ((enum omp_memory_order
)
20592 (omp_requires_mask
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
))
20594 case OMP_MEMORY_ORDER_UNSPECIFIED
:
20595 case OMP_MEMORY_ORDER_RELAXED
:
20596 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
20598 case OMP_MEMORY_ORDER_SEQ_CST
:
20599 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
20601 case OMP_MEMORY_ORDER_ACQ_REL
:
20604 case OMP_ATOMIC_READ
:
20605 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
20607 case NOP_EXPR
: /* atomic write */
20608 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
20611 memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
20616 gcc_unreachable ();
20622 case OMP_ATOMIC_READ
:
20623 if (memory_order
== OMP_MEMORY_ORDER_RELEASE
)
20625 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
20626 "%<release%> clause");
20627 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
20629 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
20630 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
20632 case NOP_EXPR
: /* atomic write */
20633 if (memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
20635 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
20636 "%<acquire%> clause");
20637 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
20639 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
20640 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
20645 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
20647 = (enum omp_memory_order
) (memory_order
20648 | (fail
<< OMP_FAIL_MEMORY_ORDER_SHIFT
));
20652 case OMP_ATOMIC_READ
:
20653 case NOP_EXPR
: /* atomic write */
20654 v
= c_parser_cast_expression (parser
, NULL
).value
;
20655 non_lvalue_p
= !lvalue_p (v
);
20656 v
= c_fully_fold (v
, false, NULL
, true);
20657 if (v
== error_mark_node
)
20660 v
= non_lvalue (v
);
20661 loc
= c_parser_peek_token (parser
)->location
;
20662 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
20664 if (code
== NOP_EXPR
)
20666 lhs
= c_parser_expression (parser
).value
;
20667 lhs
= c_fully_fold (lhs
, false, NULL
);
20668 if (lhs
== error_mark_node
)
20673 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
20674 non_lvalue_p
= !lvalue_p (lhs
);
20675 lhs
= c_fully_fold (lhs
, false, NULL
, true);
20676 if (lhs
== error_mark_node
)
20679 lhs
= non_lvalue (lhs
);
20681 if (code
== NOP_EXPR
)
20683 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
20691 case OMP_ATOMIC_CAPTURE_NEW
:
20692 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
20694 c_parser_consume_token (parser
);
20695 structured_block
= true;
20698 && c_parser_next_token_is_keyword (parser
, RID_IF
))
20702 v
= c_parser_cast_expression (parser
, NULL
).value
;
20703 non_lvalue_p
= !lvalue_p (v
);
20704 v
= c_fully_fold (v
, false, NULL
, true);
20705 if (v
== error_mark_node
)
20708 v
= non_lvalue (v
);
20709 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
20711 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
20713 eloc
= c_parser_peek_token (parser
)->location
;
20714 error_at (eloc
, "expected expression");
20723 /* For structured_block case we don't know yet whether
20724 old or new x should be captured. */
20726 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
20728 c_parser_consume_token (parser
);
20730 matching_parens parens
;
20731 if (!parens
.require_open (parser
))
20733 eloc
= c_parser_peek_token (parser
)->location
;
20737 cmp_expr
= c_parser_cast_expression (parser
, NULL
);
20738 cmp_expr
= default_function_array_conversion (eloc
, cmp_expr
);
20741 cmp_expr
= c_parser_binary_expression (parser
, NULL
, void_list_node
);
20742 parens
.skip_until_found_close (parser
);
20743 if (cmp_expr
.value
== error_mark_node
)
20747 if (!c_tree_equal (cmp_expr
.value
, unfolded_lhs
))
20749 cmp_expr
.value
= rhs1
;
20751 gcc_assert (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
);
20753 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
20755 else if (!structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
20757 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
20758 "expected %<==%> comparison in %<if%> condition");
20761 else if (TREE_CODE (cmp_expr
.value
) != GT_EXPR
20762 && TREE_CODE (cmp_expr
.value
) != LT_EXPR
)
20764 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
20765 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
20769 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
20772 extra_scope
= true;
20773 eloc
= c_parser_peek_token (parser
)->location
;
20774 expr
= c_parser_cast_expression (parser
, NULL
);
20776 expr
= default_function_array_conversion (eloc
, expr
);
20777 unfolded_lhs
= expr
.value
;
20778 lhs
= c_fully_fold (lhs
, false, NULL
, true);
20780 if (lhs
== error_mark_node
)
20782 if (!lvalue_p (unfolded_lhs
))
20783 lhs
= non_lvalue (lhs
);
20784 if (!c_parser_next_token_is (parser
, CPP_EQ
))
20786 c_parser_error (parser
, "expected %<=%>");
20789 c_parser_consume_token (parser
);
20790 eloc
= c_parser_peek_token (parser
)->location
;
20791 expr
= c_parser_expr_no_commas (parser
, NULL
);
20794 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
20797 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
20800 extra_scope
= false;
20801 no_semicolon
= true;
20803 if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), unfolded_lhs
))
20805 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
20807 opcode
= COND_EXPR
;
20808 rhs
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
20809 false, NULL
, true);
20810 rhs1
= c_fully_fold (rhs1
, false, NULL
, true);
20812 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), rhs1
))
20814 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
20815 ? MIN_EXPR
: MAX_EXPR
);
20816 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
20817 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 0),
20818 false, NULL
, true);
20823 else if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
20825 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), unfolded_lhs
)
20826 && c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), rhs1
))
20828 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
20829 ? MAX_EXPR
: MIN_EXPR
);
20830 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
20831 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
20832 false, NULL
, true);
20837 c_parser_error (parser
,
20838 "invalid form of %<#pragma omp atomic compare%>");
20842 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
20844 if (code
!= OMP_ATOMIC_CAPTURE_NEW
20845 || (structured_block
&& r
== NULL_TREE
)
20846 || TREE_CODE (cmp_expr
.value
) != EQ_EXPR
)
20848 eloc
= c_parser_peek_token (parser
)->location
;
20849 error_at (eloc
, "unexpected %<else%>");
20853 c_parser_consume_token (parser
);
20855 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
20858 extra_scope
= true;
20859 v
= c_parser_cast_expression (parser
, NULL
).value
;
20860 non_lvalue_p
= !lvalue_p (v
);
20861 v
= c_fully_fold (v
, false, NULL
, true);
20862 if (v
== error_mark_node
)
20865 v
= non_lvalue (v
);
20866 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
20869 expr
= c_parser_expr_no_commas (parser
, NULL
);
20871 if (!c_tree_equal (expr
.value
, unfolded_lhs
))
20874 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
20877 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
20880 extra_scope
= false;
20881 code
= OMP_ATOMIC_CAPTURE_OLD
;
20882 if (r
== NULL_TREE
)
20883 /* Signal to c_finish_omp_atomic that in
20884 if (x == e) { x = d; } else { v = x; }
20885 case the store to v should be conditional. */
20886 r
= void_list_node
;
20888 else if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
20890 c_parser_require_keyword (parser
, RID_ELSE
, "expected %<else%>");
20893 else if (code
== OMP_ATOMIC_CAPTURE_NEW
20899 eloc
= c_parser_peek_token (parser
)->location
;
20900 expr
= c_parser_cast_expression (parser
, NULL
);
20902 expr
= default_function_array_conversion (eloc
, expr
);
20903 unfolded_lhs
= expr
.value
;
20904 lhs
= c_fully_fold (lhs
, false, NULL
, true);
20906 switch (TREE_CODE (lhs
))
20909 error_at (eloc
, "invalid form of %<pragma omp atomic compare%>");
20913 c_parser_skip_to_end_of_block_or_statement (parser
);
20914 if (extra_scope
&& c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
20915 c_parser_consume_token (parser
);
20916 if (structured_block
)
20918 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
20919 c_parser_consume_token (parser
);
20920 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
20922 c_parser_skip_to_end_of_block_or_statement (parser
);
20923 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
20924 c_parser_consume_token (parser
);
20929 case POSTINCREMENT_EXPR
:
20930 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
20931 code
= OMP_ATOMIC_CAPTURE_OLD
;
20933 case PREINCREMENT_EXPR
:
20934 lhs
= TREE_OPERAND (lhs
, 0);
20935 unfolded_lhs
= NULL_TREE
;
20936 opcode
= PLUS_EXPR
;
20937 rhs
= integer_one_node
;
20939 goto invalid_compare
;
20942 case POSTDECREMENT_EXPR
:
20943 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
20944 code
= OMP_ATOMIC_CAPTURE_OLD
;
20946 case PREDECREMENT_EXPR
:
20947 lhs
= TREE_OPERAND (lhs
, 0);
20948 unfolded_lhs
= NULL_TREE
;
20949 opcode
= MINUS_EXPR
;
20950 rhs
= integer_one_node
;
20952 goto invalid_compare
;
20955 case COMPOUND_EXPR
:
20956 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
20957 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
20958 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
20959 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
20960 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
20961 (TREE_OPERAND (lhs
, 1), 0), 0))))
20962 /* Undo effects of boolean_increment for post {in,de}crement. */
20963 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
20966 if (TREE_CODE (lhs
) == MODIFY_EXPR
20967 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs
, 0))))
20969 /* Undo effects of boolean_increment. */
20970 if (integer_onep (TREE_OPERAND (lhs
, 1)))
20972 /* This is pre or post increment. */
20973 rhs
= TREE_OPERAND (lhs
, 1);
20974 lhs
= TREE_OPERAND (lhs
, 0);
20975 unfolded_lhs
= NULL_TREE
;
20977 if (code
== OMP_ATOMIC_CAPTURE_NEW
20978 && !structured_block
20979 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
20980 code
= OMP_ATOMIC_CAPTURE_OLD
;
20982 goto invalid_compare
;
20985 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
20986 && TREE_OPERAND (lhs
, 0)
20987 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
20989 /* This is pre or post decrement. */
20990 rhs
= TREE_OPERAND (lhs
, 1);
20991 lhs
= TREE_OPERAND (lhs
, 0);
20992 unfolded_lhs
= NULL_TREE
;
20994 if (code
== OMP_ATOMIC_CAPTURE_NEW
20995 && !structured_block
20996 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
20997 code
= OMP_ATOMIC_CAPTURE_OLD
;
20999 goto invalid_compare
;
21005 if (!lvalue_p (unfolded_lhs
))
21006 lhs
= non_lvalue (lhs
);
21007 if (compare
&& !c_parser_next_token_is (parser
, CPP_EQ
))
21009 c_parser_error (parser
, "expected %<=%>");
21012 switch (c_parser_peek_token (parser
)->type
)
21015 opcode
= MULT_EXPR
;
21018 opcode
= TRUNC_DIV_EXPR
;
21021 opcode
= PLUS_EXPR
;
21024 opcode
= MINUS_EXPR
;
21026 case CPP_LSHIFT_EQ
:
21027 opcode
= LSHIFT_EXPR
;
21029 case CPP_RSHIFT_EQ
:
21030 opcode
= RSHIFT_EXPR
;
21033 opcode
= BIT_AND_EXPR
;
21036 opcode
= BIT_IOR_EXPR
;
21039 opcode
= BIT_XOR_EXPR
;
21042 c_parser_consume_token (parser
);
21043 eloc
= c_parser_peek_token (parser
)->location
;
21044 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
21046 switch (TREE_CODE (rhs1
))
21049 case TRUNC_DIV_EXPR
:
21060 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
21062 opcode
= TREE_CODE (rhs1
);
21063 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21065 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
21069 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
21071 opcode
= TREE_CODE (rhs1
);
21072 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
21074 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21076 swapped
= !commutative_tree_code (opcode
);
21083 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) != GT_EXPR
21084 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != LT_EXPR
21085 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != EQ_EXPR
)
21087 if (!TREE_OPERAND (rhs1
, 1))
21089 if (!c_tree_equal (TREE_OPERAND (rhs1
, 2), unfolded_lhs
))
21091 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
21094 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
21096 opcode
= COND_EXPR
;
21097 rhs
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
21099 false, NULL
, true);
21100 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false,
21104 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
21105 TREE_OPERAND (rhs1
, 1)))
21107 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
21108 ? MIN_EXPR
: MAX_EXPR
);
21109 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21111 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
21113 false, NULL
, true);
21117 else if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
21119 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
21122 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
21123 TREE_OPERAND (rhs1
, 1)))
21125 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
21126 ? MAX_EXPR
: MIN_EXPR
);
21127 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21129 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
21131 false, NULL
, true);
21138 || code
!= OMP_ATOMIC_CAPTURE_NEW
21139 || !structured_block
21143 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
21144 && c_parser_peek_2nd_token (parser
)->keyword
== RID_IF
)
21148 c_parser_consume_token (parser
);
21157 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
21159 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
21161 code
= OMP_ATOMIC_CAPTURE_OLD
;
21164 expr
= default_function_array_read_conversion (eloc
, expr
);
21165 unfolded_lhs1
= expr
.value
;
21166 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
21168 c_parser_consume_token (parser
);
21171 if (structured_block
&& !compare
)
21174 expr
= default_function_array_read_conversion (eloc
, expr
);
21175 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
21180 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
21183 c_parser_error (parser
,
21184 "invalid operator for %<#pragma omp atomic%>");
21188 /* Arrange to pass the location of the assignment operator to
21189 c_finish_omp_atomic. */
21190 loc
= c_parser_peek_token (parser
)->location
;
21191 c_parser_consume_token (parser
);
21192 eloc
= c_parser_peek_token (parser
)->location
;
21193 expr
= c_parser_expression (parser
);
21194 expr
= default_function_array_read_conversion (eloc
, expr
);
21196 rhs
= c_fully_fold (rhs
, false, NULL
, true);
21200 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
&& r
== NULL_TREE
)
21203 && !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
21205 no_semicolon
= false;
21206 v
= c_parser_cast_expression (parser
, NULL
).value
;
21207 non_lvalue_p
= !lvalue_p (v
);
21208 v
= c_fully_fold (v
, false, NULL
, true);
21209 if (v
== error_mark_node
)
21212 v
= non_lvalue (v
);
21213 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21215 eloc
= c_parser_peek_token (parser
)->location
;
21216 expr
= c_parser_cast_expression (parser
, NULL
);
21218 expr
= default_function_array_read_conversion (eloc
, expr
);
21219 unfolded_lhs1
= expr
.value
;
21220 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
21221 if (lhs1
== error_mark_node
)
21223 if (!lvalue_p (unfolded_lhs1
))
21224 lhs1
= non_lvalue (lhs1
);
21226 if (structured_block
)
21229 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
21230 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
21233 if (weak
&& opcode
!= COND_EXPR
)
21235 error_at (loc
, "%<weak%> clause requires atomic equality comparison");
21238 if (unfolded_lhs
&& unfolded_lhs1
21239 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
21241 error ("%<#pragma omp atomic capture%> uses two different "
21242 "expressions for memory");
21243 stmt
= error_mark_node
;
21246 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
, r
,
21247 swapped
, memory_order
, weak
);
21248 if (stmt
!= error_mark_node
)
21251 if (!structured_block
&& !no_semicolon
)
21252 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
21257 # pragma omp barrier new-line
21261 c_parser_omp_barrier (c_parser
*parser
)
21263 location_t loc
= c_parser_peek_token (parser
)->location
;
21264 c_parser_consume_pragma (parser
);
21265 c_parser_skip_to_pragma_eol (parser
);
21267 c_finish_omp_barrier (loc
);
21271 # pragma omp critical [(name)] new-line
21275 # pragma omp critical [(name) [hint(expression)]] new-line
21277 LOC is the location of the #pragma itself. */
21279 #define OMP_CRITICAL_CLAUSE_MASK \
21280 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
21283 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
21285 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
21287 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
21289 c_parser_consume_token (parser
);
21290 if (c_parser_next_token_is (parser
, CPP_NAME
))
21292 name
= c_parser_peek_token (parser
)->value
;
21293 c_parser_consume_token (parser
);
21294 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
21297 c_parser_error (parser
, "expected identifier");
21299 if (c_parser_next_token_is (parser
, CPP_COMMA
)
21300 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
21301 c_parser_consume_token (parser
);
21303 clauses
= c_parser_omp_all_clauses (parser
, OMP_CRITICAL_CLAUSE_MASK
,
21304 "#pragma omp critical");
21305 stmt
= c_parser_omp_structured_block (parser
, if_p
);
21306 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
21310 # pragma omp depobj ( depobj ) depobj-clause new-line
21313 depend (dependence-type : locator)
21315 update (dependence-type)
21324 c_parser_omp_depobj (c_parser
*parser
)
21326 location_t loc
= c_parser_peek_token (parser
)->location
;
21327 c_parser_consume_pragma (parser
);
21328 matching_parens parens
;
21329 if (!parens
.require_open (parser
))
21331 c_parser_skip_to_pragma_eol (parser
);
21335 tree depobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
21336 if (depobj
!= error_mark_node
)
21338 if (!lvalue_p (depobj
))
21340 error_at (EXPR_LOC_OR_LOC (depobj
, loc
),
21341 "%<depobj%> expression is not lvalue expression");
21342 depobj
= error_mark_node
;
21346 tree addr
= build_unary_op (EXPR_LOC_OR_LOC (depobj
, loc
), ADDR_EXPR
,
21348 if (addr
== error_mark_node
)
21349 depobj
= error_mark_node
;
21351 depobj
= build_indirect_ref (EXPR_LOC_OR_LOC (depobj
, loc
),
21352 addr
, RO_UNARY_STAR
);
21356 parens
.skip_until_found_close (parser
);
21357 tree clause
= NULL_TREE
;
21358 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_INVALID
;
21359 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21360 c_parser_consume_token (parser
);
21361 location_t c_loc
= c_parser_peek_token (parser
)->location
;
21362 if (c_parser_next_token_is (parser
, CPP_NAME
))
21364 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21366 c_parser_consume_token (parser
);
21367 if (!strcmp ("depend", p
))
21369 clause
= c_parser_omp_clause_depend (parser
, NULL_TREE
);
21370 clause
= c_finish_omp_clauses (clause
, C_ORT_OMP
);
21372 clause
= error_mark_node
;
21374 else if (!strcmp ("destroy", p
))
21375 kind
= OMP_CLAUSE_DEPEND_LAST
;
21376 else if (!strcmp ("update", p
))
21378 matching_parens c_parens
;
21379 if (c_parens
.require_open (parser
))
21381 location_t c2_loc
= c_parser_peek_token (parser
)->location
;
21382 if (c_parser_next_token_is (parser
, CPP_NAME
))
21385 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21387 c_parser_consume_token (parser
);
21388 if (!strcmp ("in", p2
))
21389 kind
= OMP_CLAUSE_DEPEND_IN
;
21390 else if (!strcmp ("out", p2
))
21391 kind
= OMP_CLAUSE_DEPEND_OUT
;
21392 else if (!strcmp ("inout", p2
))
21393 kind
= OMP_CLAUSE_DEPEND_INOUT
;
21394 else if (!strcmp ("mutexinoutset", p2
))
21395 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
21396 else if (!strcmp ("inoutset", p2
))
21397 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
21399 if (kind
== OMP_CLAUSE_DEPEND_INVALID
)
21401 clause
= error_mark_node
;
21402 error_at (c2_loc
, "expected %<in%>, %<out%>, %<inout%>, "
21403 "%<mutexinoutset%> or %<inoutset%>");
21405 c_parens
.skip_until_found_close (parser
);
21408 clause
= error_mark_node
;
21411 if (!clause
&& kind
== OMP_CLAUSE_DEPEND_INVALID
)
21413 clause
= error_mark_node
;
21414 error_at (c_loc
, "expected %<depend%>, %<destroy%> or %<update%> clause");
21416 c_parser_skip_to_pragma_eol (parser
);
21418 c_finish_omp_depobj (loc
, depobj
, kind
, clause
);
21423 # pragma omp flush flush-vars[opt] new-line
21429 # pragma omp flush memory-order-clause new-line */
21432 c_parser_omp_flush (c_parser
*parser
)
21434 location_t loc
= c_parser_peek_token (parser
)->location
;
21435 c_parser_consume_pragma (parser
);
21436 enum memmodel mo
= MEMMODEL_LAST
;
21437 if (c_parser_next_token_is (parser
, CPP_COMMA
)
21438 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
21439 c_parser_consume_token (parser
);
21440 if (c_parser_next_token_is (parser
, CPP_NAME
))
21443 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21445 if (!strcmp (p
, "seq_cst"))
21446 mo
= MEMMODEL_SEQ_CST
;
21447 else if (!strcmp (p
, "acq_rel"))
21448 mo
= MEMMODEL_ACQ_REL
;
21449 else if (!strcmp (p
, "release"))
21450 mo
= MEMMODEL_RELEASE
;
21451 else if (!strcmp (p
, "acquire"))
21452 mo
= MEMMODEL_ACQUIRE
;
21454 error_at (c_parser_peek_token (parser
)->location
,
21455 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
21457 c_parser_consume_token (parser
);
21459 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
21461 if (mo
!= MEMMODEL_LAST
)
21462 error_at (c_parser_peek_token (parser
)->location
,
21463 "%<flush%> list specified together with memory order "
21465 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
21467 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21468 c_parser_error (parser
, "expected %<(%> or end of line");
21469 c_parser_skip_to_pragma_eol (parser
);
21471 c_finish_omp_flush (loc
, mo
);
21474 /* Return true if next tokens contain a standard attribute that contains
21475 omp::directive (DIRECTIVE). */
21478 c_parser_omp_section_scan (c_parser
*parser
, const char *directive
,
21481 if (!c_parser_nth_token_starts_std_attributes (parser
, 1))
21483 unsigned int n
= 3;
21484 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
21486 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
21487 if (token
->type
!= CPP_CLOSE_SQUARE
)
21489 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
21490 if (token
->type
!= CPP_CLOSE_SQUARE
)
21494 if (c_parser_peek_nth_token_raw (parser
, 3)->type
== CPP_NAME
21495 && c_parser_peek_nth_token_raw (parser
, 4)->type
== CPP_OPEN_PAREN
21496 && c_parser_peek_nth_token_raw (parser
, 5)->type
== CPP_NAME
)
21498 tree first
= c_parser_peek_nth_token_raw (parser
, 3)->value
;
21499 tree second
= c_parser_peek_nth_token_raw (parser
, 5)->value
;
21500 if (strcmp (IDENTIFIER_POINTER (first
), "directive")
21501 && strcmp (IDENTIFIER_POINTER (first
), "__directive__"))
21503 if (strcmp (IDENTIFIER_POINTER (second
), directive
))
21508 location_t first_loc
= c_parser_peek_token (parser
)->location
;
21509 location_t last_loc
= c_parser_peek_nth_token_raw (parser
, n
+ 1)->location
;
21510 location_t middle_loc
= UNKNOWN_LOCATION
;
21511 tree std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
21514 for (tree attr
= std_attrs
; attr
; attr
= TREE_CHAIN (attr
))
21515 if (is_attribute_namespace_p ("omp", attr
)
21516 && is_attribute_p ("directive", get_attribute_name (attr
)))
21518 for (tree a
= TREE_VALUE (attr
); a
; a
= TREE_CHAIN (a
))
21520 tree d
= TREE_VALUE (a
);
21521 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
21522 c_token
*first
= C_TOKEN_VEC_TOKENS (d
)->address ();
21524 if (first
->type
== CPP_NAME
21525 && strcmp (IDENTIFIER_POINTER (first
->value
),
21529 if (middle_loc
== UNKNOWN_LOCATION
)
21530 middle_loc
= first
->location
;
21536 if (cnt
!= 1 || TREE_CHAIN (std_attrs
))
21538 error_at (make_location (first_loc
, last_loc
, middle_loc
),
21539 "%<[[omp::directive(%s)]]%> must be the only specified "
21540 "attribute on a statement", directive
);
21543 c_parser_handle_statement_omp_attributes (parser
, std_attrs
, NULL
);
21547 /* Parse an OpenMP structured block sequence. KIND is the corresponding
21548 separating directive. */
21551 c_parser_omp_structured_block_sequence (c_parser
*parser
,
21552 enum pragma_kind kind
)
21554 tree stmt
= push_stmt_list ();
21555 c_parser_statement (parser
, NULL
);
21558 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
21560 if (c_parser_next_token_is (parser
, CPP_EOF
))
21563 if (kind
!= PRAGMA_NONE
21564 && c_parser_peek_token (parser
)->pragma_kind
== kind
)
21567 if (kind
!= PRAGMA_NONE
21568 && c_parser_omp_section_scan (parser
,
21569 kind
== PRAGMA_OMP_SCAN
21570 ? "scan" : "section", false))
21573 c_parser_statement (parser
, NULL
);
21576 return pop_stmt_list (stmt
);
21582 { structured-block scan-directive structured-block } */
21585 c_parser_omp_scan_loop_body (c_parser
*parser
, bool open_brace_parsed
)
21589 tree clauses
= NULL_TREE
;
21590 bool found_scan
= false;
21592 loc
= c_parser_peek_token (parser
)->location
;
21593 if (!open_brace_parsed
21594 && !c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
21596 /* Avoid skipping until the end of the block. */
21597 parser
->error
= false;
21601 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SCAN
)
21602 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_OMP_SCAN
);
21605 warning_at (c_parser_peek_token (parser
)->location
, 0,
21606 "%<#pragma omp scan%> with zero preceding executable "
21608 substmt
= build_empty_stmt (loc
);
21610 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, NULL_TREE
);
21611 SET_EXPR_LOCATION (substmt
, loc
);
21612 add_stmt (substmt
);
21614 loc
= c_parser_peek_token (parser
)->location
;
21615 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SCAN
)
21617 enum omp_clause_code clause
= OMP_CLAUSE_ERROR
;
21620 c_parser_consume_pragma (parser
);
21622 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21623 c_parser_consume_token (parser
);
21625 if (c_parser_next_token_is (parser
, CPP_NAME
))
21628 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21629 if (strcmp (p
, "inclusive") == 0)
21630 clause
= OMP_CLAUSE_INCLUSIVE
;
21631 else if (strcmp (p
, "exclusive") == 0)
21632 clause
= OMP_CLAUSE_EXCLUSIVE
;
21634 if (clause
!= OMP_CLAUSE_ERROR
)
21636 c_parser_consume_token (parser
);
21637 clauses
= c_parser_omp_var_list_parens (parser
, clause
, NULL_TREE
);
21640 c_parser_error (parser
, "expected %<inclusive%> or "
21641 "%<exclusive%> clause");
21642 c_parser_skip_to_pragma_eol (parser
);
21645 error ("expected %<#pragma omp scan%>");
21647 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
21648 if (!c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
21649 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_NONE
);
21653 warning_at (loc
, 0, "%<#pragma omp scan%> with zero succeeding "
21654 "executable statements");
21655 substmt
= build_empty_stmt (loc
);
21657 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, clauses
);
21658 SET_EXPR_LOCATION (substmt
, loc
);
21659 add_stmt (substmt
);
21661 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
21666 /* This function parses a single level of a loop nest, invoking itself
21667 recursively if necessary.
21669 loop-nest :: for (...) loop-body
21670 loop-body :: loop-nest
21671 | { [intervening-code] loop-body [intervening-code] }
21673 intervening-code :: structured-block-sequence
21674 final-loop-body :: structured-block
21676 For a collapsed loop nest, only a single OMP_FOR is built, pulling out
21677 all the iterator information from the inner loops into the
21678 parser->omp_for_parse_state structure.
21680 The iterator decl, init, cond, and incr are stored in vectors.
21682 Initialization code for iterator variables is collected into
21683 parser->omp_for_parse_state->pre_body and ends up inserted directly
21684 into the OMP_FOR structure. */
21687 c_parser_omp_loop_nest (c_parser
*parser
, bool *if_p
)
21689 tree decl
, cond
, incr
, init
;
21690 tree body
= NULL_TREE
;
21691 matching_parens parens
;
21693 unsigned char save_in_statement
;
21696 struct omp_for_parse_data
*omp_for_parse_state
21697 = parser
->omp_for_parse_state
;
21698 gcc_assert (omp_for_parse_state
);
21699 int depth
= omp_for_parse_state
->depth
;
21701 /* We have already matched the FOR token but not consumed it yet. */
21702 loc
= c_parser_peek_token (parser
)->location
;
21703 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
21704 c_parser_consume_token (parser
);
21706 /* Forbid break/continue in the loop initializer, condition, and
21707 increment expressions. */
21708 save_in_statement
= in_statement
;
21709 in_statement
= IN_OMP_BLOCK
;
21711 /* We are not in intervening code now. */
21712 omp_for_parse_state
->in_intervening_code
= false;
21714 if (!parens
.require_open (parser
))
21716 omp_for_parse_state
->fail
= true;
21720 /* An implicit scope block surrounds each level of FOR loop, for
21721 declarations of iteration variables at this loop depth. */
21722 loop_scope
= c_begin_compound_stmt (true);
21724 /* Parse the initialization declaration or expression. */
21725 if (c_parser_next_tokens_start_declaration (parser
))
21727 /* This is a declaration, which must be added to the pre_body code. */
21728 tree this_pre_body
= push_stmt_list ();
21729 c_in_omp_for
= true;
21730 c_parser_declaration_or_fndef (parser
, true, true, true, true, true);
21731 c_in_omp_for
= false;
21732 this_pre_body
= pop_stmt_list (this_pre_body
);
21733 append_to_statement_list_force (this_pre_body
,
21734 &(omp_for_parse_state
->pre_body
));
21735 decl
= check_for_loop_decls (omp_for_parse_state
->for_loc
, flag_isoc99
);
21738 if (DECL_INITIAL (decl
) == error_mark_node
)
21739 decl
= error_mark_node
;
21742 else if (c_parser_next_token_is (parser
, CPP_NAME
)
21743 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
21745 struct c_expr decl_exp
;
21746 struct c_expr init_exp
;
21747 location_t init_loc
;
21749 decl_exp
= c_parser_postfix_expression (parser
);
21750 decl
= decl_exp
.value
;
21752 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
21754 init_loc
= c_parser_peek_token (parser
)->location
;
21755 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
21756 init_exp
= default_function_array_read_conversion (init_loc
,
21758 c_in_omp_for
= true;
21759 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
21760 NOP_EXPR
, init_loc
, init_exp
.value
,
21761 init_exp
.original_type
);
21762 c_in_omp_for
= false;
21763 init
= c_process_expr_stmt (init_loc
, init
);
21765 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
21770 c_parser_error (parser
,
21771 "expected iteration declaration or initialization");
21772 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
21774 omp_for_parse_state
->fail
= true;
21778 /* Parse the loop condition. */
21780 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
21782 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
21783 c_in_omp_for
= true;
21784 struct c_expr cond_expr
21785 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
21786 c_in_omp_for
= false;
21788 cond
= cond_expr
.value
;
21789 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
21790 switch (cond_expr
.original_code
)
21798 if (omp_for_parse_state
->code
!= OACC_LOOP
)
21802 /* Can't be cond = error_mark_node, because we want to preserve
21803 the location until c_finish_omp_for. */
21804 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
21807 protected_set_expr_location (cond
, cond_loc
);
21809 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
21811 /* Parse the increment expression. */
21813 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
21815 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
21817 incr
= c_process_expr_stmt (incr_loc
,
21818 c_parser_expression (parser
).value
);
21820 parens
.skip_until_found_close (parser
);
21822 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
21823 omp_for_parse_state
->fail
= true;
21826 TREE_VEC_ELT (omp_for_parse_state
->declv
, depth
) = decl
;
21827 TREE_VEC_ELT (omp_for_parse_state
->initv
, depth
) = init
;
21828 TREE_VEC_ELT (omp_for_parse_state
->condv
, depth
) = cond
;
21829 TREE_VEC_ELT (omp_for_parse_state
->incrv
, depth
) = incr
;
21833 moreloops
= depth
< omp_for_parse_state
->count
- 1;
21834 omp_for_parse_state
->want_nested_loop
= moreloops
;
21835 if (moreloops
&& c_parser_next_token_is_keyword (parser
, RID_FOR
))
21837 omp_for_parse_state
->depth
++;
21838 body
= c_parser_omp_loop_nest (parser
, if_p
);
21839 omp_for_parse_state
->depth
--;
21841 else if (moreloops
&& c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
21843 /* This is the open brace in the loop-body grammar production. Rather
21844 than trying to special-case braces, just parse it as a compound
21845 statement and handle the nested loop-body case there. Note that
21846 when we see a further open brace inside the compound statement
21847 loop-body, we don't know whether it is the start of intervening
21848 code that is a compound statement, or a level of braces
21849 surrounding a nested loop-body. Use the WANT_NESTED_LOOP state
21850 bit to ensure we have only one nested loop at each level. */
21851 omp_for_parse_state
->in_intervening_code
= true;
21852 body
= c_parser_compound_statement (parser
, NULL
);
21853 omp_for_parse_state
->in_intervening_code
= false;
21854 if (omp_for_parse_state
->want_nested_loop
)
21856 /* We have already parsed the whole loop body and not found a
21858 error_at (omp_for_parse_state
->for_loc
,
21859 "not enough nested loops");
21860 omp_for_parse_state
->fail
= true;
21866 /* This is the final-loop-body case in the grammar: we have
21867 something that is not a FOR and not an open brace. */
21870 /* If we were expecting a nested loop, give an error and mark
21871 that parsing has failed, and try to recover by parsing the
21872 body as regular code without further collapsing. */
21873 error_at (omp_for_parse_state
->for_loc
,
21874 "not enough nested loops");
21875 omp_for_parse_state
->fail
= true;
21877 in_statement
= IN_OMP_FOR
;
21878 parser
->omp_for_parse_state
= NULL
;
21879 body
= push_stmt_list ();
21880 if (omp_for_parse_state
->inscan
)
21881 c_parser_omp_scan_loop_body (parser
, false);
21883 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
21884 body
= pop_stmt_list (body
);
21885 parser
->omp_for_parse_state
= omp_for_parse_state
;
21887 in_statement
= save_in_statement
;
21888 omp_for_parse_state
->want_nested_loop
= false;
21889 omp_for_parse_state
->in_intervening_code
= true;
21891 /* Pop and return the implicit scope surrounding this level of loop.
21892 If the iteration variable at this depth was bound in the for loop,
21893 pull out and save the binding. Later in c_parser_omp_for_loop,
21894 these bindings will be moved to the scope surrounding the entire
21895 OMP_FOR. That keeps the gimplifier happy later on, and meanwhile
21896 we have already resolved all references to the iteration variable
21897 in its true scope. */
21899 body
= c_end_compound_stmt (loc
, loop_scope
, true);
21900 if (decl
&& TREE_CODE (body
) == BIND_EXPR
)
21902 tree t
= BIND_EXPR_VARS (body
);
21903 tree prev
= NULL_TREE
, next
= NULL_TREE
;
21906 next
= DECL_CHAIN (t
);
21910 DECL_CHAIN (prev
) = next
;
21913 BIND_EXPR_VARS (body
) = next
;
21914 BLOCK_VARS (BIND_EXPR_BLOCK (body
)) = next
;
21916 DECL_CHAIN (t
) = omp_for_parse_state
->bindings
;
21917 omp_for_parse_state
->bindings
= t
;
21926 if (BIND_EXPR_VARS (body
) == NULL_TREE
)
21927 body
= BIND_EXPR_BODY (body
);
21933 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
21934 The real trick here is to determine the loop control variable early
21935 so that we can push a new decl if necessary to make it private.
21936 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
21940 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
21941 tree clauses
, tree
*cclauses
, bool *if_p
)
21943 tree body
, stmt
, cl
;
21944 tree ret
= NULL_TREE
;
21945 tree ordered_cl
= NULL_TREE
;
21946 int i
, collapse
= 1, ordered
= 0, count
;
21947 bool tiling
= false;
21948 bool inscan
= false;
21949 struct omp_for_parse_data data
;
21950 struct omp_for_parse_data
*save_data
= parser
->omp_for_parse_state
;
21952 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
21953 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
21954 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
21955 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
21958 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
21960 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
21961 && OMP_CLAUSE_ORDERED_EXPR (cl
))
21964 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
21966 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_REDUCTION
21967 && OMP_CLAUSE_REDUCTION_INSCAN (cl
)
21968 && (code
== OMP_SIMD
|| code
== OMP_FOR
))
21971 if (ordered
&& ordered
< collapse
)
21973 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
21974 "%<ordered%> clause parameter is less than %<collapse%>");
21975 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
21976 = build_int_cst (NULL_TREE
, collapse
);
21977 ordered
= collapse
;
21980 gcc_assert (tiling
|| (collapse
>= 1 && ordered
>= 0));
21981 count
= ordered
? ordered
: collapse
;
21983 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
))
21985 c_parser_error (parser
, "for statement expected");
21989 /* Initialize parse state for recursive descent. */
21990 data
.declv
= make_tree_vec (count
);
21991 data
.initv
= make_tree_vec (count
);
21992 data
.condv
= make_tree_vec (count
);
21993 data
.incrv
= make_tree_vec (count
);
21994 data
.pre_body
= NULL_TREE
;;
21995 data
.bindings
= NULL_TREE
;
21996 data
.for_loc
= c_parser_peek_token (parser
)->location
;
21997 data
.count
= count
;
21999 data
.want_nested_loop
= true;
22000 data
.ordered
= ordered
> 0;
22001 data
.in_intervening_code
= false;
22002 data
.perfect_nesting_fail
= false;
22004 data
.inscan
= inscan
;
22005 data
.saw_intervening_code
= false;
22007 parser
->omp_for_parse_state
= &data
;
22009 body
= c_parser_omp_loop_nest (parser
, if_p
);
22011 /* Add saved bindings for iteration variables that were declared in
22012 the nested for loop to the scope surrounding the entire loop. */
22013 for (tree t
= data
.bindings
; t
; )
22015 tree n
= TREE_CHAIN (t
);
22016 TREE_CHAIN (t
) = NULL_TREE
;
22021 /* Only bother calling c_finish_omp_for if we haven't already generated
22022 an error from the initialization parsing. */
22025 c_in_omp_for
= true;
22026 stmt
= c_finish_omp_for (loc
, code
, data
.declv
, NULL
, data
.initv
,
22027 data
.condv
, data
.incrv
,
22028 body
, data
.pre_body
, true);
22029 c_in_omp_for
= false;
22031 /* Check for iterators appearing in lb, b or incr expressions. */
22032 if (stmt
&& !c_omp_check_loop_iv (stmt
, data
.declv
, NULL
))
22035 /* Check for errors involving lb/ub/incr expressions referencing
22036 variables declared in intervening code. */
22037 if (data
.saw_intervening_code
22038 && !c_omp_check_loop_binding_exprs (stmt
, NULL
))
22045 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (stmt
)); i
++)
22047 tree init
= TREE_VEC_ELT (OMP_FOR_INIT (stmt
), i
);
22048 gcc_assert (TREE_CODE (init
) == MODIFY_EXPR
);
22049 tree decl
= TREE_OPERAND (init
, 0);
22050 tree cond
= TREE_VEC_ELT (OMP_FOR_COND (stmt
), i
);
22051 gcc_assert (COMPARISON_CLASS_P (cond
));
22052 gcc_assert (TREE_OPERAND (cond
, 0) == decl
);
22054 tree op0
= TREE_OPERAND (init
, 1);
22055 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
22056 || TREE_CODE (op0
) != TREE_VEC
)
22057 TREE_OPERAND (init
, 1) = c_fully_fold (op0
, false, NULL
);
22060 TREE_VEC_ELT (op0
, 1)
22061 = c_fully_fold (TREE_VEC_ELT (op0
, 1), false, NULL
);
22062 TREE_VEC_ELT (op0
, 2)
22063 = c_fully_fold (TREE_VEC_ELT (op0
, 2), false, NULL
);
22066 tree op1
= TREE_OPERAND (cond
, 1);
22067 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
22068 || TREE_CODE (op1
) != TREE_VEC
)
22069 TREE_OPERAND (cond
, 1) = c_fully_fold (op1
, false, NULL
);
22072 TREE_VEC_ELT (op1
, 1)
22073 = c_fully_fold (TREE_VEC_ELT (op1
, 1), false, NULL
);
22074 TREE_VEC_ELT (op1
, 2)
22075 = c_fully_fold (TREE_VEC_ELT (op1
, 2), false, NULL
);
22079 if (cclauses
!= NULL
22080 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
22083 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
22084 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
22085 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
22086 c
= &OMP_CLAUSE_CHAIN (*c
);
22089 for (i
= 0; i
< count
; i
++)
22090 if (TREE_VEC_ELT (data
.declv
, i
) == OMP_CLAUSE_DECL (*c
))
22093 c
= &OMP_CLAUSE_CHAIN (*c
);
22094 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
22097 "iteration variable %qD should not be firstprivate",
22098 OMP_CLAUSE_DECL (*c
));
22099 *c
= OMP_CLAUSE_CHAIN (*c
);
22103 /* Move lastprivate (decl) clause to
22104 OMP_FOR_CLAUSES. */
22106 *c
= OMP_CLAUSE_CHAIN (*c
);
22107 if (code
== OMP_SIMD
)
22109 OMP_CLAUSE_CHAIN (l
)
22110 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
22111 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
22115 OMP_CLAUSE_CHAIN (l
) = clauses
;
22121 OMP_FOR_CLAUSES (stmt
) = clauses
;
22126 parser
->omp_for_parse_state
= save_data
;
22130 /* Helper function for OpenMP parsing, split clauses and call
22131 finish_omp_clauses on each of the set of clauses afterwards. */
22134 omp_split_clauses (location_t loc
, enum tree_code code
,
22135 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
22138 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
22139 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
22141 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
],
22142 i
== C_OMP_CLAUSE_SPLIT_TARGET
22143 ? C_ORT_OMP_TARGET
: C_ORT_OMP
);
22147 #pragma omp loop loop-clause[optseq] new-line
22150 LOC is the location of the #pragma token.
22153 #define OMP_LOOP_CLAUSE_MASK \
22154 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22155 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22156 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22157 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22158 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
22159 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22162 c_parser_omp_loop (location_t loc
, c_parser
*parser
,
22163 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22166 tree block
, clauses
, ret
;
22168 strcat (p_name
, " loop");
22169 mask
|= OMP_LOOP_CLAUSE_MASK
;
22171 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22174 omp_split_clauses (loc
, OMP_LOOP
, mask
, clauses
, cclauses
);
22175 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_LOOP
];
22178 block
= c_begin_compound_stmt (true);
22179 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_LOOP
, clauses
, cclauses
, if_p
);
22180 block
= c_end_compound_stmt (loc
, block
, true);
22187 #pragma omp simd simd-clause[optseq] new-line
22190 LOC is the location of the #pragma token.
22193 #define OMP_SIMD_CLAUSE_MASK \
22194 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
22195 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
22196 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
22197 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
22198 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22199 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22200 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22201 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22202 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22203 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
22204 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22207 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
22208 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22211 tree block
, clauses
, ret
;
22213 strcat (p_name
, " simd");
22214 mask
|= OMP_SIMD_CLAUSE_MASK
;
22216 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22219 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
22220 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
22223 block
= c_begin_compound_stmt (true);
22224 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
22225 block
= c_end_compound_stmt (loc
, block
, true);
22232 #pragma omp for for-clause[optseq] new-line
22236 #pragma omp for simd for-simd-clause[optseq] new-line
22239 LOC is the location of the #pragma token.
22242 #define OMP_FOR_CLAUSE_MASK \
22243 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22244 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22245 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
22247 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
22249 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
22250 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22251 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
22252 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22253 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22256 c_parser_omp_for (location_t loc
, c_parser
*parser
,
22257 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22260 tree block
, clauses
, ret
;
22262 strcat (p_name
, " for");
22263 mask
|= OMP_FOR_CLAUSE_MASK
;
22264 /* parallel for{, simd} disallows nowait clause, but for
22265 target {teams distribute ,}parallel for{, simd} it should be accepted. */
22266 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
22267 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
22268 /* Composite distribute parallel for{, simd} disallows ordered clause. */
22269 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
22270 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
22272 if (c_parser_next_token_is (parser
, CPP_NAME
))
22274 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22276 if (strcmp (p
, "simd") == 0)
22278 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22279 if (cclauses
== NULL
)
22280 cclauses
= cclauses_buf
;
22282 c_parser_consume_token (parser
);
22283 if (!flag_openmp
) /* flag_openmp_simd */
22284 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
22286 block
= c_begin_compound_stmt (true);
22287 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
22288 block
= c_end_compound_stmt (loc
, block
, true);
22289 if (ret
== NULL_TREE
)
22291 ret
= make_node (OMP_FOR
);
22292 TREE_TYPE (ret
) = void_type_node
;
22293 OMP_FOR_BODY (ret
) = block
;
22294 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
22295 SET_EXPR_LOCATION (ret
, loc
);
22300 if (!flag_openmp
) /* flag_openmp_simd */
22302 c_parser_skip_to_pragma_eol (parser
, false);
22306 /* Composite distribute parallel for disallows linear clause. */
22307 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
22308 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
22310 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22313 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
22314 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
22317 block
= c_begin_compound_stmt (true);
22318 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
22319 block
= c_end_compound_stmt (loc
, block
, true);
22325 static tree
c_parser_omp_taskloop (location_t
, c_parser
*, char *,
22326 omp_clause_mask
, tree
*, bool *);
22329 # pragma omp master new-line
22332 LOC is the location of the #pragma token.
22336 c_parser_omp_master (location_t loc
, c_parser
*parser
,
22337 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22340 tree block
, clauses
, ret
;
22342 strcat (p_name
, " master");
22344 if (c_parser_next_token_is (parser
, CPP_NAME
))
22346 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22348 if (strcmp (p
, "taskloop") == 0)
22350 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22351 if (cclauses
== NULL
)
22352 cclauses
= cclauses_buf
;
22354 c_parser_consume_token (parser
);
22355 if (!flag_openmp
) /* flag_openmp_simd */
22356 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
22358 block
= c_begin_compound_stmt (true);
22359 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
22361 block
= c_end_compound_stmt (loc
, block
, true);
22362 if (ret
== NULL_TREE
)
22364 ret
= c_finish_omp_master (loc
, block
);
22365 OMP_MASTER_COMBINED (ret
) = 1;
22369 if (!flag_openmp
) /* flag_openmp_simd */
22371 c_parser_skip_to_pragma_eol (parser
, false);
22377 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, false);
22378 omp_split_clauses (loc
, OMP_MASTER
, mask
, clauses
, cclauses
);
22381 c_parser_skip_to_pragma_eol (parser
);
22383 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
22388 # pragma omp masked masked-clauses new-line
22391 LOC is the location of the #pragma token.
22394 #define OMP_MASKED_CLAUSE_MASK \
22395 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
22398 c_parser_omp_masked (location_t loc
, c_parser
*parser
,
22399 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22402 tree block
, clauses
, ret
;
22404 strcat (p_name
, " masked");
22405 mask
|= OMP_MASKED_CLAUSE_MASK
;
22407 if (c_parser_next_token_is (parser
, CPP_NAME
))
22409 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22411 if (strcmp (p
, "taskloop") == 0)
22413 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22414 if (cclauses
== NULL
)
22415 cclauses
= cclauses_buf
;
22417 c_parser_consume_token (parser
);
22418 if (!flag_openmp
) /* flag_openmp_simd */
22419 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
22421 block
= c_begin_compound_stmt (true);
22422 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
22424 block
= c_end_compound_stmt (loc
, block
, true);
22425 if (ret
== NULL_TREE
)
22427 ret
= c_finish_omp_masked (loc
, block
,
22428 cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
]);
22429 OMP_MASKED_COMBINED (ret
) = 1;
22433 if (!flag_openmp
) /* flag_openmp_simd */
22435 c_parser_skip_to_pragma_eol (parser
, false);
22439 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22442 omp_split_clauses (loc
, OMP_MASKED
, mask
, clauses
, cclauses
);
22443 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
];
22446 return c_finish_omp_masked (loc
, c_parser_omp_structured_block (parser
,
22452 # pragma omp ordered new-line
22456 # pragma omp ordered ordered-clauses new-line
22459 # pragma omp ordered depend-clauses new-line
22462 # pragma omp ordered doacross-clauses new-line */
22464 #define OMP_ORDERED_CLAUSE_MASK \
22465 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
22466 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
22468 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
22469 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
22470 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
22473 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
22476 location_t loc
= c_parser_peek_token (parser
)->location
;
22477 c_parser_consume_pragma (parser
);
22479 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
22481 c_parser_error (parser
, "expected declaration specifiers");
22482 c_parser_skip_to_pragma_eol (parser
, false);
22487 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22490 if (c_parser_peek_nth_token (parser
, n
)->type
== CPP_NAME
)
22493 = IDENTIFIER_POINTER (c_parser_peek_nth_token (parser
, n
)->value
);
22495 if (!strcmp ("depend", p
) || !strcmp ("doacross", p
))
22497 if (!flag_openmp
) /* flag_openmp_simd */
22499 c_parser_skip_to_pragma_eol (parser
, false);
22502 if (context
== pragma_stmt
)
22505 "%<#pragma omp ordered%> with %qs clause may "
22506 "only be used in compound statements", p
);
22507 c_parser_skip_to_pragma_eol (parser
, false);
22512 = c_parser_omp_all_clauses (parser
,
22513 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
22514 "#pragma omp ordered");
22515 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
22520 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
22521 "#pragma omp ordered");
22523 if (!flag_openmp
/* flag_openmp_simd */
22524 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
22527 c_finish_omp_ordered (loc
, clauses
,
22528 c_parser_omp_structured_block (parser
, if_p
));
22535 { section-sequence }
22538 section-directive[opt] structured-block
22539 section-sequence section-directive structured-block
22541 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
22543 SECTIONS_LOC is the location of the #pragma omp sections. */
22546 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
22548 tree stmt
, substmt
;
22549 bool error_suppress
= false;
22552 loc
= c_parser_peek_token (parser
)->location
;
22553 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
22555 /* Avoid skipping until the end of the block. */
22556 parser
->error
= false;
22560 stmt
= push_stmt_list ();
22562 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
22563 && !c_parser_omp_section_scan (parser
, "section", true))
22565 substmt
= c_parser_omp_structured_block_sequence (parser
,
22566 PRAGMA_OMP_SECTION
);
22567 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
22568 SET_EXPR_LOCATION (substmt
, loc
);
22569 add_stmt (substmt
);
22574 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
22576 if (c_parser_next_token_is (parser
, CPP_EOF
))
22579 loc
= c_parser_peek_token (parser
)->location
;
22580 c_parser_omp_section_scan (parser
, "section", false);
22581 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
22583 c_parser_consume_pragma (parser
);
22584 c_parser_skip_to_pragma_eol (parser
);
22585 error_suppress
= false;
22587 else if (!error_suppress
)
22589 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
22590 error_suppress
= true;
22593 substmt
= c_parser_omp_structured_block_sequence (parser
,
22594 PRAGMA_OMP_SECTION
);
22595 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
22596 SET_EXPR_LOCATION (substmt
, loc
);
22597 add_stmt (substmt
);
22599 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
22600 "expected %<#pragma omp section%> or %<}%>");
22602 substmt
= pop_stmt_list (stmt
);
22604 stmt
= make_node (OMP_SECTIONS
);
22605 SET_EXPR_LOCATION (stmt
, sections_loc
);
22606 TREE_TYPE (stmt
) = void_type_node
;
22607 OMP_SECTIONS_BODY (stmt
) = substmt
;
22609 return add_stmt (stmt
);
22613 # pragma omp sections sections-clause[optseq] newline
22616 LOC is the location of the #pragma token.
22619 #define OMP_SECTIONS_CLAUSE_MASK \
22620 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22621 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22622 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22623 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22624 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22625 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
22628 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
22629 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
22631 tree block
, clauses
, ret
;
22633 strcat (p_name
, " sections");
22634 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
22636 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
22638 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22641 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
22642 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
22645 block
= c_begin_compound_stmt (true);
22646 ret
= c_parser_omp_sections_scope (loc
, parser
);
22648 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
22649 block
= c_end_compound_stmt (loc
, block
, true);
22656 # pragma omp parallel parallel-clause[optseq] new-line
22658 # pragma omp parallel for parallel-for-clause[optseq] new-line
22660 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
22664 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
22667 LOC is the location of the #pragma token.
22670 #define OMP_PARALLEL_CLAUSE_MASK \
22671 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22672 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22673 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22674 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
22675 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
22676 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
22677 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22678 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
22679 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22680 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
22683 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
22684 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22687 tree stmt
, clauses
, block
;
22689 strcat (p_name
, " parallel");
22690 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
22691 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
22692 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
22693 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
22694 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
22696 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
22698 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22699 if (cclauses
== NULL
)
22700 cclauses
= cclauses_buf
;
22702 c_parser_consume_token (parser
);
22703 if (!flag_openmp
) /* flag_openmp_simd */
22704 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
22705 block
= c_begin_omp_parallel ();
22706 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
22708 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
22710 if (ret
== NULL_TREE
)
22712 OMP_PARALLEL_COMBINED (stmt
) = 1;
22715 /* When combined with distribute, parallel has to be followed by for.
22716 #pragma omp target parallel is allowed though. */
22718 && (mask
& (OMP_CLAUSE_MASK_1
22719 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
22721 error_at (loc
, "expected %<for%> after %qs", p_name
);
22722 c_parser_skip_to_pragma_eol (parser
);
22725 else if (c_parser_next_token_is (parser
, CPP_NAME
))
22727 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22728 if (cclauses
== NULL
&& strcmp (p
, "masked") == 0)
22730 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22731 cclauses
= cclauses_buf
;
22733 c_parser_consume_token (parser
);
22734 if (!flag_openmp
) /* flag_openmp_simd */
22735 return c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
22737 block
= c_begin_omp_parallel ();
22738 tree ret
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
22740 stmt
= c_finish_omp_parallel (loc
,
22741 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
22745 /* masked does have just filter clause, but during gimplification
22746 isn't represented by a gimplification omp context, so for
22747 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
22749 #pragma omp parallel masked
22750 #pragma omp taskloop simd lastprivate (x)
22751 isn't confused with
22752 #pragma omp parallel masked taskloop simd lastprivate (x) */
22753 if (OMP_MASKED_COMBINED (ret
))
22754 OMP_PARALLEL_COMBINED (stmt
) = 1;
22757 else if (cclauses
== NULL
&& strcmp (p
, "master") == 0)
22759 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22760 cclauses
= cclauses_buf
;
22762 c_parser_consume_token (parser
);
22763 if (!flag_openmp
) /* flag_openmp_simd */
22764 return c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
22766 block
= c_begin_omp_parallel ();
22767 tree ret
= c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
22769 stmt
= c_finish_omp_parallel (loc
,
22770 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
22774 /* master doesn't have any clauses and during gimplification
22775 isn't represented by a gimplification omp context, so for
22776 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
22778 #pragma omp parallel master
22779 #pragma omp taskloop simd lastprivate (x)
22780 isn't confused with
22781 #pragma omp parallel master taskloop simd lastprivate (x) */
22782 if (OMP_MASTER_COMBINED (ret
))
22783 OMP_PARALLEL_COMBINED (stmt
) = 1;
22786 else if (strcmp (p
, "loop") == 0)
22788 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22789 if (cclauses
== NULL
)
22790 cclauses
= cclauses_buf
;
22792 c_parser_consume_token (parser
);
22793 if (!flag_openmp
) /* flag_openmp_simd */
22794 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
22796 block
= c_begin_omp_parallel ();
22797 tree ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
22800 = c_finish_omp_parallel (loc
,
22801 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
22803 if (ret
== NULL_TREE
)
22805 OMP_PARALLEL_COMBINED (stmt
) = 1;
22808 else if (!flag_openmp
) /* flag_openmp_simd */
22810 c_parser_skip_to_pragma_eol (parser
, false);
22813 else if (cclauses
== NULL
&& strcmp (p
, "sections") == 0)
22815 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22816 cclauses
= cclauses_buf
;
22818 c_parser_consume_token (parser
);
22819 block
= c_begin_omp_parallel ();
22820 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
22821 stmt
= c_finish_omp_parallel (loc
,
22822 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
22824 OMP_PARALLEL_COMBINED (stmt
) = 1;
22828 else if (!flag_openmp
) /* flag_openmp_simd */
22830 c_parser_skip_to_pragma_eol (parser
, false);
22834 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22837 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
22838 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
22841 block
= c_begin_omp_parallel ();
22842 parser
->omp_attrs_forbidden_p
= true;
22843 c_parser_statement (parser
, if_p
);
22844 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
22850 # pragma omp single single-clause[optseq] new-line
22853 LOC is the location of the #pragma.
22856 #define OMP_SINGLE_CLAUSE_MASK \
22857 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22858 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22859 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
22860 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22861 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
22864 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
22866 tree stmt
= make_node (OMP_SINGLE
);
22867 SET_EXPR_LOCATION (stmt
, loc
);
22868 TREE_TYPE (stmt
) = void_type_node
;
22870 OMP_SINGLE_CLAUSES (stmt
)
22871 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
22872 "#pragma omp single");
22873 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
22875 return add_stmt (stmt
);
22879 # pragma omp scope scope-clause[optseq] new-line
22882 LOC is the location of the #pragma.
22885 #define OMP_SCOPE_CLAUSE_MASK \
22886 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22888 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22889 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22890 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
22893 c_parser_omp_scope (location_t loc
, c_parser
*parser
, bool *if_p
)
22895 tree stmt
= make_node (OMP_SCOPE
);
22896 SET_EXPR_LOCATION (stmt
, loc
);
22897 TREE_TYPE (stmt
) = void_type_node
;
22899 OMP_SCOPE_CLAUSES (stmt
)
22900 = c_parser_omp_all_clauses (parser
, OMP_SCOPE_CLAUSE_MASK
,
22901 "#pragma omp scope");
22902 OMP_SCOPE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
22904 return add_stmt (stmt
);
22908 # pragma omp task task-clause[optseq] new-line
22910 LOC is the location of the #pragma.
22913 #define OMP_TASK_CLAUSE_MASK \
22914 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22915 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
22916 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
22917 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22918 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22919 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
22920 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
22921 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
22922 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
22923 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
22924 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22925 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
22926 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
22927 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
22930 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
22932 tree clauses
, block
;
22934 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
22935 "#pragma omp task");
22937 block
= c_begin_omp_task ();
22938 parser
->omp_attrs_forbidden_p
= true;
22939 c_parser_statement (parser
, if_p
);
22940 return c_finish_omp_task (loc
, clauses
, block
);
22944 # pragma omp taskwait new-line
22947 # pragma omp taskwait taskwait-clause[optseq] new-line
22950 #define OMP_TASKWAIT_CLAUSE_MASK \
22951 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
22952 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
22955 c_parser_omp_taskwait (c_parser
*parser
)
22957 location_t loc
= c_parser_peek_token (parser
)->location
;
22958 c_parser_consume_pragma (parser
);
22961 = c_parser_omp_all_clauses (parser
, OMP_TASKWAIT_CLAUSE_MASK
,
22962 "#pragma omp taskwait");
22966 tree stmt
= make_node (OMP_TASK
);
22967 TREE_TYPE (stmt
) = void_node
;
22968 OMP_TASK_CLAUSES (stmt
) = clauses
;
22969 OMP_TASK_BODY (stmt
) = NULL_TREE
;
22970 SET_EXPR_LOCATION (stmt
, loc
);
22974 c_finish_omp_taskwait (loc
);
22978 # pragma omp taskyield new-line
22982 c_parser_omp_taskyield (c_parser
*parser
)
22984 location_t loc
= c_parser_peek_token (parser
)->location
;
22985 c_parser_consume_pragma (parser
);
22986 c_parser_skip_to_pragma_eol (parser
);
22988 c_finish_omp_taskyield (loc
);
22992 # pragma omp taskgroup new-line
22995 # pragma omp taskgroup taskgroup-clause[optseq] new-line
22998 #define OMP_TASKGROUP_CLAUSE_MASK \
22999 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23000 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
23003 c_parser_omp_taskgroup (location_t loc
, c_parser
*parser
, bool *if_p
)
23005 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_TASKGROUP_CLAUSE_MASK
,
23006 "#pragma omp taskgroup");
23008 tree body
= c_parser_omp_structured_block (parser
, if_p
);
23009 return c_finish_omp_taskgroup (loc
, body
, clauses
);
23013 # pragma omp cancel cancel-clause[optseq] new-line
23015 LOC is the location of the #pragma.
23018 #define OMP_CANCEL_CLAUSE_MASK \
23019 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23020 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23021 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23022 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
23023 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
23026 c_parser_omp_cancel (c_parser
*parser
)
23028 location_t loc
= c_parser_peek_token (parser
)->location
;
23030 c_parser_consume_pragma (parser
);
23031 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
23032 "#pragma omp cancel");
23034 c_finish_omp_cancel (loc
, clauses
);
23038 # pragma omp cancellation point cancelpt-clause[optseq] new-line
23040 LOC is the location of the #pragma.
23043 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
23044 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23045 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23046 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23047 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
23050 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
23052 location_t loc
= c_parser_peek_token (parser
)->location
;
23054 bool point_seen
= false;
23056 c_parser_consume_pragma (parser
);
23057 if (c_parser_next_token_is (parser
, CPP_NAME
))
23059 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23060 if (strcmp (p
, "point") == 0)
23062 c_parser_consume_token (parser
);
23068 c_parser_error (parser
, "expected %<point%>");
23069 c_parser_skip_to_pragma_eol (parser
);
23073 if (context
!= pragma_compound
)
23075 if (context
== pragma_stmt
)
23077 "%<#pragma %s%> may only be used in compound statements",
23078 "omp cancellation point");
23080 c_parser_error (parser
, "expected declaration specifiers");
23081 c_parser_skip_to_pragma_eol (parser
, false);
23086 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
23087 "#pragma omp cancellation point");
23089 c_finish_omp_cancellation_point (loc
, clauses
);
23094 #pragma omp distribute distribute-clause[optseq] new-line
23097 #define OMP_DISTRIBUTE_CLAUSE_MASK \
23098 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23099 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23100 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23101 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
23102 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23103 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23104 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
23107 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
23108 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23111 tree clauses
, block
, ret
;
23113 strcat (p_name
, " distribute");
23114 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
23116 if (c_parser_next_token_is (parser
, CPP_NAME
))
23118 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23120 bool parallel
= false;
23122 if (strcmp (p
, "simd") == 0)
23125 parallel
= strcmp (p
, "parallel") == 0;
23126 if (parallel
|| simd
)
23128 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23129 if (cclauses
== NULL
)
23130 cclauses
= cclauses_buf
;
23131 c_parser_consume_token (parser
);
23132 if (!flag_openmp
) /* flag_openmp_simd */
23135 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
23138 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
23141 block
= c_begin_compound_stmt (true);
23143 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
23146 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
23148 block
= c_end_compound_stmt (loc
, block
, true);
23151 ret
= make_node (OMP_DISTRIBUTE
);
23152 TREE_TYPE (ret
) = void_type_node
;
23153 OMP_FOR_BODY (ret
) = block
;
23154 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
23155 SET_EXPR_LOCATION (ret
, loc
);
23160 if (!flag_openmp
) /* flag_openmp_simd */
23162 c_parser_skip_to_pragma_eol (parser
, false);
23166 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23169 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
23170 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
23173 block
= c_begin_compound_stmt (true);
23174 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
23176 block
= c_end_compound_stmt (loc
, block
, true);
23183 # pragma omp teams teams-clause[optseq] new-line
23184 structured-block */
23186 #define OMP_TEAMS_CLAUSE_MASK \
23187 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23188 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23189 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23190 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23191 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
23192 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
23193 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23194 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
23197 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
23198 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23201 tree clauses
, block
, ret
;
23203 strcat (p_name
, " teams");
23204 mask
|= OMP_TEAMS_CLAUSE_MASK
;
23206 if (c_parser_next_token_is (parser
, CPP_NAME
))
23208 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23209 if (strcmp (p
, "distribute") == 0)
23211 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23212 if (cclauses
== NULL
)
23213 cclauses
= cclauses_buf
;
23215 c_parser_consume_token (parser
);
23216 if (!flag_openmp
) /* flag_openmp_simd */
23217 return c_parser_omp_distribute (loc
, parser
, p_name
, mask
,
23219 block
= c_begin_omp_parallel ();
23220 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
23222 block
= c_end_compound_stmt (loc
, block
, true);
23225 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
23226 ret
= make_node (OMP_TEAMS
);
23227 TREE_TYPE (ret
) = void_type_node
;
23228 OMP_TEAMS_CLAUSES (ret
) = clauses
;
23229 OMP_TEAMS_BODY (ret
) = block
;
23230 OMP_TEAMS_COMBINED (ret
) = 1;
23231 SET_EXPR_LOCATION (ret
, loc
);
23232 return add_stmt (ret
);
23234 else if (strcmp (p
, "loop") == 0)
23236 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23237 if (cclauses
== NULL
)
23238 cclauses
= cclauses_buf
;
23240 c_parser_consume_token (parser
);
23241 if (!flag_openmp
) /* flag_openmp_simd */
23242 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
23244 block
= c_begin_omp_parallel ();
23245 ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
23246 block
= c_end_compound_stmt (loc
, block
, true);
23249 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
23250 ret
= make_node (OMP_TEAMS
);
23251 TREE_TYPE (ret
) = void_type_node
;
23252 OMP_TEAMS_CLAUSES (ret
) = clauses
;
23253 OMP_TEAMS_BODY (ret
) = block
;
23254 OMP_TEAMS_COMBINED (ret
) = 1;
23255 SET_EXPR_LOCATION (ret
, loc
);
23256 return add_stmt (ret
);
23259 if (!flag_openmp
) /* flag_openmp_simd */
23261 c_parser_skip_to_pragma_eol (parser
, false);
23265 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23268 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
23269 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
23272 tree stmt
= make_node (OMP_TEAMS
);
23273 TREE_TYPE (stmt
) = void_type_node
;
23274 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
23275 block
= c_begin_omp_parallel ();
23276 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
23277 OMP_TEAMS_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
23278 SET_EXPR_LOCATION (stmt
, loc
);
23280 return add_stmt (stmt
);
23284 # pragma omp target data target-data-clause[optseq] new-line
23285 structured-block */
23287 #define OMP_TARGET_DATA_CLAUSE_MASK \
23288 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23289 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
23290 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23291 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
23292 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
23295 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
23299 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
23302 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
23303 "#pragma omp target data");
23304 c_omp_adjust_map_clauses (clauses
, false);
23306 for (tree
*pc
= &clauses
; *pc
;)
23308 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
23309 switch (OMP_CLAUSE_MAP_KIND (*pc
))
23312 case GOMP_MAP_ALWAYS_TO
:
23313 case GOMP_MAP_PRESENT_TO
:
23314 case GOMP_MAP_ALWAYS_PRESENT_TO
:
23315 case GOMP_MAP_FROM
:
23316 case GOMP_MAP_ALWAYS_FROM
:
23317 case GOMP_MAP_PRESENT_FROM
:
23318 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
23319 case GOMP_MAP_TOFROM
:
23320 case GOMP_MAP_ALWAYS_TOFROM
:
23321 case GOMP_MAP_PRESENT_TOFROM
:
23322 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
23323 case GOMP_MAP_ALLOC
:
23324 case GOMP_MAP_PRESENT_ALLOC
:
23327 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
23328 case GOMP_MAP_ALWAYS_POINTER
:
23329 case GOMP_MAP_ATTACH_DETACH
:
23333 error_at (OMP_CLAUSE_LOCATION (*pc
),
23334 "%<#pragma omp target data%> with map-type other "
23335 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
23336 "on %<map%> clause");
23337 *pc
= OMP_CLAUSE_CHAIN (*pc
);
23340 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
23341 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
23343 pc
= &OMP_CLAUSE_CHAIN (*pc
);
23350 "%<#pragma omp target data%> must contain at least "
23351 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
23356 tree stmt
= make_node (OMP_TARGET_DATA
);
23357 TREE_TYPE (stmt
) = void_type_node
;
23358 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
23359 keep_next_level ();
23360 tree block
= c_begin_compound_stmt (true);
23361 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
23362 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
23364 SET_EXPR_LOCATION (stmt
, loc
);
23365 return add_stmt (stmt
);
23369 # pragma omp target update target-update-clause[optseq] new-line */
23371 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
23372 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
23373 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
23374 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23375 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23376 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23377 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23380 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
23381 enum pragma_context context
)
23383 if (context
== pragma_stmt
)
23385 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
23386 "omp target update");
23387 c_parser_skip_to_pragma_eol (parser
, false);
23392 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
23393 "#pragma omp target update");
23394 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
23395 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
23398 "%<#pragma omp target update%> must contain at least one "
23399 "%<from%> or %<to%> clauses");
23405 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
23407 tree stmt
= make_node (OMP_TARGET_UPDATE
);
23408 TREE_TYPE (stmt
) = void_type_node
;
23409 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
23410 SET_EXPR_LOCATION (stmt
, loc
);
23416 # pragma omp target enter data target-data-clause[optseq] new-line */
23418 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
23419 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23420 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
23421 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23422 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23423 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23426 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
23427 enum pragma_context context
)
23429 bool data_seen
= false;
23430 if (c_parser_next_token_is (parser
, CPP_NAME
))
23432 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23433 if (strcmp (p
, "data") == 0)
23435 c_parser_consume_token (parser
);
23441 c_parser_error (parser
, "expected %<data%>");
23442 c_parser_skip_to_pragma_eol (parser
);
23446 if (context
== pragma_stmt
)
23448 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
23449 "omp target enter data");
23450 c_parser_skip_to_pragma_eol (parser
, false);
23456 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
23459 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
23460 "#pragma omp target enter data");
23461 c_omp_adjust_map_clauses (clauses
, false);
23463 for (tree
*pc
= &clauses
; *pc
;)
23465 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
23466 switch (OMP_CLAUSE_MAP_KIND (*pc
))
23469 case GOMP_MAP_ALWAYS_TO
:
23470 case GOMP_MAP_PRESENT_TO
:
23471 case GOMP_MAP_ALWAYS_PRESENT_TO
:
23472 case GOMP_MAP_ALLOC
:
23473 case GOMP_MAP_PRESENT_ALLOC
:
23476 case GOMP_MAP_TOFROM
:
23477 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_TO
);
23480 case GOMP_MAP_ALWAYS_TOFROM
:
23481 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_TO
);
23484 case GOMP_MAP_PRESENT_TOFROM
:
23485 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_PRESENT_TO
);
23488 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
23489 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_PRESENT_TO
);
23492 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
23493 case GOMP_MAP_ALWAYS_POINTER
:
23494 case GOMP_MAP_ATTACH_DETACH
:
23498 error_at (OMP_CLAUSE_LOCATION (*pc
),
23499 "%<#pragma omp target enter data%> with map-type other "
23500 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
23501 *pc
= OMP_CLAUSE_CHAIN (*pc
);
23504 pc
= &OMP_CLAUSE_CHAIN (*pc
);
23511 "%<#pragma omp target enter data%> must contain at least "
23512 "one %<map%> clause");
23516 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
23517 TREE_TYPE (stmt
) = void_type_node
;
23518 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
23519 SET_EXPR_LOCATION (stmt
, loc
);
23525 # pragma omp target exit data target-data-clause[optseq] new-line */
23527 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
23528 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23529 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
23530 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23531 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23532 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23535 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
23536 enum pragma_context context
)
23538 bool data_seen
= false;
23539 if (c_parser_next_token_is (parser
, CPP_NAME
))
23541 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23542 if (strcmp (p
, "data") == 0)
23544 c_parser_consume_token (parser
);
23550 c_parser_error (parser
, "expected %<data%>");
23551 c_parser_skip_to_pragma_eol (parser
);
23555 if (context
== pragma_stmt
)
23557 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
23558 "omp target exit data");
23559 c_parser_skip_to_pragma_eol (parser
, false);
23565 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
23568 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
23569 "#pragma omp target exit data");
23570 c_omp_adjust_map_clauses (clauses
, false);
23572 for (tree
*pc
= &clauses
; *pc
;)
23574 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
23575 switch (OMP_CLAUSE_MAP_KIND (*pc
))
23577 case GOMP_MAP_FROM
:
23578 case GOMP_MAP_ALWAYS_FROM
:
23579 case GOMP_MAP_PRESENT_FROM
:
23580 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
23581 case GOMP_MAP_RELEASE
:
23582 case GOMP_MAP_DELETE
:
23585 case GOMP_MAP_TOFROM
:
23586 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_FROM
);
23589 case GOMP_MAP_ALWAYS_TOFROM
:
23590 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_FROM
);
23593 case GOMP_MAP_PRESENT_TOFROM
:
23594 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_PRESENT_FROM
);
23597 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
23598 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_PRESENT_FROM
);
23601 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
23602 case GOMP_MAP_ALWAYS_POINTER
:
23603 case GOMP_MAP_ATTACH_DETACH
:
23607 error_at (OMP_CLAUSE_LOCATION (*pc
),
23608 "%<#pragma omp target exit data%> with map-type other "
23609 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
23610 "on %<map%> clause");
23611 *pc
= OMP_CLAUSE_CHAIN (*pc
);
23614 pc
= &OMP_CLAUSE_CHAIN (*pc
);
23621 "%<#pragma omp target exit data%> must contain at least one "
23626 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
23627 TREE_TYPE (stmt
) = void_type_node
;
23628 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
23629 SET_EXPR_LOCATION (stmt
, loc
);
23635 # pragma omp target target-clause[optseq] new-line
23636 structured-block */
23638 #define OMP_TARGET_CLAUSE_MASK \
23639 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
23641 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23642 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23643 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
23644 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23645 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23646 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23647 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
23648 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
23649 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
23650 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
23651 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
23654 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
23656 location_t loc
= c_parser_peek_token (parser
)->location
;
23657 c_parser_consume_pragma (parser
);
23658 tree
*pc
= NULL
, stmt
, block
;
23660 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
23662 c_parser_error (parser
, "expected declaration specifiers");
23663 c_parser_skip_to_pragma_eol (parser
);
23669 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
23671 if (c_parser_next_token_is (parser
, CPP_NAME
))
23673 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23674 enum tree_code ccode
= ERROR_MARK
;
23676 if (strcmp (p
, "teams") == 0)
23678 else if (strcmp (p
, "parallel") == 0)
23679 ccode
= OMP_PARALLEL
;
23680 else if (strcmp (p
, "simd") == 0)
23682 if (ccode
!= ERROR_MARK
)
23684 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
23685 char p_name
[sizeof ("#pragma omp target teams distribute "
23686 "parallel for simd")];
23688 c_parser_consume_token (parser
);
23689 strcpy (p_name
, "#pragma omp target");
23690 if (!flag_openmp
) /* flag_openmp_simd */
23696 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
23697 OMP_TARGET_CLAUSE_MASK
,
23701 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
23702 OMP_TARGET_CLAUSE_MASK
,
23706 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
23707 OMP_TARGET_CLAUSE_MASK
,
23711 gcc_unreachable ();
23713 return stmt
!= NULL_TREE
;
23715 keep_next_level ();
23716 tree block
= c_begin_compound_stmt (true), ret
;
23720 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
23721 OMP_TARGET_CLAUSE_MASK
, cclauses
,
23725 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
23726 OMP_TARGET_CLAUSE_MASK
, cclauses
,
23730 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
23731 OMP_TARGET_CLAUSE_MASK
, cclauses
,
23735 gcc_unreachable ();
23737 block
= c_end_compound_stmt (loc
, block
, true);
23738 if (ret
== NULL_TREE
)
23740 if (ccode
== OMP_TEAMS
)
23741 /* For combined target teams, ensure the num_teams and
23742 thread_limit clause expressions are evaluated on the host,
23743 before entering the target construct. */
23744 for (tree c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
23745 c
; c
= OMP_CLAUSE_CHAIN (c
))
23746 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
23747 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
23749 i
<= (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
); ++i
)
23750 if (OMP_CLAUSE_OPERAND (c
, i
)
23751 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, i
)) != INTEGER_CST
)
23753 tree expr
= OMP_CLAUSE_OPERAND (c
, i
);
23754 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
23755 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
23756 expr
, NULL_TREE
, NULL_TREE
);
23758 OMP_CLAUSE_OPERAND (c
, i
) = expr
;
23759 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
23760 OMP_CLAUSE_FIRSTPRIVATE
);
23761 OMP_CLAUSE_DECL (tc
) = tmp
;
23762 OMP_CLAUSE_CHAIN (tc
)
23763 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
23764 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
23766 tree stmt
= make_node (OMP_TARGET
);
23767 TREE_TYPE (stmt
) = void_type_node
;
23768 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
23769 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
23770 OMP_TARGET_BODY (stmt
) = block
;
23771 OMP_TARGET_COMBINED (stmt
) = 1;
23772 SET_EXPR_LOCATION (stmt
, loc
);
23774 pc
= &OMP_TARGET_CLAUSES (stmt
);
23775 goto check_clauses
;
23777 else if (!flag_openmp
) /* flag_openmp_simd */
23779 c_parser_skip_to_pragma_eol (parser
, false);
23782 else if (strcmp (p
, "data") == 0)
23784 c_parser_consume_token (parser
);
23785 c_parser_omp_target_data (loc
, parser
, if_p
);
23788 else if (strcmp (p
, "enter") == 0)
23790 c_parser_consume_token (parser
);
23791 return c_parser_omp_target_enter_data (loc
, parser
, context
);
23793 else if (strcmp (p
, "exit") == 0)
23795 c_parser_consume_token (parser
);
23796 return c_parser_omp_target_exit_data (loc
, parser
, context
);
23798 else if (strcmp (p
, "update") == 0)
23800 c_parser_consume_token (parser
);
23801 return c_parser_omp_target_update (loc
, parser
, context
);
23804 if (!flag_openmp
) /* flag_openmp_simd */
23806 c_parser_skip_to_pragma_eol (parser
, false);
23810 stmt
= make_node (OMP_TARGET
);
23811 TREE_TYPE (stmt
) = void_type_node
;
23813 OMP_TARGET_CLAUSES (stmt
)
23814 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
23815 "#pragma omp target", false);
23816 for (tree c
= OMP_TARGET_CLAUSES (stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
23817 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
)
23819 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
23820 OMP_CLAUSE_DECL (nc
) = OMP_CLAUSE_DECL (c
);
23821 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_ALWAYS_TOFROM
);
23822 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
23823 OMP_CLAUSE_CHAIN (c
) = nc
;
23825 OMP_TARGET_CLAUSES (stmt
)
23826 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt
), C_ORT_OMP_TARGET
);
23827 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
23829 pc
= &OMP_TARGET_CLAUSES (stmt
);
23830 keep_next_level ();
23831 block
= c_begin_compound_stmt (true);
23832 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
23833 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
23835 SET_EXPR_LOCATION (stmt
, loc
);
23841 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
23842 switch (OMP_CLAUSE_MAP_KIND (*pc
))
23845 case GOMP_MAP_ALWAYS_TO
:
23846 case GOMP_MAP_PRESENT_TO
:
23847 case GOMP_MAP_ALWAYS_PRESENT_TO
:
23848 case GOMP_MAP_FROM
:
23849 case GOMP_MAP_ALWAYS_FROM
:
23850 case GOMP_MAP_PRESENT_FROM
:
23851 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
23852 case GOMP_MAP_TOFROM
:
23853 case GOMP_MAP_ALWAYS_TOFROM
:
23854 case GOMP_MAP_PRESENT_TOFROM
:
23855 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
23856 case GOMP_MAP_ALLOC
:
23857 case GOMP_MAP_PRESENT_ALLOC
:
23858 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
23859 case GOMP_MAP_ALWAYS_POINTER
:
23860 case GOMP_MAP_ATTACH_DETACH
:
23863 error_at (OMP_CLAUSE_LOCATION (*pc
),
23864 "%<#pragma omp target%> with map-type other "
23865 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
23866 "on %<map%> clause");
23867 *pc
= OMP_CLAUSE_CHAIN (*pc
);
23870 pc
= &OMP_CLAUSE_CHAIN (*pc
);
23872 cfun
->has_omp_target
= true;
23877 # pragma omp declare simd declare-simd-clauses[optseq] new-line
23880 # pragma omp declare variant (identifier) match(context-selector) new-line
23883 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
23884 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
23885 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
23886 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
23887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
23888 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
23889 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
23892 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
23894 c_token
*token
= c_parser_peek_token (parser
);
23895 gcc_assert (token
->type
== CPP_NAME
);
23896 tree kind
= token
->value
;
23897 gcc_assert (strcmp (IDENTIFIER_POINTER (kind
), "simd") == 0
23898 || strcmp (IDENTIFIER_POINTER (kind
), "variant") == 0);
23900 auto_vec
<c_token
> clauses
;
23901 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
23903 c_token
*token
= c_parser_peek_token (parser
);
23904 if (token
->type
== CPP_EOF
)
23906 c_parser_skip_to_pragma_eol (parser
);
23909 clauses
.safe_push (*token
);
23910 c_parser_consume_token (parser
);
23912 clauses
.safe_push (*c_parser_peek_token (parser
));
23913 c_parser_skip_to_pragma_eol (parser
);
23915 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
23917 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_DECLARE
23918 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
23919 || c_parser_peek_2nd_token (parser
)->value
!= kind
)
23921 error ("%<#pragma omp declare %s%> must be followed by "
23922 "function declaration or definition or another "
23923 "%<#pragma omp declare %s%>",
23924 IDENTIFIER_POINTER (kind
), IDENTIFIER_POINTER (kind
));
23927 c_parser_consume_pragma (parser
);
23928 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
23930 c_token
*token
= c_parser_peek_token (parser
);
23931 if (token
->type
== CPP_EOF
)
23933 c_parser_skip_to_pragma_eol (parser
);
23936 clauses
.safe_push (*token
);
23937 c_parser_consume_token (parser
);
23939 clauses
.safe_push (*c_parser_peek_token (parser
));
23940 c_parser_skip_to_pragma_eol (parser
);
23943 /* Make sure nothing tries to read past the end of the tokens. */
23945 memset (&eof_token
, 0, sizeof (eof_token
));
23946 eof_token
.type
= CPP_EOF
;
23947 clauses
.safe_push (eof_token
);
23948 clauses
.safe_push (eof_token
);
23952 case pragma_external
:
23953 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
23954 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
23956 int ext
= disable_extension_diagnostics ();
23958 c_parser_consume_token (parser
);
23959 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
23960 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
23961 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
23963 restore_extension_diagnostics (ext
);
23966 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
23969 case pragma_struct
:
23972 error ("%<#pragma omp declare %s%> must be followed by "
23973 "function declaration or definition",
23974 IDENTIFIER_POINTER (kind
));
23976 case pragma_compound
:
23977 bool have_std_attrs
;
23979 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
23980 if (have_std_attrs
)
23981 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
23983 std_attrs
= NULL_TREE
;
23984 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
23985 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
23987 int ext
= disable_extension_diagnostics ();
23989 c_parser_consume_token (parser
);
23990 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
23991 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
23992 if (c_parser_next_tokens_start_declaration (parser
)
23993 || c_parser_nth_token_starts_std_attributes (parser
, 1))
23995 c_parser_declaration_or_fndef (parser
, true, true, true, true,
23996 true, NULL
, &clauses
,
23997 have_std_attrs
, std_attrs
);
23998 restore_extension_diagnostics (ext
);
24001 restore_extension_diagnostics (ext
);
24003 else if (c_parser_next_tokens_start_declaration (parser
))
24005 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
24006 NULL
, &clauses
, have_std_attrs
,
24010 error ("%<#pragma omp declare %s%> must be followed by "
24011 "function declaration or definition",
24012 IDENTIFIER_POINTER (kind
));
24015 gcc_unreachable ();
24019 static const char *const omp_construct_selectors
[] = {
24020 "simd", "target", "teams", "parallel", "for", NULL
};
24021 static const char *const omp_device_selectors
[] = {
24022 "kind", "isa", "arch", NULL
};
24023 static const char *const omp_implementation_selectors
[] = {
24024 "vendor", "extension", "atomic_default_mem_order", "unified_address",
24025 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL
};
24026 static const char *const omp_user_selectors
[] = {
24027 "condition", NULL
};
24032 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
24035 score(score-expression) */
24038 c_parser_omp_context_selector (c_parser
*parser
, tree set
, tree parms
)
24040 tree ret
= NULL_TREE
;
24044 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24045 || c_parser_next_token_is (parser
, CPP_NAME
))
24046 selector
= c_parser_peek_token (parser
)->value
;
24049 c_parser_error (parser
, "expected trait selector name");
24050 return error_mark_node
;
24053 tree properties
= NULL_TREE
;
24054 const char *const *selectors
= NULL
;
24055 bool allow_score
= true;
24056 bool allow_user
= false;
24057 int property_limit
= 0;
24058 enum { CTX_PROPERTY_NONE
, CTX_PROPERTY_USER
, CTX_PROPERTY_NAME_LIST
,
24059 CTX_PROPERTY_ID
, CTX_PROPERTY_EXPR
,
24060 CTX_PROPERTY_SIMD
} property_kind
= CTX_PROPERTY_NONE
;
24061 switch (IDENTIFIER_POINTER (set
)[0])
24063 case 'c': /* construct */
24064 selectors
= omp_construct_selectors
;
24065 allow_score
= false;
24066 property_limit
= 1;
24067 property_kind
= CTX_PROPERTY_SIMD
;
24069 case 'd': /* device */
24070 selectors
= omp_device_selectors
;
24071 allow_score
= false;
24073 property_limit
= 3;
24074 property_kind
= CTX_PROPERTY_NAME_LIST
;
24076 case 'i': /* implementation */
24077 selectors
= omp_implementation_selectors
;
24079 property_limit
= 3;
24080 property_kind
= CTX_PROPERTY_NAME_LIST
;
24082 case 'u': /* user */
24083 selectors
= omp_user_selectors
;
24084 property_limit
= 1;
24085 property_kind
= CTX_PROPERTY_EXPR
;
24088 gcc_unreachable ();
24090 for (int i
= 0; ; i
++)
24092 if (selectors
[i
] == NULL
)
24096 property_kind
= CTX_PROPERTY_USER
;
24101 error_at (c_parser_peek_token (parser
)->location
,
24102 "selector %qs not allowed for context selector "
24103 "set %qs", IDENTIFIER_POINTER (selector
),
24104 IDENTIFIER_POINTER (set
));
24105 c_parser_consume_token (parser
);
24106 return error_mark_node
;
24109 if (i
== property_limit
)
24110 property_kind
= CTX_PROPERTY_NONE
;
24111 if (strcmp (selectors
[i
], IDENTIFIER_POINTER (selector
)) == 0)
24114 if (property_kind
== CTX_PROPERTY_NAME_LIST
24115 && IDENTIFIER_POINTER (set
)[0] == 'i'
24116 && strcmp (IDENTIFIER_POINTER (selector
),
24117 "atomic_default_mem_order") == 0)
24118 property_kind
= CTX_PROPERTY_ID
;
24120 c_parser_consume_token (parser
);
24122 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
24124 if (property_kind
== CTX_PROPERTY_NONE
)
24126 error_at (c_parser_peek_token (parser
)->location
,
24127 "selector %qs does not accept any properties",
24128 IDENTIFIER_POINTER (selector
));
24129 return error_mark_node
;
24132 matching_parens parens
;
24133 parens
.require_open (parser
);
24135 c_token
*token
= c_parser_peek_token (parser
);
24137 && c_parser_next_token_is (parser
, CPP_NAME
)
24138 && strcmp (IDENTIFIER_POINTER (token
->value
), "score") == 0
24139 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
24141 c_parser_consume_token (parser
);
24143 matching_parens parens2
;
24144 parens2
.require_open (parser
);
24145 tree score
= c_parser_expr_no_commas (parser
, NULL
).value
;
24146 parens2
.skip_until_found_close (parser
);
24147 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
24148 if (score
!= error_mark_node
)
24150 mark_exp_read (score
);
24151 score
= c_fully_fold (score
, false, NULL
);
24152 if (!INTEGRAL_TYPE_P (TREE_TYPE (score
))
24153 || TREE_CODE (score
) != INTEGER_CST
)
24154 error_at (token
->location
, "score argument must be "
24155 "constant integer expression");
24156 else if (tree_int_cst_sgn (score
) < 0)
24157 error_at (token
->location
, "score argument must be "
24160 properties
= tree_cons (get_identifier (" score"),
24161 score
, properties
);
24163 token
= c_parser_peek_token (parser
);
24166 switch (property_kind
)
24169 case CTX_PROPERTY_USER
:
24172 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
24173 if (TREE_CODE (t
) == STRING_CST
)
24174 properties
= tree_cons (NULL_TREE
, t
, properties
);
24175 else if (t
!= error_mark_node
)
24178 t
= c_fully_fold (t
, false, NULL
);
24179 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
24180 || !tree_fits_shwi_p (t
))
24181 error_at (token
->location
, "property must be "
24182 "constant integer expression or string "
24185 properties
= tree_cons (NULL_TREE
, t
, properties
);
24188 return error_mark_node
;
24190 if (c_parser_next_token_is (parser
, CPP_COMMA
))
24191 c_parser_consume_token (parser
);
24197 case CTX_PROPERTY_ID
:
24198 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24199 || c_parser_next_token_is (parser
, CPP_NAME
))
24201 tree prop
= c_parser_peek_token (parser
)->value
;
24202 c_parser_consume_token (parser
);
24203 properties
= tree_cons (prop
, NULL_TREE
, properties
);
24207 c_parser_error (parser
, "expected identifier");
24208 return error_mark_node
;
24211 case CTX_PROPERTY_NAME_LIST
:
24214 tree prop
= NULL_TREE
, value
= NULL_TREE
;
24215 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24216 || c_parser_next_token_is (parser
, CPP_NAME
))
24218 prop
= c_parser_peek_token (parser
)->value
;
24219 c_parser_consume_token (parser
);
24221 else if (c_parser_next_token_is (parser
, CPP_STRING
))
24222 value
= c_parser_string_literal (parser
, false,
24226 c_parser_error (parser
, "expected identifier or "
24228 return error_mark_node
;
24231 properties
= tree_cons (prop
, value
, properties
);
24233 if (c_parser_next_token_is (parser
, CPP_COMMA
))
24234 c_parser_consume_token (parser
);
24240 case CTX_PROPERTY_EXPR
:
24241 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
24242 if (t
!= error_mark_node
)
24245 t
= c_fully_fold (t
, false, NULL
);
24246 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
24247 || !tree_fits_shwi_p (t
))
24248 error_at (token
->location
, "property must be "
24249 "constant integer expression");
24251 properties
= tree_cons (NULL_TREE
, t
, properties
);
24254 return error_mark_node
;
24256 case CTX_PROPERTY_SIMD
:
24257 if (parms
== NULL_TREE
)
24259 error_at (token
->location
, "properties for %<simd%> "
24260 "selector may not be specified in "
24261 "%<metadirective%>");
24262 return error_mark_node
;
24265 c
= c_parser_omp_all_clauses (parser
,
24266 OMP_DECLARE_SIMD_CLAUSE_MASK
,
24268 c
= c_omp_declare_simd_clauses_to_numbers (parms
24270 ? NULL_TREE
: parms
,
24275 gcc_unreachable ();
24278 parens
.skip_until_found_close (parser
);
24279 properties
= nreverse (properties
);
24281 else if (property_kind
== CTX_PROPERTY_NAME_LIST
24282 || property_kind
== CTX_PROPERTY_ID
24283 || property_kind
== CTX_PROPERTY_EXPR
)
24285 c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>");
24286 return error_mark_node
;
24289 ret
= tree_cons (selector
, properties
, ret
);
24291 if (c_parser_next_token_is (parser
, CPP_COMMA
))
24292 c_parser_consume_token (parser
);
24298 return nreverse (ret
);
24303 trait-set-selector[,trait-set-selector[,...]]
24305 trait-set-selector:
24306 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
24308 trait-set-selector-name:
24315 c_parser_omp_context_selector_specification (c_parser
*parser
, tree parms
)
24317 tree ret
= NULL_TREE
;
24320 const char *setp
= "";
24321 if (c_parser_next_token_is (parser
, CPP_NAME
))
24322 setp
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24326 if (strcmp (setp
, "construct") == 0)
24330 if (strcmp (setp
, "device") == 0)
24334 if (strcmp (setp
, "implementation") == 0)
24338 if (strcmp (setp
, "user") == 0)
24346 c_parser_error (parser
, "expected %<construct%>, %<device%>, "
24347 "%<implementation%> or %<user%>");
24348 return error_mark_node
;
24351 tree set
= c_parser_peek_token (parser
)->value
;
24352 c_parser_consume_token (parser
);
24354 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
24355 return error_mark_node
;
24357 matching_braces braces
;
24358 if (!braces
.require_open (parser
))
24359 return error_mark_node
;
24361 tree selectors
= c_parser_omp_context_selector (parser
, set
, parms
);
24362 if (selectors
== error_mark_node
)
24363 ret
= error_mark_node
;
24364 else if (ret
!= error_mark_node
)
24365 ret
= tree_cons (set
, selectors
, ret
);
24367 braces
.skip_until_found_close (parser
);
24369 if (c_parser_next_token_is (parser
, CPP_COMMA
))
24370 c_parser_consume_token (parser
);
24376 if (ret
== error_mark_node
)
24378 return nreverse (ret
);
24381 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
24382 that into "omp declare variant base" attribute. */
24385 c_finish_omp_declare_variant (c_parser
*parser
, tree fndecl
, tree parms
)
24387 matching_parens parens
;
24388 if (!parens
.require_open (parser
))
24391 c_parser_skip_to_pragma_eol (parser
, false);
24395 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
24396 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
24398 c_parser_error (parser
, "expected identifier");
24402 c_token
*token
= c_parser_peek_token (parser
);
24403 tree variant
= lookup_name (token
->value
);
24405 if (variant
== NULL_TREE
)
24407 undeclared_variable (token
->location
, token
->value
);
24408 variant
= error_mark_node
;
24411 c_parser_consume_token (parser
);
24413 parens
.require_close (parser
);
24415 if (c_parser_next_token_is (parser
, CPP_COMMA
)
24416 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
24417 c_parser_consume_token (parser
);
24419 const char *clause
= "";
24420 location_t match_loc
= c_parser_peek_token (parser
)->location
;
24421 if (c_parser_next_token_is (parser
, CPP_NAME
))
24422 clause
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24423 if (strcmp (clause
, "match"))
24425 c_parser_error (parser
, "expected %<match%>");
24429 c_parser_consume_token (parser
);
24431 if (!parens
.require_open (parser
))
24434 if (parms
== NULL_TREE
)
24435 parms
= error_mark_node
;
24437 tree ctx
= c_parser_omp_context_selector_specification (parser
, parms
);
24438 if (ctx
== error_mark_node
)
24440 ctx
= omp_check_context_selector (match_loc
, ctx
);
24441 if (ctx
!= error_mark_node
&& variant
!= error_mark_node
)
24443 if (TREE_CODE (variant
) != FUNCTION_DECL
)
24445 error_at (token
->location
, "variant %qD is not a function", variant
);
24446 variant
= error_mark_node
;
24448 else if (omp_get_context_selector (ctx
, "construct", "simd") == NULL_TREE
24449 && !comptypes (TREE_TYPE (fndecl
), TREE_TYPE (variant
)))
24451 error_at (token
->location
, "variant %qD and base %qD have "
24452 "incompatible types", variant
, fndecl
);
24453 variant
= error_mark_node
;
24455 else if (fndecl_built_in_p (variant
)
24456 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
24457 "__builtin_", strlen ("__builtin_")) == 0
24458 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
24459 "__sync_", strlen ("__sync_")) == 0
24460 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
24461 "__atomic_", strlen ("__atomic_")) == 0))
24463 error_at (token
->location
, "variant %qD is a built-in", variant
);
24464 variant
= error_mark_node
;
24466 if (variant
!= error_mark_node
)
24468 C_DECL_USED (variant
) = 1;
24469 tree construct
= omp_get_context_selector (ctx
, "construct", NULL
);
24470 omp_mark_declare_variant (match_loc
, variant
, construct
);
24471 if (omp_context_selector_matches (ctx
))
24474 = tree_cons (get_identifier ("omp declare variant base"),
24475 build_tree_list (variant
, ctx
),
24476 DECL_ATTRIBUTES (fndecl
));
24477 DECL_ATTRIBUTES (fndecl
) = attr
;
24482 parens
.require_close (parser
);
24483 c_parser_skip_to_pragma_eol (parser
);
24486 /* Finalize #pragma omp declare simd or #pragma omp declare variant
24487 clauses after FNDECL has been parsed, and put that into "omp declare simd"
24488 or "omp declare variant base" attribute. */
24491 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
24492 vec
<c_token
> *pclauses
)
24494 vec
<c_token
> &clauses
= *pclauses
;
24496 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
24497 indicates error has been reported and CPP_PRAGMA that
24498 c_finish_omp_declare_simd has already processed the tokens. */
24499 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
24501 const char *kind
= "simd";
24502 if (clauses
.exists ()
24503 && (clauses
[0].type
== CPP_NAME
|| clauses
[0].type
== CPP_PRAGMA
))
24504 kind
= IDENTIFIER_POINTER (clauses
[0].value
);
24505 gcc_assert (strcmp (kind
, "simd") == 0 || strcmp (kind
, "variant") == 0);
24506 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
24508 error ("%<#pragma omp declare %s%> not immediately followed by "
24509 "a function declaration or definition", kind
);
24510 clauses
[0].type
= CPP_EOF
;
24513 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
24515 error_at (DECL_SOURCE_LOCATION (fndecl
),
24516 "%<#pragma omp declare %s%> not immediately followed by "
24517 "a single function declaration or definition", kind
);
24518 clauses
[0].type
= CPP_EOF
;
24522 if (parms
== NULL_TREE
)
24523 parms
= DECL_ARGUMENTS (fndecl
);
24525 unsigned int tokens_avail
= parser
->tokens_avail
;
24526 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
24528 parser
->tokens
= clauses
.address ();
24529 parser
->tokens_avail
= clauses
.length ();
24531 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
24532 while (parser
->tokens_avail
> 3)
24534 c_token
*token
= c_parser_peek_token (parser
);
24535 gcc_assert (token
->type
== CPP_NAME
);
24536 kind
= IDENTIFIER_POINTER (token
->value
);
24537 c_parser_consume_token (parser
);
24538 parser
->in_pragma
= true;
24540 if (strcmp (kind
, "simd") == 0)
24543 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
24544 "#pragma omp declare simd");
24545 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
24546 if (c
!= NULL_TREE
)
24547 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
24548 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
24549 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
24550 DECL_ATTRIBUTES (fndecl
) = c
;
24554 gcc_assert (strcmp (kind
, "variant") == 0);
24555 c_finish_omp_declare_variant (parser
, fndecl
, parms
);
24559 parser
->tokens
= &parser
->tokens_buf
[0];
24560 parser
->tokens_avail
= tokens_avail
;
24561 if (clauses
.exists ())
24562 clauses
[0].type
= CPP_PRAGMA
;
24565 /* D should be C_TOKEN_VEC from omp::decl attribute. If it contains
24566 a threadprivate, groupprivate, allocate or declare target directive,
24567 return true and parse it for DECL. */
24570 c_maybe_parse_omp_decl (tree decl
, tree d
)
24572 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
24573 vec
<c_token
, va_gc
> *toks
= C_TOKEN_VEC_TOKENS (d
);
24574 c_token
*first
= toks
->address ();
24575 c_token
*last
= first
+ toks
->length ();
24576 const char *directive
[3] = {};
24577 for (int j
= 0; j
< 3; j
++)
24579 tree id
= NULL_TREE
;
24580 if (first
+ j
== last
)
24582 if (first
[j
].type
== CPP_NAME
)
24583 id
= first
[j
].value
;
24584 else if (first
[j
].type
== CPP_KEYWORD
)
24585 id
= ridpointers
[(int) first
[j
].keyword
];
24588 directive
[j
] = IDENTIFIER_POINTER (id
);
24590 const c_omp_directive
*dir
= NULL
;
24592 dir
= c_omp_categorize_directive (directive
[0], directive
[1],
24596 error_at (first
->location
,
24597 "unknown OpenMP directive name in "
24598 "%qs attribute argument", "omp::decl");
24601 if (dir
->id
!= PRAGMA_OMP_THREADPRIVATE
24602 /* && dir->id != PRAGMA_OMP_GROUPPRIVATE */
24603 && dir
->id
!= PRAGMA_OMP_ALLOCATE
24604 && (dir
->id
!= PRAGMA_OMP_DECLARE
24605 || strcmp (directive
[1], "target") != 0))
24608 if (!flag_openmp
&& !dir
->simd
)
24611 c_parser
*parser
= the_parser
;
24612 unsigned int tokens_avail
= parser
->tokens_avail
;
24613 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
24615 vec_safe_reserve (toks
, last
- first
+ 2, true);
24617 tok
.type
= CPP_PRAGMA
;
24618 tok
.keyword
= RID_MAX
;
24619 tok
.pragma_kind
= pragma_kind (dir
->id
);
24620 tok
.location
= first
->location
;
24621 toks
->quick_push (tok
);
24622 while (++first
< last
)
24623 toks
->quick_push (*first
);
24625 tok
.type
= CPP_PRAGMA_EOL
;
24626 tok
.keyword
= RID_MAX
;
24627 tok
.location
= last
[-1].location
;
24628 toks
->quick_push (tok
);
24630 tok
.type
= CPP_EOF
;
24631 tok
.keyword
= RID_MAX
;
24632 tok
.location
= last
[-1].location
;
24633 tok
.flags
= tokens_avail
;
24634 toks
->quick_push (tok
);
24635 parser
->in_omp_decl_attribute
= decl
;
24636 parser
->tokens
= toks
->address ();
24637 parser
->tokens_avail
= toks
->length ();
24638 parser
->in_omp_attribute_pragma
= toks
;
24639 c_parser_pragma (parser
, pragma_external
, NULL
);
24640 parser
->in_omp_decl_attribute
= NULL_TREE
;
24645 # pragma omp declare target new-line
24646 declarations and definitions
24647 # pragma omp end declare target new-line
24650 # pragma omp declare target ( extended-list ) new-line
24652 # pragma omp declare target declare-target-clauses[seq] new-line */
24654 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
24655 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
24656 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
24657 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
24658 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
24659 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
24662 c_parser_omp_declare_target (c_parser
*parser
)
24664 tree clauses
= NULL_TREE
;
24665 int device_type
= 0;
24666 bool indirect
= false;
24667 bool only_device_type_or_indirect
= true;
24668 if (c_parser_next_token_is (parser
, CPP_NAME
)
24669 || (c_parser_next_token_is (parser
, CPP_COMMA
)
24670 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
))
24671 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
24672 "#pragma omp declare target");
24673 else if (parser
->in_omp_decl_attribute
24674 || c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
24676 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
24678 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
24679 c_parser_skip_to_pragma_eol (parser
);
24683 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
24684 c_parser_skip_to_pragma_eol (parser
);
24685 c_omp_declare_target_attr attr
= { attr_syntax
, -1, 0 };
24686 vec_safe_push (current_omp_declare_target_attribute
, attr
);
24689 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
24691 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
24692 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
24693 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_INDIRECT
)
24694 indirect
|= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c
));
24696 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
24698 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
24699 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_INDIRECT
)
24701 tree t
= OMP_CLAUSE_DECL (c
), id
;
24702 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
24703 tree at2
= lookup_attribute ("omp declare target link",
24704 DECL_ATTRIBUTES (t
));
24705 only_device_type_or_indirect
= false;
24706 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
24708 id
= get_identifier ("omp declare target link");
24709 std::swap (at1
, at2
);
24712 id
= get_identifier ("omp declare target");
24715 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_ENTER
)
24716 error_at (OMP_CLAUSE_LOCATION (c
),
24717 "%qD specified both in declare target %<link%> and %qs"
24718 " clauses", t
, OMP_CLAUSE_ENTER_TO (c
) ? "to" : "enter");
24720 error_at (OMP_CLAUSE_LOCATION (c
),
24721 "%qD specified both in declare target %<link%> and "
24722 "%<to%> or %<enter%> clauses", t
);
24727 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
24728 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
24731 symtab_node
*node
= symtab_node::get (t
);
24734 node
->offloadable
= 1;
24735 if (ENABLE_OFFLOADING
)
24737 g
->have_offload
= true;
24738 if (is_a
<varpool_node
*> (node
))
24739 vec_safe_push (offload_vars
, t
);
24743 if (TREE_CODE (t
) != FUNCTION_DECL
)
24745 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_HOST
) != 0)
24747 tree at3
= lookup_attribute ("omp declare target host",
24748 DECL_ATTRIBUTES (t
));
24749 if (at3
== NULL_TREE
)
24751 id
= get_identifier ("omp declare target host");
24752 DECL_ATTRIBUTES (t
)
24753 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
24756 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_NOHOST
) != 0)
24758 tree at3
= lookup_attribute ("omp declare target nohost",
24759 DECL_ATTRIBUTES (t
));
24760 if (at3
== NULL_TREE
)
24762 id
= get_identifier ("omp declare target nohost");
24763 DECL_ATTRIBUTES (t
)
24764 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
24769 tree at4
= lookup_attribute ("omp declare target indirect",
24770 DECL_ATTRIBUTES (t
));
24771 if (at4
== NULL_TREE
)
24773 id
= get_identifier ("omp declare target indirect");
24774 DECL_ATTRIBUTES (t
)
24775 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
24779 if ((device_type
|| indirect
) && only_device_type_or_indirect
)
24780 error_at (OMP_CLAUSE_LOCATION (clauses
),
24781 "directive with only %<device_type%> or %<indirect%> clauses");
24782 if (indirect
&& device_type
&& device_type
!= OMP_CLAUSE_DEVICE_TYPE_ANY
)
24783 error_at (OMP_CLAUSE_LOCATION (clauses
),
24784 "%<device_type%> clause must specify 'any' when used with "
24785 "an %<indirect%> clause");
24789 #pragma omp begin assumes clauses[optseq] new-line
24791 #pragma omp begin declare target clauses[optseq] new-line */
24793 #define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \
24794 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
24795 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
24798 c_parser_omp_begin (c_parser
*parser
)
24800 const char *p
= "";
24801 c_parser_consume_pragma (parser
);
24802 if (c_parser_next_token_is (parser
, CPP_NAME
))
24803 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24804 if (strcmp (p
, "declare") == 0)
24806 c_parser_consume_token (parser
);
24808 if (c_parser_next_token_is (parser
, CPP_NAME
))
24809 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24810 if (strcmp (p
, "target") == 0)
24812 c_parser_consume_token (parser
);
24813 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
24815 = c_parser_omp_all_clauses (parser
,
24816 OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK
,
24817 "#pragma omp begin declare target");
24818 int device_type
= 0;
24820 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
24822 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
24823 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
24824 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_INDIRECT
)
24825 indirect
|= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c
));
24827 c_omp_declare_target_attr attr
= { attr_syntax
, device_type
,
24829 vec_safe_push (current_omp_declare_target_attribute
, attr
);
24833 c_parser_error (parser
, "expected %<target%>");
24834 c_parser_skip_to_pragma_eol (parser
);
24837 else if (strcmp (p
, "assumes") == 0)
24839 c_parser_consume_token (parser
);
24840 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
24841 c_parser_omp_assumption_clauses (parser
, false);
24842 struct c_omp_begin_assumes_data a
= { attr_syntax
};
24843 vec_safe_push (current_omp_begin_assumes
, a
);
24847 c_parser_error (parser
, "expected %<declare target%> or %<assumes%>");
24848 c_parser_skip_to_pragma_eol (parser
);
24853 #pragma omp end declare target
24856 #pragma omp end assumes */
24859 c_parser_omp_end (c_parser
*parser
)
24861 location_t loc
= c_parser_peek_token (parser
)->location
;
24862 const char *p
= "";
24863 c_parser_consume_pragma (parser
);
24864 if (c_parser_next_token_is (parser
, CPP_NAME
))
24865 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24866 if (strcmp (p
, "declare") == 0)
24868 c_parser_consume_token (parser
);
24869 if (c_parser_next_token_is (parser
, CPP_NAME
)
24870 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
24872 c_parser_consume_token (parser
);
24875 c_parser_error (parser
, "expected %<target%>");
24876 c_parser_skip_to_pragma_eol (parser
);
24879 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
24880 c_parser_skip_to_pragma_eol (parser
);
24881 if (!vec_safe_length (current_omp_declare_target_attribute
))
24882 error_at (loc
, "%<#pragma omp end declare target%> without "
24883 "corresponding %<#pragma omp declare target%> or "
24884 "%<#pragma omp begin declare target%>");
24887 c_omp_declare_target_attr
24888 a
= current_omp_declare_target_attribute
->pop ();
24889 if (a
.attr_syntax
!= attr_syntax
)
24893 "%qs in attribute syntax terminated "
24894 "with %qs in pragma syntax",
24895 a
.device_type
>= 0 ? "begin declare target"
24896 : "declare target",
24897 "end declare target");
24900 "%qs in pragma syntax terminated "
24901 "with %qs in attribute syntax",
24902 a
.device_type
>= 0 ? "begin declare target"
24903 : "declare target",
24904 "end declare target");
24908 else if (strcmp (p
, "assumes") == 0)
24910 c_parser_consume_token (parser
);
24911 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
24912 c_parser_skip_to_pragma_eol (parser
);
24913 if (!vec_safe_length (current_omp_begin_assumes
))
24914 error_at (loc
, "%qs without corresponding %qs",
24915 "#pragma omp end assumes", "#pragma omp begin assumes");
24918 c_omp_begin_assumes_data
24919 a
= current_omp_begin_assumes
->pop ();
24920 if (a
.attr_syntax
!= attr_syntax
)
24924 "%qs in attribute syntax terminated "
24925 "with %qs in pragma syntax",
24926 "begin assumes", "end assumes");
24929 "%qs in pragma syntax terminated "
24930 "with %qs in attribute syntax",
24931 "begin assumes", "end assumes");
24937 c_parser_error (parser
, "expected %<declare%> or %<assumes%>");
24938 c_parser_skip_to_pragma_eol (parser
);
24943 #pragma omp declare reduction (reduction-id : typename-list : expression) \
24944 initializer-clause[opt] new-line
24946 initializer-clause:
24947 initializer (omp_priv = initializer)
24948 initializer (function-name (argument-list)) */
24951 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
24953 unsigned int tokens_avail
= 0, i
;
24954 c_token
*saved_tokens
= NULL
;
24955 vec
<tree
> types
= vNULL
;
24956 vec
<c_token
> clauses
= vNULL
;
24957 enum tree_code reduc_code
= ERROR_MARK
;
24958 tree reduc_id
= NULL_TREE
;
24960 location_t rloc
= c_parser_peek_token (parser
)->location
;
24962 if (context
== pragma_struct
|| context
== pragma_param
)
24964 error ("%<#pragma omp declare reduction%> not at file or block scope");
24968 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
24971 switch (c_parser_peek_token (parser
)->type
)
24974 reduc_code
= PLUS_EXPR
;
24977 reduc_code
= MULT_EXPR
;
24980 reduc_code
= MINUS_EXPR
;
24983 reduc_code
= BIT_AND_EXPR
;
24986 reduc_code
= BIT_XOR_EXPR
;
24989 reduc_code
= BIT_IOR_EXPR
;
24992 reduc_code
= TRUTH_ANDIF_EXPR
;
24995 reduc_code
= TRUTH_ORIF_EXPR
;
24999 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25000 if (strcmp (p
, "min") == 0)
25002 reduc_code
= MIN_EXPR
;
25005 if (strcmp (p
, "max") == 0)
25007 reduc_code
= MAX_EXPR
;
25010 reduc_id
= c_parser_peek_token (parser
)->value
;
25013 c_parser_error (parser
,
25014 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
25015 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
25019 tree orig_reduc_id
, reduc_decl
;
25020 orig_reduc_id
= reduc_id
;
25021 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
25022 reduc_decl
= c_omp_reduction_decl (reduc_id
);
25023 c_parser_consume_token (parser
);
25025 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
25030 location_t loc
= c_parser_peek_token (parser
)->location
;
25031 struct c_type_name
*ctype
= c_parser_type_name (parser
);
25034 type
= groktypename (ctype
, NULL
, NULL
);
25035 if (type
== error_mark_node
)
25037 else if ((INTEGRAL_TYPE_P (type
)
25038 || SCALAR_FLOAT_TYPE_P (type
)
25039 || TREE_CODE (type
) == COMPLEX_TYPE
)
25040 && orig_reduc_id
== NULL_TREE
)
25041 error_at (loc
, "predeclared arithmetic type in "
25042 "%<#pragma omp declare reduction%>");
25043 else if (TREE_CODE (type
) == FUNCTION_TYPE
25044 || TREE_CODE (type
) == ARRAY_TYPE
)
25045 error_at (loc
, "function or array type in "
25046 "%<#pragma omp declare reduction%>");
25047 else if (TYPE_ATOMIC (type
))
25048 error_at (loc
, "%<_Atomic%> qualified type in "
25049 "%<#pragma omp declare reduction%>");
25050 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
25051 error_at (loc
, "const, volatile or restrict qualified type in "
25052 "%<#pragma omp declare reduction%>");
25056 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
25057 if (comptypes (TREE_PURPOSE (t
), type
))
25059 error_at (loc
, "redeclaration of %qs "
25060 "%<#pragma omp declare reduction%> for "
25062 IDENTIFIER_POINTER (reduc_id
)
25063 + sizeof ("omp declare reduction ") - 1,
25066 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
25068 error_at (ploc
, "previous %<#pragma omp declare "
25072 if (t
== NULL_TREE
)
25073 types
.safe_push (type
);
25075 if (c_parser_next_token_is (parser
, CPP_COMMA
))
25076 c_parser_consume_token (parser
);
25084 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
25085 || types
.is_empty ())
25088 clauses
.release ();
25092 c_token
*token
= c_parser_peek_token (parser
);
25093 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
25095 c_parser_consume_token (parser
);
25097 c_parser_skip_to_pragma_eol (parser
);
25101 if (types
.length () > 1)
25103 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
25105 c_token
*token
= c_parser_peek_token (parser
);
25106 if (token
->type
== CPP_EOF
)
25108 clauses
.safe_push (*token
);
25109 c_parser_consume_token (parser
);
25111 clauses
.safe_push (*c_parser_peek_token (parser
));
25112 c_parser_skip_to_pragma_eol (parser
);
25114 /* Make sure nothing tries to read past the end of the tokens. */
25116 memset (&eof_token
, 0, sizeof (eof_token
));
25117 eof_token
.type
= CPP_EOF
;
25118 clauses
.safe_push (eof_token
);
25119 clauses
.safe_push (eof_token
);
25122 int errs
= errorcount
;
25123 FOR_EACH_VEC_ELT (types
, i
, type
)
25125 saved_tokens
= parser
->tokens
;
25126 tokens_avail
= parser
->tokens_avail
;
25127 if (!clauses
.is_empty ())
25129 parser
->tokens
= clauses
.address ();
25130 parser
->tokens_avail
= clauses
.length ();
25131 parser
->in_pragma
= true;
25134 bool nested
= current_function_decl
!= NULL_TREE
;
25136 c_push_function_context ();
25137 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
25138 reduc_id
, default_function_type
);
25139 current_function_decl
= fndecl
;
25140 allocate_struct_function (fndecl
, true);
25142 tree stmt
= push_stmt_list ();
25143 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
25144 warn about these. */
25145 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
25146 get_identifier ("omp_out"), type
);
25147 DECL_ARTIFICIAL (omp_out
) = 1;
25148 DECL_CONTEXT (omp_out
) = fndecl
;
25149 pushdecl (omp_out
);
25150 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
25151 get_identifier ("omp_in"), type
);
25152 DECL_ARTIFICIAL (omp_in
) = 1;
25153 DECL_CONTEXT (omp_in
) = fndecl
;
25155 struct c_expr combiner
= c_parser_expression (parser
);
25156 struct c_expr initializer
;
25157 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
25159 initializer
.set_error ();
25160 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
25162 else if (c_parser_next_token_is (parser
, CPP_COMMA
)
25163 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
25164 c_parser_consume_token (parser
);
25166 && (c_parser_next_token_is (parser
, CPP_NAME
)
25167 && strcmp (IDENTIFIER_POINTER
25168 (c_parser_peek_token (parser
)->value
),
25169 "initializer") == 0))
25171 c_parser_consume_token (parser
);
25174 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
25175 get_identifier ("omp_priv"), type
);
25176 DECL_ARTIFICIAL (omp_priv
) = 1;
25177 DECL_INITIAL (omp_priv
) = error_mark_node
;
25178 DECL_CONTEXT (omp_priv
) = fndecl
;
25179 pushdecl (omp_priv
);
25180 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
25181 get_identifier ("omp_orig"), type
);
25182 DECL_ARTIFICIAL (omp_orig
) = 1;
25183 DECL_CONTEXT (omp_orig
) = fndecl
;
25184 pushdecl (omp_orig
);
25185 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
25187 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
25189 c_parser_error (parser
, "expected %<omp_priv%> or "
25193 else if (strcmp (IDENTIFIER_POINTER
25194 (c_parser_peek_token (parser
)->value
),
25197 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
25198 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
25200 c_parser_error (parser
, "expected function-name %<(%>");
25204 initializer
= c_parser_postfix_expression (parser
);
25205 if (initializer
.value
25206 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
25209 tree c
= initializer
.value
;
25210 for (j
= 0; j
< call_expr_nargs (c
); j
++)
25212 tree a
= CALL_EXPR_ARG (c
, j
);
25214 if (TREE_CODE (a
) == ADDR_EXPR
25215 && TREE_OPERAND (a
, 0) == omp_priv
)
25218 if (j
== call_expr_nargs (c
))
25219 error ("one of the initializer call arguments should be "
25225 c_parser_consume_token (parser
);
25226 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
25230 tree st
= push_stmt_list ();
25231 location_t loc
= c_parser_peek_token (parser
)->location
;
25232 rich_location
richloc (line_table
, loc
);
25233 start_init (omp_priv
, NULL_TREE
, false, false, &richloc
);
25234 struct c_expr init
= c_parser_initializer (parser
, omp_priv
);
25236 finish_decl (omp_priv
, loc
, init
.value
,
25237 init
.original_type
, NULL_TREE
);
25238 pop_stmt_list (st
);
25242 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
25248 c_parser_skip_to_pragma_eol (parser
);
25250 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
25251 DECL_INITIAL (reduc_decl
));
25252 DECL_INITIAL (reduc_decl
) = t
;
25253 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
25254 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
25255 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
25256 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
25257 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
25258 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
25261 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
25262 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
25263 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
25264 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
25265 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
25266 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
25267 walk_tree (&DECL_INITIAL (omp_priv
),
25268 c_check_omp_declare_reduction_r
,
25269 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
25273 pop_stmt_list (stmt
);
25275 if (cfun
->language
!= NULL
)
25277 ggc_free (cfun
->language
);
25278 cfun
->language
= NULL
;
25281 current_function_decl
= NULL_TREE
;
25283 c_pop_function_context ();
25285 if (!clauses
.is_empty ())
25287 parser
->tokens
= saved_tokens
;
25288 parser
->tokens_avail
= tokens_avail
;
25292 if (errs
!= errorcount
)
25296 clauses
.release ();
25302 #pragma omp declare simd declare-simd-clauses[optseq] new-line
25303 #pragma omp declare reduction (reduction-id : typename-list : expression) \
25304 initializer-clause[opt] new-line
25305 #pragma omp declare target new-line
25308 #pragma omp declare variant (identifier) match (context-selector) */
25311 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
25313 c_parser_consume_pragma (parser
);
25314 if (c_parser_next_token_is (parser
, CPP_NAME
))
25316 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25317 if (strcmp (p
, "simd") == 0)
25319 /* c_parser_consume_token (parser); done in
25320 c_parser_omp_declare_simd. */
25321 c_parser_omp_declare_simd (parser
, context
);
25324 if (strcmp (p
, "reduction") == 0)
25326 c_parser_consume_token (parser
);
25327 c_parser_omp_declare_reduction (parser
, context
);
25330 if (!flag_openmp
) /* flag_openmp_simd */
25332 c_parser_skip_to_pragma_eol (parser
, false);
25335 if (strcmp (p
, "target") == 0)
25337 c_parser_consume_token (parser
);
25338 c_parser_omp_declare_target (parser
);
25341 if (strcmp (p
, "variant") == 0)
25343 /* c_parser_consume_token (parser); done in
25344 c_parser_omp_declare_simd. */
25345 c_parser_omp_declare_simd (parser
, context
);
25350 c_parser_error (parser
, "expected %<simd%>, %<reduction%>, "
25351 "%<target%> or %<variant%>");
25352 c_parser_skip_to_pragma_eol (parser
);
25357 #pragma omp requires clauses[optseq] new-line */
25360 c_parser_omp_requires (c_parser
*parser
)
25362 enum omp_requires new_req
= (enum omp_requires
) 0;
25364 c_parser_consume_pragma (parser
);
25366 location_t loc
= c_parser_peek_token (parser
)->location
;
25367 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
25369 if (c_parser_next_token_is (parser
, CPP_COMMA
)
25370 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
25371 c_parser_consume_token (parser
);
25373 if (c_parser_next_token_is (parser
, CPP_NAME
))
25376 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25377 location_t cloc
= c_parser_peek_token (parser
)->location
;
25378 enum omp_requires this_req
= (enum omp_requires
) 0;
25380 if (!strcmp (p
, "unified_address"))
25381 this_req
= OMP_REQUIRES_UNIFIED_ADDRESS
;
25382 else if (!strcmp (p
, "unified_shared_memory"))
25383 this_req
= OMP_REQUIRES_UNIFIED_SHARED_MEMORY
;
25384 else if (!strcmp (p
, "dynamic_allocators"))
25385 this_req
= OMP_REQUIRES_DYNAMIC_ALLOCATORS
;
25386 else if (!strcmp (p
, "reverse_offload"))
25387 this_req
= OMP_REQUIRES_REVERSE_OFFLOAD
;
25388 else if (!strcmp (p
, "atomic_default_mem_order"))
25390 c_parser_consume_token (parser
);
25392 matching_parens parens
;
25393 if (parens
.require_open (parser
))
25395 if (c_parser_next_token_is (parser
, CPP_NAME
))
25397 tree v
= c_parser_peek_token (parser
)->value
;
25398 p
= IDENTIFIER_POINTER (v
);
25400 if (!strcmp (p
, "seq_cst"))
25402 = (enum omp_requires
) OMP_MEMORY_ORDER_SEQ_CST
;
25403 else if (!strcmp (p
, "relaxed"))
25405 = (enum omp_requires
) OMP_MEMORY_ORDER_RELAXED
;
25406 else if (!strcmp (p
, "acq_rel"))
25408 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQ_REL
;
25412 error_at (c_parser_peek_token (parser
)->location
,
25413 "expected %<seq_cst%>, %<relaxed%> or "
25415 switch (c_parser_peek_token (parser
)->type
)
25418 case CPP_PRAGMA_EOL
:
25419 case CPP_CLOSE_PAREN
:
25422 if (c_parser_peek_2nd_token (parser
)->type
25423 == CPP_CLOSE_PAREN
)
25424 c_parser_consume_token (parser
);
25429 c_parser_consume_token (parser
);
25431 parens
.skip_until_found_close (parser
);
25434 c_parser_skip_to_pragma_eol (parser
, false);
25442 error_at (cloc
, "expected %<unified_address%>, "
25443 "%<unified_shared_memory%>, "
25444 "%<dynamic_allocators%>, "
25445 "%<reverse_offload%> "
25446 "or %<atomic_default_mem_order%> clause");
25447 c_parser_skip_to_pragma_eol (parser
, false);
25451 c_parser_consume_token (parser
);
25454 if ((this_req
& ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
25456 if ((this_req
& new_req
) != 0)
25457 error_at (cloc
, "too many %qs clauses", p
);
25458 if (this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
25459 && (omp_requires_mask
& OMP_REQUIRES_TARGET_USED
) != 0)
25460 error_at (cloc
, "%qs clause used lexically after first "
25461 "target construct or offloading API", p
);
25463 else if ((new_req
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
25465 error_at (cloc
, "too many %qs clauses",
25466 "atomic_default_mem_order");
25467 this_req
= (enum omp_requires
) 0;
25469 else if ((omp_requires_mask
25470 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
25472 error_at (cloc
, "more than one %<atomic_default_mem_order%>"
25473 " clause in a single compilation unit");
25475 = (enum omp_requires
)
25477 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
);
25479 else if ((omp_requires_mask
25480 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
) != 0)
25481 error_at (cloc
, "%<atomic_default_mem_order%> clause used "
25482 "lexically after first %<atomic%> construct "
25483 "without memory order clause");
25484 new_req
= (enum omp_requires
) (new_req
| this_req
);
25486 = (enum omp_requires
) (omp_requires_mask
| this_req
);
25492 c_parser_skip_to_pragma_eol (parser
);
25495 error_at (loc
, "%<pragma omp requires%> requires at least one clause");
25498 /* Helper function for c_parser_omp_taskloop.
25499 Disallow zero sized or potentially zero sized task reductions. */
25502 c_finish_taskloop_clauses (tree clauses
)
25504 tree
*pc
= &clauses
;
25505 for (tree c
= clauses
; c
; c
= *pc
)
25507 bool remove
= false;
25508 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
25510 tree type
= strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
25511 if (integer_zerop (TYPE_SIZE_UNIT (type
)))
25513 error_at (OMP_CLAUSE_LOCATION (c
),
25514 "zero sized type %qT in %<reduction%> clause", type
);
25517 else if (TREE_CODE (TYPE_SIZE_UNIT (type
)) != INTEGER_CST
)
25519 error_at (OMP_CLAUSE_LOCATION (c
),
25520 "variable sized type %qT in %<reduction%> clause",
25526 *pc
= OMP_CLAUSE_CHAIN (c
);
25528 pc
= &OMP_CLAUSE_CHAIN (c
);
25534 #pragma omp taskloop taskloop-clause[optseq] new-line
25537 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
25540 #define OMP_TASKLOOP_CLAUSE_MASK \
25541 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
25542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
25543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
25544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
25545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
25546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
25547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
25548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
25549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
25550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
25551 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
25552 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
25553 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
25554 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
25555 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
25556 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
25557 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
25560 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
25561 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
25564 tree clauses
, block
, ret
;
25566 strcat (p_name
, " taskloop");
25567 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
25568 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
25570 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
)) != 0)
25571 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_IN_REDUCTION
);
25573 if (c_parser_next_token_is (parser
, CPP_NAME
))
25575 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25577 if (strcmp (p
, "simd") == 0)
25579 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
25580 if (cclauses
== NULL
)
25581 cclauses
= cclauses_buf
;
25582 c_parser_consume_token (parser
);
25583 if (!flag_openmp
) /* flag_openmp_simd */
25584 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
25586 block
= c_begin_compound_stmt (true);
25587 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
25588 block
= c_end_compound_stmt (loc
, block
, true);
25591 ret
= make_node (OMP_TASKLOOP
);
25592 TREE_TYPE (ret
) = void_type_node
;
25593 OMP_FOR_BODY (ret
) = block
;
25594 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
25595 OMP_FOR_CLAUSES (ret
)
25596 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret
));
25597 SET_EXPR_LOCATION (ret
, loc
);
25602 if (!flag_openmp
) /* flag_openmp_simd */
25604 c_parser_skip_to_pragma_eol (parser
, false);
25608 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
25611 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
25612 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
25615 clauses
= c_finish_taskloop_clauses (clauses
);
25616 block
= c_begin_compound_stmt (true);
25617 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
25618 block
= c_end_compound_stmt (loc
, block
, true);
25625 #pragma omp nothing new-line */
25628 c_parser_omp_nothing (c_parser
*parser
)
25630 c_parser_consume_pragma (parser
);
25631 c_parser_skip_to_pragma_eol (parser
);
25635 #pragma omp error clauses[optseq] new-line */
25638 c_parser_omp_error (c_parser
*parser
, enum pragma_context context
)
25640 int at_compilation
= -1;
25641 int severity_fatal
= -1;
25642 tree message
= NULL_TREE
;
25644 location_t loc
= c_parser_peek_token (parser
)->location
;
25646 c_parser_consume_pragma (parser
);
25648 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
25650 if (c_parser_next_token_is (parser
, CPP_COMMA
)
25651 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
25652 c_parser_consume_token (parser
);
25654 if (!c_parser_next_token_is (parser
, CPP_NAME
))
25658 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25659 location_t cloc
= c_parser_peek_token (parser
)->location
;
25660 static const char *args
[] = {
25661 "execution", "compilation", "warning", "fatal"
25664 int idx
= 0, n
= -1;
25665 tree m
= NULL_TREE
;
25667 if (!strcmp (p
, "at"))
25668 v
= &at_compilation
;
25669 else if (!strcmp (p
, "severity"))
25671 v
= &severity_fatal
;
25674 else if (strcmp (p
, "message"))
25677 "expected %<at%>, %<severity%> or %<message%> clause");
25678 c_parser_skip_to_pragma_eol (parser
, false);
25682 c_parser_consume_token (parser
);
25684 matching_parens parens
;
25685 if (parens
.require_open (parser
))
25689 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
25690 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
25691 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
25692 m
= convert (const_string_type_node
, expr
.value
);
25693 m
= c_fully_fold (m
, false, NULL
);
25697 if (c_parser_next_token_is (parser
, CPP_NAME
))
25699 tree val
= c_parser_peek_token (parser
)->value
;
25700 const char *q
= IDENTIFIER_POINTER (val
);
25702 if (!strcmp (q
, args
[idx
]))
25704 else if (!strcmp (q
, args
[idx
+ 1]))
25709 error_at (c_parser_peek_token (parser
)->location
,
25710 "expected %qs or %qs", args
[idx
], args
[idx
+ 1]);
25712 switch (c_parser_peek_token (parser
)->type
)
25715 case CPP_PRAGMA_EOL
:
25716 case CPP_CLOSE_PAREN
:
25719 if (c_parser_peek_2nd_token (parser
)->type
25720 == CPP_CLOSE_PAREN
)
25721 c_parser_consume_token (parser
);
25726 c_parser_consume_token (parser
);
25729 parens
.skip_until_found_close (parser
);
25735 error_at (cloc
, "too many %qs clauses", p
);
25745 error_at (cloc
, "too many %qs clauses", p
);
25755 c_parser_skip_to_pragma_eol (parser
);
25759 if (at_compilation
== -1)
25760 at_compilation
= 1;
25761 if (severity_fatal
== -1)
25762 severity_fatal
= 1;
25763 if (!at_compilation
)
25765 if (context
!= pragma_compound
)
25767 error_at (loc
, "%<#pragma omp error%> with %<at(execution)%> clause "
25768 "may only be used in compound statements");
25772 = builtin_decl_explicit (severity_fatal
? BUILT_IN_GOMP_ERROR
25773 : BUILT_IN_GOMP_WARNING
);
25775 message
= build_zero_cst (const_string_type_node
);
25776 tree stmt
= build_call_expr_loc (loc
, fndecl
, 2, message
,
25777 build_all_ones_cst (size_type_node
));
25781 const char *msg
= NULL
;
25784 msg
= c_getstr (message
);
25786 msg
= _("<message unknown at compile time>");
25789 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
25790 "%<pragma omp error%> encountered: %s", msg
);
25792 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
25793 "%<pragma omp error%> encountered");
25797 /* Assumption clauses:
25799 absent (directive-name-list)
25800 contains (directive-name-list)
25807 c_parser_omp_assumption_clauses (c_parser
*parser
, bool is_assume
)
25809 bool no_openmp
= false;
25810 bool no_openmp_routines
= false;
25811 bool no_parallelism
= false;
25812 bitmap_head absent_head
, contains_head
;
25814 bitmap_obstack_initialize (NULL
);
25815 bitmap_initialize (&absent_head
, &bitmap_default_obstack
);
25816 bitmap_initialize (&contains_head
, &bitmap_default_obstack
);
25818 if (c_parser_next_token_is (parser
, CPP_PRAGMA_EOL
))
25819 error_at (c_parser_peek_token (parser
)->location
,
25820 "expected at least one assumption clause");
25822 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
25824 if (c_parser_next_token_is (parser
, CPP_COMMA
)
25825 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
25826 c_parser_consume_token (parser
);
25828 if (!c_parser_next_token_is (parser
, CPP_NAME
))
25832 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25833 location_t cloc
= c_parser_peek_token (parser
)->location
;
25835 if (!strcmp (p
, "no_openmp"))
25837 c_parser_consume_token (parser
);
25839 error_at (cloc
, "too many %qs clauses", "no_openmp");
25842 else if (!strcmp (p
, "no_openmp_routines"))
25844 c_parser_consume_token (parser
);
25845 if (no_openmp_routines
)
25846 error_at (cloc
, "too many %qs clauses", "no_openmp_routines");
25847 no_openmp_routines
= true;
25849 else if (!strcmp (p
, "no_parallelism"))
25851 c_parser_consume_token (parser
);
25852 if (no_parallelism
)
25853 error_at (cloc
, "too many %qs clauses", "no_parallelism");
25854 no_parallelism
= true;
25856 else if (!strcmp (p
, "holds"))
25858 c_parser_consume_token (parser
);
25859 matching_parens parens
;
25860 if (parens
.require_open (parser
))
25862 location_t eloc
= c_parser_peek_token (parser
)->location
;
25863 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
25864 tree t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
25865 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
25866 t
= c_fully_fold (t
, false, NULL
);
25867 if (is_assume
&& t
!= error_mark_node
)
25869 tree fn
= build_call_expr_internal_loc (eloc
, IFN_ASSUME
,
25874 parens
.skip_until_found_close (parser
);
25877 else if (!strcmp (p
, "absent") || !strcmp (p
, "contains"))
25879 c_parser_consume_token (parser
);
25880 matching_parens parens
;
25881 if (parens
.require_open (parser
))
25885 const char *directive
[3] = {};
25887 location_t dloc
= c_parser_peek_token (parser
)->location
;
25888 for (i
= 0; i
< 3; i
++)
25891 if (c_parser_peek_nth_token (parser
, i
+ 1)->type
25893 id
= c_parser_peek_nth_token (parser
, i
+ 1)->value
;
25894 else if (c_parser_peek_nth_token (parser
, i
+ 1)->keyword
25898 = c_parser_peek_nth_token (parser
, i
+ 1)->keyword
;
25899 id
= ridpointers
[rid
];
25903 directive
[i
] = IDENTIFIER_POINTER (id
);
25906 error_at (dloc
, "expected directive name");
25909 const struct c_omp_directive
*dir
25910 = c_omp_categorize_directive (directive
[0],
25914 || dir
->kind
== C_OMP_DIR_DECLARATIVE
25915 || dir
->kind
== C_OMP_DIR_INFORMATIONAL
25916 || dir
->id
== PRAGMA_OMP_END
25917 || (!dir
->second
&& directive
[1])
25918 || (!dir
->third
&& directive
[2]))
25919 error_at (dloc
, "unknown OpenMP directive name in "
25920 "%qs clause argument", p
);
25923 int id
= dir
- c_omp_directives
;
25924 if (bitmap_bit_p (p
[0] == 'a' ? &contains_head
25925 : &absent_head
, id
))
25926 error_at (dloc
, "%<%s%s%s%s%s%> directive "
25927 "mentioned in both %<absent%> and "
25928 "%<contains%> clauses",
25930 directive
[1] ? " " : "",
25931 directive
[1] ? directive
[1] : "",
25932 directive
[2] ? " " : "",
25933 directive
[2] ? directive
[2] : "");
25934 else if (!bitmap_set_bit (p
[0] == 'a'
25936 : &contains_head
, id
))
25937 error_at (dloc
, "%<%s%s%s%s%s%> directive "
25938 "mentioned multiple times in %qs "
25941 directive
[1] ? " " : "",
25942 directive
[1] ? directive
[1] : "",
25943 directive
[2] ? " " : "",
25944 directive
[2] ? directive
[2] : "", p
);
25947 c_parser_consume_token (parser
);
25949 if (c_parser_next_token_is (parser
, CPP_COMMA
))
25950 c_parser_consume_token (parser
);
25955 parens
.skip_until_found_close (parser
);
25958 else if (startswith (p
, "ext_"))
25960 warning_at (cloc
, 0, "unknown assumption clause %qs", p
);
25961 c_parser_consume_token (parser
);
25962 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
25964 matching_parens parens
;
25965 parens
.consume_open (parser
);
25966 c_parser_balanced_token_sequence (parser
);
25967 parens
.require_close (parser
);
25972 c_parser_consume_token (parser
);
25973 error_at (cloc
, "expected assumption clause");
25977 c_parser_skip_to_pragma_eol (parser
);
25981 #pragma omp assume clauses[optseq] new-line */
25984 c_parser_omp_assume (c_parser
*parser
, bool *if_p
)
25986 c_parser_omp_assumption_clauses (parser
, true);
25987 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
25991 #pragma omp assumes clauses[optseq] new-line */
25994 c_parser_omp_assumes (c_parser
*parser
)
25996 c_parser_consume_pragma (parser
);
25997 c_parser_omp_assumption_clauses (parser
, false);
26000 /* Main entry point to parsing most OpenMP pragmas. */
26003 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
26005 enum pragma_kind p_kind
;
26008 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
26009 omp_clause_mask
mask (0);
26011 loc
= c_parser_peek_token (parser
)->location
;
26012 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
26013 c_parser_consume_pragma (parser
);
26017 case PRAGMA_OACC_ATOMIC
:
26018 c_parser_omp_atomic (loc
, parser
, true);
26020 case PRAGMA_OACC_CACHE
:
26021 strcpy (p_name
, "#pragma acc");
26022 stmt
= c_parser_oacc_cache (loc
, parser
);
26024 case PRAGMA_OACC_DATA
:
26025 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
26027 case PRAGMA_OACC_HOST_DATA
:
26028 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
26030 case PRAGMA_OACC_KERNELS
:
26031 case PRAGMA_OACC_PARALLEL
:
26032 case PRAGMA_OACC_SERIAL
:
26033 strcpy (p_name
, "#pragma acc");
26034 stmt
= c_parser_oacc_compute (loc
, parser
, p_kind
, p_name
, if_p
);
26036 case PRAGMA_OACC_LOOP
:
26037 strcpy (p_name
, "#pragma acc");
26038 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26040 case PRAGMA_OACC_WAIT
:
26041 strcpy (p_name
, "#pragma wait");
26042 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
26044 case PRAGMA_OMP_ATOMIC
:
26045 c_parser_omp_atomic (loc
, parser
, false);
26047 case PRAGMA_OMP_CRITICAL
:
26048 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
26050 case PRAGMA_OMP_DISTRIBUTE
:
26051 strcpy (p_name
, "#pragma omp");
26052 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26054 case PRAGMA_OMP_FOR
:
26055 strcpy (p_name
, "#pragma omp");
26056 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26058 case PRAGMA_OMP_LOOP
:
26059 strcpy (p_name
, "#pragma omp");
26060 stmt
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26062 case PRAGMA_OMP_MASKED
:
26063 strcpy (p_name
, "#pragma omp");
26064 stmt
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26066 case PRAGMA_OMP_MASTER
:
26067 strcpy (p_name
, "#pragma omp");
26068 stmt
= c_parser_omp_master (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26070 case PRAGMA_OMP_PARALLEL
:
26071 strcpy (p_name
, "#pragma omp");
26072 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26074 case PRAGMA_OMP_SCOPE
:
26075 stmt
= c_parser_omp_scope (loc
, parser
, if_p
);
26077 case PRAGMA_OMP_SECTIONS
:
26078 strcpy (p_name
, "#pragma omp");
26079 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
26081 case PRAGMA_OMP_SIMD
:
26082 strcpy (p_name
, "#pragma omp");
26083 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26085 case PRAGMA_OMP_SINGLE
:
26086 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
26088 case PRAGMA_OMP_TASK
:
26089 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
26091 case PRAGMA_OMP_TASKGROUP
:
26092 stmt
= c_parser_omp_taskgroup (loc
, parser
, if_p
);
26094 case PRAGMA_OMP_TASKLOOP
:
26095 strcpy (p_name
, "#pragma omp");
26096 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26098 case PRAGMA_OMP_TEAMS
:
26099 strcpy (p_name
, "#pragma omp");
26100 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26102 case PRAGMA_OMP_ASSUME
:
26103 c_parser_omp_assume (parser
, if_p
);
26106 gcc_unreachable ();
26109 if (stmt
&& stmt
!= error_mark_node
)
26110 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
26115 # pragma omp threadprivate (variable-list) */
26118 c_parser_omp_threadprivate (c_parser
*parser
)
26123 c_parser_consume_pragma (parser
);
26124 loc
= c_parser_peek_token (parser
)->location
;
26125 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
26127 /* Mark every variable in VARS to be assigned thread local storage. */
26128 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
26130 tree v
= TREE_PURPOSE (t
);
26132 /* FIXME diagnostics: Ideally we should keep individual
26133 locations for all the variables in the var list to make the
26134 following errors more precise. Perhaps
26135 c_parser_omp_var_list_parens() should construct a list of
26136 locations to go along with the var list. */
26138 /* If V had already been marked threadprivate, it doesn't matter
26139 whether it had been used prior to this point. */
26141 error_at (loc
, "%qD is not a variable", v
);
26142 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
26143 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
26144 else if (! is_global_var (v
))
26145 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
26146 else if (TREE_TYPE (v
) == error_mark_node
)
26148 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
26149 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
26152 if (! DECL_THREAD_LOCAL_P (v
))
26154 set_decl_tls_model (v
, decl_default_tls_model (v
));
26155 /* If rtl has been already set for this var, call
26156 make_decl_rtl once again, so that encode_section_info
26157 has a chance to look at the new decl flags. */
26158 if (DECL_RTL_SET_P (v
))
26161 C_DECL_THREADPRIVATE_P (v
) = 1;
26165 c_parser_skip_to_pragma_eol (parser
);
26168 /* Parse a transaction attribute (GCC Extension).
26170 transaction-attribute:
26172 attribute-specifier
26176 c_parser_transaction_attributes (c_parser
*parser
)
26178 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
26179 return c_parser_gnu_attributes (parser
);
26181 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
26183 return c_parser_std_attribute_specifier (parser
, true);
26186 /* Parse a __transaction_atomic or __transaction_relaxed statement
26189 transaction-statement:
26190 __transaction_atomic transaction-attribute[opt] compound-statement
26191 __transaction_relaxed compound-statement
26193 Note that the only valid attribute is: "outer".
26197 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
26199 unsigned int old_in
= parser
->in_transaction
;
26200 unsigned int this_in
= 1, new_in
;
26201 location_t loc
= c_parser_peek_token (parser
)->location
;
26204 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
26205 || keyword
== RID_TRANSACTION_RELAXED
)
26206 && c_parser_next_token_is_keyword (parser
, keyword
));
26207 c_parser_consume_token (parser
);
26209 if (keyword
== RID_TRANSACTION_RELAXED
)
26210 this_in
|= TM_STMT_ATTR_RELAXED
;
26213 attrs
= c_parser_transaction_attributes (parser
);
26215 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
26218 /* Keep track if we're in the lexical scope of an outer transaction. */
26219 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
26221 parser
->in_transaction
= new_in
;
26222 stmt
= c_parser_compound_statement (parser
);
26223 parser
->in_transaction
= old_in
;
26226 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
26228 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
26229 "%<__transaction_atomic%> without transactional memory support enabled"
26230 : "%<__transaction_relaxed %> "
26231 "without transactional memory support enabled"));
26236 /* Parse a __transaction_atomic or __transaction_relaxed expression
26239 transaction-expression:
26240 __transaction_atomic ( expression )
26241 __transaction_relaxed ( expression )
26244 static struct c_expr
26245 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
26248 unsigned int old_in
= parser
->in_transaction
;
26249 unsigned int this_in
= 1;
26250 location_t loc
= c_parser_peek_token (parser
)->location
;
26253 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
26254 || keyword
== RID_TRANSACTION_RELAXED
)
26255 && c_parser_next_token_is_keyword (parser
, keyword
));
26256 c_parser_consume_token (parser
);
26258 if (keyword
== RID_TRANSACTION_RELAXED
)
26259 this_in
|= TM_STMT_ATTR_RELAXED
;
26262 attrs
= c_parser_transaction_attributes (parser
);
26264 this_in
|= parse_tm_stmt_attr (attrs
, 0);
26267 parser
->in_transaction
= this_in
;
26268 matching_parens parens
;
26269 if (parens
.require_open (parser
))
26271 tree expr
= c_parser_expression (parser
).value
;
26272 ret
.original_type
= TREE_TYPE (expr
);
26273 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
26274 if (this_in
& TM_STMT_ATTR_RELAXED
)
26275 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
26276 SET_EXPR_LOCATION (ret
.value
, loc
);
26277 ret
.original_code
= TRANSACTION_EXPR
;
26279 if (!parens
.require_close (parser
))
26281 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
26289 ret
.original_code
= ERROR_MARK
;
26290 ret
.original_type
= NULL
;
26292 parser
->in_transaction
= old_in
;
26295 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
26296 "%<__transaction_atomic%> without transactional memory support enabled"
26297 : "%<__transaction_relaxed %> "
26298 "without transactional memory support enabled"));
26300 set_c_expr_source_range (&ret
, loc
, loc
);
26305 /* Parse a __transaction_cancel statement (GCC Extension).
26307 transaction-cancel-statement:
26308 __transaction_cancel transaction-attribute[opt] ;
26310 Note that the only valid attribute is "outer".
26314 c_parser_transaction_cancel (c_parser
*parser
)
26316 location_t loc
= c_parser_peek_token (parser
)->location
;
26318 bool is_outer
= false;
26320 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
26321 c_parser_consume_token (parser
);
26323 attrs
= c_parser_transaction_attributes (parser
);
26325 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
26329 error_at (loc
, "%<__transaction_cancel%> without "
26330 "transactional memory support enabled");
26333 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
26335 error_at (loc
, "%<__transaction_cancel%> within a "
26336 "%<__transaction_relaxed%>");
26341 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
26342 && !is_tm_may_cancel_outer (current_function_decl
))
26344 error_at (loc
, "outer %<__transaction_cancel%> not "
26345 "within outer %<__transaction_atomic%> or "
26346 "a %<transaction_may_cancel_outer%> function");
26350 else if (parser
->in_transaction
== 0)
26352 error_at (loc
, "%<__transaction_cancel%> not within "
26353 "%<__transaction_atomic%>");
26357 return add_stmt (build_tm_abort_call (loc
, is_outer
));
26360 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
26363 /* Parse a single source file. */
26366 c_parse_file (void)
26368 /* Use local storage to begin. If the first token is a pragma, parse it.
26369 If it is #pragma GCC pch_preprocess, then this will load a PCH file
26370 which will cause garbage collection. */
26373 memset (&tparser
, 0, sizeof tparser
);
26374 tparser
.translate_strings_p
= true;
26375 tparser
.tokens
= &tparser
.tokens_buf
[0];
26376 the_parser
= &tparser
;
26378 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
26379 c_parser_pragma_pch_preprocess (&tparser
);
26381 c_common_no_more_pch ();
26383 the_parser
= ggc_alloc
<c_parser
> ();
26384 *the_parser
= tparser
;
26385 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
26386 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
26388 /* Initialize EH, if we've been told to do so. */
26389 if (flag_exceptions
)
26390 using_eh_for_cleanups ();
26392 c_parser_translation_unit (the_parser
);
26397 c_init_preprocess (void)
26399 /* Create a parser for use by pragma_lex during preprocessing. */
26400 the_parser
= ggc_alloc
<c_parser
> ();
26401 memset (the_parser
, 0, sizeof (c_parser
));
26402 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
26405 /* Parse the body of a function declaration marked with "__RTL".
26407 The RTL parser works on the level of characters read from a
26408 FILE *, whereas c_parser works at the level of tokens.
26409 Square this circle by consuming all of the tokens up to and
26410 including the closing brace, recording the start/end of the RTL
26411 fragment, and reopening the file and re-reading the relevant
26412 lines within the RTL parser.
26414 This requires the opening and closing braces of the C function
26415 to be on separate lines from the RTL they wrap.
26417 Take ownership of START_WITH_PASS, if non-NULL. */
26420 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
26422 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
26424 free (start_with_pass
);
26425 return c_parser_peek_token (parser
)->location
;
26428 location_t start_loc
= c_parser_peek_token (parser
)->location
;
26430 /* Consume all tokens, up to the closing brace, handling
26431 matching pairs of braces in the rtl dump. */
26432 int num_open_braces
= 1;
26435 switch (c_parser_peek_token (parser
)->type
)
26437 case CPP_OPEN_BRACE
:
26440 case CPP_CLOSE_BRACE
:
26441 if (--num_open_braces
== 0)
26442 goto found_closing_brace
;
26445 error_at (start_loc
, "no closing brace");
26446 free (start_with_pass
);
26447 return c_parser_peek_token (parser
)->location
;
26451 c_parser_consume_token (parser
);
26454 found_closing_brace
:
26455 /* At the closing brace; record its location. */
26456 location_t end_loc
= c_parser_peek_token (parser
)->location
;
26458 /* Consume the closing brace. */
26459 c_parser_consume_token (parser
);
26461 /* Invoke the RTL parser. */
26462 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
26464 free (start_with_pass
);
26468 /* Run the backend on the cfun created above, transferring ownership of
26469 START_WITH_PASS. */
26470 run_rtl_passes (start_with_pass
);
26474 #include "gt-c-c-parser.h"