1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2024 Free Software Foundation, Inc.
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 Make sure all relevant comments, and all relevant code from all
26 actions, brought over from old parser. Verify exact correspondence
29 Add testcases covering every input symbol in every state in old and
32 Include full syntax for GNU C, including erroneous cases accepted
33 with error messages, in syntax productions in comments.
35 Make more diagnostics in the front end generally take an explicit
36 location rather than implicitly using input_location. */
39 #define INCLUDE_MEMORY
41 #include "coretypes.h"
46 #include "stringpool.h"
49 #include "stor-layout.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
54 #include "c-family/c-objc.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
63 #include "gcc-rich-location.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
71 #include "tree-pretty-print.h"
73 #include "c-family/known-headers.h"
75 #include "analyzer/analyzer-language.h"
78 /* We need to walk over decls with incomplete struct/union/enum types
79 after parsing the whole translation unit.
80 In finish_decl(), if the decl is static, has incomplete
81 struct/union/enum type, it is appended to incomplete_record_decls.
82 In c_parser_translation_unit(), we iterate over incomplete_record_decls
83 and report error if any of the decls are still incomplete. */
85 vec
<tree
> incomplete_record_decls
;
88 set_c_expr_source_range (c_expr
*expr
,
89 location_t start
, location_t finish
)
91 expr
->src_range
.m_start
= start
;
92 expr
->src_range
.m_finish
= finish
;
94 set_source_range (expr
->value
, start
, finish
);
98 set_c_expr_source_range (c_expr
*expr
,
99 source_range src_range
)
101 expr
->src_range
= src_range
;
103 set_source_range (expr
->value
, src_range
);
107 /* Initialization routine for this file. */
112 /* The only initialization required is of the reserved word
118 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
119 the c_token structure. */
120 gcc_assert (RID_MAX
<= 255);
129 mask
|= D_ASM
| D_EXT
;
135 if (!c_dialect_objc ())
136 mask
|= D_OBJC
| D_CXX_OBJC
;
138 ridpointers
= ggc_cleared_vec_alloc
<tree
> ((int) RID_MAX
);
139 for (i
= 0; i
< num_c_common_reswords
; i
++)
141 /* If a keyword is disabled, do not enter it into the table
142 and so create a canonical spelling that isn't a keyword. */
143 if (c_common_reswords
[i
].disable
& mask
)
146 && (c_common_reswords
[i
].disable
& D_CXXWARN
))
148 id
= get_identifier (c_common_reswords
[i
].word
);
149 C_SET_RID_CODE (id
, RID_CXX_COMPAT_WARN
);
150 C_IS_RESERVED_WORD (id
) = 1;
155 id
= get_identifier (c_common_reswords
[i
].word
);
156 C_SET_RID_CODE (id
, c_common_reswords
[i
].rid
);
157 C_IS_RESERVED_WORD (id
) = 1;
158 ridpointers
[(int) c_common_reswords
[i
].rid
] = id
;
161 for (i
= 0; i
< NUM_INT_N_ENTS
; i
++)
163 /* We always create the symbols but they aren't always supported. */
165 sprintf (name
, "__int%d", int_n_data
[i
].bitsize
);
166 id
= get_identifier (name
);
167 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
168 C_IS_RESERVED_WORD (id
) = 1;
170 sprintf (name
, "__int%d__", int_n_data
[i
].bitsize
);
171 id
= get_identifier (name
);
172 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
173 C_IS_RESERVED_WORD (id
) = 1;
178 id
= get_identifier ("omp_all_memory");
179 C_SET_RID_CODE (id
, RID_OMP_ALL_MEMORY
);
180 C_IS_RESERVED_WORD (id
) = 1;
181 ridpointers
[RID_OMP_ALL_MEMORY
] = id
;
185 /* A parser structure recording information about the state and
186 context of parsing. Includes lexer information with up to two
187 tokens of look-ahead; more are not needed for C. */
188 struct GTY(()) c_parser
{
189 /* The look-ahead tokens. */
190 c_token
* GTY((skip
)) tokens
;
191 /* Buffer for look-ahead tokens. */
192 c_token tokens_buf
[4];
193 /* How many look-ahead tokens are available (0 - 4, or
194 more if parsing from pre-lexed tokens). */
195 unsigned int tokens_avail
;
196 /* Raw look-ahead tokens, used only for checking in Objective-C
197 whether '[[' starts attributes. */
198 vec
<c_token
, va_gc
> *raw_tokens
;
199 /* The number of raw look-ahead tokens that have since been fully
201 unsigned int raw_tokens_used
;
202 /* True if a syntax error is being recovered from; false otherwise.
203 c_parser_error sets this flag. It should clear this flag when
204 enough tokens have been consumed to recover from the error. */
205 BOOL_BITFIELD error
: 1;
206 /* True if we're processing a pragma, and shouldn't automatically
207 consume CPP_PRAGMA_EOL. */
208 BOOL_BITFIELD in_pragma
: 1;
209 /* True if we're parsing the outermost block of an if statement. */
210 BOOL_BITFIELD in_if_block
: 1;
211 /* True if we want to lex a translated, joined string (for an
212 initial #pragma pch_preprocess). Otherwise the parser is
213 responsible for concatenating strings and translating to the
214 execution character set as needed. */
215 BOOL_BITFIELD lex_joined_string
: 1;
216 /* True if, when the parser is concatenating string literals, it
217 should translate them to the execution character set (false
218 inside attributes). */
219 BOOL_BITFIELD translate_strings_p
: 1;
221 /* Objective-C specific parser/lexer information. */
223 /* True if we are in a context where the Objective-C "PQ" keywords
224 are considered keywords. */
225 BOOL_BITFIELD objc_pq_context
: 1;
226 /* True if we are parsing a (potential) Objective-C foreach
227 statement. This is set to true after we parsed 'for (' and while
228 we wait for 'in' or ';' to decide if it's a standard C for loop or an
229 Objective-C foreach loop. */
230 BOOL_BITFIELD objc_could_be_foreach_context
: 1;
231 /* The following flag is needed to contextualize Objective-C lexical
232 analysis. In some cases (e.g., 'int NSObject;'), it is
233 undesirable to bind an identifier to an Objective-C class, even
234 if a class with that name exists. */
235 BOOL_BITFIELD objc_need_raw_identifier
: 1;
236 /* Nonzero if we're processing a __transaction statement. The value
237 is 1 | TM_STMT_ATTR_*. */
238 unsigned int in_transaction
: 4;
239 /* True if we are in a context where the Objective-C "Property attribute"
240 keywords are valid. */
241 BOOL_BITFIELD objc_property_attr_context
: 1;
243 /* Whether we have just seen/constructed a string-literal. Set when
244 returning a string-literal from c_parser_string_literal. Reset
245 in consume_token. Useful when we get a parse error and see an
246 unknown token, which could have been a string-literal constant
248 BOOL_BITFIELD seen_string_literal
: 1;
250 /* TRUE if omp::directive, omp::decl or omp::sequence attributes may not
252 BOOL_BITFIELD omp_attrs_forbidden_p
: 1;
254 /* Location of the last consumed token. */
255 location_t last_token_location
;
257 /* Holds state for parsing collapsed OMP_FOR loops. Managed by
258 c_parser_omp_for_loop. */
259 struct omp_for_parse_data
* GTY((skip
)) omp_for_parse_state
;
261 /* If we're in the context of OpenMP directives written as C23
262 attributes turned into pragma, vector of tokens created from that,
264 vec
<c_token
, va_gc
> *in_omp_attribute_pragma
;
266 /* Set for omp::decl attribute parsing to the decl to which it
268 tree in_omp_decl_attribute
;
271 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
274 c_parser_tokens_buf (c_parser
*parser
, unsigned n
)
276 return &parser
->tokens_buf
[n
];
279 /* Return the error state of PARSER. */
282 c_parser_error (c_parser
*parser
)
284 return parser
->error
;
287 /* Set the error state of PARSER to ERR. */
290 c_parser_set_error (c_parser
*parser
, bool err
)
296 /* The actual parser and external interface. ??? Does this need to be
297 garbage-collected? */
299 static GTY (()) c_parser
*the_parser
;
301 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
302 context-sensitive postprocessing of the token is not done. */
305 c_lex_one_token (c_parser
*parser
, c_token
*token
, bool raw
= false)
307 timevar_push (TV_LEX
);
309 if (raw
|| vec_safe_length (parser
->raw_tokens
) == 0)
311 token
->type
= c_lex_with_flags (&token
->value
, &token
->location
,
313 (parser
->lex_joined_string
314 ? 0 : C_LEX_STRING_NO_JOIN
));
315 token
->id_kind
= C_ID_NONE
;
316 token
->keyword
= RID_MAX
;
317 token
->pragma_kind
= PRAGMA_NONE
;
321 /* Use a token previously lexed as a raw look-ahead token, and
322 complete the processing on it. */
323 *token
= (*parser
->raw_tokens
)[parser
->raw_tokens_used
];
324 ++parser
->raw_tokens_used
;
325 if (parser
->raw_tokens_used
== vec_safe_length (parser
->raw_tokens
))
327 vec_free (parser
->raw_tokens
);
328 parser
->raw_tokens_used
= 0;
341 bool objc_force_identifier
= parser
->objc_need_raw_identifier
;
342 if (c_dialect_objc ())
343 parser
->objc_need_raw_identifier
= false;
345 if (C_IS_RESERVED_WORD (token
->value
))
347 enum rid rid_code
= C_RID_CODE (token
->value
);
349 if (rid_code
== RID_CXX_COMPAT_WARN
)
351 warning_at (token
->location
,
353 "identifier %qE conflicts with C++ keyword",
356 else if (rid_code
>= RID_FIRST_ADDR_SPACE
357 && rid_code
<= RID_LAST_ADDR_SPACE
)
360 as
= (addr_space_t
) (rid_code
- RID_FIRST_ADDR_SPACE
);
361 targetm
.addr_space
.diagnose_usage (as
, token
->location
);
362 token
->id_kind
= C_ID_ADDRSPACE
;
363 token
->keyword
= rid_code
;
366 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code
))
368 /* We found an Objective-C "pq" keyword (in, out,
369 inout, bycopy, byref, oneway). They need special
370 care because the interpretation depends on the
372 if (parser
->objc_pq_context
)
374 token
->type
= CPP_KEYWORD
;
375 token
->keyword
= rid_code
;
378 else if (parser
->objc_could_be_foreach_context
379 && rid_code
== RID_IN
)
381 /* We are in Objective-C, inside a (potential)
382 foreach context (which means after having
383 parsed 'for (', but before having parsed ';'),
384 and we found 'in'. We consider it the keyword
385 which terminates the declaration at the
386 beginning of a foreach-statement. Note that
387 this means you can't use 'in' for anything else
388 in that context; in particular, in Objective-C
389 you can't use 'in' as the name of the running
390 variable in a C for loop. We could potentially
391 try to add code here to disambiguate, but it
392 seems a reasonable limitation. */
393 token
->type
= CPP_KEYWORD
;
394 token
->keyword
= rid_code
;
397 /* Else, "pq" keywords outside of the "pq" context are
398 not keywords, and we fall through to the code for
401 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code
))
403 /* We found an Objective-C "property attribute"
404 keyword (getter, setter, readonly, etc). These are
405 only valid in the property context. */
406 if (parser
->objc_property_attr_context
)
408 token
->type
= CPP_KEYWORD
;
409 token
->keyword
= rid_code
;
412 /* Else they are not special keywords.
415 else if (c_dialect_objc ()
416 && (OBJC_IS_AT_KEYWORD (rid_code
)
417 || OBJC_IS_CXX_KEYWORD (rid_code
)))
419 /* We found one of the Objective-C "@" keywords (defs,
420 selector, synchronized, etc) or one of the
421 Objective-C "cxx" keywords (class, private,
422 protected, public, try, catch, throw) without a
423 preceding '@' sign. Do nothing and fall through to
424 the code for normal tokens (in C++ we would still
425 consider the CXX ones keywords, but not in C). */
430 token
->type
= CPP_KEYWORD
;
431 token
->keyword
= rid_code
;
436 decl
= lookup_name (token
->value
);
439 if (TREE_CODE (decl
) == TYPE_DECL
)
441 token
->id_kind
= C_ID_TYPENAME
;
445 else if (c_dialect_objc ())
447 tree objc_interface_decl
= objc_is_class_name (token
->value
);
448 /* Objective-C class names are in the same namespace as
449 variables and typedefs, and hence are shadowed by local
451 if (objc_interface_decl
452 && (!objc_force_identifier
|| global_bindings_p ()))
454 token
->value
= objc_interface_decl
;
455 token
->id_kind
= C_ID_CLASSNAME
;
459 token
->id_kind
= C_ID_ID
;
463 /* This only happens in Objective-C; it must be a keyword. */
464 token
->type
= CPP_KEYWORD
;
465 switch (C_RID_CODE (token
->value
))
467 /* Replace 'class' with '@class', 'private' with '@private',
468 etc. This prevents confusion with the C++ keyword
469 'class', and makes the tokens consistent with other
470 Objective-C 'AT' keywords. For example '@class' is
471 reported as RID_AT_CLASS which is consistent with
472 '@synchronized', which is reported as
475 case RID_CLASS
: token
->keyword
= RID_AT_CLASS
; break;
476 case RID_PRIVATE
: token
->keyword
= RID_AT_PRIVATE
; break;
477 case RID_PROTECTED
: token
->keyword
= RID_AT_PROTECTED
; break;
478 case RID_PUBLIC
: token
->keyword
= RID_AT_PUBLIC
; break;
479 case RID_THROW
: token
->keyword
= RID_AT_THROW
; break;
480 case RID_TRY
: token
->keyword
= RID_AT_TRY
; break;
481 case RID_CATCH
: token
->keyword
= RID_AT_CATCH
; break;
482 case RID_SYNCHRONIZED
: token
->keyword
= RID_AT_SYNCHRONIZED
; break;
483 default: token
->keyword
= C_RID_CODE (token
->value
);
488 case CPP_CLOSE_PAREN
:
490 /* These tokens may affect the interpretation of any identifiers
491 following, if doing Objective-C. */
492 if (c_dialect_objc ())
493 parser
->objc_need_raw_identifier
= false;
496 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
497 token
->pragma_kind
= (enum pragma_kind
) TREE_INT_CST_LOW (token
->value
);
504 timevar_pop (TV_LEX
);
507 /* Return a pointer to the next token from PARSER, reading it in if
511 c_parser_peek_token (c_parser
*parser
)
513 if (parser
->tokens_avail
== 0)
515 c_lex_one_token (parser
, &parser
->tokens
[0]);
516 parser
->tokens_avail
= 1;
518 return &parser
->tokens
[0];
521 /* Return a pointer to the next-but-one token from PARSER, reading it
522 in if necessary. The next token is already read in. */
525 c_parser_peek_2nd_token (c_parser
*parser
)
527 if (parser
->tokens_avail
>= 2)
528 return &parser
->tokens
[1];
529 gcc_assert (parser
->tokens_avail
== 1);
530 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
531 gcc_assert (parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
532 c_lex_one_token (parser
, &parser
->tokens
[1]);
533 parser
->tokens_avail
= 2;
534 return &parser
->tokens
[1];
537 /* Return a pointer to the Nth token from PARSER, reading it
538 in if necessary. The N-1th token is already read in. */
541 c_parser_peek_nth_token (c_parser
*parser
, unsigned int n
)
543 /* N is 1-based, not zero-based. */
546 if (parser
->tokens_avail
>= n
)
547 return &parser
->tokens
[n
- 1];
548 gcc_assert (parser
->tokens_avail
== n
- 1);
549 c_lex_one_token (parser
, &parser
->tokens
[n
- 1]);
550 parser
->tokens_avail
= n
;
551 return &parser
->tokens
[n
- 1];
554 /* Return a pointer to the Nth token from PARSER, reading it in as a
555 raw look-ahead token if necessary. The N-1th token is already read
556 in. Raw look-ahead tokens remain available for when the non-raw
557 functions above are called. */
560 c_parser_peek_nth_token_raw (c_parser
*parser
, unsigned int n
)
562 /* N is 1-based, not zero-based. */
565 if (parser
->tokens_avail
>= n
)
566 return &parser
->tokens
[n
- 1];
567 unsigned int raw_len
= vec_safe_length (parser
->raw_tokens
);
568 unsigned int raw_avail
569 = parser
->tokens_avail
+ raw_len
- parser
->raw_tokens_used
;
570 gcc_assert (raw_avail
>= n
- 1);
572 return &(*parser
->raw_tokens
)[parser
->raw_tokens_used
573 + n
- 1 - parser
->tokens_avail
];
574 vec_safe_reserve (parser
->raw_tokens
, 1);
575 parser
->raw_tokens
->quick_grow (raw_len
+ 1);
576 c_lex_one_token (parser
, &(*parser
->raw_tokens
)[raw_len
], true);
577 return &(*parser
->raw_tokens
)[raw_len
];
581 c_keyword_starts_typename (enum rid keyword
)
605 case RID_TYPEOF_UNQUAL
:
618 if (keyword
>= RID_FIRST_INT_N
619 && keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
620 && int_n_enabled_p
[keyword
- RID_FIRST_INT_N
])
626 /* Return true if TOKEN can start a type name,
629 c_token_starts_typename (c_token
*token
)
634 switch (token
->id_kind
)
643 gcc_assert (c_dialect_objc ());
649 return c_keyword_starts_typename (token
->keyword
);
651 if (c_dialect_objc ())
659 /* Return true if the next token from PARSER can start a type name,
660 false otherwise. LA specifies how to do lookahead in order to
661 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
664 c_parser_next_tokens_start_typename (c_parser
*parser
, enum c_lookahead_kind la
)
666 c_token
*token
= c_parser_peek_token (parser
);
667 if (c_token_starts_typename (token
))
670 /* Try a bit harder to detect an unknown typename. */
671 if (la
!= cla_prefer_id
672 && token
->type
== CPP_NAME
673 && token
->id_kind
== C_ID_ID
675 /* Do not try too hard when we could have "object in array". */
676 && !parser
->objc_could_be_foreach_context
678 && (la
== cla_prefer_type
679 || c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
680 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
682 /* Only unknown identifiers. */
683 && !lookup_name (token
->value
))
689 /* Return true if TOKEN, after an open parenthesis, can start a
690 compound literal (either a storage class specifier allowed in that
691 context, or a type name), false otherwise. */
693 c_token_starts_compound_literal (c_token
*token
)
698 switch (token
->keyword
)
710 return c_token_starts_typename (token
);
714 /* Return true if TOKEN is a type qualifier, false otherwise. */
716 c_token_is_qualifier (c_token
*token
)
721 switch (token
->id_kind
)
729 switch (token
->keyword
)
747 /* Return true if the next token from PARSER is a type qualifier,
750 c_parser_next_token_is_qualifier (c_parser
*parser
)
752 c_token
*token
= c_parser_peek_token (parser
);
753 return c_token_is_qualifier (token
);
756 /* Return true if TOKEN can start declaration specifiers (not
757 including standard attributes), false otherwise. */
759 c_token_starts_declspecs (c_token
*token
)
764 switch (token
->id_kind
)
773 gcc_assert (c_dialect_objc ());
779 switch (token
->keyword
)
809 case RID_TYPEOF_UNQUAL
:
823 if (token
->keyword
>= RID_FIRST_INT_N
824 && token
->keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
825 && int_n_enabled_p
[token
->keyword
- RID_FIRST_INT_N
])
830 if (c_dialect_objc ())
839 /* Return true if TOKEN can start declaration specifiers (not
840 including standard attributes) or a static assertion, false
843 c_token_starts_declaration (c_token
*token
)
845 if (c_token_starts_declspecs (token
)
846 || token
->keyword
== RID_STATIC_ASSERT
)
852 /* Return true if the next token from PARSER can start declaration
853 specifiers (not including standard attributes), false
856 c_parser_next_token_starts_declspecs (c_parser
*parser
)
858 c_token
*token
= c_parser_peek_token (parser
);
860 /* In Objective-C, a classname normally starts a declspecs unless it
861 is immediately followed by a dot. In that case, it is the
862 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
863 setter/getter on the class. c_token_starts_declspecs() can't
864 differentiate between the two cases because it only checks the
865 current token, so we have a special check here. */
866 if (c_dialect_objc ()
867 && token
->type
== CPP_NAME
868 && token
->id_kind
== C_ID_CLASSNAME
869 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
872 return c_token_starts_declspecs (token
);
875 /* Return true if the next tokens from PARSER can start declaration
876 specifiers (not including standard attributes) or a static
877 assertion, false otherwise. */
879 c_parser_next_tokens_start_declaration (c_parser
*parser
)
881 c_token
*token
= c_parser_peek_token (parser
);
884 if (c_dialect_objc ()
885 && token
->type
== CPP_NAME
886 && token
->id_kind
== C_ID_CLASSNAME
887 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
890 /* Labels do not start declarations. */
891 if (token
->type
== CPP_NAME
892 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
895 if (c_token_starts_declaration (token
))
898 if (c_parser_next_tokens_start_typename (parser
, cla_nonabstract_decl
))
904 /* Consume the next token from PARSER. */
907 c_parser_consume_token (c_parser
*parser
)
909 gcc_assert (parser
->tokens_avail
>= 1);
910 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
911 gcc_assert (!parser
->in_pragma
|| parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
912 gcc_assert (parser
->error
|| parser
->tokens
[0].type
!= CPP_PRAGMA
);
913 parser
->last_token_location
= parser
->tokens
[0].location
;
914 if (parser
->tokens
!= &parser
->tokens_buf
[0])
916 else if (parser
->tokens_avail
>= 2)
918 parser
->tokens
[0] = parser
->tokens
[1];
919 if (parser
->tokens_avail
>= 3)
921 parser
->tokens
[1] = parser
->tokens
[2];
922 if (parser
->tokens_avail
>= 4)
923 parser
->tokens
[2] = parser
->tokens
[3];
926 parser
->tokens_avail
--;
927 parser
->seen_string_literal
= false;
930 /* Expect the current token to be a #pragma. Consume it and remember
931 that we've begun parsing a pragma. */
934 c_parser_consume_pragma (c_parser
*parser
)
936 gcc_assert (!parser
->in_pragma
);
937 gcc_assert (parser
->tokens_avail
>= 1);
938 gcc_assert (parser
->tokens
[0].type
== CPP_PRAGMA
);
939 if (parser
->tokens
!= &parser
->tokens_buf
[0])
941 else if (parser
->tokens_avail
>= 2)
943 parser
->tokens
[0] = parser
->tokens
[1];
944 if (parser
->tokens_avail
>= 3)
945 parser
->tokens
[1] = parser
->tokens
[2];
947 parser
->tokens_avail
--;
948 parser
->in_pragma
= true;
951 /* Update the global input_location from TOKEN. */
953 c_parser_set_source_position_from_token (c_token
*token
)
955 if (token
->type
!= CPP_EOF
)
957 input_location
= token
->location
;
961 /* Helper function for c_parser_error.
962 Having peeked a token of kind TOK1_KIND that might signify
963 a conflict marker, peek successor tokens to determine
964 if we actually do have a conflict marker.
965 Specifically, we consider a run of 7 '<', '=' or '>' characters
966 at the start of a line as a conflict marker.
967 These come through the lexer as three pairs and a single,
968 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
969 If it returns true, *OUT_LOC is written to with the location/range
973 c_parser_peek_conflict_marker (c_parser
*parser
, enum cpp_ttype tok1_kind
,
976 c_token
*token2
= c_parser_peek_2nd_token (parser
);
977 if (token2
->type
!= tok1_kind
)
979 c_token
*token3
= c_parser_peek_nth_token (parser
, 3);
980 if (token3
->type
!= tok1_kind
)
982 c_token
*token4
= c_parser_peek_nth_token (parser
, 4);
983 if (token4
->type
!= conflict_marker_get_final_tok_kind (tok1_kind
))
986 /* It must be at the start of the line. */
987 location_t start_loc
= c_parser_peek_token (parser
)->location
;
988 if (LOCATION_COLUMN (start_loc
) != 1)
991 /* We have a conflict marker. Construct a location of the form:
994 with start == caret, finishing at the end of the marker. */
995 location_t finish_loc
= get_finish (token4
->location
);
996 *out_loc
= make_location (start_loc
, start_loc
, finish_loc
);
1001 /* Issue a diagnostic of the form
1002 FILE:LINE: MESSAGE before TOKEN
1003 where TOKEN is the next token in the input stream of PARSER.
1004 MESSAGE (specified by the caller) is usually of the form "expected
1007 Use RICHLOC as the location of the diagnostic.
1009 Do not issue a diagnostic if still recovering from an error.
1011 Return true iff an error was actually emitted.
1013 ??? This is taken from the C++ parser, but building up messages in
1014 this way is not i18n-friendly and some other approach should be
1018 c_parser_error_richloc (c_parser
*parser
, const char *gmsgid
,
1019 rich_location
*richloc
)
1021 c_token
*token
= c_parser_peek_token (parser
);
1024 parser
->error
= true;
1028 /* If this is actually a conflict marker, report it as such. */
1029 if (token
->type
== CPP_LSHIFT
1030 || token
->type
== CPP_RSHIFT
1031 || token
->type
== CPP_EQ_EQ
)
1034 if (c_parser_peek_conflict_marker (parser
, token
->type
, &loc
))
1036 error_at (loc
, "version control conflict marker in file");
1041 /* If we were parsing a string-literal and there is an unknown name
1042 token right after, then check to see if that could also have been
1043 a literal string by checking the name against a list of known
1044 standard string literal constants defined in header files. If
1045 there is one, then add that as an hint to the error message. */
1046 auto_diagnostic_group d
;
1048 if (parser
->seen_string_literal
&& token
->type
== CPP_NAME
)
1050 tree name
= token
->value
;
1051 const char *token_name
= IDENTIFIER_POINTER (name
);
1052 const char *header_hint
1053 = get_c_stdlib_header_for_string_macro_name (token_name
);
1054 if (header_hint
!= NULL
)
1055 h
= name_hint (NULL
, new suggest_missing_header (token
->location
,
1060 c_parse_error (gmsgid
,
1061 /* Because c_parse_error does not understand
1062 CPP_KEYWORD, keywords are treated like
1064 (token
->type
== CPP_KEYWORD
? CPP_NAME
: token
->type
),
1065 /* ??? The C parser does not save the cpp flags of a
1066 token, we need to pass 0 here and we will not get
1067 the source spelling of some tokens but rather the
1068 canonical spelling. */
1069 token
->value
, /*flags=*/0, richloc
);
1073 /* As c_parser_error_richloc, but issue the message at the
1074 location of PARSER's next token, or at input_location
1075 if the next token is EOF. */
1078 c_parser_error (c_parser
*parser
, const char *gmsgid
)
1080 c_token
*token
= c_parser_peek_token (parser
);
1081 c_parser_set_source_position_from_token (token
);
1082 rich_location
richloc (line_table
, input_location
);
1083 return c_parser_error_richloc (parser
, gmsgid
, &richloc
);
1086 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1087 This class is for tracking such a matching pair of symbols.
1088 In particular, it tracks the location of the first token,
1089 so that if the second token is missing, we can highlight the
1090 location of the first token when notifying the user about the
1093 template <typename traits_t
>
1097 /* token_pair's ctor. */
1098 token_pair () : m_open_loc (UNKNOWN_LOCATION
) {}
1100 /* If the next token is the opening symbol for this pair, consume it and
1102 Otherwise, issue an error and return false.
1103 In either case, record the location of the opening token. */
1105 bool require_open (c_parser
*parser
)
1107 c_token
*token
= c_parser_peek_token (parser
);
1109 m_open_loc
= token
->location
;
1111 return c_parser_require (parser
, traits_t::open_token_type
,
1112 traits_t::open_gmsgid
);
1115 /* Consume the next token from PARSER, recording its location as
1116 that of the opening token within the pair. */
1118 void consume_open (c_parser
*parser
)
1120 c_token
*token
= c_parser_peek_token (parser
);
1121 gcc_assert (token
->type
== traits_t::open_token_type
);
1122 m_open_loc
= token
->location
;
1123 c_parser_consume_token (parser
);
1126 /* If the next token is the closing symbol for this pair, consume it
1128 Otherwise, issue an error, highlighting the location of the
1129 corresponding opening token, and return false. */
1131 bool require_close (c_parser
*parser
) const
1133 return c_parser_require (parser
, traits_t::close_token_type
,
1134 traits_t::close_gmsgid
, m_open_loc
);
1137 /* Like token_pair::require_close, except that tokens will be skipped
1138 until the desired token is found. An error message is still produced
1139 if the next token is not as expected. */
1141 void skip_until_found_close (c_parser
*parser
) const
1143 c_parser_skip_until_found (parser
, traits_t::close_token_type
,
1144 traits_t::close_gmsgid
, m_open_loc
);
1148 location_t m_open_loc
;
1151 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1153 struct matching_paren_traits
1155 static const enum cpp_ttype open_token_type
= CPP_OPEN_PAREN
;
1156 static const char * const open_gmsgid
;
1157 static const enum cpp_ttype close_token_type
= CPP_CLOSE_PAREN
;
1158 static const char * const close_gmsgid
;
1161 const char * const matching_paren_traits::open_gmsgid
= "expected %<(%>";
1162 const char * const matching_paren_traits::close_gmsgid
= "expected %<)%>";
1164 /* "matching_parens" is a token_pair<T> class for tracking matching
1165 pairs of parentheses. */
1167 typedef token_pair
<matching_paren_traits
> matching_parens
;
1169 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1171 struct matching_brace_traits
1173 static const enum cpp_ttype open_token_type
= CPP_OPEN_BRACE
;
1174 static const char * const open_gmsgid
;
1175 static const enum cpp_ttype close_token_type
= CPP_CLOSE_BRACE
;
1176 static const char * const close_gmsgid
;
1179 const char * const matching_brace_traits::open_gmsgid
= "expected %<{%>";
1180 const char * const matching_brace_traits::close_gmsgid
= "expected %<}%>";
1182 /* "matching_braces" is a token_pair<T> class for tracking matching
1185 typedef token_pair
<matching_brace_traits
> matching_braces
;
1187 /* Get a description of the matching symbol to TYPE e.g. "(" for
1191 get_matching_symbol (enum cpp_ttype type
)
1197 case CPP_CLOSE_PAREN
:
1199 case CPP_CLOSE_BRACE
:
1204 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1205 issue the error MSGID. If MSGID is NULL then a message has already
1206 been produced and no message will be produced this time. Returns
1207 true if found, false otherwise.
1209 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1210 within any error as the location of an "opening" token matching
1211 the close token TYPE (e.g. the location of the '(' when TYPE is
1214 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1215 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1216 attempt to generate a fix-it hint for the problem.
1217 Otherwise msgid describes multiple token types (e.g.
1218 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1219 generate a fix-it hint. */
1222 c_parser_require (c_parser
*parser
,
1223 enum cpp_ttype type
,
1225 location_t matching_location
,
1226 bool type_is_unique
)
1228 if (c_parser_next_token_is (parser
, type
))
1230 c_parser_consume_token (parser
);
1235 location_t next_token_loc
= c_parser_peek_token (parser
)->location
;
1236 gcc_rich_location
richloc (next_token_loc
);
1238 /* Potentially supply a fix-it hint, suggesting to add the
1239 missing token immediately after the *previous* token.
1240 This may move the primary location within richloc. */
1241 if (!parser
->error
&& type_is_unique
)
1242 maybe_suggest_missing_token_insertion (&richloc
, type
,
1243 parser
->last_token_location
);
1245 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1246 Attempt to consolidate diagnostics by printing it as a
1247 secondary range within the main diagnostic. */
1248 bool added_matching_location
= false;
1249 if (matching_location
!= UNKNOWN_LOCATION
)
1250 added_matching_location
1251 = richloc
.add_location_if_nearby (matching_location
);
1253 if (c_parser_error_richloc (parser
, msgid
, &richloc
))
1254 /* If we weren't able to consolidate matching_location, then
1255 print it as a secondary diagnostic. */
1256 if (matching_location
!= UNKNOWN_LOCATION
&& !added_matching_location
)
1257 inform (matching_location
, "to match this %qs",
1258 get_matching_symbol (type
));
1264 /* If the next token is the indicated keyword, consume it. Otherwise,
1265 issue the error MSGID. Returns true if found, false otherwise. */
1268 c_parser_require_keyword (c_parser
*parser
,
1272 if (c_parser_next_token_is_keyword (parser
, keyword
))
1274 c_parser_consume_token (parser
);
1279 c_parser_error (parser
, msgid
);
1284 /* Like c_parser_require, except that tokens will be skipped until the
1285 desired token is found. An error message is still produced if the
1286 next token is not as expected. If MSGID is NULL then a message has
1287 already been produced and no message will be produced this
1290 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1291 within any error as the location of an "opening" token matching
1292 the close token TYPE (e.g. the location of the '(' when TYPE is
1293 CPP_CLOSE_PAREN). */
1296 c_parser_skip_until_found (c_parser
*parser
,
1297 enum cpp_ttype type
,
1299 location_t matching_location
)
1301 unsigned nesting_depth
= 0;
1303 if (c_parser_require (parser
, type
, msgid
, matching_location
))
1305 if (UNLIKELY (type
== CPP_PRAGMA_EOL
) && parser
->in_omp_attribute_pragma
)
1307 c_token
*token
= c_parser_peek_token (parser
);
1308 if (token
->type
== CPP_EOF
)
1310 parser
->tokens
= &parser
->tokens_buf
[0];
1311 parser
->tokens_avail
= token
->flags
;
1312 parser
->in_omp_attribute_pragma
= NULL
;
1318 /* Skip tokens until the desired token is found. */
1321 /* Peek at the next token. */
1322 c_token
*token
= c_parser_peek_token (parser
);
1323 /* If we've reached the token we want, consume it and stop. */
1324 if (token
->type
== type
&& !nesting_depth
)
1326 c_parser_consume_token (parser
);
1327 if (UNLIKELY (type
== CPP_PRAGMA_EOL
)
1328 && parser
->in_omp_attribute_pragma
)
1330 c_token
*token
= c_parser_peek_token (parser
);
1331 if (token
->type
== CPP_EOF
)
1333 parser
->tokens
= &parser
->tokens_buf
[0];
1334 parser
->tokens_avail
= token
->flags
;
1335 parser
->in_omp_attribute_pragma
= NULL
;
1341 /* If we've run out of tokens, stop. */
1342 if (token
->type
== CPP_EOF
)
1344 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1346 if (token
->type
== CPP_OPEN_BRACE
1347 || token
->type
== CPP_OPEN_PAREN
1348 || token
->type
== CPP_OPEN_SQUARE
)
1350 else if (token
->type
== CPP_CLOSE_BRACE
1351 || token
->type
== CPP_CLOSE_PAREN
1352 || token
->type
== CPP_CLOSE_SQUARE
)
1354 if (nesting_depth
-- == 0)
1357 /* Consume this token. */
1358 c_parser_consume_token (parser
);
1360 parser
->error
= false;
1363 /* Skip tokens until the end of a parameter is found, but do not
1364 consume the comma, semicolon or closing delimiter. */
1367 c_parser_skip_to_end_of_parameter (c_parser
*parser
)
1369 unsigned nesting_depth
= 0;
1373 c_token
*token
= c_parser_peek_token (parser
);
1374 if ((token
->type
== CPP_COMMA
|| token
->type
== CPP_SEMICOLON
)
1377 /* If we've run out of tokens, stop. */
1378 if (token
->type
== CPP_EOF
)
1380 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1382 if (token
->type
== CPP_OPEN_BRACE
1383 || token
->type
== CPP_OPEN_PAREN
1384 || token
->type
== CPP_OPEN_SQUARE
)
1386 else if (token
->type
== CPP_CLOSE_BRACE
1387 || token
->type
== CPP_CLOSE_PAREN
1388 || token
->type
== CPP_CLOSE_SQUARE
)
1390 if (nesting_depth
-- == 0)
1393 /* Consume this token. */
1394 c_parser_consume_token (parser
);
1396 parser
->error
= false;
1399 /* Expect to be at the end of the pragma directive and consume an
1400 end of line marker. */
1403 c_parser_skip_to_pragma_eol (c_parser
*parser
, bool error_if_not_eol
= true)
1405 gcc_assert (parser
->in_pragma
);
1406 parser
->in_pragma
= false;
1408 if (error_if_not_eol
&& c_parser_peek_token (parser
)->type
!= CPP_PRAGMA_EOL
)
1409 c_parser_error (parser
, "expected end of line");
1411 cpp_ttype token_type
;
1414 c_token
*token
= c_parser_peek_token (parser
);
1415 token_type
= token
->type
;
1416 if (token_type
== CPP_EOF
)
1418 c_parser_consume_token (parser
);
1420 while (token_type
!= CPP_PRAGMA_EOL
);
1422 if (parser
->in_omp_attribute_pragma
)
1424 c_token
*token
= c_parser_peek_token (parser
);
1425 if (token
->type
== CPP_EOF
)
1427 parser
->tokens
= &parser
->tokens_buf
[0];
1428 parser
->tokens_avail
= token
->flags
;
1429 parser
->in_omp_attribute_pragma
= NULL
;
1433 parser
->error
= false;
1436 /* Skip tokens until we have consumed an entire block, or until we
1437 have consumed a non-nested ';'. */
1440 c_parser_skip_to_end_of_block_or_statement (c_parser
*parser
)
1442 unsigned nesting_depth
= 0;
1443 bool save_error
= parser
->error
;
1449 /* Peek at the next token. */
1450 token
= c_parser_peek_token (parser
);
1452 switch (token
->type
)
1457 case CPP_PRAGMA_EOL
:
1458 if (parser
->in_pragma
)
1463 /* If the next token is a ';', we have reached the
1464 end of the statement. */
1467 /* Consume the ';'. */
1468 c_parser_consume_token (parser
);
1473 case CPP_CLOSE_BRACE
:
1474 /* If the next token is a non-nested '}', then we have
1475 reached the end of the current block. */
1476 if (nesting_depth
== 0 || --nesting_depth
== 0)
1478 c_parser_consume_token (parser
);
1483 case CPP_OPEN_BRACE
:
1484 /* If it the next token is a '{', then we are entering a new
1485 block. Consume the entire block. */
1490 /* If we see a pragma, consume the whole thing at once. We
1491 have some safeguards against consuming pragmas willy-nilly.
1492 Normally, we'd expect to be here with parser->error set,
1493 which disables these safeguards. But it's possible to get
1494 here for secondary error recovery, after parser->error has
1496 c_parser_consume_pragma (parser
);
1497 c_parser_skip_to_pragma_eol (parser
);
1498 parser
->error
= save_error
;
1505 c_parser_consume_token (parser
);
1509 parser
->error
= false;
1512 /* CPP's options (initialized by c-opts.cc). */
1513 extern cpp_options
*cpp_opts
;
1515 /* Save the warning flags which are controlled by __extension__. */
1518 disable_extension_diagnostics (void)
1521 | (warn_pointer_arith
<< 1)
1522 | (warn_traditional
<< 2)
1524 | (warn_long_long
<< 4)
1525 | (warn_cxx_compat
<< 5)
1526 | (warn_overlength_strings
<< 6)
1527 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1528 play tricks to properly restore it. */
1529 | ((warn_c90_c99_compat
== 1) << 7)
1530 | ((warn_c90_c99_compat
== -1) << 8)
1531 /* Similarly for warn_c99_c11_compat. */
1532 | ((warn_c99_c11_compat
== 1) << 9)
1533 | ((warn_c99_c11_compat
== -1) << 10)
1534 /* Similarly for warn_c11_c23_compat. */
1535 | ((warn_c11_c23_compat
== 1) << 11)
1536 | ((warn_c11_c23_compat
== -1) << 12)
1538 cpp_opts
->cpp_pedantic
= pedantic
= 0;
1539 warn_pointer_arith
= 0;
1540 cpp_opts
->cpp_warn_traditional
= warn_traditional
= 0;
1542 cpp_opts
->cpp_warn_long_long
= warn_long_long
= 0;
1543 warn_cxx_compat
= 0;
1544 warn_overlength_strings
= 0;
1545 warn_c90_c99_compat
= 0;
1546 warn_c99_c11_compat
= 0;
1547 warn_c11_c23_compat
= 0;
1551 /* Restore the warning flags which are controlled by __extension__.
1552 FLAGS is the return value from disable_extension_diagnostics. */
1555 restore_extension_diagnostics (int flags
)
1557 cpp_opts
->cpp_pedantic
= pedantic
= flags
& 1;
1558 warn_pointer_arith
= (flags
>> 1) & 1;
1559 cpp_opts
->cpp_warn_traditional
= warn_traditional
= (flags
>> 2) & 1;
1560 flag_iso
= (flags
>> 3) & 1;
1561 cpp_opts
->cpp_warn_long_long
= warn_long_long
= (flags
>> 4) & 1;
1562 warn_cxx_compat
= (flags
>> 5) & 1;
1563 warn_overlength_strings
= (flags
>> 6) & 1;
1564 /* See above for why is this needed. */
1565 warn_c90_c99_compat
= (flags
>> 7) & 1 ? 1 : ((flags
>> 8) & 1 ? -1 : 0);
1566 warn_c99_c11_compat
= (flags
>> 9) & 1 ? 1 : ((flags
>> 10) & 1 ? -1 : 0);
1567 warn_c11_c23_compat
= (flags
>> 11) & 1 ? 1 : ((flags
>> 12) & 1 ? -1 : 0);
1570 /* Helper data structure for parsing #pragma acc routine. */
1571 struct oacc_routine_data
{
1572 bool error_seen
; /* Set if error has been reported. */
1573 bool fndecl_seen
; /* Set if one fn decl/definition has been seen already. */
1578 /* Used for parsing objc foreach statements. */
1579 static tree objc_foreach_break_label
, objc_foreach_continue_label
;
1581 /* Used for parsing OMP for loops.
1583 Some notes on flags used for context:
1584 parser->omp_for_parse_state is non-null anywhere inside the OMP FOR
1585 construct, except for the final-loop-body.
1586 The want_nested_loop flag is true if inside a {} sequence where
1587 a loop-nest (or another {} sequence containing a loop-nest) is expected,
1588 but has not yet been seen. It's false when parsing intervening code
1589 statements or their substatements that cannot contain a loop-nest.
1590 The in_intervening_code flag is true when parsing any intervening code,
1591 including substatements, and whether or not want_nested_loop is true.
1593 And, about error handling:
1594 The saw_intervening_code flag is set if the loop is not perfectly
1595 nested, even in the usual case where this is not an error.
1596 perfect_nesting_fail is set if an error has been diagnosed because an
1597 imperfectly-nested loop was found where a perfectly-nested one is
1598 required (we diagnose this only once).
1599 fail is set if any kind of structural error in the loop nest
1600 has been found and diagnosed.
1602 struct omp_for_parse_data
{
1603 enum tree_code code
;
1604 tree declv
, condv
, incrv
, initv
;
1607 int count
; /* Expected nesting depth. */
1608 int depth
; /* Current nesting depth. */
1612 bool want_nested_loop
: 1;
1613 bool in_intervening_code
: 1;
1614 bool saw_intervening_code
: 1;
1615 bool perfect_nesting_fail
: 1;
1619 static bool c_parser_nth_token_starts_std_attributes (c_parser
*,
1621 static tree
c_parser_std_attribute_specifier_sequence (c_parser
*);
1622 static void c_parser_external_declaration (c_parser
*);
1623 static void c_parser_asm_definition (c_parser
*);
1624 static void c_parser_declaration_or_fndef (c_parser
*, bool, bool, bool,
1625 bool, bool, tree
* = NULL
,
1626 vec
<c_token
> * = NULL
,
1627 bool have_attrs
= false,
1629 struct oacc_routine_data
* = NULL
,
1631 static bool c_parser_handle_statement_omp_attributes (c_parser
*, tree
&,
1633 static void c_parser_static_assert_declaration_no_semi (c_parser
*);
1634 static void c_parser_static_assert_declaration (c_parser
*);
1635 static struct c_typespec
c_parser_enum_specifier (c_parser
*);
1636 static struct c_typespec
c_parser_struct_or_union_specifier (c_parser
*);
1637 static tree
c_parser_struct_declaration (c_parser
*, tree
*);
1638 static struct c_typespec
c_parser_typeof_specifier (c_parser
*);
1639 static tree
c_parser_alignas_specifier (c_parser
*);
1640 static struct c_declarator
*c_parser_direct_declarator (c_parser
*, bool,
1642 static struct c_declarator
*c_parser_direct_declarator_inner (c_parser
*,
1644 struct c_declarator
*);
1645 static struct c_arg_info
*c_parser_parms_declarator (c_parser
*, bool, tree
,
1647 static struct c_arg_info
*c_parser_parms_list_declarator (c_parser
*, tree
,
1649 static struct c_parm
*c_parser_parameter_declaration (c_parser
*, tree
, bool);
1650 static tree
c_parser_simple_asm_expr (c_parser
*);
1651 static tree
c_parser_gnu_attributes (c_parser
*);
1652 static struct c_expr
c_parser_initializer (c_parser
*, tree
);
1653 static struct c_expr
c_parser_braced_init (c_parser
*, tree
, bool,
1654 struct obstack
*, tree
);
1655 static void c_parser_initelt (c_parser
*, struct obstack
*);
1656 static void c_parser_initval (c_parser
*, struct c_expr
*,
1658 static tree
c_parser_compound_statement (c_parser
*, location_t
* = NULL
);
1659 static location_t
c_parser_compound_statement_nostart (c_parser
*);
1660 static void c_parser_label (c_parser
*, tree
);
1661 static void c_parser_statement (c_parser
*, bool *, location_t
* = NULL
);
1662 static void c_parser_statement_after_labels (c_parser
*, bool *,
1663 vec
<tree
> * = NULL
);
1664 static tree
c_parser_c99_block_statement (c_parser
*, bool *,
1665 location_t
* = NULL
);
1666 static void c_parser_if_statement (c_parser
*, bool *, vec
<tree
> *);
1667 static void c_parser_switch_statement (c_parser
*, bool *);
1668 static void c_parser_while_statement (c_parser
*, bool, unsigned short, bool,
1670 static void c_parser_do_statement (c_parser
*, bool, unsigned short, bool);
1671 static void c_parser_for_statement (c_parser
*, bool, unsigned short, bool,
1673 static tree
c_parser_asm_statement (c_parser
*);
1674 static tree
c_parser_asm_operands (c_parser
*);
1675 static tree
c_parser_asm_goto_operands (c_parser
*);
1676 static tree
c_parser_asm_clobbers (c_parser
*);
1677 static struct c_expr
c_parser_expr_no_commas (c_parser
*, struct c_expr
*,
1679 static struct c_expr
c_parser_conditional_expression (c_parser
*,
1680 struct c_expr
*, tree
);
1681 static struct c_expr
c_parser_binary_expression (c_parser
*, struct c_expr
*,
1683 static struct c_expr
c_parser_cast_expression (c_parser
*, struct c_expr
*);
1684 static struct c_expr
c_parser_unary_expression (c_parser
*);
1685 static struct c_expr
c_parser_sizeof_expression (c_parser
*);
1686 static struct c_expr
c_parser_alignof_expression (c_parser
*);
1687 static struct c_expr
c_parser_postfix_expression (c_parser
*);
1688 static struct c_expr
c_parser_postfix_expression_after_paren_type (c_parser
*,
1689 struct c_declspecs
*,
1690 struct c_type_name
*,
1692 static struct c_expr
c_parser_postfix_expression_after_primary (c_parser
*,
1695 static tree
c_parser_transaction (c_parser
*, enum rid
);
1696 static struct c_expr
c_parser_transaction_expression (c_parser
*, enum rid
);
1697 static tree
c_parser_transaction_cancel (c_parser
*);
1698 static struct c_expr
c_parser_expression (c_parser
*);
1699 static struct c_expr
c_parser_expression_conv (c_parser
*);
1700 static vec
<tree
, va_gc
> *c_parser_expr_list (c_parser
*, bool, bool,
1701 vec
<tree
, va_gc
> **, location_t
*,
1702 tree
*, vec
<location_t
> *,
1703 unsigned int * = NULL
);
1704 static struct c_expr
c_parser_has_attribute_expression (c_parser
*);
1706 static void c_parser_oacc_declare (c_parser
*);
1707 static void c_parser_oacc_enter_exit_data (c_parser
*, bool);
1708 static void c_parser_oacc_update (c_parser
*);
1709 static void c_parser_omp_construct (c_parser
*, bool *);
1710 static void c_parser_omp_threadprivate (c_parser
*);
1711 static void c_parser_omp_barrier (c_parser
*);
1712 static void c_parser_omp_depobj (c_parser
*);
1713 static void c_parser_omp_flush (c_parser
*);
1714 static tree
c_parser_omp_loop_nest (c_parser
*, bool *);
1715 static tree
c_parser_omp_for_loop (location_t
, c_parser
*, enum tree_code
,
1716 tree
, tree
*, bool *);
1717 static void c_parser_omp_taskwait (c_parser
*);
1718 static void c_parser_omp_taskyield (c_parser
*);
1719 static void c_parser_omp_cancel (c_parser
*);
1720 static void c_parser_omp_nothing (c_parser
*);
1722 enum pragma_context
{ pragma_external
, pragma_struct
, pragma_param
,
1723 pragma_stmt
, pragma_compound
};
1724 static bool c_parser_pragma (c_parser
*, enum pragma_context
, bool *);
1725 static bool c_parser_omp_cancellation_point (c_parser
*, enum pragma_context
);
1726 static bool c_parser_omp_target (c_parser
*, enum pragma_context
, bool *);
1727 static void c_parser_omp_begin (c_parser
*);
1728 static void c_parser_omp_end (c_parser
*);
1729 static bool c_parser_omp_declare (c_parser
*, enum pragma_context
);
1730 static void c_parser_omp_requires (c_parser
*);
1731 static bool c_parser_omp_error (c_parser
*, enum pragma_context
);
1732 static void c_parser_omp_assumption_clauses (c_parser
*, bool);
1733 static void c_parser_omp_allocate (c_parser
*);
1734 static void c_parser_omp_assumes (c_parser
*);
1735 static bool c_parser_omp_ordered (c_parser
*, enum pragma_context
, bool *);
1736 static void c_parser_oacc_routine (c_parser
*, enum pragma_context
);
1738 /* These Objective-C parser functions are only ever called when
1739 compiling Objective-C. */
1740 static void c_parser_objc_class_definition (c_parser
*, tree
);
1741 static void c_parser_objc_class_instance_variables (c_parser
*);
1742 static void c_parser_objc_class_declaration (c_parser
*);
1743 static void c_parser_objc_alias_declaration (c_parser
*);
1744 static void c_parser_objc_protocol_definition (c_parser
*, tree
);
1745 static bool c_parser_objc_method_type (c_parser
*);
1746 static void c_parser_objc_method_definition (c_parser
*);
1747 static void c_parser_objc_methodprotolist (c_parser
*);
1748 static void c_parser_objc_methodproto (c_parser
*);
1749 static tree
c_parser_objc_method_decl (c_parser
*, bool, tree
*, tree
*);
1750 static tree
c_parser_objc_type_name (c_parser
*);
1751 static tree
c_parser_objc_protocol_refs (c_parser
*);
1752 static void c_parser_objc_try_catch_finally_statement (c_parser
*);
1753 static void c_parser_objc_synchronized_statement (c_parser
*);
1754 static tree
c_parser_objc_selector (c_parser
*);
1755 static tree
c_parser_objc_selector_arg (c_parser
*);
1756 static tree
c_parser_objc_receiver (c_parser
*);
1757 static tree
c_parser_objc_message_args (c_parser
*);
1758 static tree
c_parser_objc_keywordexpr (c_parser
*);
1759 static void c_parser_objc_at_property_declaration (c_parser
*);
1760 static void c_parser_objc_at_synthesize_declaration (c_parser
*);
1761 static void c_parser_objc_at_dynamic_declaration (c_parser
*);
1762 static bool c_parser_objc_diagnose_bad_element_prefix
1763 (c_parser
*, struct c_declspecs
*);
1764 static location_t
c_parser_parse_rtl_body (c_parser
*, char *);
1770 /* Concrete implementation of ana::translation_unit for the C frontend. */
1772 class c_translation_unit
: public translation_unit
1775 /* Implementation of translation_unit::lookup_constant_by_id for use by the
1776 analyzer to look up named constants in the user's source code. */
1777 tree
lookup_constant_by_id (tree id
) const final override
1779 /* Consider decls. */
1780 if (tree decl
= lookup_name (id
))
1781 if (TREE_CODE (decl
) == CONST_DECL
)
1782 if (tree value
= DECL_INITIAL (decl
))
1783 if (TREE_CODE (value
) == INTEGER_CST
)
1786 /* Consider macros. */
1787 cpp_hashnode
*hashnode
= C_CPP_HASHNODE (id
);
1788 if (cpp_macro_p (hashnode
))
1789 if (tree value
= consider_macro (hashnode
->value
.macro
))
1796 lookup_type_by_id (tree id
) const final override
1798 if (tree type_decl
= lookup_name (id
))
1799 if (TREE_CODE (type_decl
) == TYPE_DECL
)
1801 tree record_type
= TREE_TYPE (type_decl
);
1802 if (TREE_CODE (record_type
) == RECORD_TYPE
)
1810 lookup_global_var_by_id (tree id
) const final override
1812 if (tree var_decl
= lookup_name (id
))
1813 if (TREE_CODE (var_decl
) == VAR_DECL
)
1820 /* Attempt to get an INTEGER_CST from MACRO.
1821 Only handle the simplest cases: where MACRO's definition is a single
1822 token containing a number, by lexing the number again.
1823 This will handle e.g.
1825 and other bases but not negative numbers, parentheses or e.g.
1827 as doing so would require a parser. */
1828 tree
consider_macro (cpp_macro
*macro
) const
1830 if (macro
->paramc
> 0)
1832 if (macro
->kind
!= cmk_macro
)
1834 if (macro
->count
!= 1)
1836 const cpp_token
&tok
= macro
->exp
.tokens
[0];
1837 if (tok
.type
!= CPP_NUMBER
)
1840 cpp_reader
*old_parse_in
= parse_in
;
1841 parse_in
= cpp_create_reader (CLK_GNUC89
, NULL
, line_table
);
1844 pp_string (&pp
, (const char *) tok
.val
.str
.text
);
1846 cpp_push_buffer (parse_in
,
1847 (const unsigned char *) pp_formatted_text (&pp
),
1848 strlen (pp_formatted_text (&pp
)),
1853 unsigned char cpp_flags
;
1854 c_lex_with_flags (&value
, &loc
, &cpp_flags
, 0);
1856 cpp_destroy (parse_in
);
1857 parse_in
= old_parse_in
;
1859 if (value
&& TREE_CODE (value
) == INTEGER_CST
)
1868 #endif /* #if ENABLE_ANALYZER */
1870 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1873 external-declarations
1875 external-declarations:
1876 external-declaration
1877 external-declarations external-declaration
1886 c_parser_translation_unit (c_parser
*parser
)
1888 if (c_parser_next_token_is (parser
, CPP_EOF
))
1890 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1891 "ISO C forbids an empty translation unit");
1895 void *obstack_position
= obstack_alloc (&parser_obstack
, 0);
1896 mark_valid_location_for_stdc_pragma (false);
1900 c_parser_external_declaration (parser
);
1901 obstack_free (&parser_obstack
, obstack_position
);
1903 while (c_parser_next_token_is_not (parser
, CPP_EOF
));
1908 FOR_EACH_VEC_ELT (incomplete_record_decls
, i
, decl
)
1909 if (DECL_SIZE (decl
) == NULL_TREE
&& TREE_TYPE (decl
) != error_mark_node
)
1910 error ("storage size of %q+D isn%'t known", decl
);
1912 if (vec_safe_length (current_omp_declare_target_attribute
))
1914 c_omp_declare_target_attr
1915 a
= current_omp_declare_target_attribute
->pop ();
1917 error ("%qs without corresponding %qs",
1918 a
.device_type
>= 0 ? "#pragma omp begin declare target"
1919 : "#pragma omp declare target",
1920 "#pragma omp end declare target");
1921 vec_safe_truncate (current_omp_declare_target_attribute
, 0);
1923 if (vec_safe_length (current_omp_begin_assumes
))
1926 error ("%qs without corresponding %qs",
1927 "#pragma omp begin assumes", "#pragma omp end assumes");
1928 vec_safe_truncate (current_omp_begin_assumes
, 0);
1934 ana::c_translation_unit tu
;
1935 ana::on_finish_translation_unit (tu
);
1940 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1942 external-declaration:
1948 external-declaration:
1951 __extension__ external-declaration
1955 external-declaration:
1956 objc-class-definition
1957 objc-class-declaration
1958 objc-alias-declaration
1959 objc-protocol-definition
1960 objc-method-definition
1965 c_parser_external_declaration (c_parser
*parser
)
1968 switch (c_parser_peek_token (parser
)->type
)
1971 switch (c_parser_peek_token (parser
)->keyword
)
1974 ext
= disable_extension_diagnostics ();
1975 c_parser_consume_token (parser
);
1976 c_parser_external_declaration (parser
);
1977 restore_extension_diagnostics (ext
);
1980 c_parser_asm_definition (parser
);
1982 case RID_AT_INTERFACE
:
1983 case RID_AT_IMPLEMENTATION
:
1984 gcc_assert (c_dialect_objc ());
1985 c_parser_objc_class_definition (parser
, NULL_TREE
);
1988 gcc_assert (c_dialect_objc ());
1989 c_parser_objc_class_declaration (parser
);
1992 gcc_assert (c_dialect_objc ());
1993 c_parser_objc_alias_declaration (parser
);
1995 case RID_AT_PROTOCOL
:
1996 gcc_assert (c_dialect_objc ());
1997 c_parser_objc_protocol_definition (parser
, NULL_TREE
);
1999 case RID_AT_PROPERTY
:
2000 gcc_assert (c_dialect_objc ());
2001 c_parser_objc_at_property_declaration (parser
);
2003 case RID_AT_SYNTHESIZE
:
2004 gcc_assert (c_dialect_objc ());
2005 c_parser_objc_at_synthesize_declaration (parser
);
2007 case RID_AT_DYNAMIC
:
2008 gcc_assert (c_dialect_objc ());
2009 c_parser_objc_at_dynamic_declaration (parser
);
2012 gcc_assert (c_dialect_objc ());
2013 c_parser_consume_token (parser
);
2014 objc_finish_implementation ();
2021 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
2022 "ISO C does not allow extra %<;%> outside of a function");
2023 c_parser_consume_token (parser
);
2026 mark_valid_location_for_stdc_pragma (true);
2027 c_parser_pragma (parser
, pragma_external
, NULL
);
2028 mark_valid_location_for_stdc_pragma (false);
2032 if (c_dialect_objc ())
2034 c_parser_objc_method_definition (parser
);
2037 /* Else fall through, and yield a syntax error trying to parse
2038 as a declaration or function definition. */
2042 /* A declaration or a function definition (or, in Objective-C,
2043 an @interface or @protocol with prefix attributes). We can
2044 only tell which after parsing the declaration specifiers, if
2045 any, and the first declarator. */
2046 c_parser_declaration_or_fndef (parser
, true, true, true, false, true);
2051 static void c_parser_handle_directive_omp_attributes (tree
&, vec
<c_token
> *&,
2053 static void c_finish_omp_declare_simd (c_parser
*, tree
, tree
, vec
<c_token
> *);
2054 static void c_finish_oacc_routine (struct oacc_routine_data
*, tree
, bool);
2056 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
2059 add_debug_begin_stmt (location_t loc
)
2061 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
2062 if (!MAY_HAVE_DEBUG_MARKER_STMTS
|| !building_stmt_list_p ())
2065 tree stmt
= build0 (DEBUG_BEGIN_STMT
, void_type_node
);
2066 SET_EXPR_LOCATION (stmt
, loc
);
2070 /* Helper function for c_parser_declaration_or_fndef and
2071 Handle assume attribute(s). */
2074 handle_assume_attribute (location_t here
, tree attrs
, bool nested
)
2077 for (tree attr
= lookup_attribute ("gnu", "assume", attrs
); attr
;
2078 attr
= lookup_attribute ("gnu", "assume", TREE_CHAIN (attr
)))
2080 tree args
= TREE_VALUE (attr
);
2081 int nargs
= list_length (args
);
2084 error_at (here
, "wrong number of arguments specified "
2085 "for %qE attribute",
2086 get_attribute_name (attr
));
2087 inform (here
, "expected %i, found %i", 1, nargs
);
2091 tree arg
= TREE_VALUE (args
);
2092 arg
= c_objc_common_truthvalue_conversion (here
, arg
);
2093 arg
= c_fully_fold (arg
, false, NULL
);
2094 if (arg
!= error_mark_node
)
2096 tree fn
= build_call_expr_internal_loc (here
, IFN_ASSUME
,
2104 pedwarn (here
, OPT_Wattributes
,
2105 "%<assume%> attribute at top level");
2107 return remove_attribute ("gnu", "assume", attrs
);
2110 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
2111 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
2112 is accepted; otherwise (old-style parameter declarations) only other
2113 declarations are accepted. If STATIC_ASSERT_OK is true, a static
2114 assertion is accepted; otherwise (old-style parameter declarations)
2115 it is not. If NESTED is true, we are inside a function or parsing
2116 old-style parameter declarations; any functions encountered are
2117 nested functions and declaration specifiers are required; otherwise
2118 we are at top level and functions are normal functions and
2119 declaration specifiers may be optional. If EMPTY_OK is true, empty
2120 declarations are OK (subject to all other constraints); otherwise
2121 (old-style parameter declarations) they are diagnosed. If
2122 START_ATTR_OK is true, the declaration specifiers may start with
2123 attributes (GNU or standard); otherwise they may not.
2124 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
2125 declaration when parsing an Objective-C foreach statement.
2126 FALLTHRU_ATTR_P is used to signal whether this function parsed
2127 "__attribute__((fallthrough));". ATTRS are any standard attributes
2128 parsed in the caller (in contexts where such attributes had to be
2129 parsed to determine whether what follows is a declaration or a
2130 statement); HAVE_ATTRS says whether there were any such attributes
2134 declaration-specifiers init-declarator-list[opt] ;
2135 static_assert-declaration
2137 function-definition:
2138 declaration-specifiers[opt] declarator declaration-list[opt]
2143 declaration-list declaration
2145 init-declarator-list:
2147 init-declarator-list , init-declarator
2150 declarator simple-asm-expr[opt] gnu-attributes[opt]
2151 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
2155 nested-function-definition:
2156 declaration-specifiers declarator declaration-list[opt]
2162 gnu-attributes objc-class-definition
2163 gnu-attributes objc-category-definition
2164 gnu-attributes objc-protocol-definition
2166 The simple-asm-expr and gnu-attributes are GNU extensions.
2168 This function does not handle __extension__; that is handled in its
2169 callers. ??? Following the old parser, __extension__ may start
2170 external declarations, declarations in functions and declarations
2171 at the start of "for" loops, but not old-style parameter
2174 C99 requires declaration specifiers in a function definition; the
2175 absence is diagnosed through the diagnosis of implicit int. In GNU
2176 C we also allow but diagnose declarations without declaration
2177 specifiers, but only at top level (elsewhere they conflict with
2180 In Objective-C, declarations of the looping variable in a foreach
2181 statement are exceptionally terminated by 'in' (for example, 'for
2182 (NSObject *object in array) { ... }').
2187 threadprivate-directive
2191 gimple-function-definition:
2192 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
2193 declaration-list[opt] compound-statement
2195 rtl-function-definition:
2196 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
2197 declaration-list[opt] compound-statement */
2200 c_parser_declaration_or_fndef (c_parser
*parser
, bool fndef_ok
,
2201 bool static_assert_ok
, bool empty_ok
,
2202 bool nested
, bool start_attr_ok
,
2203 tree
*objc_foreach_object_declaration
2205 vec
<c_token
> *omp_declare_simd_clauses
2207 bool have_attrs
/* = false */,
2208 tree attrs
/* = NULL_TREE */,
2209 struct oacc_routine_data
*oacc_routine_data
2211 bool *fallthru_attr_p
/* = NULL */)
2213 struct c_declspecs
*specs
;
2215 tree all_prefix_attrs
;
2216 bool diagnosed_no_specs
= false;
2217 location_t here
= c_parser_peek_token (parser
)->location
;
2219 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
2221 if (static_assert_ok
2222 && c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
2224 c_parser_static_assert_declaration (parser
);
2227 specs
= build_null_declspecs ();
2229 /* Handle any standard attributes parsed in the caller. */
2232 declspecs_add_attrs (here
, specs
, attrs
);
2233 specs
->non_std_attrs_seen_p
= false;
2236 /* Try to detect an unknown type name when we have "A B" or "A *B". */
2237 if (c_parser_peek_token (parser
)->type
== CPP_NAME
2238 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
2239 && (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
2240 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
2241 && (!nested
|| !lookup_name (c_parser_peek_token (parser
)->value
)))
2243 tree name
= c_parser_peek_token (parser
)->value
;
2245 /* Issue a warning about NAME being an unknown type name, perhaps
2246 with some kind of hint.
2247 If the user forgot a "struct" etc, suggest inserting
2248 it. Otherwise, attempt to look for misspellings. */
2249 gcc_rich_location
richloc (here
);
2250 if (tag_exists_p (RECORD_TYPE
, name
))
2252 /* This is not C++ with its implicit typedef. */
2253 richloc
.add_fixit_insert_before ("struct ");
2255 "unknown type name %qE;"
2256 " use %<struct%> keyword to refer to the type",
2259 else if (tag_exists_p (UNION_TYPE
, name
))
2261 richloc
.add_fixit_insert_before ("union ");
2263 "unknown type name %qE;"
2264 " use %<union%> keyword to refer to the type",
2267 else if (tag_exists_p (ENUMERAL_TYPE
, name
))
2269 richloc
.add_fixit_insert_before ("enum ");
2271 "unknown type name %qE;"
2272 " use %<enum%> keyword to refer to the type",
2277 auto_diagnostic_group d
;
2278 name_hint hint
= lookup_name_fuzzy (name
, FUZZY_LOOKUP_TYPENAME
,
2280 if (const char *suggestion
= hint
.suggestion ())
2282 richloc
.add_fixit_replace (suggestion
);
2284 "unknown type name %qE; did you mean %qs?",
2288 error_at (here
, "unknown type name %qE", name
);
2291 /* Parse declspecs normally to get a correct pointer type, but avoid
2292 a further "fails to be a type name" error. Refuse nested functions
2293 since it is not how the user likely wants us to recover. */
2294 c_parser_peek_token (parser
)->type
= CPP_KEYWORD
;
2295 c_parser_peek_token (parser
)->keyword
= RID_VOID
;
2296 c_parser_peek_token (parser
)->value
= error_mark_node
;
2300 /* When there are standard attributes at the start of the
2301 declaration (to apply to the entity being declared), an
2302 init-declarator-list or function definition must be present. */
2303 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
2306 c_parser_declspecs (parser
, specs
, true, true, start_attr_ok
,
2307 true, true, start_attr_ok
, true, cla_nonabstract_decl
);
2310 c_parser_skip_to_end_of_block_or_statement (parser
);
2313 if (nested
&& !specs
->declspecs_seen_p
)
2315 c_parser_error (parser
, "expected declaration specifiers");
2316 c_parser_skip_to_end_of_block_or_statement (parser
);
2320 finish_declspecs (specs
);
2321 bool gnu_auto_type_p
= specs
->typespec_word
== cts_auto_type
;
2322 bool std_auto_type_p
= specs
->c23_auto_p
;
2323 bool any_auto_type_p
= gnu_auto_type_p
|| std_auto_type_p
;
2324 gcc_assert (!(gnu_auto_type_p
&& std_auto_type_p
));
2325 const char *auto_type_keyword
= gnu_auto_type_p
? "__auto_type" : "auto";
2326 if (specs
->constexpr_p
)
2328 /* An underspecified declaration may not declare tags or members
2329 or structures or unions; it is undefined behavior to declare
2330 the members of an enumeration. Where the structure, union or
2331 enumeration type is declared within an initializer, this is
2332 diagnosed elsewhere. Diagnose here the case of declaring
2333 such a type in the type specifiers of a constexpr
2335 switch (specs
->typespec_kind
)
2337 case ctsk_tagfirstref
:
2338 case ctsk_tagfirstref_attrs
:
2339 error_at (here
, "%qT declared in underspecified object declaration",
2344 error_at (here
, "%qT defined in underspecified object declaration",
2352 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2354 bool handled_assume
= false;
2357 && specs
->typespec_kind
== ctsk_none
2358 && c_parser_handle_statement_omp_attributes (parser
, specs
->attrs
,
2362 c_warn_unused_attributes (specs
->attrs
);
2363 while (parser
->in_omp_attribute_pragma
)
2365 gcc_assert (c_parser_next_token_is (parser
, CPP_PRAGMA
));
2366 c_parser_pragma (parser
, pragma_external
, NULL
);
2368 c_parser_consume_token (parser
);
2371 if (specs
->typespec_kind
== ctsk_none
2372 && lookup_attribute ("gnu", "assume", specs
->attrs
))
2374 handled_assume
= true;
2376 = handle_assume_attribute (here
, specs
->attrs
, nested
);
2378 if (any_auto_type_p
)
2379 error_at (here
, "%qs in empty declaration", auto_type_keyword
);
2380 else if (specs
->typespec_kind
== ctsk_none
2381 && attribute_fallthrough_p (specs
->attrs
))
2383 if (fallthru_attr_p
!= NULL
)
2384 *fallthru_attr_p
= true;
2387 tree fn
= build_call_expr_internal_loc (here
, IFN_FALLTHROUGH
,
2392 pedwarn (here
, OPT_Wattributes
,
2393 "%<fallthrough%> attribute at top level");
2396 && !(have_attrs
&& specs
->non_std_attrs_seen_p
)
2401 shadow_tag_warned (specs
, 1);
2402 if (!handled_assume
)
2403 pedwarn (here
, 0, "empty declaration");
2405 /* We still have to evaluate size expressions. */
2407 add_stmt (fold_convert (void_type_node
, specs
->expr
));
2408 c_parser_consume_token (parser
);
2409 if (oacc_routine_data
)
2410 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2414 /* Provide better error recovery. Note that a type name here is usually
2415 better diagnosed as a redeclaration. */
2417 && specs
->typespec_kind
== ctsk_tagdef
2418 && c_parser_next_token_starts_declspecs (parser
)
2419 && !c_parser_next_token_is (parser
, CPP_NAME
))
2421 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
2422 parser
->error
= false;
2423 shadow_tag_warned (specs
, 1);
2426 else if (c_dialect_objc () && !any_auto_type_p
)
2428 /* Prefix attributes are an error on method decls. */
2429 switch (c_parser_peek_token (parser
)->type
)
2433 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2437 warning_at (c_parser_peek_token (parser
)->location
,
2439 "prefix attributes are ignored for methods");
2440 specs
->attrs
= NULL_TREE
;
2443 c_parser_objc_method_definition (parser
);
2445 c_parser_objc_methodproto (parser
);
2451 /* This is where we parse 'attributes @interface ...',
2452 'attributes @implementation ...', 'attributes @protocol ...'
2453 (where attributes could be, for example, __attribute__
2456 switch (c_parser_peek_token (parser
)->keyword
)
2458 case RID_AT_INTERFACE
:
2460 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2462 c_parser_objc_class_definition (parser
, specs
->attrs
);
2466 case RID_AT_IMPLEMENTATION
:
2468 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2472 warning_at (c_parser_peek_token (parser
)->location
,
2474 "prefix attributes are ignored for implementations");
2475 specs
->attrs
= NULL_TREE
;
2477 c_parser_objc_class_definition (parser
, NULL_TREE
);
2481 case RID_AT_PROTOCOL
:
2483 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2485 c_parser_objc_protocol_definition (parser
, specs
->attrs
);
2492 case RID_AT_PROPERTY
:
2495 c_parser_error (parser
, "unexpected attribute");
2496 specs
->attrs
= NULL
;
2503 else if (attribute_fallthrough_p (specs
->attrs
))
2504 warning_at (here
, OPT_Wattributes
,
2505 "%<fallthrough%> attribute not followed by %<;%>");
2506 else if (lookup_attribute ("gnu", "assume", specs
->attrs
))
2507 warning_at (here
, OPT_Wattributes
,
2508 "%<assume%> attribute not followed by %<;%>");
2510 auto_vec
<c_token
> omp_declare_simd_attr_clauses
;
2511 c_parser_handle_directive_omp_attributes (specs
->attrs
,
2512 omp_declare_simd_clauses
,
2513 &omp_declare_simd_attr_clauses
);
2514 pending_xref_error ();
2515 prefix_attrs
= specs
->attrs
;
2516 all_prefix_attrs
= prefix_attrs
;
2517 specs
->attrs
= NULL_TREE
;
2520 struct c_declarator
*declarator
;
2523 tree fnbody
= NULL_TREE
;
2524 tree underspec_name
= NULL_TREE
;
2525 auto_vec
<c_token
> omp_dsimd_idattr_clauses
;
2526 /* Declaring either one or more declarators (in which case we
2527 should diagnose if there were no declaration specifiers) or a
2528 function definition (in which case the diagnostic for
2529 implicit int suffices). */
2530 declarator
= c_parser_declarator (parser
,
2531 specs
->typespec_kind
!= ctsk_none
,
2532 C_DTR_NORMAL
, &dummy
);
2533 if (declarator
== NULL
)
2535 if (omp_declare_simd_clauses
)
2536 c_finish_omp_declare_simd (parser
, NULL_TREE
, NULL_TREE
,
2537 omp_declare_simd_clauses
);
2538 if (oacc_routine_data
)
2539 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2540 c_parser_skip_to_end_of_block_or_statement (parser
);
2543 if (flag_openmp
|| flag_openmp_simd
)
2545 struct c_declarator
*d
= declarator
;
2546 while (d
->kind
!= cdk_id
)
2548 vec
<c_token
> *dummy
= NULL
;
2549 c_parser_handle_directive_omp_attributes (d
->u
.id
.attrs
, dummy
,
2550 &omp_dsimd_idattr_clauses
);
2552 if (gnu_auto_type_p
&& declarator
->kind
!= cdk_id
)
2555 "%<__auto_type%> requires a plain identifier"
2557 c_parser_skip_to_end_of_block_or_statement (parser
);
2560 if (std_auto_type_p
)
2562 struct c_declarator
*d
= declarator
;
2563 while (d
->kind
== cdk_attrs
)
2565 if (d
->kind
!= cdk_id
)
2568 "%<auto%> requires a plain identifier, possibly with"
2569 " attributes, as declarator");
2570 c_parser_skip_to_end_of_block_or_statement (parser
);
2573 underspec_name
= d
->u
.id
.id
;
2575 else if (specs
->constexpr_p
)
2577 struct c_declarator
*d
= declarator
;
2578 while (d
->kind
!= cdk_id
)
2580 underspec_name
= d
->u
.id
.id
;
2582 if (c_parser_next_token_is (parser
, CPP_EQ
)
2583 || c_parser_next_token_is (parser
, CPP_COMMA
)
2584 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
2585 || c_parser_next_token_is_keyword (parser
, RID_ASM
)
2586 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
)
2587 || c_parser_next_token_is_keyword (parser
, RID_IN
))
2589 tree asm_name
= NULL_TREE
;
2590 tree postfix_attrs
= NULL_TREE
;
2591 if (!diagnosed_no_specs
&& !specs
->declspecs_seen_p
)
2593 diagnosed_no_specs
= true;
2594 pedwarn (here
, 0, "data definition has no type or storage class");
2596 /* Having seen a data definition, there cannot now be a
2597 function definition. */
2599 if (c_parser_next_token_is_keyword (parser
, RID_ASM
))
2600 asm_name
= c_parser_simple_asm_expr (parser
);
2601 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2603 postfix_attrs
= c_parser_gnu_attributes (parser
);
2604 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2606 /* This means there is an attribute specifier after
2607 the declarator in a function definition. Provide
2608 some more information for the user. */
2609 error_at (here
, "attributes should be specified before the "
2610 "declarator in a function definition");
2611 c_parser_skip_to_end_of_block_or_statement (parser
);
2615 if (c_parser_next_token_is (parser
, CPP_EQ
))
2619 location_t init_loc
;
2620 c_parser_consume_token (parser
);
2621 if (any_auto_type_p
)
2623 init_loc
= c_parser_peek_token (parser
)->location
;
2624 rich_location
richloc (line_table
, init_loc
);
2625 unsigned int underspec_state
= 0;
2626 if (std_auto_type_p
)
2628 start_underspecified_init (init_loc
, underspec_name
);
2629 start_init (NULL_TREE
, asm_name
,
2630 (global_bindings_p ()
2631 || specs
->storage_class
== csc_static
2632 || specs
->constexpr_p
),
2633 specs
->constexpr_p
, &richloc
);
2634 /* A parameter is initialized, which is invalid. Don't
2635 attempt to instrument the initializer. */
2636 int flag_sanitize_save
= flag_sanitize
;
2637 if (nested
&& !empty_ok
)
2639 init
= c_parser_expr_no_commas (parser
, NULL
);
2640 if (std_auto_type_p
)
2641 finish_underspecified_init (underspec_name
,
2643 flag_sanitize
= flag_sanitize_save
;
2645 && TREE_CODE (init
.value
) == COMPONENT_REF
2646 && DECL_C_BIT_FIELD (TREE_OPERAND (init
.value
, 1)))
2648 "%<__auto_type%> used with a bit-field"
2650 init
= convert_lvalue_to_rvalue (init_loc
, init
, true, true,
2652 tree init_type
= TREE_TYPE (init
.value
);
2653 bool vm_type
= c_type_variably_modified_p (init_type
);
2655 init
.value
= save_expr (init
.value
);
2657 specs
->typespec_kind
= ctsk_typeof
;
2658 specs
->locations
[cdw_typedef
] = init_loc
;
2659 specs
->typedef_p
= true;
2660 specs
->type
= init_type
;
2661 if (specs
->postfix_attrs
)
2663 /* Postfix [[]] attributes are valid with C23
2664 auto, although not with __auto_type, and
2665 modify the type given by the initializer. */
2666 specs
->postfix_attrs
=
2667 c_warn_type_attributes (specs
->postfix_attrs
);
2668 decl_attributes (&specs
->type
, specs
->postfix_attrs
, 0);
2669 specs
->postfix_attrs
= NULL_TREE
;
2673 bool maybe_const
= true;
2674 tree type_expr
= c_fully_fold (init
.value
, false,
2676 specs
->expr_const_operands
&= maybe_const
;
2678 specs
->expr
= build2 (COMPOUND_EXPR
,
2679 TREE_TYPE (type_expr
),
2680 specs
->expr
, type_expr
);
2682 specs
->expr
= type_expr
;
2684 d
= start_decl (declarator
, specs
, true,
2685 chainon (postfix_attrs
, all_prefix_attrs
));
2687 d
= error_mark_node
;
2688 if (omp_declare_simd_clauses
)
2689 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2690 omp_declare_simd_clauses
);
2691 if (!omp_dsimd_idattr_clauses
.is_empty ())
2692 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2693 &omp_dsimd_idattr_clauses
);
2697 /* The declaration of the variable is in effect while
2698 its initializer is parsed, except for a constexpr
2700 init_loc
= c_parser_peek_token (parser
)->location
;
2701 rich_location
richloc (line_table
, init_loc
);
2702 unsigned int underspec_state
= 0;
2703 if (specs
->constexpr_p
)
2705 start_underspecified_init (init_loc
, underspec_name
);
2706 d
= start_decl (declarator
, specs
, true,
2707 chainon (postfix_attrs
,
2709 !specs
->constexpr_p
);
2711 d
= error_mark_node
;
2712 if (!specs
->constexpr_p
&& omp_declare_simd_clauses
)
2713 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2714 omp_declare_simd_clauses
);
2715 if (!specs
->constexpr_p
2716 && !omp_dsimd_idattr_clauses
.is_empty ())
2717 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2718 &omp_dsimd_idattr_clauses
);
2719 start_init (d
, asm_name
,
2720 TREE_STATIC (d
) || specs
->constexpr_p
,
2721 specs
->constexpr_p
, &richloc
);
2722 /* A parameter is initialized, which is invalid. Don't
2723 attempt to instrument the initializer. */
2724 int flag_sanitize_save
= flag_sanitize
;
2725 if (TREE_CODE (d
) == PARM_DECL
)
2727 init
= c_parser_initializer (parser
, d
);
2728 flag_sanitize
= flag_sanitize_save
;
2729 if (specs
->constexpr_p
)
2731 finish_underspecified_init (underspec_name
,
2734 if (omp_declare_simd_clauses
)
2735 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2736 omp_declare_simd_clauses
);
2737 if (!specs
->constexpr_p
2738 && !omp_dsimd_idattr_clauses
.is_empty ())
2739 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2740 &omp_dsimd_idattr_clauses
);
2744 if (oacc_routine_data
)
2745 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2746 if (d
!= error_mark_node
)
2748 maybe_warn_string_init (init_loc
, TREE_TYPE (d
), init
);
2749 finish_decl (d
, init_loc
, init
.value
,
2750 init
.original_type
, asm_name
);
2755 if (any_auto_type_p
|| specs
->constexpr_p
)
2758 "%qs requires an initialized data declaration",
2759 any_auto_type_p
? auto_type_keyword
: "constexpr");
2760 c_parser_skip_to_end_of_block_or_statement (parser
);
2764 location_t lastloc
= UNKNOWN_LOCATION
;
2765 tree attrs
= chainon (postfix_attrs
, all_prefix_attrs
);
2766 tree d
= start_decl (declarator
, specs
, false, attrs
, true,
2768 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2770 /* Find the innermost declarator that is neither cdk_id
2772 const struct c_declarator
*decl
= declarator
;
2773 const struct c_declarator
*last_non_id_attrs
= NULL
;
2781 last_non_id_attrs
= decl
;
2782 decl
= decl
->declarator
;
2786 decl
= decl
->declarator
;
2797 /* If it exists and is cdk_function declaration whose
2798 arguments have not been set yet, use its arguments. */
2799 if (last_non_id_attrs
2800 && last_non_id_attrs
->kind
== cdk_function
)
2802 tree parms
= last_non_id_attrs
->u
.arg_info
->parms
;
2803 if (DECL_ARGUMENTS (d
) == NULL_TREE
2804 && DECL_INITIAL (d
) == NULL_TREE
)
2805 DECL_ARGUMENTS (d
) = parms
;
2807 warn_parm_array_mismatch (lastloc
, d
, parms
);
2810 if (omp_declare_simd_clauses
2811 || !omp_dsimd_idattr_clauses
.is_empty ())
2813 tree parms
= NULL_TREE
;
2814 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2816 struct c_declarator
*ce
= declarator
;
2818 if (ce
->kind
== cdk_function
)
2820 parms
= ce
->u
.arg_info
->parms
;
2824 ce
= ce
->declarator
;
2827 temp_store_parm_decls (d
, parms
);
2828 if (omp_declare_simd_clauses
)
2829 c_finish_omp_declare_simd (parser
, d
, parms
,
2830 omp_declare_simd_clauses
);
2831 if (!specs
->constexpr_p
2832 && !omp_dsimd_idattr_clauses
.is_empty ())
2833 c_finish_omp_declare_simd (parser
, d
, parms
,
2834 &omp_dsimd_idattr_clauses
);
2836 temp_pop_parm_decls ();
2838 if (oacc_routine_data
)
2839 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2841 finish_decl (d
, UNKNOWN_LOCATION
, NULL_TREE
,
2842 NULL_TREE
, asm_name
);
2844 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2847 *objc_foreach_object_declaration
= d
;
2849 *objc_foreach_object_declaration
= error_mark_node
;
2852 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2854 if (any_auto_type_p
|| specs
->constexpr_p
)
2857 "%qs may only be used with a single declarator",
2858 any_auto_type_p
? auto_type_keyword
: "constexpr");
2859 c_parser_skip_to_end_of_block_or_statement (parser
);
2862 c_parser_consume_token (parser
);
2863 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2864 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
2867 all_prefix_attrs
= prefix_attrs
;
2870 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2872 c_parser_consume_token (parser
);
2875 else if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2877 /* This can only happen in Objective-C: we found the
2878 'in' that terminates the declaration inside an
2879 Objective-C foreach statement. Do not consume the
2880 token, so that the caller can use it to determine
2881 that this indeed is a foreach context. */
2886 c_parser_error (parser
, "expected %<,%> or %<;%>");
2887 c_parser_skip_to_end_of_block_or_statement (parser
);
2891 else if (any_auto_type_p
|| specs
->constexpr_p
)
2894 "%qs requires an initialized data declaration",
2895 any_auto_type_p
? auto_type_keyword
: "constexpr");
2896 c_parser_skip_to_end_of_block_or_statement (parser
);
2901 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, "
2902 "%<asm%> or %<__attribute__%>");
2903 c_parser_skip_to_end_of_block_or_statement (parser
);
2906 /* Function definition (nested or otherwise). */
2909 pedwarn (here
, OPT_Wpedantic
, "ISO C forbids nested functions");
2910 c_push_function_context ();
2912 if (!start_function (specs
, declarator
, all_prefix_attrs
))
2914 /* At this point we've consumed:
2915 declaration-specifiers declarator
2916 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2917 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2919 declaration-specifiers declarator
2920 aren't grokkable as a function definition, so we have
2922 gcc_assert (!c_parser_next_token_is (parser
, CPP_SEMICOLON
));
2923 if (c_parser_next_token_starts_declspecs (parser
))
2926 declaration-specifiers declarator decl-specs
2927 then assume we have a missing semicolon, which would
2929 declaration-specifiers declarator decl-specs
2932 <~~~~~~~~~ declaration ~~~~~~~~~~>
2933 Use c_parser_require to get an error with a fix-it hint. */
2934 c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>");
2935 parser
->error
= false;
2939 /* This can appear in many cases looking nothing like a
2940 function definition, so we don't give a more specific
2941 error suggesting there was one. */
2942 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2943 "or %<__attribute__%>");
2946 c_pop_function_context ();
2950 if (DECL_DECLARED_INLINE_P (current_function_decl
))
2951 tv
= TV_PARSE_INLINE
;
2954 auto_timevar
at (g_timer
, tv
);
2956 /* Parse old-style parameter declarations. ??? Attributes are
2957 not allowed to start declaration specifiers here because of a
2958 syntax conflict between a function declaration with attribute
2959 suffix and a function definition with an attribute prefix on
2960 first old-style parameter declaration. Following the old
2961 parser, they are not accepted on subsequent old-style
2962 parameter declarations either. However, there is no
2963 ambiguity after the first declaration, nor indeed on the
2964 first as long as we don't allow postfix attributes after a
2965 declarator with a nonempty identifier list in a definition;
2966 and postfix attributes have never been accepted here in
2967 function definitions either. */
2968 int save_debug_nonbind_markers_p
= debug_nonbind_markers_p
;
2969 debug_nonbind_markers_p
= 0;
2970 while (c_parser_next_token_is_not (parser
, CPP_EOF
)
2971 && c_parser_next_token_is_not (parser
, CPP_OPEN_BRACE
))
2972 c_parser_declaration_or_fndef (parser
, false, false, false,
2974 debug_nonbind_markers_p
= save_debug_nonbind_markers_p
;
2975 store_parm_decls ();
2976 if (omp_declare_simd_clauses
)
2977 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2978 omp_declare_simd_clauses
);
2979 if (!omp_dsimd_idattr_clauses
.is_empty ())
2980 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2981 &omp_dsimd_idattr_clauses
);
2982 if (oacc_routine_data
)
2983 c_finish_oacc_routine (oacc_routine_data
, current_function_decl
, true);
2984 location_t startloc
= c_parser_peek_token (parser
)->location
;
2985 DECL_STRUCT_FUNCTION (current_function_decl
)->function_start_locus
2987 location_t endloc
= startloc
;
2989 /* If the definition was marked with __RTL, use the RTL parser now,
2990 consuming the function body. */
2991 if (specs
->declspec_il
== cdil_rtl
)
2993 endloc
= c_parser_parse_rtl_body (parser
, specs
->gimple_or_rtl_pass
);
2995 /* Normally, store_parm_decls sets next_is_function_body,
2996 anticipating a function body. We need a push_scope/pop_scope
2997 pair to flush out this state, or subsequent function parsing
3002 finish_function (endloc
);
3005 /* If the definition was marked with __GIMPLE then parse the
3006 function body as GIMPLE. */
3007 else if (specs
->declspec_il
!= cdil_none
)
3009 bool saved
= in_late_binary_op
;
3010 in_late_binary_op
= true;
3011 c_parser_parse_gimple_body (parser
, specs
->gimple_or_rtl_pass
,
3013 specs
->entry_bb_count
);
3014 in_late_binary_op
= saved
;
3017 fnbody
= c_parser_compound_statement (parser
, &endloc
);
3018 tree fndecl
= current_function_decl
;
3021 tree decl
= current_function_decl
;
3022 /* Mark nested functions as needing static-chain initially.
3023 lower_nested_functions will recompute it but the
3024 DECL_STATIC_CHAIN flag is also used before that happens,
3025 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
3026 DECL_STATIC_CHAIN (decl
) = 1;
3028 finish_function (endloc
);
3029 c_pop_function_context ();
3030 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl
), DECL_EXPR
, decl
));
3036 finish_function (endloc
);
3038 /* Get rid of the empty stmt list for GIMPLE/RTL. */
3039 if (specs
->declspec_il
!= cdil_none
)
3040 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
3046 /* Parse an asm-definition (asm() outside a function body). This is a
3054 c_parser_asm_definition (c_parser
*parser
)
3056 tree asm_str
= c_parser_simple_asm_expr (parser
);
3058 symtab
->finalize_toplevel_asm (asm_str
);
3059 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
3062 /* Parse a static assertion (C11 6.7.10).
3064 static_assert-declaration:
3065 static_assert-declaration-no-semi ;
3069 c_parser_static_assert_declaration (c_parser
*parser
)
3071 c_parser_static_assert_declaration_no_semi (parser
);
3073 || !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
3074 c_parser_skip_to_end_of_block_or_statement (parser
);
3077 /* Parse a static assertion (C11 6.7.10), without the trailing
3080 static_assert-declaration-no-semi:
3081 _Static_assert ( constant-expression , string-literal )
3084 static_assert-declaration-no-semi:
3085 _Static_assert ( constant-expression )
3089 c_parser_static_assert_declaration_no_semi (c_parser
*parser
)
3091 location_t assert_loc
, value_loc
;
3093 tree string
= NULL_TREE
;
3095 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
));
3096 tree spelling
= c_parser_peek_token (parser
)->value
;
3097 assert_loc
= c_parser_peek_token (parser
)->location
;
3099 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
3100 "ISO C99 does not support %qE", spelling
);
3102 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
3103 "ISO C90 does not support %qE", spelling
);
3104 c_parser_consume_token (parser
);
3105 matching_parens parens
;
3106 if (!parens
.require_open (parser
))
3108 location_t value_tok_loc
= c_parser_peek_token (parser
)->location
;
3109 value
= convert_lvalue_to_rvalue (value_tok_loc
,
3110 c_parser_expr_no_commas (parser
, NULL
),
3112 value_loc
= EXPR_LOC_OR_LOC (value
, value_tok_loc
);
3113 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3115 c_parser_consume_token (parser
);
3116 switch (c_parser_peek_token (parser
)->type
)
3122 case CPP_UTF8STRING
:
3123 string
= c_parser_string_literal (parser
, false, true).value
;
3126 c_parser_error (parser
, "expected string literal");
3130 else if (flag_isoc11
)
3131 /* If pedantic for pre-C11, the use of _Static_assert itself will
3132 have been diagnosed, so do not also diagnose the use of this
3133 new C23 feature of _Static_assert. */
3134 pedwarn_c11 (assert_loc
, OPT_Wpedantic
,
3135 "ISO C11 does not support omitting the string in "
3137 parens
.require_close (parser
);
3139 if (!INTEGRAL_TYPE_P (TREE_TYPE (value
)))
3141 error_at (value_loc
, "expression in static assertion is not an integer");
3144 if (TREE_CODE (value
) != INTEGER_CST
)
3146 value
= c_fully_fold (value
, false, NULL
);
3147 /* Strip no-op conversions. */
3148 STRIP_TYPE_NOPS (value
);
3149 if (TREE_CODE (value
) == INTEGER_CST
)
3150 pedwarn (value_loc
, OPT_Wpedantic
, "expression in static assertion "
3151 "is not an integer constant expression");
3153 if (TREE_CODE (value
) != INTEGER_CST
)
3155 error_at (value_loc
, "expression in static assertion is not constant");
3158 constant_expression_warning (value
);
3159 if (integer_zerop (value
))
3162 error_at (assert_loc
, "static assertion failed: %E", string
);
3164 error_at (assert_loc
, "static assertion failed");
3168 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
3169 6.7, C11 6.7), adding them to SPECS (which may already include some).
3170 Storage class specifiers are accepted iff SCSPEC_OK; type
3171 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
3172 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
3173 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
3174 addition to the syntax shown, standard attributes are accepted at
3175 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
3176 unlike gnu-attributes, they are not accepted in the middle of the
3177 list. (This combines various different syntax productions in the C
3178 standard, and in some cases gnu-attributes and standard attributes
3179 at the start may already have been parsed before this function is
3182 declaration-specifiers:
3183 storage-class-specifier declaration-specifiers[opt]
3184 type-specifier declaration-specifiers[opt]
3185 type-qualifier declaration-specifiers[opt]
3186 function-specifier declaration-specifiers[opt]
3187 alignment-specifier declaration-specifiers[opt]
3189 Function specifiers (inline) are from C99, and are currently
3190 handled as storage class specifiers, as is __thread. Alignment
3191 specifiers are from C11.
3193 C90 6.5.1, C99 6.7.1, C11 6.7.1:
3194 storage-class-specifier:
3202 (_Thread_local is new in C11.)
3204 C99 6.7.4, C11 6.7.4:
3209 (_Noreturn is new in C11.)
3211 C90 6.5.2, C99 6.7.2, C11 6.7.2:
3224 [_Imaginary removed in C99 TC2]
3225 _BitInt ( constant-expression )
3226 struct-or-union-specifier
3229 atomic-type-specifier
3231 (_Bool and _Complex are new in C99.)
3232 (atomic-type-specifier is new in C11.)
3233 (_BitInt is new in C23.)
3235 C90 6.5.3, C99 6.7.3, C11 6.7.3:
3241 address-space-qualifier
3244 (restrict is new in C99.)
3245 (_Atomic is new in C11.)
3249 declaration-specifiers:
3250 gnu-attributes declaration-specifiers[opt]
3256 identifier recognized by the target
3258 storage-class-specifier:
3272 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
3273 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
3275 atomic-type-specifier
3276 _Atomic ( type-name )
3281 class-name objc-protocol-refs[opt]
3282 typedef-name objc-protocol-refs
3287 c_parser_declspecs (c_parser
*parser
, struct c_declspecs
*specs
,
3288 bool scspec_ok
, bool typespec_ok
, bool start_attr_ok
,
3289 bool alignspec_ok
, bool auto_type_ok
,
3290 bool start_std_attr_ok
, bool end_std_attr_ok
,
3291 enum c_lookahead_kind la
)
3293 bool attrs_ok
= start_attr_ok
;
3294 bool seen_type
= specs
->typespec_kind
!= ctsk_none
;
3297 gcc_assert (la
== cla_prefer_id
);
3299 if (start_std_attr_ok
3300 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3302 gcc_assert (!specs
->non_std_attrs_seen_p
);
3303 location_t loc
= c_parser_peek_token (parser
)->location
;
3304 tree attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3305 declspecs_add_attrs (loc
, specs
, attrs
);
3306 specs
->non_std_attrs_seen_p
= false;
3309 while (c_parser_next_token_is (parser
, CPP_NAME
)
3310 || c_parser_next_token_is (parser
, CPP_KEYWORD
)
3311 || (c_dialect_objc () && c_parser_next_token_is (parser
, CPP_LESS
)))
3313 struct c_typespec t
;
3316 location_t loc
= c_parser_peek_token (parser
)->location
;
3318 /* If we cannot accept a type, exit if the next token must start
3319 one. Also, if we already have seen a tagged definition,
3320 a typename would be an error anyway and likely the user
3321 has simply forgotten a semicolon, so we exit. */
3322 if ((!typespec_ok
|| specs
->typespec_kind
== ctsk_tagdef
)
3323 && c_parser_next_tokens_start_typename (parser
, la
)
3324 && !c_parser_next_token_is_qualifier (parser
)
3325 && !c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
))
3328 if (c_parser_next_token_is (parser
, CPP_NAME
))
3330 c_token
*name_token
= c_parser_peek_token (parser
);
3331 tree value
= name_token
->value
;
3332 c_id_kind kind
= name_token
->id_kind
;
3334 if (kind
== C_ID_ADDRSPACE
)
3337 = name_token
->keyword
- RID_FIRST_ADDR_SPACE
;
3338 declspecs_add_addrspace (name_token
->location
, specs
, as
);
3339 c_parser_consume_token (parser
);
3344 gcc_assert (!c_parser_next_token_is_qualifier (parser
));
3346 /* If we cannot accept a type, and the next token must start one,
3347 exit. Do the same if we already have seen a tagged definition,
3348 since it would be an error anyway and likely the user has simply
3349 forgotten a semicolon. */
3350 if (seen_type
|| !c_parser_next_tokens_start_typename (parser
, la
))
3353 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
3354 a C_ID_CLASSNAME. */
3355 c_parser_consume_token (parser
);
3358 if (kind
== C_ID_ID
)
3360 auto_diagnostic_group d
;
3361 name_hint hint
= lookup_name_fuzzy (value
, FUZZY_LOOKUP_TYPENAME
,
3363 if (const char *suggestion
= hint
.suggestion ())
3365 gcc_rich_location
richloc (loc
);
3366 richloc
.add_fixit_replace (suggestion
);
3368 "unknown type name %qE; did you mean %qs?",
3372 error_at (loc
, "unknown type name %qE", value
);
3373 t
.kind
= ctsk_typedef
;
3374 t
.spec
= error_mark_node
;
3376 else if (kind
== C_ID_TYPENAME
3377 && (!c_dialect_objc ()
3378 || c_parser_next_token_is_not (parser
, CPP_LESS
)))
3380 t
.kind
= ctsk_typedef
;
3381 /* For a typedef name, record the meaning, not the name.
3382 In case of 'foo foo, bar;'. */
3383 t
.spec
= lookup_name (value
);
3387 tree proto
= NULL_TREE
;
3388 gcc_assert (c_dialect_objc ());
3390 if (c_parser_next_token_is (parser
, CPP_LESS
))
3391 proto
= c_parser_objc_protocol_refs (parser
);
3392 t
.spec
= objc_get_protocol_qualified_type (value
, proto
);
3395 t
.expr_const_operands
= true;
3396 t
.has_enum_type_specifier
= false;
3397 declspecs_add_type (name_token
->location
, specs
, t
);
3400 if (c_parser_next_token_is (parser
, CPP_LESS
))
3402 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
3403 nisse@lysator.liu.se. */
3405 gcc_assert (c_dialect_objc ());
3406 if (!typespec_ok
|| seen_type
)
3408 proto
= c_parser_objc_protocol_refs (parser
);
3410 t
.spec
= objc_get_protocol_qualified_type (NULL_TREE
, proto
);
3412 t
.expr_const_operands
= true;
3413 t
.has_enum_type_specifier
= false;
3414 declspecs_add_type (loc
, specs
, t
);
3417 gcc_assert (c_parser_next_token_is (parser
, CPP_KEYWORD
));
3418 switch (c_parser_peek_token (parser
)->keyword
)
3432 /* TODO: Distinguish between function specifiers (inline, noreturn)
3433 and storage class specifiers, either here or in
3434 declspecs_add_scspec. */
3435 declspecs_add_scspec (loc
, specs
,
3436 c_parser_peek_token (parser
)->value
);
3437 c_parser_consume_token (parser
);
3469 if (c_dialect_objc ())
3470 parser
->objc_need_raw_identifier
= true;
3471 t
.kind
= ctsk_resword
;
3472 t
.spec
= c_parser_peek_token (parser
)->value
;
3474 t
.expr_const_operands
= true;
3475 t
.has_enum_type_specifier
= false;
3476 declspecs_add_type (loc
, specs
, t
);
3477 c_parser_consume_token (parser
);
3484 t
= c_parser_enum_specifier (parser
);
3485 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
3486 declspecs_add_type (loc
, specs
, t
);
3494 t
= c_parser_struct_or_union_specifier (parser
);
3495 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
3496 declspecs_add_type (loc
, specs
, t
);
3499 case RID_TYPEOF_UNQUAL
:
3500 /* ??? The old parser rejected typeof after other type
3501 specifiers, but is a syntax error the best way of
3503 if (!typespec_ok
|| seen_type
)
3507 t
= c_parser_typeof_specifier (parser
);
3508 declspecs_add_type (loc
, specs
, t
);
3517 t
.kind
= ctsk_resword
;
3518 t
.spec
= c_parser_peek_token (parser
)->value
;
3519 t
.expr
= error_mark_node
;
3520 t
.expr_const_operands
= true;
3521 t
.has_enum_type_specifier
= false;
3522 c_parser_consume_token (parser
);
3523 matching_parens parens
;
3524 if (parens
.require_open (parser
))
3526 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
3527 t
.expr
= convert_lvalue_to_rvalue (loc
, expr
, true,
3529 parens
.skip_until_found_close (parser
);
3531 declspecs_add_type (loc
, specs
, t
);
3535 /* C parser handling of Objective-C constructs needs
3536 checking for correct lvalue-to-rvalue conversions, and
3537 the code in build_modify_expr handling various
3538 Objective-C cases, and that in build_unary_op handling
3539 Objective-C cases for increment / decrement, also needs
3540 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3541 and objc_types_are_equivalent may also need updates. */
3542 if (c_dialect_objc ())
3543 sorry ("%<_Atomic%> in Objective-C");
3545 pedwarn_c99 (loc
, OPT_Wpedantic
,
3546 "ISO C99 does not support the %<_Atomic%> qualifier");
3548 pedwarn_c99 (loc
, OPT_Wpedantic
,
3549 "ISO C90 does not support the %<_Atomic%> qualifier");
3552 value
= c_parser_peek_token (parser
)->value
;
3553 c_parser_consume_token (parser
);
3554 if (typespec_ok
&& c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3556 /* _Atomic ( type-name ). */
3558 c_parser_consume_token (parser
);
3559 struct c_type_name
*type
= c_parser_type_name (parser
);
3560 t
.kind
= ctsk_typeof
;
3561 t
.spec
= error_mark_node
;
3563 t
.expr_const_operands
= true;
3564 t
.has_enum_type_specifier
= false;
3566 t
.spec
= groktypename (type
, &t
.expr
,
3567 &t
.expr_const_operands
);
3568 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3570 if (t
.spec
!= error_mark_node
)
3572 if (TREE_CODE (t
.spec
) == ARRAY_TYPE
)
3573 error_at (loc
, "%<_Atomic%>-qualified array type");
3574 else if (TREE_CODE (t
.spec
) == FUNCTION_TYPE
)
3575 error_at (loc
, "%<_Atomic%>-qualified function type");
3576 else if (TYPE_QUALS (t
.spec
) != TYPE_UNQUALIFIED
)
3577 error_at (loc
, "%<_Atomic%> applied to a qualified type");
3579 t
.spec
= c_build_qualified_type (t
.spec
, TYPE_QUAL_ATOMIC
);
3581 declspecs_add_type (loc
, specs
, t
);
3584 declspecs_add_qual (loc
, specs
, value
);
3590 declspecs_add_qual (loc
, specs
, c_parser_peek_token (parser
)->value
);
3591 c_parser_consume_token (parser
);
3596 attrs
= c_parser_gnu_attributes (parser
);
3597 declspecs_add_attrs (loc
, specs
, attrs
);
3602 align
= c_parser_alignas_specifier (parser
);
3603 declspecs_add_alignas (loc
, specs
, align
);
3607 error_at (loc
, "%<__GIMPLE%> only valid with %<-fgimple%>");
3608 c_parser_consume_token (parser
);
3609 specs
->declspec_il
= cdil_gimple
;
3610 specs
->locations
[cdw_gimple
] = loc
;
3611 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3614 c_parser_consume_token (parser
);
3615 specs
->declspec_il
= cdil_rtl
;
3616 specs
->locations
[cdw_rtl
] = loc
;
3617 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3625 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3626 specs
->postfix_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3629 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3632 enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3633 { enumerator-list } gnu-attributes[opt]
3634 enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3635 { enumerator-list , } gnu-attributes[opt] enum-type-specifier[opt]
3636 enum gnu-attributes[opt] identifier
3638 The form with trailing comma is new in C99; enum-type-specifiers
3639 are new in C23. The forms with gnu-attributes are GNU extensions.
3640 In GNU C, we accept any expression without commas in the syntax
3641 (assignment expressions, not just conditional expressions);
3642 assignment expressions will be diagnosed as non-constant.
3644 enum-type-specifier:
3645 : specifier-qualifier-list
3649 enumerator-list , enumerator
3652 enumeration-constant attribute-specifier-sequence[opt]
3653 enumeration-constant attribute-specifier-sequence[opt]
3654 = constant-expression
3659 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3660 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3661 = constant-expression
3665 static struct c_typespec
3666 c_parser_enum_specifier (c_parser
*parser
)
3668 struct c_typespec ret
;
3669 bool have_std_attrs
;
3670 bool potential_nesting_p
= false;
3671 tree std_attrs
= NULL_TREE
;
3673 tree ident
= NULL_TREE
;
3674 tree fixed_underlying_type
= NULL_TREE
;
3675 location_t enum_loc
;
3676 location_t ident_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3677 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ENUM
));
3678 c_parser_consume_token (parser
);
3679 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3681 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3682 attrs
= c_parser_gnu_attributes (parser
);
3683 enum_loc
= c_parser_peek_token (parser
)->location
;
3684 /* Set the location in case we create a decl now. */
3685 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3686 if (c_parser_next_token_is (parser
, CPP_NAME
))
3688 ident
= c_parser_peek_token (parser
)->value
;
3689 ident_loc
= c_parser_peek_token (parser
)->location
;
3690 enum_loc
= ident_loc
;
3691 c_parser_consume_token (parser
);
3693 if (c_parser_next_token_is (parser
, CPP_COLON
)
3694 /* Distinguish an enum-type-specifier from a bit-field
3695 declaration of the form "enum e : constant-expression;". */
3696 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
3698 pedwarn_c11 (enum_loc
, OPT_Wpedantic
,
3699 "ISO C does not support specifying %<enum%> underlying "
3700 "types before C23");
3703 /* The tag is in scope during the enum-type-specifier (which
3704 may refer to the tag inside typeof). */
3705 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
,
3706 have_std_attrs
, std_attrs
, true);
3707 if (!ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
))
3708 error_at (enum_loc
, "%<enum%> declared both with and without "
3709 "fixed underlying type");
3710 potential_nesting_p
= NULL_TREE
== TYPE_VALUES (ret
.spec
);
3714 /* There must be an enum definition, so this initialization
3715 (to avoid possible warnings about uninitialized data)
3716 will be replaced later (either with the results of that
3717 definition, or with the results of error handling for the
3718 case of no tag and no definition). */
3719 ret
.spec
= NULL_TREE
;
3720 ret
.kind
= ctsk_tagdef
;
3721 ret
.expr
= NULL_TREE
;
3722 ret
.expr_const_operands
= true;
3723 ret
.has_enum_type_specifier
= true;
3725 c_parser_consume_token (parser
);
3726 struct c_declspecs
*specs
= build_null_declspecs ();
3727 c_parser_declspecs (parser
, specs
, false, true, false, false, false,
3728 false, true, cla_prefer_id
);
3729 finish_declspecs (specs
);
3730 if (specs
->default_int_p
)
3731 error_at (enum_loc
, "no %<enum%> underlying type specified");
3732 else if (TREE_CODE (specs
->type
) != INTEGER_TYPE
3733 && TREE_CODE (specs
->type
) != BOOLEAN_TYPE
)
3735 error_at (enum_loc
, "invalid %<enum%> underlying type");
3736 specs
->type
= integer_type_node
;
3738 else if (specs
->restrict_p
)
3739 error_at (enum_loc
, "invalid use of %<restrict%>");
3740 fixed_underlying_type
= TYPE_MAIN_VARIANT (specs
->type
);
3743 /* The type specified must be consistent with any previously
3744 specified underlying type. If this is a newly declared
3745 type, it is now a complete type. */
3746 if (ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
)
3747 && ENUM_UNDERLYING_TYPE (ret
.spec
) == NULL_TREE
)
3749 TYPE_MIN_VALUE (ret
.spec
) =
3750 TYPE_MIN_VALUE (fixed_underlying_type
);
3751 TYPE_MAX_VALUE (ret
.spec
) =
3752 TYPE_MAX_VALUE (fixed_underlying_type
);
3753 TYPE_UNSIGNED (ret
.spec
) = TYPE_UNSIGNED (fixed_underlying_type
);
3754 SET_TYPE_ALIGN (ret
.spec
, TYPE_ALIGN (fixed_underlying_type
));
3755 TYPE_SIZE (ret
.spec
) = NULL_TREE
;
3756 TYPE_PRECISION (ret
.spec
) =
3757 TYPE_PRECISION (fixed_underlying_type
);
3758 ENUM_UNDERLYING_TYPE (ret
.spec
) = fixed_underlying_type
;
3759 layout_type (ret
.spec
);
3761 else if (ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
)
3762 && !comptypes (fixed_underlying_type
,
3763 ENUM_UNDERLYING_TYPE (ret
.spec
)))
3765 error_at (enum_loc
, "%<enum%> underlying type incompatible with "
3766 "previous declaration");
3767 fixed_underlying_type
= ENUM_UNDERLYING_TYPE (ret
.spec
);
3771 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3773 /* Parse an enum definition. */
3774 struct c_enum_contents the_enum
;
3777 /* We chain the enumerators in reverse order, then put them in
3778 forward order at the end. */
3780 timevar_push (TV_PARSE_ENUM
);
3781 type
= start_enum (enum_loc
, &the_enum
, ident
, fixed_underlying_type
,
3782 potential_nesting_p
);
3784 c_parser_consume_token (parser
);
3792 location_t comma_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3793 location_t decl_loc
, value_loc
;
3794 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
3796 /* Give a nicer error for "enum {}". */
3797 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3800 error_at (c_parser_peek_token (parser
)->location
,
3801 "empty enum is invalid");
3802 parser
->error
= true;
3805 c_parser_error (parser
, "expected identifier");
3806 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3807 values
= error_mark_node
;
3810 token
= c_parser_peek_token (parser
);
3811 enum_id
= token
->value
;
3812 /* Set the location in case we create a decl now. */
3813 c_parser_set_source_position_from_token (token
);
3814 decl_loc
= value_loc
= token
->location
;
3815 c_parser_consume_token (parser
);
3816 /* Parse any specified attributes. */
3817 tree std_attrs
= NULL_TREE
;
3818 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3819 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3820 tree enum_attrs
= chainon (std_attrs
,
3821 c_parser_gnu_attributes (parser
));
3822 if (c_parser_next_token_is (parser
, CPP_EQ
))
3824 c_parser_consume_token (parser
);
3825 value_loc
= c_parser_peek_token (parser
)->location
;
3826 enum_value
= convert_lvalue_to_rvalue (value_loc
,
3827 (c_parser_expr_no_commas
3832 enum_value
= NULL_TREE
;
3833 enum_decl
= build_enumerator (decl_loc
, value_loc
,
3834 &the_enum
, enum_id
, enum_value
);
3836 decl_attributes (&TREE_PURPOSE (enum_decl
), enum_attrs
, 0);
3837 TREE_CHAIN (enum_decl
) = values
;
3840 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3842 comma_loc
= c_parser_peek_token (parser
)->location
;
3844 c_parser_consume_token (parser
);
3846 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3849 pedwarn_c90 (comma_loc
, OPT_Wpedantic
,
3850 "comma at end of enumerator list");
3851 c_parser_consume_token (parser
);
3856 c_parser_error (parser
, "expected %<,%> or %<}%>");
3857 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3858 values
= error_mark_node
;
3862 postfix_attrs
= c_parser_gnu_attributes (parser
);
3863 ret
.spec
= finish_enum (type
, nreverse (values
),
3865 chainon (attrs
, postfix_attrs
)));
3866 ret
.kind
= ctsk_tagdef
;
3867 ret
.expr
= NULL_TREE
;
3868 ret
.expr_const_operands
= true;
3869 ret
.has_enum_type_specifier
= fixed_underlying_type
!= NULL_TREE
;
3870 timevar_pop (TV_PARSE_ENUM
);
3875 c_parser_error (parser
, "expected %<{%>");
3876 ret
.spec
= error_mark_node
;
3877 ret
.kind
= ctsk_tagref
;
3878 ret
.expr
= NULL_TREE
;
3879 ret
.expr_const_operands
= true;
3880 ret
.has_enum_type_specifier
= false;
3883 /* Attributes may only appear when the members are defined or in
3884 certain forward declarations (treat enum forward declarations in
3885 GNU C analogously to struct and union forward declarations in
3887 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3888 c_parser_error (parser
, "expected %<;%>");
3889 if (fixed_underlying_type
== NULL_TREE
)
3891 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
, have_std_attrs
,
3893 /* In ISO C, enumerated types without a fixed underlying type
3894 can be referred to only if already defined. */
3895 if (pedantic
&& !COMPLETE_TYPE_P (ret
.spec
))
3898 pedwarn (enum_loc
, OPT_Wpedantic
,
3899 "ISO C forbids forward references to %<enum%> types");
3905 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3907 struct-or-union-specifier:
3908 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3909 identifier[opt] { struct-contents } gnu-attributes[opt]
3910 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3914 struct-declaration-list
3916 struct-declaration-list:
3917 struct-declaration ;
3918 struct-declaration-list struct-declaration ;
3925 struct-declaration-list struct-declaration
3927 struct-declaration-list:
3928 struct-declaration-list ;
3931 (Note that in the syntax here, unlike that in ISO C, the semicolons
3932 are included here rather than in struct-declaration, in order to
3933 describe the syntax with extra semicolons and missing semicolon at
3938 struct-declaration-list:
3939 @defs ( class-name )
3941 (Note this does not include a trailing semicolon, but can be
3942 followed by further declarations, and gets a pedwarn-if-pedantic
3943 when followed by a semicolon.) */
3945 static struct c_typespec
3946 c_parser_struct_or_union_specifier (c_parser
*parser
)
3948 struct c_typespec ret
;
3949 bool have_std_attrs
;
3950 tree std_attrs
= NULL_TREE
;
3952 tree ident
= NULL_TREE
;
3953 location_t struct_loc
;
3954 location_t ident_loc
= UNKNOWN_LOCATION
;
3955 enum tree_code code
;
3956 switch (c_parser_peek_token (parser
)->keyword
)
3967 struct_loc
= c_parser_peek_token (parser
)->location
;
3968 c_parser_consume_token (parser
);
3969 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3971 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3972 attrs
= c_parser_gnu_attributes (parser
);
3974 /* Set the location in case we create a decl now. */
3975 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3977 if (c_parser_next_token_is (parser
, CPP_NAME
))
3979 ident
= c_parser_peek_token (parser
)->value
;
3980 ident_loc
= c_parser_peek_token (parser
)->location
;
3981 struct_loc
= ident_loc
;
3982 c_parser_consume_token (parser
);
3984 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3986 /* Parse a struct or union definition. Start the scope of the
3987 tag before parsing components. */
3988 class c_struct_parse_info
*struct_info
;
3989 tree type
= start_struct (struct_loc
, code
, ident
, &struct_info
);
3991 /* We chain the components in reverse order, then put them in
3992 forward order at the end. Each struct-declaration may
3993 declare multiple components (comma-separated), so we must use
3994 chainon to join them, although when parsing each
3995 struct-declaration we can use TREE_CHAIN directly.
3997 The theory behind all this is that there will be more
3998 semicolon separated fields than comma separated fields, and
3999 so we'll be minimizing the number of node traversals required
4003 timevar_push (TV_PARSE_STRUCT
);
4004 contents
= NULL_TREE
;
4005 c_parser_consume_token (parser
);
4006 /* Handle the Objective-C @defs construct,
4007 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
4008 if (c_parser_next_token_is_keyword (parser
, RID_AT_DEFS
))
4011 gcc_assert (c_dialect_objc ());
4012 c_parser_consume_token (parser
);
4013 matching_parens parens
;
4014 if (!parens
.require_open (parser
))
4016 if (c_parser_next_token_is (parser
, CPP_NAME
)
4017 && c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
)
4019 name
= c_parser_peek_token (parser
)->value
;
4020 c_parser_consume_token (parser
);
4024 c_parser_error (parser
, "expected class name");
4025 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4028 parens
.skip_until_found_close (parser
);
4029 contents
= nreverse (objc_get_class_ivars (name
));
4032 /* Parse the struct-declarations and semicolons. Problems with
4033 semicolons are diagnosed here; empty structures are diagnosed
4038 /* Parse any stray semicolon. */
4039 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4041 location_t semicolon_loc
4042 = c_parser_peek_token (parser
)->location
;
4043 gcc_rich_location
richloc (semicolon_loc
);
4044 richloc
.add_fixit_remove ();
4045 pedwarn (&richloc
, OPT_Wpedantic
,
4046 "extra semicolon in struct or union specified");
4047 c_parser_consume_token (parser
);
4050 /* Stop if at the end of the struct or union contents. */
4051 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4053 c_parser_consume_token (parser
);
4056 /* Accept #pragmas at struct scope. */
4057 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
4059 c_parser_pragma (parser
, pragma_struct
, NULL
);
4062 /* Parse some comma-separated declarations, but not the
4063 trailing semicolon if any. */
4064 decls
= c_parser_struct_declaration (parser
, &expr
);
4065 contents
= chainon (decls
, contents
);
4066 /* If no semicolon follows, either we have a parse error or
4067 are at the end of the struct or union and should
4069 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4070 c_parser_consume_token (parser
);
4073 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4074 pedwarn (c_parser_peek_token (parser
)->location
, 0,
4075 "no semicolon at end of struct or union");
4076 else if (parser
->error
4077 || !c_parser_next_token_starts_declspecs (parser
))
4079 c_parser_error (parser
, "expected %<;%>");
4080 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
4084 /* If we come here, we have already emitted an error
4085 for an expected `;', identifier or `(', and we also
4086 recovered already. Go on with the next field. */
4089 postfix_attrs
= c_parser_gnu_attributes (parser
);
4090 ret
.spec
= finish_struct (struct_loc
, type
, nreverse (contents
),
4092 chainon (attrs
, postfix_attrs
)),
4093 struct_info
, &expr
);
4094 ret
.kind
= ctsk_tagdef
;
4096 ret
.expr_const_operands
= true;
4097 ret
.has_enum_type_specifier
= false;
4098 timevar_pop (TV_PARSE_STRUCT
);
4103 c_parser_error (parser
, "expected %<{%>");
4104 ret
.spec
= error_mark_node
;
4105 ret
.kind
= ctsk_tagref
;
4106 ret
.expr
= NULL_TREE
;
4107 ret
.expr_const_operands
= true;
4108 ret
.has_enum_type_specifier
= false;
4111 /* Attributes may only appear when the members are defined or in
4112 certain forward declarations. */
4113 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
4114 c_parser_error (parser
, "expected %<;%>");
4115 /* ??? Existing practice is that GNU attributes are ignored after
4116 the struct or union keyword when not defining the members. */
4117 ret
= parser_xref_tag (ident_loc
, code
, ident
, have_std_attrs
, std_attrs
,
4122 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
4123 *without* the trailing semicolon.
4126 attribute-specifier-sequence[opt] specifier-qualifier-list
4127 attribute-specifier-sequence[opt] struct-declarator-list
4128 static_assert-declaration-no-semi
4130 specifier-qualifier-list:
4131 type-specifier specifier-qualifier-list[opt]
4132 type-qualifier specifier-qualifier-list[opt]
4133 alignment-specifier specifier-qualifier-list[opt]
4134 gnu-attributes specifier-qualifier-list[opt]
4136 struct-declarator-list:
4138 struct-declarator-list , gnu-attributes[opt] struct-declarator
4141 declarator gnu-attributes[opt]
4142 declarator[opt] : constant-expression gnu-attributes[opt]
4147 __extension__ struct-declaration
4148 specifier-qualifier-list
4150 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
4151 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
4152 any expression without commas in the syntax (assignment
4153 expressions, not just conditional expressions); assignment
4154 expressions will be diagnosed as non-constant. */
4157 c_parser_struct_declaration (c_parser
*parser
, tree
*expr
)
4159 struct c_declspecs
*specs
;
4161 tree all_prefix_attrs
;
4163 location_t decl_loc
;
4164 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
4168 ext
= disable_extension_diagnostics ();
4169 c_parser_consume_token (parser
);
4170 decl
= c_parser_struct_declaration (parser
, expr
);
4171 restore_extension_diagnostics (ext
);
4174 if (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
4176 c_parser_static_assert_declaration_no_semi (parser
);
4179 specs
= build_null_declspecs ();
4180 decl_loc
= c_parser_peek_token (parser
)->location
;
4181 /* Strictly by the standard, we shouldn't allow _Alignas here,
4182 but it appears to have been intended to allow it there, so
4183 we're keeping it as it is until WG14 reaches a conclusion
4185 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
4186 c_parser_declspecs (parser
, specs
, false, true, true,
4187 true, false, true, true, cla_nonabstract_decl
);
4190 if (!specs
->declspecs_seen_p
)
4192 c_parser_error (parser
, "expected specifier-qualifier-list");
4195 finish_declspecs (specs
);
4196 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
4197 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4200 if (specs
->typespec_kind
== ctsk_none
)
4202 pedwarn (decl_loc
, OPT_Wpedantic
,
4203 "ISO C forbids member declarations with no members");
4204 shadow_tag_warned (specs
, pedantic
);
4209 /* Support for unnamed structs or unions as members of
4210 structs or unions (which is [a] useful and [b] supports
4214 ret
= grokfield (c_parser_peek_token (parser
)->location
,
4215 build_id_declarator (NULL_TREE
), specs
,
4216 NULL_TREE
, &attrs
, expr
);
4218 decl_attributes (&ret
, attrs
, 0);
4223 /* Provide better error recovery. Note that a type name here is valid,
4224 and will be treated as a field name. */
4225 if (specs
->typespec_kind
== ctsk_tagdef
4226 && TREE_CODE (specs
->type
) != ENUMERAL_TYPE
4227 && c_parser_next_token_starts_declspecs (parser
)
4228 && !c_parser_next_token_is (parser
, CPP_NAME
))
4230 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
4231 parser
->error
= false;
4235 pending_xref_error ();
4236 prefix_attrs
= specs
->attrs
;
4237 all_prefix_attrs
= prefix_attrs
;
4238 specs
->attrs
= NULL_TREE
;
4242 /* Declaring one or more declarators or un-named bit-fields. */
4243 struct c_declarator
*declarator
;
4245 if (c_parser_next_token_is (parser
, CPP_COLON
))
4246 declarator
= build_id_declarator (NULL_TREE
);
4248 declarator
= c_parser_declarator (parser
,
4249 specs
->typespec_kind
!= ctsk_none
,
4250 C_DTR_NORMAL
, &dummy
);
4251 if (declarator
== NULL
)
4253 c_parser_skip_to_end_of_block_or_statement (parser
);
4256 if (c_parser_next_token_is (parser
, CPP_COLON
)
4257 || c_parser_next_token_is (parser
, CPP_COMMA
)
4258 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
4259 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
4260 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4262 tree postfix_attrs
= NULL_TREE
;
4263 tree width
= NULL_TREE
;
4265 if (c_parser_next_token_is (parser
, CPP_COLON
))
4267 c_parser_consume_token (parser
);
4268 location_t loc
= c_parser_peek_token (parser
)->location
;
4269 width
= convert_lvalue_to_rvalue (loc
,
4270 (c_parser_expr_no_commas
4274 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4275 postfix_attrs
= c_parser_gnu_attributes (parser
);
4276 d
= grokfield (c_parser_peek_token (parser
)->location
,
4277 declarator
, specs
, width
, &all_prefix_attrs
, expr
);
4278 decl_attributes (&d
, chainon (postfix_attrs
,
4279 all_prefix_attrs
), 0);
4280 DECL_CHAIN (d
) = decls
;
4282 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4283 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
4286 all_prefix_attrs
= prefix_attrs
;
4287 if (c_parser_next_token_is (parser
, CPP_COMMA
))
4288 c_parser_consume_token (parser
);
4289 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
4290 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4292 /* Semicolon consumed in caller. */
4297 c_parser_error (parser
, "expected %<,%>, %<;%> or %<}%>");
4303 c_parser_error (parser
,
4304 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
4305 "%<__attribute__%>");
4312 /* Parse a typeof specifier (a GNU extension adopted in C23).
4315 typeof ( expression )
4316 typeof ( type-name )
4317 typeof_unqual ( expression )
4318 typeof_unqual ( type-name )
4321 static struct c_typespec
4322 c_parser_typeof_specifier (c_parser
*parser
)
4326 struct c_typespec ret
;
4327 ret
.kind
= ctsk_typeof
;
4328 ret
.spec
= error_mark_node
;
4329 ret
.expr
= NULL_TREE
;
4330 ret
.expr_const_operands
= true;
4331 ret
.has_enum_type_specifier
= false;
4332 if (c_parser_next_token_is_keyword (parser
, RID_TYPEOF
))
4335 tree spelling
= c_parser_peek_token (parser
)->value
;
4336 is_std
= (flag_isoc23
4337 && strcmp (IDENTIFIER_POINTER (spelling
), "typeof") == 0);
4341 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TYPEOF_UNQUAL
));
4343 tree spelling
= c_parser_peek_token (parser
)->value
;
4344 is_std
= strcmp (IDENTIFIER_POINTER (spelling
), "typeof_unqual") == 0;
4346 c_parser_consume_token (parser
);
4347 c_inhibit_evaluation_warnings
++;
4349 matching_parens parens
;
4350 if (!parens
.require_open (parser
))
4352 c_inhibit_evaluation_warnings
--;
4356 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
4358 struct c_type_name
*type
= c_parser_type_name (parser
);
4359 c_inhibit_evaluation_warnings
--;
4363 ret
.spec
= groktypename (type
, &ret
.expr
, &ret
.expr_const_operands
);
4364 pop_maybe_used (c_type_variably_modified_p (ret
.spec
));
4370 location_t here
= c_parser_peek_token (parser
)->location
;
4371 struct c_expr expr
= c_parser_expression (parser
);
4372 c_inhibit_evaluation_warnings
--;
4374 if (TREE_CODE (expr
.value
) == COMPONENT_REF
4375 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
4376 error_at (here
, "%<typeof%> applied to a bit-field");
4377 mark_exp_read (expr
.value
);
4378 ret
.spec
= TREE_TYPE (expr
.value
);
4379 was_vm
= c_type_variably_modified_p (ret
.spec
);
4380 /* This is returned with the type so that when the type is
4381 evaluated, this can be evaluated. */
4383 ret
.expr
= c_fully_fold (expr
.value
, false, &ret
.expr_const_operands
);
4384 pop_maybe_used (was_vm
);
4386 parens
.skip_until_found_close (parser
);
4387 if (ret
.spec
!= error_mark_node
)
4389 if (is_unqual
&& TYPE_QUALS (ret
.spec
) != TYPE_UNQUALIFIED
)
4390 ret
.spec
= TYPE_MAIN_VARIANT (ret
.spec
);
4393 /* In ISO C terms, _Noreturn is not part of the type of
4394 expressions such as &abort, but in GCC it is represented
4395 internally as a type qualifier. */
4396 if (TREE_CODE (ret
.spec
) == FUNCTION_TYPE
4397 && TYPE_QUALS (ret
.spec
) != TYPE_UNQUALIFIED
)
4398 ret
.spec
= TYPE_MAIN_VARIANT (ret
.spec
);
4399 else if (FUNCTION_POINTER_TYPE_P (ret
.spec
)
4400 && TYPE_QUALS (TREE_TYPE (ret
.spec
)) != TYPE_UNQUALIFIED
)
4402 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (ret
.spec
)));
4408 /* Parse an alignment-specifier.
4412 alignment-specifier:
4413 _Alignas ( type-name )
4414 _Alignas ( constant-expression )
4418 c_parser_alignas_specifier (c_parser
* parser
)
4420 tree ret
= error_mark_node
;
4421 location_t loc
= c_parser_peek_token (parser
)->location
;
4422 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
));
4423 tree spelling
= c_parser_peek_token (parser
)->value
;
4424 c_parser_consume_token (parser
);
4426 pedwarn_c99 (loc
, OPT_Wpedantic
,
4427 "ISO C99 does not support %qE", spelling
);
4429 pedwarn_c99 (loc
, OPT_Wpedantic
,
4430 "ISO C90 does not support %qE", spelling
);
4431 matching_parens parens
;
4432 if (!parens
.require_open (parser
))
4434 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
4436 struct c_type_name
*type
= c_parser_type_name (parser
);
4438 ret
= c_sizeof_or_alignof_type (loc
, groktypename (type
, NULL
, NULL
),
4442 ret
= convert_lvalue_to_rvalue (loc
,
4443 c_parser_expr_no_commas (parser
, NULL
),
4445 parens
.skip_until_found_close (parser
);
4449 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
4450 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
4451 a typedef name may be redeclared; otherwise it may not. KIND
4452 indicates which kind of declarator is wanted. Returns a valid
4453 declarator except in the case of a syntax error in which case NULL is
4454 returned. *SEEN_ID is set to true if an identifier being declared is
4455 seen; this is used to diagnose bad forms of abstract array declarators
4456 and to determine whether an identifier list is syntactically permitted.
4459 pointer[opt] direct-declarator
4463 ( gnu-attributes[opt] declarator )
4464 direct-declarator array-declarator
4465 direct-declarator ( parameter-type-list )
4466 direct-declarator ( identifier-list[opt] )
4469 * type-qualifier-list[opt]
4470 * type-qualifier-list[opt] pointer
4472 type-qualifier-list:
4475 type-qualifier-list type-qualifier
4476 type-qualifier-list gnu-attributes
4479 [ type-qualifier-list[opt] assignment-expression[opt] ]
4480 [ static type-qualifier-list[opt] assignment-expression ]
4481 [ type-qualifier-list static assignment-expression ]
4482 [ type-qualifier-list[opt] * ]
4484 parameter-type-list:
4486 parameter-list , ...
4489 parameter-declaration
4490 parameter-list , parameter-declaration
4492 parameter-declaration:
4493 declaration-specifiers declarator gnu-attributes[opt]
4494 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
4498 identifier-list , identifier
4500 abstract-declarator:
4502 pointer[opt] direct-abstract-declarator
4504 direct-abstract-declarator:
4505 ( gnu-attributes[opt] abstract-declarator )
4506 direct-abstract-declarator[opt] array-declarator
4507 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
4512 direct-declarator ( parameter-forward-declarations
4513 parameter-type-list[opt] )
4515 direct-abstract-declarator:
4516 direct-abstract-declarator[opt] ( parameter-forward-declarations
4517 parameter-type-list[opt] )
4519 parameter-forward-declarations:
4521 parameter-forward-declarations parameter-list ;
4523 The uses of gnu-attributes shown above are GNU extensions.
4525 Some forms of array declarator are not included in C99 in the
4526 syntax for abstract declarators; these are disallowed elsewhere.
4527 This may be a defect (DR#289).
4529 This function also accepts an omitted abstract declarator as being
4530 an abstract declarator, although not part of the formal syntax. */
4532 struct c_declarator
*
4533 c_parser_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
4536 /* Parse any initial pointer part. */
4537 if (c_parser_next_token_is (parser
, CPP_MULT
))
4539 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4540 struct c_declarator
*inner
;
4541 c_parser_consume_token (parser
);
4542 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4543 false, false, true, false, cla_prefer_id
);
4544 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4548 return make_pointer_declarator (quals_attrs
, inner
);
4550 /* Now we have a direct declarator, direct abstract declarator or
4551 nothing (which counts as a direct abstract declarator here). */
4552 return c_parser_direct_declarator (parser
, type_seen_p
, kind
, seen_id
);
4555 /* Parse a direct declarator or direct abstract declarator; arguments
4556 as c_parser_declarator. */
4558 static struct c_declarator
*
4559 c_parser_direct_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
4562 /* The direct declarator must start with an identifier (possibly
4563 omitted) or a parenthesized declarator (possibly abstract). In
4564 an ordinary declarator, initial parentheses must start a
4565 parenthesized declarator. In an abstract declarator or parameter
4566 declarator, they could start a parenthesized declarator or a
4567 parameter list. To tell which, the open parenthesis and any
4568 following gnu-attributes must be read. If a declaration
4569 specifier or standard attributes follow, then it is a parameter
4570 list; if the specifier is a typedef name, there might be an
4571 ambiguity about redeclaring it, which is resolved in the
4572 direction of treating it as a typedef name. If a close
4573 parenthesis follows, it is also an empty parameter list, as the
4574 syntax does not permit empty abstract declarators. Otherwise, it
4575 is a parenthesized declarator (in which case the analysis may be
4576 repeated inside it, recursively).
4578 ??? There is an ambiguity in a parameter declaration "int
4579 (__attribute__((foo)) x)", where x is not a typedef name: it
4580 could be an abstract declarator for a function, or declare x with
4581 parentheses. The proper resolution of this ambiguity needs
4582 documenting. At present we follow an accident of the old
4583 parser's implementation, whereby the first parameter must have
4584 some declaration specifiers other than just gnu-attributes. Thus as
4585 a parameter declaration it is treated as a parenthesized
4586 parameter named x, and as an abstract declarator it is
4589 ??? Also following the old parser, gnu-attributes inside an empty
4590 parameter list are ignored, making it a list not yielding a
4591 prototype, rather than giving an error or making it have one
4592 parameter with implicit type int.
4594 ??? Also following the old parser, typedef names may be
4595 redeclared in declarators, but not Objective-C class names. */
4597 if (kind
!= C_DTR_ABSTRACT
4598 && c_parser_next_token_is (parser
, CPP_NAME
)
4600 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
4601 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
4602 || c_parser_peek_token (parser
)->id_kind
== C_ID_ID
))
4604 struct c_declarator
*inner
4605 = build_id_declarator (c_parser_peek_token (parser
)->value
);
4607 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
4608 c_parser_consume_token (parser
);
4609 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4610 inner
->u
.id
.attrs
= c_parser_std_attribute_specifier_sequence (parser
);
4611 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4614 if (kind
!= C_DTR_NORMAL
4615 && c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4616 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4618 struct c_declarator
*inner
= build_id_declarator (NULL_TREE
);
4619 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
4620 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4623 /* Either we are at the end of an abstract declarator, or we have
4626 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4629 struct c_declarator
*inner
;
4630 c_parser_consume_token (parser
);
4631 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4633 attrs
= c_parser_gnu_attributes (parser
);
4634 if (kind
!= C_DTR_NORMAL
4635 && (c_parser_next_token_starts_declspecs (parser
)
4637 && (c_parser_nth_token_starts_std_attributes (parser
, 1)
4638 || c_parser_next_token_is (parser
, CPP_ELLIPSIS
)))
4639 || c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
)))
4641 struct c_arg_info
*args
4642 = c_parser_parms_declarator (parser
, kind
== C_DTR_NORMAL
,
4643 attrs
, have_gnu_attrs
);
4648 inner
= build_id_declarator (NULL_TREE
);
4650 && args
->types
!= error_mark_node
4651 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4652 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4655 = c_parser_std_attribute_specifier_sequence (parser
);
4657 inner
= build_attrs_declarator (std_attrs
, inner
);
4659 inner
= build_function_declarator (args
, inner
);
4660 return c_parser_direct_declarator_inner (parser
, *seen_id
,
4664 /* A parenthesized declarator. */
4665 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4666 if (inner
!= NULL
&& attrs
!= NULL
)
4667 inner
= build_attrs_declarator (attrs
, inner
);
4668 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4670 c_parser_consume_token (parser
);
4674 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4678 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4685 if (kind
== C_DTR_NORMAL
)
4687 c_parser_error (parser
, "expected identifier or %<(%>");
4691 return build_id_declarator (NULL_TREE
);
4695 /* Parse part of a direct declarator or direct abstract declarator,
4696 given that some (in INNER) has already been parsed; ID_PRESENT is
4697 true if an identifier is present, false for an abstract
4700 static struct c_declarator
*
4701 c_parser_direct_declarator_inner (c_parser
*parser
, bool id_present
,
4702 struct c_declarator
*inner
)
4704 /* Parse a sequence of array declarators and parameter lists. */
4705 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4706 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4708 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
4709 struct c_declarator
*declarator
;
4710 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4713 struct c_expr dimen
;
4714 dimen
.value
= NULL_TREE
;
4715 dimen
.original_code
= ERROR_MARK
;
4716 dimen
.original_type
= NULL_TREE
;
4717 c_parser_consume_token (parser
);
4718 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4719 false, false, false, false, cla_prefer_id
);
4720 static_seen
= c_parser_next_token_is_keyword (parser
, RID_STATIC
);
4722 c_parser_consume_token (parser
);
4723 if (static_seen
&& !quals_attrs
->declspecs_seen_p
)
4724 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4725 false, false, false, false, cla_prefer_id
);
4726 if (!quals_attrs
->declspecs_seen_p
)
4728 /* If "static" is present, there must be an array dimension.
4729 Otherwise, there may be a dimension, "*", or no
4734 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4738 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4740 dimen
.value
= NULL_TREE
;
4743 else if (c_parser_next_token_is (parser
, CPP_MULT
))
4745 if (c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_SQUARE
)
4747 dimen
.value
= NULL_TREE
;
4749 c_parser_consume_token (parser
);
4754 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4760 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4763 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4764 c_parser_consume_token (parser
);
4767 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4772 dimen
= convert_lvalue_to_rvalue (brace_loc
, dimen
, true, true);
4773 declarator
= build_array_declarator (brace_loc
, dimen
.value
, quals_attrs
,
4774 static_seen
, star_seen
);
4775 if (declarator
== NULL
)
4777 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4780 = c_parser_std_attribute_specifier_sequence (parser
);
4782 inner
= build_attrs_declarator (std_attrs
, inner
);
4784 inner
= set_array_declarator_inner (declarator
, inner
);
4785 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4787 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4790 struct c_arg_info
*args
;
4791 c_parser_consume_token (parser
);
4792 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4794 attrs
= c_parser_gnu_attributes (parser
);
4795 args
= c_parser_parms_declarator (parser
, id_present
, attrs
,
4802 && args
->types
!= error_mark_node
4803 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4804 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4807 = c_parser_std_attribute_specifier_sequence (parser
);
4809 inner
= build_attrs_declarator (std_attrs
, inner
);
4811 inner
= build_function_declarator (args
, inner
);
4812 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4818 /* Parse a parameter list or identifier list, including the closing
4819 parenthesis but not the opening one. ATTRS are the gnu-attributes
4820 at the start of the list. ID_LIST_OK is true if an identifier list
4821 is acceptable; such a list must not have attributes at the start.
4822 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4823 attributes) were present (in which case standard attributes cannot
4826 static struct c_arg_info
*
4827 c_parser_parms_declarator (c_parser
*parser
, bool id_list_ok
, tree attrs
,
4828 bool have_gnu_attrs
)
4831 declare_parm_level ();
4832 /* If the list starts with an identifier, it is an identifier list.
4833 Otherwise, it is either a prototype list or an empty list. */
4836 && c_parser_next_token_is (parser
, CPP_NAME
)
4837 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4839 /* Look ahead to detect typos in type names. */
4840 && c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
4841 && c_parser_peek_2nd_token (parser
)->type
!= CPP_MULT
4842 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
4843 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_SQUARE
4844 && c_parser_peek_2nd_token (parser
)->type
!= CPP_KEYWORD
)
4846 tree list
= NULL_TREE
, *nextp
= &list
;
4847 while (c_parser_next_token_is (parser
, CPP_NAME
)
4848 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
4850 *nextp
= build_tree_list (NULL_TREE
,
4851 c_parser_peek_token (parser
)->value
);
4852 nextp
= & TREE_CHAIN (*nextp
);
4853 c_parser_consume_token (parser
);
4854 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
4856 c_parser_consume_token (parser
);
4857 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4859 c_parser_error (parser
, "expected identifier");
4863 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4865 struct c_arg_info
*ret
= build_arg_info ();
4867 c_parser_consume_token (parser
);
4873 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4881 struct c_arg_info
*ret
4882 = c_parser_parms_list_declarator (parser
, attrs
, NULL
, have_gnu_attrs
);
4888 /* Parse a parameter list (possibly empty), including the closing
4889 parenthesis but not the opening one. ATTRS are the gnu-attributes
4890 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4891 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4892 which means standard attributes cannot start the list. EXPR is
4893 NULL or an expression that needs to be evaluated for the side
4894 effects of array size expressions in the parameters. */
4896 static struct c_arg_info
*
4897 c_parser_parms_list_declarator (c_parser
*parser
, tree attrs
, tree expr
,
4898 bool have_gnu_attrs
)
4900 bool bad_parm
= false;
4902 /* ??? Following the old parser, forward parameter declarations may
4903 use abstract declarators, and if no real parameter declarations
4904 follow the forward declarations then this is not diagnosed. Also
4905 note as above that gnu-attributes are ignored as the only contents of
4906 the parentheses, or as the only contents after forward
4908 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4910 struct c_arg_info
*ret
= build_arg_info ();
4911 c_parser_consume_token (parser
);
4914 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
) && !have_gnu_attrs
)
4916 struct c_arg_info
*ret
= build_arg_info ();
4918 ret
->types
= NULL_TREE
;
4919 pedwarn_c11 (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
4920 "ISO C requires a named argument before %<...%> "
4922 c_parser_consume_token (parser
);
4923 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4925 ret
->no_named_args_stdarg_p
= true;
4926 c_parser_consume_token (parser
);
4931 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4936 /* Nonempty list of parameters, either terminated with semicolon
4937 (forward declarations; recurse) or with close parenthesis (normal
4938 function) or with ", ... )" (variadic function). */
4941 /* Parse a parameter. */
4942 struct c_parm
*parm
= c_parser_parameter_declaration (parser
, attrs
,
4945 have_gnu_attrs
= false;
4949 push_parm_decl (parm
, &expr
);
4950 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4953 c_parser_consume_token (parser
);
4954 mark_forward_parm_decls ();
4955 bool new_have_gnu_attrs
4956 = c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
);
4957 new_attrs
= c_parser_gnu_attributes (parser
);
4958 return c_parser_parms_list_declarator (parser
, new_attrs
, expr
,
4959 new_have_gnu_attrs
);
4961 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4963 c_parser_consume_token (parser
);
4967 return get_parm_info (false, expr
);
4969 if (!c_parser_require (parser
, CPP_COMMA
,
4970 "expected %<;%>, %<,%> or %<)%>",
4971 UNKNOWN_LOCATION
, false))
4973 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4976 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4978 c_parser_consume_token (parser
);
4979 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4981 c_parser_consume_token (parser
);
4985 return get_parm_info (true, expr
);
4989 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4997 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4998 start of the declaration if it is the first parameter;
4999 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
5002 static struct c_parm
*
5003 c_parser_parameter_declaration (c_parser
*parser
, tree attrs
,
5004 bool have_gnu_attrs
)
5006 struct c_declspecs
*specs
;
5007 struct c_declarator
*declarator
;
5009 tree postfix_attrs
= NULL_TREE
;
5012 /* Accept #pragmas between parameter declarations. */
5013 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
5014 c_parser_pragma (parser
, pragma_param
, NULL
);
5016 if (!c_parser_next_token_starts_declspecs (parser
)
5017 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
5019 c_token
*token
= c_parser_peek_token (parser
);
5022 c_parser_set_source_position_from_token (token
);
5023 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
5025 auto_diagnostic_group d
;
5026 name_hint hint
= lookup_name_fuzzy (token
->value
,
5027 FUZZY_LOOKUP_TYPENAME
,
5029 if (const char *suggestion
= hint
.suggestion ())
5031 gcc_rich_location
richloc (token
->location
);
5032 richloc
.add_fixit_replace (suggestion
);
5034 "unknown type name %qE; did you mean %qs?",
5035 token
->value
, suggestion
);
5038 error_at (token
->location
, "unknown type name %qE", token
->value
);
5039 parser
->error
= true;
5041 /* ??? In some Objective-C cases '...' isn't applicable so there
5042 should be a different message. */
5044 c_parser_error (parser
,
5045 "expected declaration specifiers or %<...%>");
5046 c_parser_skip_to_end_of_parameter (parser
);
5050 location_t start_loc
= c_parser_peek_token (parser
)->location
;
5052 specs
= build_null_declspecs ();
5055 declspecs_add_attrs (input_location
, specs
, attrs
);
5058 c_parser_declspecs (parser
, specs
, true, true, true, true, false,
5059 !have_gnu_attrs
, true, cla_nonabstract_decl
);
5060 finish_declspecs (specs
);
5061 pending_xref_error ();
5062 prefix_attrs
= specs
->attrs
;
5063 specs
->attrs
= NULL_TREE
;
5064 declarator
= c_parser_declarator (parser
,
5065 specs
->typespec_kind
!= ctsk_none
,
5066 C_DTR_PARM
, &dummy
);
5067 if (declarator
== NULL
)
5069 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5072 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
5073 postfix_attrs
= c_parser_gnu_attributes (parser
);
5075 /* Generate a location for the parameter, ranging from the start of the
5076 initial token to the end of the final token.
5078 If we have a identifier, then use it for the caret location, e.g.
5080 extern int callee (int one, int (*two)(int, int), float three);
5081 ~~~~~~^~~~~~~~~~~~~~
5083 otherwise, reuse the start location for the caret location e.g.:
5085 extern int callee (int one, int (*)(int, int), float three);
5088 location_t end_loc
= parser
->last_token_location
;
5090 /* Find any cdk_id declarator; determine if we have an identifier. */
5091 c_declarator
*id_declarator
= declarator
;
5092 while (id_declarator
&& id_declarator
->kind
!= cdk_id
)
5093 id_declarator
= id_declarator
->declarator
;
5094 location_t caret_loc
= (id_declarator
->u
.id
.id
5095 ? id_declarator
->id_loc
5097 location_t param_loc
= make_location (caret_loc
, start_loc
, end_loc
);
5099 return build_c_parm (specs
, chainon (postfix_attrs
, prefix_attrs
),
5100 declarator
, param_loc
);
5103 /* Parse a string literal in an asm expression. It should not be
5104 translated, and wide string literals are an error although
5105 permitted by the syntax. This is a GNU extension.
5112 c_parser_asm_string_literal (c_parser
*parser
)
5115 int save_flag
= warn_overlength_strings
;
5116 warn_overlength_strings
= 0;
5117 str
= c_parser_string_literal (parser
, false, false).value
;
5118 warn_overlength_strings
= save_flag
;
5122 /* Parse a simple asm expression. This is used in restricted
5123 contexts, where a full expression with inputs and outputs does not
5124 make sense. This is a GNU extension.
5127 asm ( asm-string-literal )
5131 c_parser_simple_asm_expr (c_parser
*parser
)
5134 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
5135 c_parser_consume_token (parser
);
5136 matching_parens parens
;
5137 if (!parens
.require_open (parser
))
5139 str
= c_parser_asm_string_literal (parser
);
5140 if (!parens
.require_close (parser
))
5142 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
5149 c_parser_gnu_attribute_any_word (c_parser
*parser
)
5151 tree attr_name
= NULL_TREE
;
5153 if (c_parser_next_token_is (parser
, CPP_KEYWORD
))
5155 /* ??? See comment above about what keywords are accepted here. */
5157 switch (c_parser_peek_token (parser
)->keyword
)
5189 case RID_TRANSACTION_ATOMIC
:
5190 case RID_TRANSACTION_CANCEL
:
5207 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
5208 attr_name
= ridpointers
[(int) c_parser_peek_token (parser
)->keyword
];
5210 else if (c_parser_next_token_is (parser
, CPP_NAME
))
5211 attr_name
= c_parser_peek_token (parser
)->value
;
5216 /* Parse attribute arguments. This is a common form of syntax
5217 covering all currently valid GNU and standard attributes.
5219 gnu-attribute-arguments:
5221 identifier , nonempty-expr-list
5224 where the "identifier" must not be declared as a type. ??? Why not
5225 allow identifiers declared as types to start the arguments? */
5228 c_parser_attribute_arguments (c_parser
*parser
, bool takes_identifier
,
5229 bool require_string
, bool assume_attr
,
5230 bool allow_empty_args
)
5232 vec
<tree
, va_gc
> *expr_list
;
5234 /* Parse the attribute contents. If they start with an
5235 identifier which is followed by a comma or close
5236 parenthesis, then the arguments start with that
5237 identifier; otherwise they are an expression list.
5238 In objective-c the identifier may be a classname. */
5239 if (c_parser_next_token_is (parser
, CPP_NAME
)
5240 && (c_parser_peek_token (parser
)->id_kind
== C_ID_ID
5241 || (c_dialect_objc ()
5242 && c_parser_peek_token (parser
)->id_kind
5244 && ((c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
5245 || (c_parser_peek_2nd_token (parser
)->type
5246 == CPP_CLOSE_PAREN
))
5247 && (takes_identifier
5248 || (c_dialect_objc ()
5250 && c_parser_peek_token (parser
)->id_kind
5251 == C_ID_CLASSNAME
)))
5253 tree arg1
= c_parser_peek_token (parser
)->value
;
5254 c_parser_consume_token (parser
);
5255 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5256 attr_args
= build_tree_list (NULL_TREE
, arg1
);
5260 c_parser_consume_token (parser
);
5261 expr_list
= c_parser_expr_list (parser
, false, true,
5262 NULL
, NULL
, NULL
, NULL
);
5263 tree_list
= build_tree_list_vec (expr_list
);
5264 attr_args
= tree_cons (NULL_TREE
, arg1
, tree_list
);
5265 release_tree_vector (expr_list
);
5270 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5272 if (!allow_empty_args
)
5273 error_at (c_parser_peek_token (parser
)->location
,
5274 "parentheses must be omitted if "
5275 "attribute argument list is empty");
5276 attr_args
= NULL_TREE
;
5278 else if (require_string
)
5280 /* The only valid argument for this attribute is a string
5281 literal. Handle this specially here to avoid accepting
5282 string literals with excess parentheses. */
5283 tree string
= c_parser_string_literal (parser
, false, true).value
;
5284 attr_args
= build_tree_list (NULL_TREE
, string
);
5286 else if (assume_attr
)
5289 = c_parser_conditional_expression (parser
, NULL
, NULL_TREE
).value
;
5290 if (!c_parser_next_token_is (parser
, CPP_COMMA
))
5291 attr_args
= build_tree_list (NULL_TREE
, cond
);
5295 c_parser_consume_token (parser
);
5296 expr_list
= c_parser_expr_list (parser
, false, true,
5297 NULL
, NULL
, NULL
, NULL
);
5298 tree_list
= build_tree_list_vec (expr_list
);
5299 attr_args
= tree_cons (NULL_TREE
, cond
, tree_list
);
5300 release_tree_vector (expr_list
);
5305 expr_list
= c_parser_expr_list (parser
, false, true,
5306 NULL
, NULL
, NULL
, NULL
);
5307 attr_args
= build_tree_list_vec (expr_list
);
5308 release_tree_vector (expr_list
);
5314 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
5318 gnu-attributes gnu-attribute
5321 __attribute__ ( ( gnu-attribute-list ) )
5325 gnu-attribute_list , gnu-attrib
5330 any-word ( gnu-attribute-arguments )
5332 where "any-word" may be any identifier (including one declared as a
5333 type), a reserved word storage class specifier, type specifier or
5334 type qualifier. ??? This still leaves out most reserved keywords
5335 (following the old parser), shouldn't we include them?
5336 When EXPECT_COMMA is true, expect the attribute to be preceded
5337 by a comma and fail if it isn't.
5338 When EMPTY_OK is true, allow and consume any number of consecutive
5339 commas with no attributes in between. */
5342 c_parser_gnu_attribute (c_parser
*parser
, tree attrs
,
5343 bool expect_comma
= false, bool empty_ok
= true)
5345 bool comma_first
= c_parser_next_token_is (parser
, CPP_COMMA
);
5347 && !c_parser_next_token_is (parser
, CPP_NAME
)
5348 && !c_parser_next_token_is (parser
, CPP_KEYWORD
))
5351 while (c_parser_next_token_is (parser
, CPP_COMMA
))
5353 c_parser_consume_token (parser
);
5358 tree attr_name
= c_parser_gnu_attribute_any_word (parser
);
5359 if (attr_name
== NULL_TREE
)
5362 attr_name
= canonicalize_attr_name (attr_name
);
5363 c_parser_consume_token (parser
);
5366 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
5368 if (expect_comma
&& !comma_first
)
5370 /* A comma is missing between the last attribute on the chain
5372 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5374 return error_mark_node
;
5376 attr
= build_tree_list (attr_name
, NULL_TREE
);
5377 /* Add this attribute to the list. */
5378 attrs
= chainon (attrs
, attr
);
5381 c_parser_consume_token (parser
);
5384 = c_parser_attribute_arguments (parser
,
5385 attribute_takes_identifier_p (attr_name
),
5387 is_attribute_p ("assume", attr_name
),
5390 attr
= build_tree_list (attr_name
, attr_args
);
5391 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5392 c_parser_consume_token (parser
);
5395 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5397 return error_mark_node
;
5400 if (expect_comma
&& !comma_first
)
5402 /* A comma is missing between the last attribute on the chain
5404 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5406 return error_mark_node
;
5409 /* Add this attribute to the list. */
5410 attrs
= chainon (attrs
, attr
);
5415 c_parser_gnu_attributes (c_parser
*parser
)
5417 tree attrs
= NULL_TREE
;
5418 while (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
5420 bool save_translate_strings_p
= parser
->translate_strings_p
;
5421 parser
->translate_strings_p
= false;
5422 /* Consume the `__attribute__' keyword. */
5423 c_parser_consume_token (parser
);
5424 /* Look for the two `(' tokens. */
5425 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
5427 parser
->translate_strings_p
= save_translate_strings_p
;
5430 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
5432 parser
->translate_strings_p
= save_translate_strings_p
;
5433 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
5436 /* Parse the attribute list. Require a comma between successive
5437 (possibly empty) attributes. */
5438 for (bool expect_comma
= false; ; expect_comma
= true)
5440 /* Parse a single attribute. */
5441 tree attr
= c_parser_gnu_attribute (parser
, attrs
, expect_comma
);
5442 if (attr
== error_mark_node
)
5449 /* Look for the two `)' tokens. */
5450 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5451 c_parser_consume_token (parser
);
5454 parser
->translate_strings_p
= save_translate_strings_p
;
5455 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5459 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5460 c_parser_consume_token (parser
);
5463 parser
->translate_strings_p
= save_translate_strings_p
;
5464 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5468 parser
->translate_strings_p
= save_translate_strings_p
;
5474 /* Parse an optional balanced token sequence.
5476 balanced-token-sequence:
5478 balanced-token-sequence balanced-token
5481 ( balanced-token-sequence[opt] )
5482 [ balanced-token-sequence[opt] ]
5483 { balanced-token-sequence[opt] }
5484 any token other than ()[]{}
5488 c_parser_balanced_token_sequence (c_parser
*parser
)
5492 c_token
*token
= c_parser_peek_token (parser
);
5493 switch (token
->type
)
5495 case CPP_OPEN_BRACE
:
5497 matching_braces braces
;
5498 braces
.consume_open (parser
);
5499 c_parser_balanced_token_sequence (parser
);
5500 braces
.require_close (parser
);
5504 case CPP_OPEN_PAREN
:
5506 matching_parens parens
;
5507 parens
.consume_open (parser
);
5508 c_parser_balanced_token_sequence (parser
);
5509 parens
.require_close (parser
);
5513 case CPP_OPEN_SQUARE
:
5514 c_parser_consume_token (parser
);
5515 c_parser_balanced_token_sequence (parser
);
5516 c_parser_require (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5519 case CPP_CLOSE_BRACE
:
5520 case CPP_CLOSE_PAREN
:
5521 case CPP_CLOSE_SQUARE
:
5526 c_parser_consume_pragma (parser
);
5527 c_parser_skip_to_pragma_eol (parser
, false);
5531 c_parser_consume_token (parser
);
5537 static bool c_parser_check_balanced_raw_token_sequence (c_parser
*,
5540 /* Parse arguments of omp::directive or omp::decl attribute.
5542 directive-name ,[opt] clause-list[opt]
5544 For directive just remember the tokens in a vector for subsequent
5548 c_parser_omp_directive_args (c_parser
*parser
, tree attribute
, bool decl_p
)
5551 c_token
*first
= c_parser_peek_token (parser
);
5552 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
)
5553 || (c_parser_peek_nth_token_raw (parser
, n
)->type
5554 != CPP_CLOSE_PAREN
))
5556 c_parser_balanced_token_sequence (parser
);
5557 TREE_VALUE (attribute
) = NULL_TREE
;
5562 error_at (first
->location
, "expected OpenMP directive name");
5563 TREE_VALUE (attribute
) = NULL_TREE
;
5566 vec
<c_token
, va_gc
> *v
;
5567 vec_alloc (v
, n
- 1);
5570 c_token
*tok
= c_parser_peek_token (parser
);
5571 v
->quick_push (*tok
);
5572 c_parser_consume_token (parser
);
5574 tree arg
= make_node (C_TOKEN_VEC
);
5575 C_TOKEN_VEC_TOKENS (arg
) = v
;
5577 TREE_PUBLIC (arg
) = 1;
5578 TREE_VALUE (attribute
) = tree_cons (NULL_TREE
, arg
, TREE_VALUE (attribute
));
5581 /* Parse arguments of omp::sequence attribute.
5583 omp::[opt] directive-attr [ , omp::[opt] directive-attr ]... */
5586 c_parser_omp_sequence_args (c_parser
*parser
, tree attribute
)
5590 c_token
*token
= c_parser_peek_token (parser
);
5591 if (token
->type
== CPP_NAME
5592 && strcmp (IDENTIFIER_POINTER (token
->value
), "omp") == 0
5593 && c_parser_peek_2nd_token (parser
)->type
== CPP_SCOPE
)
5595 c_parser_consume_token (parser
);
5596 c_parser_consume_token (parser
);
5597 token
= c_parser_peek_token (parser
);
5599 bool directive
= false;
5601 if (token
->type
!= CPP_NAME
)
5604 p
= IDENTIFIER_POINTER (token
->value
);
5605 if (strcmp (p
, "directive") == 0)
5607 else if (strcmp (p
, "sequence") != 0)
5609 error_at (token
->location
, "expected %<directive%> or %<sequence%>");
5610 unsigned nesting_depth
= 0;
5614 /* Peek at the next token. */
5615 token
= c_parser_peek_token (parser
);
5616 /* If we've reached the token we want, consume it and stop. */
5617 if ((token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_COMMA
)
5620 /* If we've run out of tokens, stop. */
5621 if (token
->type
== CPP_EOF
)
5623 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
5625 if (token
->type
== CPP_OPEN_BRACE
5626 || token
->type
== CPP_OPEN_PAREN
5627 || token
->type
== CPP_OPEN_SQUARE
)
5629 else if (token
->type
== CPP_CLOSE_BRACE
5630 || token
->type
== CPP_CLOSE_PAREN
5631 || token
->type
== CPP_CLOSE_SQUARE
)
5633 if (nesting_depth
-- == 0)
5636 /* Consume this token. */
5637 c_parser_consume_token (parser
);
5639 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5641 c_parser_consume_token (parser
);
5644 c_parser_consume_token (parser
);
5645 matching_parens parens
;
5646 if (parens
.require_open (parser
))
5649 c_parser_omp_directive_args (parser
, attribute
, false);
5651 c_parser_omp_sequence_args (parser
, attribute
);
5652 parens
.skip_until_found_close (parser
);
5653 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5655 c_parser_consume_token (parser
);
5657 else if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5660 c_parser_consume_token (parser
);
5665 /* Parse standard (C23) attributes (including GNU attributes in the
5668 attribute-specifier-sequence:
5669 attribute-specifier-sequence[opt] attribute-specifier
5671 attribute-specifier:
5672 [ [ attribute-list ] ]
5676 attribute-list, attribute[opt]
5679 attribute-token attribute-argument-clause[opt]
5683 attribute-prefixed-token
5688 attribute-prefixed-token:
5689 attribute-prefix :: identifier
5694 attribute-argument-clause:
5695 ( balanced-token-sequence[opt] )
5697 Keywords are accepted as identifiers for this purpose.
5699 As an extension, we permit an attribute-specifier to be:
5701 [ [ __extension__ attribute-list ] ]
5703 Two colons are then accepted as a synonym for ::. No attempt is made
5704 to check whether the colons are immediately adjacent. LOOSE_SCOPE_P
5705 indicates whether this relaxation is in effect. */
5708 c_parser_std_attribute (c_parser
*parser
, bool for_tm
,
5709 bool loose_scope_p
= false)
5711 c_token
*token
= c_parser_peek_token (parser
);
5712 tree ns
, name
, attribute
;
5714 /* Parse the attribute-token. */
5715 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
5717 c_parser_error (parser
, "expected identifier");
5718 return error_mark_node
;
5720 name
= canonicalize_attr_name (token
->value
);
5721 c_parser_consume_token (parser
);
5722 if (c_parser_next_token_is (parser
, CPP_SCOPE
)
5724 && c_parser_next_token_is (parser
, CPP_COLON
)
5725 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5728 if (c_parser_next_token_is (parser
, CPP_COLON
))
5729 c_parser_consume_token (parser
);
5730 c_parser_consume_token (parser
);
5731 token
= c_parser_peek_token (parser
);
5732 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
5734 c_parser_error (parser
, "expected identifier");
5735 return error_mark_node
;
5737 name
= canonicalize_attr_name (token
->value
);
5738 c_parser_consume_token (parser
);
5742 attribute
= build_tree_list (build_tree_list (ns
, name
), NULL_TREE
);
5744 /* Parse the arguments, if any. */
5745 const attribute_spec
*as
= lookup_attribute_spec (TREE_PURPOSE (attribute
));
5746 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
5748 if ((flag_openmp
|| flag_openmp_simd
)
5750 && is_attribute_p ("omp", ns
)
5751 && (is_attribute_p ("directive", name
)
5752 || is_attribute_p ("sequence", name
)
5753 || is_attribute_p ("decl", name
)))
5755 error ("%<omp::%E%> attribute requires argument", name
);
5756 return error_mark_node
;
5761 location_t open_loc
= c_parser_peek_token (parser
)->location
;
5762 matching_parens parens
;
5763 parens
.consume_open (parser
);
5764 if ((as
&& as
->max_length
== 0)
5765 /* Special-case the transactional-memory attribute "outer",
5766 which is specially handled but not registered as an
5767 attribute, to avoid allowing arbitrary balanced token
5768 sequences as arguments. */
5769 || is_attribute_p ("outer", name
))
5771 error_at (open_loc
, "%qE attribute does not take any arguments", name
);
5772 parens
.skip_until_found_close (parser
);
5773 return error_mark_node
;
5775 /* If this is a fake attribute created to handle -Wno-attributes,
5776 we must skip parsing the arguments. */
5777 if (as
&& !attribute_ignored_p (as
))
5779 bool takes_identifier
5781 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
5782 && attribute_takes_identifier_p (name
));
5785 && (strcmp (IDENTIFIER_POINTER (name
), "deprecated") == 0
5786 || strcmp (IDENTIFIER_POINTER (name
), "nodiscard") == 0));
5789 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
5790 && strcmp (IDENTIFIER_POINTER (name
), "assume") == 0);
5791 TREE_VALUE (attribute
)
5792 = c_parser_attribute_arguments (parser
, takes_identifier
,
5793 require_string
, assume_attr
, false);
5797 if ((flag_openmp
|| flag_openmp_simd
)
5799 && is_attribute_p ("omp", ns
))
5801 if (is_attribute_p ("directive", name
))
5803 c_parser_omp_directive_args (parser
, attribute
, false);
5804 parens
.skip_until_found_close (parser
);
5807 else if (is_attribute_p ("decl", name
))
5809 TREE_VALUE (TREE_PURPOSE (attribute
))
5810 = get_identifier ("directive");
5811 c_parser_omp_directive_args (parser
, attribute
, true);
5812 parens
.skip_until_found_close (parser
);
5815 else if (is_attribute_p ("sequence", name
))
5817 TREE_VALUE (TREE_PURPOSE (attribute
))
5818 = get_identifier ("directive");
5819 c_parser_omp_sequence_args (parser
, attribute
);
5820 parens
.skip_until_found_close (parser
);
5821 TREE_VALUE (attribute
) = nreverse (TREE_VALUE (attribute
));
5825 c_parser_balanced_token_sequence (parser
);
5827 parens
.require_close (parser
);
5830 if (ns
== NULL_TREE
&& !for_tm
&& !as
)
5832 /* An attribute with standard syntax and no namespace specified
5833 is a constraint violation if it is not one of the known
5834 standard attributes. Diagnose it here with a pedwarn and
5835 then discard it to prevent a duplicate warning later. */
5836 pedwarn (input_location
, OPT_Wattributes
, "%qE attribute ignored",
5838 return error_mark_node
;
5844 c_parser_std_attribute_list (c_parser
*parser
, bool for_tm
,
5845 bool loose_scope_p
= false)
5847 tree attributes
= NULL_TREE
;
5850 c_token
*token
= c_parser_peek_token (parser
);
5851 if (token
->type
== CPP_CLOSE_SQUARE
)
5853 if (token
->type
== CPP_COMMA
)
5855 c_parser_consume_token (parser
);
5858 tree attribute
= c_parser_std_attribute (parser
, for_tm
, loose_scope_p
);
5859 if (attribute
!= error_mark_node
)
5861 TREE_CHAIN (attribute
) = attributes
;
5862 attributes
= attribute
;
5864 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5871 c_parser_std_attribute_specifier (c_parser
*parser
, bool for_tm
)
5873 location_t loc
= c_parser_peek_token (parser
)->location
;
5874 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
5876 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
5878 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5882 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
5884 auto ext
= disable_extension_diagnostics ();
5885 c_parser_consume_token (parser
);
5886 attributes
= c_parser_std_attribute_list (parser
, for_tm
, true);
5887 restore_extension_diagnostics (ext
);
5892 pedwarn_c11 (loc
, OPT_Wpedantic
,
5893 "ISO C does not support %<[[]]%> attributes before C23");
5894 attributes
= c_parser_std_attribute_list (parser
, for_tm
);
5896 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5897 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5898 return nreverse (attributes
);
5901 /* Look past an optional balanced token sequence of raw look-ahead
5902 tokens starting with the *Nth token. *N is updated to point to the
5903 following token. Return true if such a sequence was found, false
5904 if the tokens parsed were not balanced. */
5907 c_parser_check_balanced_raw_token_sequence (c_parser
*parser
, unsigned int *n
)
5911 c_token
*token
= c_parser_peek_nth_token_raw (parser
, *n
);
5912 switch (token
->type
)
5914 case CPP_OPEN_BRACE
:
5917 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5919 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5920 if (token
->type
== CPP_CLOSE_BRACE
)
5930 case CPP_OPEN_PAREN
:
5933 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5935 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5936 if (token
->type
== CPP_CLOSE_PAREN
)
5946 case CPP_OPEN_SQUARE
:
5949 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5951 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5952 if (token
->type
== CPP_CLOSE_SQUARE
)
5962 case CPP_CLOSE_BRACE
:
5963 case CPP_CLOSE_PAREN
:
5964 case CPP_CLOSE_SQUARE
:
5975 /* Return whether standard attributes start with the Nth token. */
5978 c_parser_nth_token_starts_std_attributes (c_parser
*parser
, unsigned int n
)
5980 if (!(c_parser_peek_nth_token (parser
, n
)->type
== CPP_OPEN_SQUARE
5981 && c_parser_peek_nth_token (parser
, n
+ 1)->type
== CPP_OPEN_SQUARE
))
5983 /* In C, '[[' must start attributes. In Objective-C, we need to
5984 check whether '[[' is matched by ']]'. */
5985 if (!c_dialect_objc ())
5988 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
5990 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
5991 if (token
->type
!= CPP_CLOSE_SQUARE
)
5993 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
5994 return token
->type
== CPP_CLOSE_SQUARE
;
5998 c_parser_std_attribute_specifier_sequence (c_parser
*parser
)
6000 tree attributes
= NULL_TREE
;
6003 tree attrs
= c_parser_std_attribute_specifier (parser
, false);
6004 attributes
= chainon (attributes
, attrs
);
6006 while (c_parser_nth_token_starts_std_attributes (parser
, 1));
6010 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
6011 says whether alignment specifiers are OK (only in cases that might
6012 be the type name of a compound literal).
6015 specifier-qualifier-list abstract-declarator[opt]
6018 struct c_type_name
*
6019 c_parser_type_name (c_parser
*parser
, bool alignas_ok
)
6021 struct c_declspecs
*specs
= build_null_declspecs ();
6022 struct c_declarator
*declarator
;
6023 struct c_type_name
*ret
;
6025 c_parser_declspecs (parser
, specs
, false, true, true, alignas_ok
, false,
6026 false, true, cla_prefer_type
);
6027 if (!specs
->declspecs_seen_p
)
6029 c_parser_error (parser
, "expected specifier-qualifier-list");
6032 if (specs
->type
!= error_mark_node
)
6034 pending_xref_error ();
6035 finish_declspecs (specs
);
6037 declarator
= c_parser_declarator (parser
,
6038 specs
->typespec_kind
!= ctsk_none
,
6039 C_DTR_ABSTRACT
, &dummy
);
6040 if (declarator
== NULL
)
6042 ret
= XOBNEW (&parser_obstack
, struct c_type_name
);
6044 ret
->declarator
= declarator
;
6048 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
6051 assignment-expression
6052 { initializer-list }
6053 { initializer-list , }
6056 designation[opt] initializer
6057 initializer-list , designation[opt] initializer
6064 designator-list designator
6071 [ constant-expression ]
6083 [ constant-expression ... constant-expression ]
6085 Any expression without commas is accepted in the syntax for the
6086 constant-expressions, with non-constant expressions rejected later.
6088 DECL is the declaration we're parsing this initializer for.
6090 This function is only used for top-level initializers; for nested
6091 ones, see c_parser_initval. */
6093 static struct c_expr
6094 c_parser_initializer (c_parser
*parser
, tree decl
)
6096 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6097 return c_parser_braced_init (parser
, NULL_TREE
, false, NULL
, decl
);
6101 location_t loc
= c_parser_peek_token (parser
)->location
;
6102 ret
= c_parser_expr_no_commas (parser
, NULL
);
6103 if (decl
!= error_mark_node
&& C_DECL_VARIABLE_SIZE (decl
))
6106 "variable-sized object may not be initialized except "
6107 "with an empty initializer");
6110 /* This is handled mostly by gimplify.cc, but we have to deal with
6111 not warning about int x = x; as it is a GCC extension to turn off
6112 this warning but only if warn_init_self is zero. */
6114 && !DECL_EXTERNAL (decl
)
6115 && !TREE_STATIC (decl
)
6116 && ret
.value
== decl
6117 && !warning_enabled_at (DECL_SOURCE_LOCATION (decl
), OPT_Winit_self
))
6118 suppress_warning (decl
, OPT_Winit_self
);
6119 if (TREE_CODE (ret
.value
) != STRING_CST
6120 && (TREE_CODE (ret
.value
) != COMPOUND_LITERAL_EXPR
6121 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6123 ret
= convert_lvalue_to_rvalue (loc
, ret
, true, true, true);
6128 /* The location of the last comma within the current initializer list,
6129 or UNKNOWN_LOCATION if not within one. */
6131 location_t last_init_list_comma
;
6133 /* Parse a braced initializer list. TYPE is the type specified for a
6134 compound literal, and NULL_TREE for other initializers and for
6135 nested braced lists. NESTED_P is true for nested braced lists,
6136 false for the list of a compound literal or the list that is the
6137 top-level initializer in a declaration. DECL is the declaration for
6138 the top-level initializer for a declaration, otherwise NULL_TREE. */
6140 static struct c_expr
6141 c_parser_braced_init (c_parser
*parser
, tree type
, bool nested_p
,
6142 struct obstack
*outer_obstack
, tree decl
)
6145 struct obstack braced_init_obstack
;
6146 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
6147 gcc_obstack_init (&braced_init_obstack
);
6148 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
6149 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
6150 c_omp_array_section_p
= false;
6151 matching_braces braces
;
6152 braces
.consume_open (parser
);
6155 finish_implicit_inits (brace_loc
, outer_obstack
);
6156 push_init_level (brace_loc
, 0, &braced_init_obstack
);
6159 really_start_incremental_init (type
);
6160 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
6162 pedwarn_c11 (brace_loc
, OPT_Wpedantic
,
6163 "ISO C forbids empty initializer braces before C23");
6167 if (decl
&& decl
!= error_mark_node
&& C_DECL_VARIABLE_SIZE (decl
))
6168 error_at (brace_loc
,
6169 "variable-sized object may not be initialized except "
6170 "with an empty initializer");
6171 /* Parse a non-empty initializer list, possibly with a trailing
6175 c_parser_initelt (parser
, &braced_init_obstack
);
6178 if (c_parser_next_token_is (parser
, CPP_COMMA
))
6180 last_init_list_comma
= c_parser_peek_token (parser
)->location
;
6181 c_parser_consume_token (parser
);
6185 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
6189 c_omp_array_section_p
= save_c_omp_array_section_p
;
6190 c_token
*next_tok
= c_parser_peek_token (parser
);
6191 if (next_tok
->type
!= CPP_CLOSE_BRACE
)
6194 ret
.original_code
= ERROR_MARK
;
6195 ret
.original_type
= NULL
;
6196 braces
.skip_until_found_close (parser
);
6197 pop_init_level (brace_loc
, 0, &braced_init_obstack
, last_init_list_comma
);
6198 obstack_free (&braced_init_obstack
, NULL
);
6201 location_t close_loc
= next_tok
->location
;
6202 c_parser_consume_token (parser
);
6203 ret
= pop_init_level (brace_loc
, 0, &braced_init_obstack
, close_loc
);
6204 obstack_free (&braced_init_obstack
, NULL
);
6205 set_c_expr_source_range (&ret
, brace_loc
, close_loc
);
6209 /* Parse a nested initializer, including designators. */
6212 c_parser_initelt (c_parser
*parser
, struct obstack
* braced_init_obstack
)
6214 /* Parse any designator or designator list. A single array
6215 designator may have the subsequent "=" omitted in GNU C, but a
6216 longer list or a structure member designator may not. */
6217 if (c_parser_next_token_is (parser
, CPP_NAME
)
6218 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
6220 /* Old-style structure member designator. */
6221 set_init_label (c_parser_peek_token (parser
)->location
,
6222 c_parser_peek_token (parser
)->value
,
6223 c_parser_peek_token (parser
)->location
,
6224 braced_init_obstack
);
6225 /* Use the colon as the error location. */
6226 pedwarn (c_parser_peek_2nd_token (parser
)->location
, OPT_Wpedantic
,
6227 "obsolete use of designated initializer with %<:%>");
6228 c_parser_consume_token (parser
);
6229 c_parser_consume_token (parser
);
6233 /* des_seen is 0 if there have been no designators, 1 if there
6234 has been a single array designator and 2 otherwise. */
6236 /* Location of a designator. */
6237 location_t des_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
6238 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
6239 || c_parser_next_token_is (parser
, CPP_DOT
))
6241 int des_prev
= des_seen
;
6243 des_loc
= c_parser_peek_token (parser
)->location
;
6246 if (c_parser_next_token_is (parser
, CPP_DOT
))
6249 c_parser_consume_token (parser
);
6250 if (c_parser_next_token_is (parser
, CPP_NAME
))
6252 set_init_label (des_loc
, c_parser_peek_token (parser
)->value
,
6253 c_parser_peek_token (parser
)->location
,
6254 braced_init_obstack
);
6255 c_parser_consume_token (parser
);
6261 init
.original_code
= ERROR_MARK
;
6262 init
.original_type
= NULL
;
6263 c_parser_error (parser
, "expected identifier");
6264 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
6265 process_init_element (input_location
, init
, false,
6266 braced_init_obstack
);
6272 struct c_expr first_expr
;
6274 location_t ellipsis_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
6275 location_t array_index_loc
= UNKNOWN_LOCATION
;
6276 /* ??? Following the old parser, [ objc-receiver
6277 objc-message-args ] is accepted as an initializer,
6278 being distinguished from a designator by what follows
6279 the first assignment expression inside the square
6280 brackets, but after a first array designator a
6281 subsequent square bracket is for Objective-C taken to
6282 start an expression, using the obsolete form of
6283 designated initializer without '=', rather than
6284 possibly being a second level of designation: in LALR
6285 terms, the '[' is shifted rather than reducing
6286 designator to designator-list. */
6287 if (des_prev
== 1 && c_dialect_objc ())
6289 des_seen
= des_prev
;
6292 if (des_prev
== 0 && c_dialect_objc ())
6294 /* This might be an array designator or an
6295 Objective-C message expression. If the former,
6296 continue parsing here; if the latter, parse the
6297 remainder of the initializer given the starting
6298 primary-expression. ??? It might make sense to
6299 distinguish when des_prev == 1 as well; see
6300 previous comment. */
6302 struct c_expr mexpr
;
6303 c_parser_consume_token (parser
);
6304 if (c_parser_peek_token (parser
)->type
== CPP_NAME
6305 && ((c_parser_peek_token (parser
)->id_kind
6307 || (c_parser_peek_token (parser
)->id_kind
6308 == C_ID_CLASSNAME
)))
6310 /* Type name receiver. */
6311 tree id
= c_parser_peek_token (parser
)->value
;
6312 c_parser_consume_token (parser
);
6313 rec
= objc_get_class_reference (id
);
6314 goto parse_message_args
;
6316 array_index_loc
= c_parser_peek_token (parser
)->location
;
6317 first_expr
= c_parser_expr_no_commas (parser
, NULL
);
6318 mark_exp_read (first_expr
.value
);
6319 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
)
6320 || c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
6321 goto array_desig_after_first
;
6322 first
= first_expr
.value
;
6323 /* Expression receiver. So far only one part
6324 without commas has been parsed; there might be
6325 more of the expression. */
6327 while (c_parser_next_token_is (parser
, CPP_COMMA
))
6330 location_t comma_loc
, exp_loc
;
6331 comma_loc
= c_parser_peek_token (parser
)->location
;
6332 c_parser_consume_token (parser
);
6333 exp_loc
= c_parser_peek_token (parser
)->location
;
6334 next
= c_parser_expr_no_commas (parser
, NULL
);
6335 next
= convert_lvalue_to_rvalue (exp_loc
, next
,
6337 rec
= build_compound_expr (comma_loc
, rec
, next
.value
);
6340 /* Now parse the objc-message-args. */
6341 args
= c_parser_objc_message_args (parser
);
6342 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
6345 = objc_build_message_expr (rec
, args
);
6346 mexpr
.original_code
= ERROR_MARK
;
6347 mexpr
.original_type
= NULL
;
6348 mexpr
.m_decimal
= 0;
6349 /* Now parse and process the remainder of the
6350 initializer, starting with this message
6351 expression as a primary-expression. */
6352 c_parser_initval (parser
, &mexpr
, braced_init_obstack
);
6355 c_parser_consume_token (parser
);
6356 array_index_loc
= c_parser_peek_token (parser
)->location
;
6357 first_expr
= c_parser_expr_no_commas (parser
, NULL
);
6358 mark_exp_read (first_expr
.value
);
6359 array_desig_after_first
:
6360 first_expr
= convert_lvalue_to_rvalue (array_index_loc
,
6363 first
= first_expr
.value
;
6364 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
6366 ellipsis_loc
= c_parser_peek_token (parser
)->location
;
6367 c_parser_consume_token (parser
);
6368 second
= convert_lvalue_to_rvalue (ellipsis_loc
,
6369 (c_parser_expr_no_commas
6372 mark_exp_read (second
);
6376 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
6378 c_parser_consume_token (parser
);
6379 set_init_index (array_index_loc
, first
, second
,
6380 braced_init_obstack
);
6382 pedwarn (ellipsis_loc
, OPT_Wpedantic
,
6383 "ISO C forbids specifying range of elements to initialize");
6386 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
6392 if (c_parser_next_token_is (parser
, CPP_EQ
))
6394 pedwarn_c90 (des_loc
, OPT_Wpedantic
,
6395 "ISO C90 forbids specifying subobject "
6397 c_parser_consume_token (parser
);
6402 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
6403 "obsolete use of designated initializer without %<=%>");
6408 init
.original_code
= ERROR_MARK
;
6409 init
.original_type
= NULL
;
6410 c_parser_error (parser
, "expected %<=%>");
6411 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
6412 process_init_element (input_location
, init
, false,
6413 braced_init_obstack
);
6419 c_parser_initval (parser
, NULL
, braced_init_obstack
);
6422 /* Parse a nested initializer; as c_parser_initializer but parses
6423 initializers within braced lists, after any designators have been
6424 applied. If AFTER is not NULL then it is an Objective-C message
6425 expression which is the primary-expression starting the
6429 c_parser_initval (c_parser
*parser
, struct c_expr
*after
,
6430 struct obstack
* braced_init_obstack
)
6433 gcc_assert (!after
|| c_dialect_objc ());
6434 location_t loc
= c_parser_peek_token (parser
)->location
;
6436 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
) && !after
)
6437 init
= c_parser_braced_init (parser
, NULL_TREE
, true,
6438 braced_init_obstack
, NULL_TREE
);
6441 init
= c_parser_expr_no_commas (parser
, after
);
6442 if (init
.value
!= NULL_TREE
6443 && TREE_CODE (init
.value
) != STRING_CST
6444 && (TREE_CODE (init
.value
) != COMPOUND_LITERAL_EXPR
6445 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6447 init
= convert_lvalue_to_rvalue (loc
, init
, true, true, true);
6449 process_init_element (loc
, init
, false, braced_init_obstack
);
6452 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
6453 C99 6.8.2, C11 6.8.2, C23 6.8.2).
6456 { block-item-list[opt] }
6457 { label-declarations block-item-list }
6461 block-item-list block-item
6474 { label-declarations block-item-list }
6477 __extension__ nested-declaration
6478 nested-function-definition
6482 label-declarations label-declaration
6485 __label__ identifier-list ;
6487 Allowing the mixing of declarations and code is new in C99. The
6488 GNU syntax also permits (not shown above) labels at the end of
6489 compound statements, which yield an error. We don't allow labels
6490 on declarations; this might seem like a natural extension, but
6491 there would be a conflict between gnu-attributes on the label and
6492 prefix gnu-attributes on the declaration. ??? The syntax follows the
6493 old parser in requiring something after label declarations.
6494 Although they are erroneous if the labels declared aren't defined,
6495 is it useful for the syntax to be this way?
6516 cancellation-point-directive */
6519 c_parser_compound_statement (c_parser
*parser
, location_t
*endlocp
)
6522 location_t brace_loc
;
6523 brace_loc
= c_parser_peek_token (parser
)->location
;
6524 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
6526 /* Ensure a scope is entered and left anyway to avoid confusion
6527 if we have just prepared to enter a function body. */
6528 stmt
= c_begin_compound_stmt (true);
6529 c_end_compound_stmt (brace_loc
, stmt
, true);
6530 return error_mark_node
;
6532 stmt
= c_begin_compound_stmt (true);
6533 location_t end_loc
= c_parser_compound_statement_nostart (parser
);
6537 return c_end_compound_stmt (brace_loc
, stmt
, true);
6540 /* Diagnose errors related to imperfectly nested loops in an OMP
6541 loop construct. This function is called when such code is seen.
6542 Only issue one such diagnostic no matter how much invalid
6543 intervening code there is in the loop.
6544 FIXME: maybe the location associated with the diagnostic should
6545 be the current parser token instead of the location of the outer loop
6549 check_omp_intervening_code (c_parser
*parser
)
6551 struct omp_for_parse_data
*omp_for_parse_state
= parser
->omp_for_parse_state
;
6552 gcc_assert (omp_for_parse_state
);
6554 if (!omp_for_parse_state
->in_intervening_code
)
6556 omp_for_parse_state
->saw_intervening_code
= true;
6558 /* Only diagnose errors related to perfect nesting once. */
6559 if (!omp_for_parse_state
->perfect_nesting_fail
)
6562 /* OpenACC does not (yet) permit intervening code, in
6563 addition to situations forbidden by the OpenMP spec. */
6564 if (omp_for_parse_state
->code
== OACC_LOOP
)
6566 error_at (omp_for_parse_state
->for_loc
,
6567 "inner loops must be perfectly nested in "
6568 "%<#pragma acc loop%>");
6569 omp_for_parse_state
->perfect_nesting_fail
= true;
6571 else if (omp_for_parse_state
->ordered
)
6573 error_at (omp_for_parse_state
->for_loc
,
6574 "inner loops must be perfectly nested with "
6575 "%<ordered%> clause");
6576 omp_for_parse_state
->perfect_nesting_fail
= true;
6578 else if (omp_for_parse_state
->inscan
)
6580 error_at (omp_for_parse_state
->for_loc
,
6581 "inner loops must be perfectly nested with "
6582 "%<reduction%> %<inscan%> clause");
6583 omp_for_parse_state
->perfect_nesting_fail
= true;
6585 /* TODO: Also reject loops with TILE directive. */
6586 if (omp_for_parse_state
->perfect_nesting_fail
)
6587 omp_for_parse_state
->fail
= true;
6591 /* Helper function for below: wrap an OMP_STRUCTURED_BLOCK around SL
6592 and add the statement to the current list. If SL is an empty statement
6593 list, do nothing. */
6595 add_structured_block_stmt (tree sl
)
6597 if (TREE_CODE (sl
) != STATEMENT_LIST
6598 || !tsi_end_p (tsi_start (sl
)))
6599 add_stmt (build1 (OMP_STRUCTURED_BLOCK
, void_type_node
, sl
));
6602 struct c_omp_attribute_data
6604 vec
<c_token
, va_gc
> *tokens
;
6605 const c_omp_directive
*dir
;
6606 c_omp_directive_kind kind
;
6609 /* Handle omp::directive and omp::sequence attributes in ATTRS
6610 (if any) at the start of a statement or in attribute-declaration. */
6613 c_parser_handle_statement_omp_attributes (c_parser
*parser
, tree
&attrs
,
6614 bool *have_std_attrs
)
6616 if (!flag_openmp
&& !flag_openmp_simd
)
6619 auto_vec
<c_omp_attribute_data
, 16> vd
;
6623 for (tree
*pa
= &attrs
; *pa
; )
6624 if (is_attribute_namespace_p ("omp", *pa
)
6625 && is_attribute_p ("directive", get_attribute_name (*pa
)))
6628 for (tree a
= TREE_VALUE (*pa
); a
; a
= TREE_CHAIN (a
))
6630 tree d
= TREE_VALUE (a
);
6631 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
6632 vec
<c_token
, va_gc
> *toks
= C_TOKEN_VEC_TOKENS (d
);
6633 c_token
*first
= toks
->address ();
6634 c_token
*last
= first
+ toks
->length ();
6635 if (parser
->omp_attrs_forbidden_p
)
6637 error_at (first
->location
,
6638 "mixing OpenMP directives with attribute and pragma "
6639 "syntax on the same statement");
6640 parser
->omp_attrs_forbidden_p
= false;
6643 else if (TREE_PUBLIC (d
))
6645 error_at (first
->location
,
6646 "OpenMP %<omp::decl%> attribute on a statement");
6649 const char *directive
[3] = {};
6650 for (int i
= 0; i
< 3; i
++)
6652 tree id
= NULL_TREE
;
6653 if (first
+ i
== last
)
6655 if (first
[i
].type
== CPP_NAME
)
6656 id
= first
[i
].value
;
6657 else if (first
[i
].type
== CPP_KEYWORD
)
6658 id
= ridpointers
[(int) first
[i
].keyword
];
6661 directive
[i
] = IDENTIFIER_POINTER (id
);
6663 const c_omp_directive
*dir
= NULL
;
6665 dir
= c_omp_categorize_directive (directive
[0], directive
[1],
6669 error_at (first
->location
,
6670 "unknown OpenMP directive name in %qs attribute "
6672 TREE_PUBLIC (d
) ? "omp::decl" : "omp::directive");
6675 c_omp_directive_kind kind
= dir
->kind
;
6676 if (dir
->id
== PRAGMA_OMP_ORDERED
)
6678 /* ordered is C_OMP_DIR_CONSTRUCT only if it doesn't contain
6679 depend/doacross clause. */
6681 && (strcmp (directive
[1], "depend") == 0
6682 || strcmp (directive
[1], "doacross") == 0))
6683 kind
= C_OMP_DIR_STANDALONE
;
6684 else if (first
+ 2 < last
6685 && first
[1].type
== CPP_COMMA
6686 && first
[2].type
== CPP_NAME
6687 && (strcmp (IDENTIFIER_POINTER (first
[2].value
),
6689 || strcmp (IDENTIFIER_POINTER (first
[2].value
),
6691 kind
= C_OMP_DIR_STANDALONE
;
6693 else if (dir
->id
== PRAGMA_OMP_ERROR
)
6695 /* error with at(execution) clause is C_OMP_DIR_STANDALONE. */
6696 int paren_depth
= 0;
6697 for (int i
= 1; first
+ i
< last
; i
++)
6698 if (first
[i
].type
== CPP_OPEN_PAREN
)
6700 else if (first
[i
].type
== CPP_CLOSE_PAREN
)
6702 else if (paren_depth
== 0
6703 && first
+ i
+ 2 < last
6704 && first
[i
].type
== CPP_NAME
6705 && first
[i
+ 1].type
== CPP_OPEN_PAREN
6706 && first
[i
+ 2].type
== CPP_NAME
6707 && !strcmp (IDENTIFIER_POINTER (first
[i
].value
),
6709 && !strcmp (IDENTIFIER_POINTER (first
[i
6713 kind
= C_OMP_DIR_STANDALONE
;
6717 c_omp_attribute_data v
= { toks
, dir
, kind
};
6719 if (flag_openmp
|| dir
->simd
)
6720 tokens
+= (last
- first
) + 1;
6722 c_omp_attribute_data v
= {};
6724 *pa
= TREE_CHAIN (*pa
);
6727 pa
= &TREE_CHAIN (*pa
);
6732 if (have_std_attrs
&& attrs
== NULL
)
6733 *have_std_attrs
= false;
6738 c_omp_attribute_data
*v
;
6739 c_omp_attribute_data
*construct_seen
= nullptr;
6740 c_omp_attribute_data
*standalone_seen
= nullptr;
6741 c_omp_attribute_data
*prev_standalone_seen
= nullptr;
6742 FOR_EACH_VEC_ELT (vd
, i
, v
)
6745 if (v
->kind
== C_OMP_DIR_CONSTRUCT
&& !construct_seen
)
6747 else if (v
->kind
== C_OMP_DIR_STANDALONE
&& !standalone_seen
)
6748 standalone_seen
= v
;
6752 if (standalone_seen
&& !prev_standalone_seen
)
6754 prev_standalone_seen
= standalone_seen
;
6755 standalone_seen
= nullptr;
6759 if (cnt
> 1 && construct_seen
)
6761 error_at ((*construct_seen
->tokens
)[0].location
,
6762 "OpenMP construct among %<omp::directive%> attributes"
6763 " requires all %<omp::directive%> attributes on the"
6764 " same statement to be in the same %<omp::sequence%>");
6767 if (cnt
> 1 && standalone_seen
&& prev_standalone_seen
)
6769 error_at ((*standalone_seen
->tokens
)[0].location
,
6770 "multiple OpenMP standalone directives among"
6771 " %<omp::directive%> attributes must be all within the"
6772 " same %<omp::sequence%>");
6776 if (prev_standalone_seen
)
6777 standalone_seen
= prev_standalone_seen
;
6779 && !c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6781 error_at (standalone_seen
->tokens
->address ()->location
,
6782 "standalone OpenMP directives in %<omp::directive%> attribute"
6783 " can only appear on an empty statement");
6786 if (cnt
&& c_parser_next_token_is (parser
, CPP_PRAGMA
))
6788 c_token
*token
= c_parser_peek_token (parser
);
6789 enum pragma_kind kind
= token
->pragma_kind
;
6790 if (kind
>= PRAGMA_OMP__START_
&& kind
<= PRAGMA_OMP__LAST_
)
6792 error_at (token
->location
,
6793 "mixing OpenMP directives with attribute and pragma "
6794 "syntax on the same statement");
6802 unsigned int tokens_avail
= parser
->tokens_avail
;
6803 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
6806 vec
<c_token
, va_gc
> *toks
= NULL
;
6807 vec_safe_reserve (toks
, tokens
, true);
6808 FOR_EACH_VEC_ELT (vd
, i
, v
)
6812 if (!flag_openmp
&& !v
->dir
->simd
)
6814 c_token
*first
= v
->tokens
->address ();
6815 c_token
*last
= first
+ v
->tokens
->length ();
6817 tok
.type
= CPP_PRAGMA
;
6818 tok
.keyword
= RID_MAX
;
6819 tok
.pragma_kind
= pragma_kind (v
->dir
->id
);
6820 tok
.location
= first
->location
;
6821 toks
->quick_push (tok
);
6822 while (++first
< last
)
6823 toks
->quick_push (*first
);
6825 tok
.type
= CPP_PRAGMA_EOL
;
6826 tok
.keyword
= RID_MAX
;
6827 tok
.location
= last
[-1].location
;
6828 toks
->quick_push (tok
);
6833 tok
.keyword
= RID_MAX
;
6834 tok
.location
= toks
->last ().location
;
6835 tok
.flags
= tokens_avail
;
6836 toks
->quick_push (tok
);
6838 parser
->tokens
= toks
->address ();
6839 parser
->tokens_avail
= tokens
;
6840 parser
->in_omp_attribute_pragma
= toks
;
6844 /* Handle omp::directive and omp::sequence attributes in ATTRS
6845 (if any) at the start or after declaration-id of a declaration. */
6848 c_parser_handle_directive_omp_attributes (tree
&attrs
,
6849 vec
<c_token
> *&pragma_clauses
,
6850 vec
<c_token
> *attr_clauses
)
6852 if (!flag_openmp
&& !flag_openmp_simd
)
6855 for (tree
*pa
= &attrs
; *pa
; )
6856 if (is_attribute_namespace_p ("omp", *pa
)
6857 && is_attribute_p ("directive", get_attribute_name (*pa
)))
6860 for (tree
*pa2
= &TREE_VALUE (*pa
); *pa2
; )
6863 tree d
= TREE_VALUE (a
);
6864 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
6865 vec
<c_token
, va_gc
> *toks
= C_TOKEN_VEC_TOKENS (d
);
6866 c_token
*first
= toks
->address ();
6867 c_token
*last
= first
+ toks
->length ();
6868 const char *directive
[3] = {};
6869 for (int i
= 0; i
< 3; i
++)
6871 tree id
= NULL_TREE
;
6872 if (first
+ i
== last
)
6874 if (first
[i
].type
== CPP_NAME
)
6875 id
= first
[i
].value
;
6876 else if (first
[i
].type
== CPP_KEYWORD
)
6877 id
= ridpointers
[(int) first
[i
].keyword
];
6880 directive
[i
] = IDENTIFIER_POINTER (id
);
6882 const c_omp_directive
*dir
= NULL
;
6884 dir
= c_omp_categorize_directive (directive
[0], directive
[1],
6888 error_at (first
->location
,
6889 "unknown OpenMP directive name in "
6890 "%qs attribute argument",
6891 TREE_PUBLIC (d
) ? "omp::decl" : "omp::directive");
6892 *pa2
= TREE_CHAIN (a
);
6894 else if (dir
->id
== PRAGMA_OMP_DECLARE
6895 && (strcmp (directive
[1], "simd") == 0
6896 || strcmp (directive
[1], "variant") == 0))
6900 error_at (first
->location
,
6901 "mixing OpenMP directives with attribute and "
6902 "pragma syntax on the same declaration");
6903 for (pa
= &attrs
; *pa
; )
6904 if (is_attribute_namespace_p ("omp", *pa
)
6905 && is_attribute_p ("directive",
6906 get_attribute_name (*pa
)))
6907 *pa
= TREE_CHAIN (*pa
);
6909 pa
= &TREE_CHAIN (*pa
);
6913 attr_clauses
->reserve (attr_clauses
->length ()
6914 + toks
->length () + 2);
6915 for (++first
; first
< last
; ++first
)
6916 attr_clauses
->quick_push (*first
);
6918 tok
.type
= CPP_PRAGMA_EOL
;
6919 tok
.keyword
= RID_MAX
;
6920 tok
.location
= last
[-1].location
;
6921 attr_clauses
->quick_push (tok
);
6922 *pa2
= TREE_CHAIN (a
);
6925 pa2
= &TREE_CHAIN (a
);
6927 if (cnt
&& TREE_VALUE (*pa
) == NULL_TREE
)
6928 *pa
= TREE_CHAIN (*pa
);
6930 pa
= &TREE_CHAIN (*pa
);
6933 pa
= &TREE_CHAIN (*pa
);
6934 if (attr_clauses
->length ())
6938 tok
.keyword
= RID_MAX
;
6939 tok
.location
= attr_clauses
->last ().location
;
6940 attr_clauses
->quick_push (tok
);
6941 attr_clauses
->quick_push (tok
);
6942 pragma_clauses
= attr_clauses
;
6946 /* Parse a compound statement except for the opening brace. This is
6947 used for parsing both compound statements and statement expressions
6948 (which follow different paths to handling the opening). */
6951 c_parser_compound_statement_nostart (c_parser
*parser
)
6953 bool last_stmt
= false;
6954 bool last_label
= false;
6955 bool save_valid_for_pragma
= valid_location_for_stdc_pragma_p ();
6956 location_t label_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
6957 struct omp_for_parse_data
*omp_for_parse_state
6958 = parser
->omp_for_parse_state
;
6959 bool in_omp_loop_block
6960 = omp_for_parse_state
? omp_for_parse_state
->want_nested_loop
: false;
6961 tree sl
= NULL_TREE
;
6963 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
6965 location_t endloc
= c_parser_peek_token (parser
)->location
;
6966 add_debug_begin_stmt (endloc
);
6967 c_parser_consume_token (parser
);
6971 /* If we're parsing a {} sequence in an OMP_FOR body, start a
6972 statement list for intervening code. */
6973 if (in_omp_loop_block
)
6974 sl
= push_stmt_list ();
6976 mark_valid_location_for_stdc_pragma (true);
6977 if (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
6979 /* Read zero or more forward-declarations for labels that nested
6980 functions can jump to. */
6981 mark_valid_location_for_stdc_pragma (false);
6982 if (in_omp_loop_block
)
6983 check_omp_intervening_code (parser
);
6984 while (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
6986 label_loc
= c_parser_peek_token (parser
)->location
;
6987 c_parser_consume_token (parser
);
6988 /* Any identifiers, including those declared as type names,
6993 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
6995 c_parser_error (parser
, "expected identifier");
6999 = declare_label (c_parser_peek_token (parser
)->value
);
7000 C_DECLARED_LABEL_FLAG (label
) = 1;
7001 add_stmt (build_stmt (label_loc
, DECL_EXPR
, label
));
7002 c_parser_consume_token (parser
);
7003 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7004 c_parser_consume_token (parser
);
7008 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
7010 pedwarn (label_loc
, OPT_Wpedantic
, "ISO C forbids label declarations");
7012 /* We must now have at least one statement, label or declaration. */
7013 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
7015 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7016 c_parser_error (parser
, "expected declaration or statement");
7017 location_t endloc
= c_parser_peek_token (parser
)->location
;
7018 c_parser_consume_token (parser
);
7021 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_BRACE
))
7023 location_t loc
= c_parser_peek_token (parser
)->location
;
7024 loc
= expansion_point_location_if_in_system_header (loc
);
7026 bool want_nested_loop
= (omp_for_parse_state
7027 ? omp_for_parse_state
->want_nested_loop
7030 /* First take care of special cases for OpenMP "canonical loop
7031 nest form", that do not allow standard attributes, labels, or
7032 __extension__ before the nested statement. */
7033 if (in_omp_loop_block
&& !last_label
)
7035 if (want_nested_loop
7036 && c_parser_next_token_is_keyword (parser
, RID_FOR
))
7038 /* Found the next nested loop. If there were intervening
7039 code statements collected before now, wrap them in an
7040 OMP_STRUCTURED_BLOCK node, and start a new structured
7041 block to hold statements that may come after the FOR. */
7043 add_structured_block_stmt (pop_stmt_list (sl
));
7044 omp_for_parse_state
->depth
++;
7045 add_stmt (c_parser_omp_loop_nest (parser
, NULL
));
7046 omp_for_parse_state
->depth
--;
7047 sl
= push_stmt_list ();
7048 parser
->error
= false;
7051 else if (want_nested_loop
7052 && c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7054 /* If this nested compound statement contains the nested loop,
7055 we need to separate the other statements in the current
7056 statement into separate blocks of intervening code. If
7057 there's no nested loop, it's all part of the same
7058 chunk of intervening code. */
7059 tree pre_sl
= pop_stmt_list (sl
);
7060 tree nested_sl
= push_stmt_list ();
7061 mark_valid_location_for_stdc_pragma (false);
7062 c_parser_statement_after_labels (parser
, NULL
);
7063 nested_sl
= pop_stmt_list (nested_sl
);
7064 if (omp_for_parse_state
->want_nested_loop
)
7066 /* This block didn't contain a loop-nest, so it's
7067 all part of the same chunk of intervening code. */
7068 check_omp_intervening_code (parser
);
7069 sl
= push_stmt_list ();
7071 add_stmt (nested_sl
);
7075 /* It contains the nested loop. */
7076 add_structured_block_stmt (pre_sl
);
7077 add_stmt (nested_sl
);
7078 sl
= push_stmt_list ();
7080 parser
->error
= false;
7083 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7085 /* Prior to implementing the OpenMP 5.1 syntax for canonical
7086 loop form, GCC used to accept an empty statements that
7087 would now be flagged as intervening code. Continue to
7088 do that, as an extension. */
7089 /* FIXME: Maybe issue a warning or something here? */
7090 c_parser_consume_token (parser
);
7095 /* Standard attributes may start a label, statement or declaration. */
7097 = c_parser_nth_token_starts_std_attributes (parser
, 1);
7098 tree std_attrs
= NULL_TREE
;
7100 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
7101 if (c_parser_next_token_is_keyword (parser
, RID_CASE
)
7102 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
7103 || (c_parser_next_token_is (parser
, CPP_NAME
)
7104 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
7106 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
7107 label_loc
= c_parser_peek_2nd_token (parser
)->location
;
7109 label_loc
= c_parser_peek_token (parser
)->location
;
7112 mark_valid_location_for_stdc_pragma (false);
7113 if (in_omp_loop_block
)
7114 check_omp_intervening_code (parser
);
7115 c_parser_label (parser
, std_attrs
);
7117 else if (c_parser_next_tokens_start_declaration (parser
)
7119 && !c_parser_handle_statement_omp_attributes
7120 (parser
, std_attrs
, &have_std_attrs
)
7121 && c_parser_next_token_is (parser
, CPP_SEMICOLON
)
7122 && (have_std_attrs
= true)))
7125 pedwarn_c11 (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
7126 "a label can only be part of a statement and "
7127 "a declaration is not a statement");
7128 /* It's unlikely we'll see a nested loop in a declaration in
7129 intervening code in an OMP loop, but disallow it anyway. */
7130 if (in_omp_loop_block
)
7132 check_omp_intervening_code (parser
);
7133 omp_for_parse_state
->want_nested_loop
= false;
7135 mark_valid_location_for_stdc_pragma (false);
7136 bool fallthru_attr_p
= false;
7137 c_parser_declaration_or_fndef (parser
, true, !have_std_attrs
,
7138 true, true, true, NULL
,
7139 NULL
, have_std_attrs
, std_attrs
,
7140 NULL
, &fallthru_attr_p
);
7142 if (in_omp_loop_block
)
7143 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7144 if (last_stmt
&& !fallthru_attr_p
)
7145 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
7146 "ISO C90 forbids mixed declarations and code");
7147 last_stmt
= fallthru_attr_p
;
7150 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
7152 /* __extension__ can start a declaration, but is also an
7153 unary operator that can start an expression. Consume all
7154 but the last of a possible series of __extension__ to
7155 determine which. If standard attributes have already
7156 been seen, it must start a statement, not a declaration,
7157 but standard attributes starting a declaration may appear
7158 after __extension__. */
7159 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
7160 && (c_parser_peek_2nd_token (parser
)->keyword
7162 c_parser_consume_token (parser
);
7164 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
7165 || c_parser_nth_token_starts_std_attributes (parser
, 2)))
7168 ext
= disable_extension_diagnostics ();
7169 c_parser_consume_token (parser
);
7171 /* It's unlikely we'll see a nested loop in a declaration in
7172 intervening code in an OMP loop, but disallow it anyway. */
7173 if (in_omp_loop_block
)
7175 check_omp_intervening_code (parser
);
7176 omp_for_parse_state
->want_nested_loop
= false;
7178 mark_valid_location_for_stdc_pragma (false);
7179 c_parser_declaration_or_fndef (parser
, true, true, true, true,
7181 if (in_omp_loop_block
)
7182 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7183 /* Following the old parser, __extension__ does not
7184 disable this diagnostic. */
7185 restore_extension_diagnostics (ext
);
7187 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
7188 "ISO C90 forbids mixed declarations and code");
7194 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
7196 if (have_std_attrs
&& !parser
->in_omp_attribute_pragma
)
7197 c_parser_error (parser
, "expected declaration or statement");
7199 c_warn_unused_attributes (std_attrs
);
7200 /* External pragmas, and some omp pragmas, are not associated
7201 with regular c code, and so are not to be considered statements
7202 syntactically. This ensures that the user doesn't put them
7203 places that would turn into syntax errors if the directive
7205 if (omp_for_parse_state
)
7206 omp_for_parse_state
->want_nested_loop
= false;
7207 if (c_parser_pragma (parser
,
7208 last_label
? pragma_stmt
: pragma_compound
,
7213 if (omp_for_parse_state
)
7214 check_omp_intervening_code (parser
);
7216 if (omp_for_parse_state
)
7217 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7219 else if (c_parser_next_token_is (parser
, CPP_EOF
))
7221 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7222 c_parser_error (parser
, "expected declaration or statement");
7223 return c_parser_peek_token (parser
)->location
;
7225 else if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
7227 if (parser
->in_if_block
)
7229 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7230 error_at (loc
, "expected %<}%> before %<else%>");
7231 return c_parser_peek_token (parser
)->location
;
7235 error_at (loc
, "%<else%> without a previous %<if%>");
7236 c_parser_consume_token (parser
);
7243 c_warn_unused_attributes (std_attrs
);
7246 mark_valid_location_for_stdc_pragma (false);
7247 if (!omp_for_parse_state
)
7248 c_parser_statement_after_labels (parser
, NULL
);
7251 /* In canonical loop nest form, nested loops can only appear
7252 directly, or in a directly nested compound statement. We
7253 already took care of those cases above, so now we have
7254 something else. This statement and everything inside
7255 it must be intervening code. */
7256 omp_for_parse_state
->want_nested_loop
= false;
7257 check_omp_intervening_code (parser
);
7258 c_parser_statement_after_labels (parser
, NULL
);
7259 omp_for_parse_state
->want_nested_loop
= want_nested_loop
;
7263 parser
->error
= false;
7266 pedwarn_c11 (label_loc
, OPT_Wpedantic
, "label at end of compound statement");
7267 location_t endloc
= c_parser_peek_token (parser
)->location
;
7268 c_parser_consume_token (parser
);
7270 /* Restore the value we started with. */
7271 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
7273 /* Package leftover intervening code, or the whole contents of the
7274 compound statement if we were looking for a nested loop in an OMP_FOR
7275 construct and didn't find one. */
7278 sl
= pop_stmt_list (sl
);
7279 if (omp_for_parse_state
->want_nested_loop
)
7282 add_structured_block_stmt (sl
);
7287 /* Parse all consecutive labels, possibly preceded by standard
7288 attributes. In this context, a statement is required, not a
7289 declaration, so attributes must be followed by a statement that is
7290 not just a semicolon. */
7293 c_parser_all_labels (c_parser
*parser
)
7295 bool have_std_attrs
;
7296 tree std_attrs
= NULL
;
7297 if ((have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1)))
7298 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
7299 while (c_parser_next_token_is_keyword (parser
, RID_CASE
)
7300 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
7301 || (c_parser_next_token_is (parser
, CPP_NAME
)
7302 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
7304 c_parser_label (parser
, std_attrs
);
7306 if ((have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
,
7308 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
7311 && (!c_parser_handle_statement_omp_attributes (parser
, std_attrs
, &have_std_attrs
)
7314 if (have_std_attrs
&& c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7315 c_parser_error (parser
, "expected statement");
7316 c_warn_unused_attributes (std_attrs
);
7318 else if (have_std_attrs
&& c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7319 c_parser_error (parser
, "expected statement");
7322 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
7325 identifier : gnu-attributes[opt]
7326 case constant-expression :
7332 case constant-expression ... constant-expression :
7334 The use of gnu-attributes on labels is a GNU extension. The syntax in
7335 GNU C accepts any expressions without commas, non-constant
7336 expressions being rejected later. Any standard
7337 attribute-specifier-sequence before the first label has been parsed
7338 in the caller, to distinguish statements from declarations. Any
7339 attribute-specifier-sequence after the label is parsed in this
7342 c_parser_label (c_parser
*parser
, tree std_attrs
)
7344 location_t loc1
= c_parser_peek_token (parser
)->location
;
7345 tree label
= NULL_TREE
;
7347 /* Remember whether this case or a user-defined label is allowed to fall
7349 bool fallthrough_p
= c_parser_peek_token (parser
)->flags
& PREV_FALLTHROUGH
;
7351 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
7354 c_parser_consume_token (parser
);
7355 exp1
= convert_lvalue_to_rvalue (loc1
,
7356 c_parser_expr_no_commas (parser
, NULL
),
7358 if (c_parser_next_token_is (parser
, CPP_COLON
))
7360 c_parser_consume_token (parser
);
7361 label
= do_case (loc1
, exp1
, NULL_TREE
, std_attrs
);
7363 else if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
7365 c_parser_consume_token (parser
);
7366 exp2
= convert_lvalue_to_rvalue (loc1
,
7367 c_parser_expr_no_commas (parser
,
7370 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7371 label
= do_case (loc1
, exp1
, exp2
, std_attrs
);
7374 c_parser_error (parser
, "expected %<:%> or %<...%>");
7376 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
7378 c_parser_consume_token (parser
);
7379 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7380 label
= do_case (loc1
, NULL_TREE
, NULL_TREE
, std_attrs
);
7384 tree name
= c_parser_peek_token (parser
)->value
;
7387 location_t loc2
= c_parser_peek_token (parser
)->location
;
7388 gcc_assert (c_parser_next_token_is (parser
, CPP_NAME
));
7389 c_parser_consume_token (parser
);
7390 gcc_assert (c_parser_next_token_is (parser
, CPP_COLON
));
7391 c_parser_consume_token (parser
);
7392 attrs
= c_parser_gnu_attributes (parser
);
7393 tlab
= define_label (loc2
, name
);
7396 decl_attributes (&tlab
, attrs
, 0);
7397 decl_attributes (&tlab
, std_attrs
, 0);
7398 label
= add_stmt (build_stmt (loc1
, LABEL_EXPR
, tlab
));
7401 && c_parser_next_tokens_start_declaration (parser
))
7402 warning_at (loc2
, OPT_Wattributes
, "GNU-style attribute between"
7403 " label and declaration appertains to the label");
7407 if (TREE_CODE (label
) == LABEL_EXPR
)
7408 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label
)) = fallthrough_p
;
7410 FALLTHROUGH_LABEL_P (CASE_LABEL (label
)) = fallthrough_p
;
7414 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
7418 attribute-specifier-sequence[opt] compound-statement
7419 expression-statement
7420 attribute-specifier-sequence[opt] selection-statement
7421 attribute-specifier-sequence[opt] iteration-statement
7422 attribute-specifier-sequence[opt] jump-statement
7425 attribute-specifier-sequence[opt] label statement
7427 expression-statement:
7429 attribute-specifier-sequence expression ;
7431 selection-statement:
7435 iteration-statement:
7444 return expression[opt] ;
7449 attribute-specifier-sequence[opt] asm-statement
7454 expression-statement:
7460 attribute-specifier-sequence[opt] objc-throw-statement
7461 attribute-specifier-sequence[opt] objc-try-catch-statement
7462 attribute-specifier-sequence[opt] objc-synchronized-statement
7464 objc-throw-statement:
7471 attribute-specifier-sequence[opt] openacc-construct
7480 parallel-directive structured-block
7483 kernels-directive structured-block
7486 data-directive structured-block
7489 loop-directive structured-block
7494 attribute-specifier-sequence[opt] openmp-construct
7503 parallel-for-construct
7504 parallel-for-simd-construct
7505 parallel-sections-construct
7512 parallel-directive structured-block
7515 for-directive iteration-statement
7518 simd-directive iteration-statements
7521 for-simd-directive iteration-statements
7524 sections-directive section-scope
7527 single-directive structured-block
7529 parallel-for-construct:
7530 parallel-for-directive iteration-statement
7532 parallel-for-simd-construct:
7533 parallel-for-simd-directive iteration-statement
7535 parallel-sections-construct:
7536 parallel-sections-directive section-scope
7539 master-directive structured-block
7542 critical-directive structured-block
7545 atomic-directive expression-statement
7548 ordered-directive structured-block
7550 Transactional Memory:
7553 attribute-specifier-sequence[opt] transaction-statement
7554 attribute-specifier-sequence[opt] transaction-cancel-statement
7556 IF_P is used to track whether there's a (possibly labeled) if statement
7557 which is not enclosed in braces and has an else clause. This is used to
7558 implement -Wparentheses. */
7561 c_parser_statement (c_parser
*parser
, bool *if_p
, location_t
*loc_after_labels
)
7563 c_parser_all_labels (parser
);
7564 if (loc_after_labels
)
7565 *loc_after_labels
= c_parser_peek_token (parser
)->location
;
7566 parser
->omp_attrs_forbidden_p
= false;
7567 c_parser_statement_after_labels (parser
, if_p
, NULL
);
7570 /* Parse a statement, other than a labeled statement. CHAIN is a vector
7571 of if-else-if conditions. All labels and standard attributes have
7572 been parsed in the caller.
7574 IF_P is used to track whether there's a (possibly labeled) if statement
7575 which is not enclosed in braces and has an else clause. This is used to
7576 implement -Wparentheses. */
7579 c_parser_statement_after_labels (c_parser
*parser
, bool *if_p
,
7582 location_t loc
= c_parser_peek_token (parser
)->location
;
7583 tree stmt
= NULL_TREE
;
7584 bool in_if_block
= parser
->in_if_block
;
7585 parser
->in_if_block
= false;
7589 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_BRACE
)
7590 add_debug_begin_stmt (loc
);
7593 switch (c_parser_peek_token (parser
)->type
)
7595 case CPP_OPEN_BRACE
:
7596 add_stmt (c_parser_compound_statement (parser
));
7599 switch (c_parser_peek_token (parser
)->keyword
)
7602 c_parser_if_statement (parser
, if_p
, chain
);
7605 c_parser_switch_statement (parser
, if_p
);
7608 c_parser_while_statement (parser
, false, 0, false, if_p
);
7611 c_parser_do_statement (parser
, false, 0, false);
7614 c_parser_for_statement (parser
, false, 0, false, if_p
);
7617 c_parser_consume_token (parser
);
7618 if (c_parser_next_token_is (parser
, CPP_NAME
))
7620 stmt
= c_finish_goto_label (loc
,
7621 c_parser_peek_token (parser
)->value
);
7622 c_parser_consume_token (parser
);
7624 else if (c_parser_next_token_is (parser
, CPP_MULT
))
7628 c_parser_consume_token (parser
);
7629 val
= c_parser_expression (parser
);
7630 val
= convert_lvalue_to_rvalue (loc
, val
, false, true);
7631 stmt
= c_finish_goto_ptr (loc
, val
);
7634 c_parser_error (parser
, "expected identifier or %<*%>");
7635 goto expect_semicolon
;
7637 c_parser_consume_token (parser
);
7638 stmt
= c_finish_bc_stmt (loc
, objc_foreach_continue_label
, false);
7639 goto expect_semicolon
;
7641 c_parser_consume_token (parser
);
7642 stmt
= c_finish_bc_stmt (loc
, objc_foreach_break_label
, true);
7643 goto expect_semicolon
;
7645 c_parser_consume_token (parser
);
7646 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7648 stmt
= c_finish_return (loc
, NULL_TREE
, NULL_TREE
);
7649 c_parser_consume_token (parser
);
7653 location_t xloc
= c_parser_peek_token (parser
)->location
;
7654 struct c_expr expr
= c_parser_expression_conv (parser
);
7655 mark_exp_read (expr
.value
);
7656 stmt
= c_finish_return (EXPR_LOC_OR_LOC (expr
.value
, xloc
),
7657 expr
.value
, expr
.original_type
);
7658 goto expect_semicolon
;
7662 stmt
= c_parser_asm_statement (parser
);
7664 case RID_TRANSACTION_ATOMIC
:
7665 case RID_TRANSACTION_RELAXED
:
7666 stmt
= c_parser_transaction (parser
,
7667 c_parser_peek_token (parser
)->keyword
);
7669 case RID_TRANSACTION_CANCEL
:
7670 stmt
= c_parser_transaction_cancel (parser
);
7671 goto expect_semicolon
;
7673 gcc_assert (c_dialect_objc ());
7674 c_parser_consume_token (parser
);
7675 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7677 stmt
= objc_build_throw_stmt (loc
, NULL_TREE
);
7678 c_parser_consume_token (parser
);
7682 struct c_expr expr
= c_parser_expression (parser
);
7683 expr
= convert_lvalue_to_rvalue (loc
, expr
, false, false);
7684 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
7685 stmt
= objc_build_throw_stmt (loc
, expr
.value
);
7686 goto expect_semicolon
;
7690 gcc_assert (c_dialect_objc ());
7691 c_parser_objc_try_catch_finally_statement (parser
);
7693 case RID_AT_SYNCHRONIZED
:
7694 gcc_assert (c_dialect_objc ());
7695 c_parser_objc_synchronized_statement (parser
);
7699 /* Allow '__attribute__((fallthrough));' or
7700 '__attribute__((assume(cond)));'. */
7701 tree attrs
= c_parser_gnu_attributes (parser
);
7702 bool has_assume
= lookup_attribute ("assume", attrs
);
7705 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7706 attrs
= handle_assume_attribute (loc
, attrs
, true);
7709 warning_at (loc
, OPT_Wattributes
,
7710 "%<assume%> attribute not followed by %<;%>");
7714 if (attribute_fallthrough_p (attrs
))
7716 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7718 tree fn
= build_call_expr_internal_loc (loc
,
7723 c_parser_consume_token (parser
);
7726 warning_at (loc
, OPT_Wattributes
,
7727 "%<fallthrough%> attribute not followed "
7730 else if (has_assume
)
7732 c_parser_consume_token (parser
);
7733 else if (attrs
!= NULL_TREE
)
7734 warning_at (loc
, OPT_Wattributes
,
7735 "only attribute %<fallthrough%> or %<assume%> can "
7736 "be applied to a null statement");
7744 c_parser_consume_token (parser
);
7746 case CPP_CLOSE_PAREN
:
7747 case CPP_CLOSE_SQUARE
:
7748 /* Avoid infinite loop in error recovery:
7749 c_parser_skip_until_found stops at a closing nesting
7750 delimiter without consuming it, but here we need to consume
7751 it to proceed further. */
7752 c_parser_error (parser
, "expected statement");
7753 c_parser_consume_token (parser
);
7756 if (!c_parser_pragma (parser
, pragma_stmt
, if_p
))
7761 stmt
= c_finish_expr_stmt (loc
, c_parser_expression_conv (parser
).value
);
7763 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
7766 /* Two cases cannot and do not have line numbers associated: If stmt
7767 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
7768 cannot hold line numbers. But that's OK because the statement
7769 will either be changed to a MODIFY_EXPR during gimplification of
7770 the statement expr, or discarded. If stmt was compound, but
7771 without new variables, we will have skipped the creation of a
7772 BIND and will have a bare STATEMENT_LIST. But that's OK because
7773 (recursively) all of the component statements should already have
7774 line numbers assigned. ??? Can we discard no-op statements
7776 if (EXPR_LOCATION (stmt
) == UNKNOWN_LOCATION
)
7777 protected_set_expr_location (stmt
, loc
);
7779 parser
->in_if_block
= in_if_block
;
7782 /* Parse the condition from an if, do, while or for statements. */
7785 c_parser_condition (c_parser
*parser
)
7787 location_t loc
= c_parser_peek_token (parser
)->location
;
7789 cond
= c_parser_expression_conv (parser
).value
;
7790 cond
= c_objc_common_truthvalue_conversion (loc
, cond
);
7791 cond
= c_fully_fold (cond
, false, NULL
);
7792 if (warn_sequence_point
)
7793 verify_sequence_points (cond
);
7797 /* Parse a parenthesized condition from an if, do or while statement.
7803 c_parser_paren_condition (c_parser
*parser
)
7806 matching_parens parens
;
7807 if (!parens
.require_open (parser
))
7808 return error_mark_node
;
7809 cond
= c_parser_condition (parser
);
7810 parens
.skip_until_found_close (parser
);
7814 /* Parse a statement which is a block in C99.
7816 IF_P is used to track whether there's a (possibly labeled) if statement
7817 which is not enclosed in braces and has an else clause. This is used to
7818 implement -Wparentheses. */
7821 c_parser_c99_block_statement (c_parser
*parser
, bool *if_p
,
7822 location_t
*loc_after_labels
)
7824 tree block
= c_begin_compound_stmt (flag_isoc99
);
7825 location_t loc
= c_parser_peek_token (parser
)->location
;
7826 c_parser_statement (parser
, if_p
, loc_after_labels
);
7827 return c_end_compound_stmt (loc
, block
, flag_isoc99
);
7830 /* Parse the body of an if statement. This is just parsing a
7831 statement but (a) it is a block in C99, (b) we track whether the
7832 body is an if statement for the sake of -Wparentheses warnings, (c)
7833 we handle an empty body specially for the sake of -Wempty-body
7834 warnings, and (d) we call parser_compound_statement directly
7835 because c_parser_statement_after_labels resets
7836 parser->in_if_block.
7838 IF_P is used to track whether there's a (possibly labeled) if statement
7839 which is not enclosed in braces and has an else clause. This is used to
7840 implement -Wparentheses. */
7843 c_parser_if_body (c_parser
*parser
, bool *if_p
,
7844 const token_indent_info
&if_tinfo
)
7846 tree block
= c_begin_compound_stmt (flag_isoc99
);
7847 location_t body_loc
= c_parser_peek_token (parser
)->location
;
7848 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
7849 token_indent_info body_tinfo
7850 = get_token_indent_info (c_parser_peek_token (parser
));
7852 c_parser_all_labels (parser
);
7853 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7855 location_t loc
= c_parser_peek_token (parser
)->location
;
7856 add_stmt (build_empty_stmt (loc
));
7857 c_parser_consume_token (parser
);
7858 if (!c_parser_next_token_is_keyword (parser
, RID_ELSE
))
7859 warning_at (loc
, OPT_Wempty_body
,
7860 "suggest braces around empty body in an %<if%> statement");
7862 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7863 add_stmt (c_parser_compound_statement (parser
));
7866 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
7867 c_parser_statement_after_labels (parser
, if_p
);
7870 token_indent_info next_tinfo
7871 = get_token_indent_info (c_parser_peek_token (parser
));
7872 warn_for_misleading_indentation (if_tinfo
, body_tinfo
, next_tinfo
);
7873 if (body_loc_after_labels
!= UNKNOWN_LOCATION
7874 && next_tinfo
.type
!= CPP_SEMICOLON
)
7875 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
7876 if_tinfo
.location
, RID_IF
);
7878 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
7881 /* Parse the else body of an if statement. This is just parsing a
7882 statement but (a) it is a block in C99, (b) we handle an empty body
7883 specially for the sake of -Wempty-body warnings. CHAIN is a vector
7884 of if-else-if conditions. */
7887 c_parser_else_body (c_parser
*parser
, const token_indent_info
&else_tinfo
,
7890 location_t body_loc
= c_parser_peek_token (parser
)->location
;
7891 tree block
= c_begin_compound_stmt (flag_isoc99
);
7892 token_indent_info body_tinfo
7893 = get_token_indent_info (c_parser_peek_token (parser
));
7894 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
7896 c_parser_all_labels (parser
);
7897 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7899 location_t loc
= c_parser_peek_token (parser
)->location
;
7902 "suggest braces around empty body in an %<else%> statement");
7903 add_stmt (build_empty_stmt (loc
));
7904 c_parser_consume_token (parser
);
7908 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
7909 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
7910 c_parser_statement_after_labels (parser
, NULL
, chain
);
7913 token_indent_info next_tinfo
7914 = get_token_indent_info (c_parser_peek_token (parser
));
7915 warn_for_misleading_indentation (else_tinfo
, body_tinfo
, next_tinfo
);
7916 if (body_loc_after_labels
!= UNKNOWN_LOCATION
7917 && next_tinfo
.type
!= CPP_SEMICOLON
)
7918 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
7919 else_tinfo
.location
, RID_ELSE
);
7921 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
7924 /* We might need to reclassify any previously-lexed identifier, e.g.
7925 when we've left a for loop with an if-statement without else in the
7926 body - we might have used a wrong scope for the token. See PR67784. */
7929 c_parser_maybe_reclassify_token (c_parser
*parser
)
7931 if (c_parser_next_token_is (parser
, CPP_NAME
))
7933 c_token
*token
= c_parser_peek_token (parser
);
7935 if (token
->id_kind
!= C_ID_CLASSNAME
)
7937 tree decl
= lookup_name (token
->value
);
7939 token
->id_kind
= C_ID_ID
;
7942 if (TREE_CODE (decl
) == TYPE_DECL
)
7943 token
->id_kind
= C_ID_TYPENAME
;
7945 else if (c_dialect_objc ())
7947 tree objc_interface_decl
= objc_is_class_name (token
->value
);
7948 /* Objective-C class names are in the same namespace as
7949 variables and typedefs, and hence are shadowed by local
7951 if (objc_interface_decl
)
7953 token
->value
= objc_interface_decl
;
7954 token
->id_kind
= C_ID_CLASSNAME
;
7961 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
7964 if ( expression ) statement
7965 if ( expression ) statement else statement
7967 CHAIN is a vector of if-else-if conditions.
7968 IF_P is used to track whether there's a (possibly labeled) if statement
7969 which is not enclosed in braces and has an else clause. This is used to
7970 implement -Wparentheses. */
7973 c_parser_if_statement (c_parser
*parser
, bool *if_p
, vec
<tree
> *chain
)
7978 bool nested_if
= false;
7979 tree first_body
, second_body
;
7982 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_IF
));
7983 token_indent_info if_tinfo
7984 = get_token_indent_info (c_parser_peek_token (parser
));
7985 c_parser_consume_token (parser
);
7986 block
= c_begin_compound_stmt (flag_isoc99
);
7987 loc
= c_parser_peek_token (parser
)->location
;
7988 cond
= c_parser_paren_condition (parser
);
7989 in_if_block
= parser
->in_if_block
;
7990 parser
->in_if_block
= true;
7991 first_body
= c_parser_if_body (parser
, &nested_if
, if_tinfo
);
7992 parser
->in_if_block
= in_if_block
;
7994 if (warn_duplicated_cond
)
7995 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond
), cond
, &chain
);
7997 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
7999 token_indent_info else_tinfo
8000 = get_token_indent_info (c_parser_peek_token (parser
));
8001 c_parser_consume_token (parser
);
8002 if (warn_duplicated_cond
)
8004 if (c_parser_next_token_is_keyword (parser
, RID_IF
)
8007 /* We've got "if (COND) else if (COND2)". Start the
8008 condition chain and add COND as the first element. */
8009 chain
= new vec
<tree
> ();
8010 if (!CONSTANT_CLASS_P (cond
) && !TREE_SIDE_EFFECTS (cond
))
8011 chain
->safe_push (cond
);
8013 else if (!c_parser_next_token_is_keyword (parser
, RID_IF
))
8014 /* This is if-else without subsequent if. Zap the condition
8015 chain; we would have already warned at this point. */
8018 second_body
= c_parser_else_body (parser
, else_tinfo
, chain
);
8019 /* Set IF_P to true to indicate that this if statement has an
8020 else clause. This may trigger the Wparentheses warning
8021 below when we get back up to the parent if statement. */
8027 second_body
= NULL_TREE
;
8029 /* Diagnose an ambiguous else if if-then-else is nested inside
8032 warning_at (loc
, OPT_Wdangling_else
,
8033 "suggest explicit braces to avoid ambiguous %<else%>");
8035 if (warn_duplicated_cond
)
8036 /* This if statement does not have an else clause. We don't
8037 need the condition chain anymore. */
8040 c_finish_if_stmt (loc
, cond
, first_body
, second_body
);
8041 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
8043 c_parser_maybe_reclassify_token (parser
);
8046 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
8049 switch (expression) statement
8053 c_parser_switch_statement (c_parser
*parser
, bool *if_p
)
8056 tree block
, expr
, body
;
8057 unsigned char save_in_statement
;
8058 location_t switch_loc
= c_parser_peek_token (parser
)->location
;
8059 location_t switch_cond_loc
;
8060 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SWITCH
));
8061 c_parser_consume_token (parser
);
8062 block
= c_begin_compound_stmt (flag_isoc99
);
8063 bool explicit_cast_p
= false;
8064 matching_parens parens
;
8065 if (parens
.require_open (parser
))
8067 switch_cond_loc
= c_parser_peek_token (parser
)->location
;
8068 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8069 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8070 explicit_cast_p
= true;
8071 ce
= c_parser_expression (parser
);
8072 ce
= convert_lvalue_to_rvalue (switch_cond_loc
, ce
, true, true);
8074 /* ??? expr has no valid location? */
8075 parens
.skip_until_found_close (parser
);
8079 switch_cond_loc
= UNKNOWN_LOCATION
;
8080 expr
= error_mark_node
;
8081 ce
.original_type
= error_mark_node
;
8083 c_start_switch (switch_loc
, switch_cond_loc
, expr
, explicit_cast_p
);
8084 save_in_statement
= in_statement
;
8085 in_statement
|= IN_SWITCH_STMT
;
8086 location_t loc_after_labels
;
8087 bool open_brace_p
= c_parser_peek_token (parser
)->type
== CPP_OPEN_BRACE
;
8088 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
8089 location_t next_loc
= c_parser_peek_token (parser
)->location
;
8090 if (!open_brace_p
&& c_parser_peek_token (parser
)->type
!= CPP_SEMICOLON
)
8091 warn_for_multistatement_macros (loc_after_labels
, next_loc
, switch_loc
,
8093 c_finish_switch (body
, ce
.original_type
);
8094 in_statement
= save_in_statement
;
8095 add_stmt (c_end_compound_stmt (switch_loc
, block
, flag_isoc99
));
8096 c_parser_maybe_reclassify_token (parser
);
8099 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8102 while (expression) statement
8104 IF_P is used to track whether there's a (possibly labeled) if statement
8105 which is not enclosed in braces and has an else clause. This is used to
8106 implement -Wparentheses. */
8109 c_parser_while_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
8110 bool novector
, bool *if_p
)
8112 tree block
, cond
, body
;
8113 unsigned char save_in_statement
;
8115 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_WHILE
));
8116 token_indent_info while_tinfo
8117 = get_token_indent_info (c_parser_peek_token (parser
));
8119 if (parser
->omp_for_parse_state
)
8121 error_at (c_parser_peek_token (parser
)->location
,
8122 "loop not permitted in intervening code in OpenMP loop body");
8123 parser
->omp_for_parse_state
->fail
= true;
8126 c_parser_consume_token (parser
);
8127 block
= c_begin_compound_stmt (flag_isoc99
);
8128 loc
= c_parser_peek_token (parser
)->location
;
8129 cond
= c_parser_paren_condition (parser
);
8130 if (ivdep
&& cond
!= error_mark_node
)
8131 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8132 build_int_cst (integer_type_node
,
8133 annot_expr_ivdep_kind
),
8135 if (unroll
&& cond
!= error_mark_node
)
8136 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8137 build_int_cst (integer_type_node
,
8138 annot_expr_unroll_kind
),
8139 build_int_cst (integer_type_node
, unroll
));
8140 if (novector
&& cond
!= error_mark_node
)
8141 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8142 build_int_cst (integer_type_node
,
8143 annot_expr_no_vector_kind
),
8145 save_in_statement
= in_statement
;
8146 in_statement
= IN_ITERATION_STMT
;
8148 token_indent_info body_tinfo
8149 = get_token_indent_info (c_parser_peek_token (parser
));
8151 location_t loc_after_labels
;
8152 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
8153 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
8154 add_stmt (build_stmt (loc
, WHILE_STMT
, cond
, body
));
8155 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
8156 c_parser_maybe_reclassify_token (parser
);
8158 token_indent_info next_tinfo
8159 = get_token_indent_info (c_parser_peek_token (parser
));
8160 warn_for_misleading_indentation (while_tinfo
, body_tinfo
, next_tinfo
);
8162 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
8163 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
8164 while_tinfo
.location
, RID_WHILE
);
8166 in_statement
= save_in_statement
;
8169 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8172 do statement while ( expression ) ;
8176 c_parser_do_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
8179 tree block
, cond
, body
;
8180 unsigned char save_in_statement
;
8182 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_DO
));
8184 if (parser
->omp_for_parse_state
)
8186 error_at (c_parser_peek_token (parser
)->location
,
8187 "loop not permitted in intervening code in OpenMP loop body");
8188 parser
->omp_for_parse_state
->fail
= true;
8191 c_parser_consume_token (parser
);
8192 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
8193 warning_at (c_parser_peek_token (parser
)->location
,
8195 "suggest braces around empty body in %<do%> statement");
8196 block
= c_begin_compound_stmt (flag_isoc99
);
8197 loc
= c_parser_peek_token (parser
)->location
;
8198 save_in_statement
= in_statement
;
8199 in_statement
= IN_ITERATION_STMT
;
8200 body
= c_parser_c99_block_statement (parser
, NULL
);
8201 c_parser_require_keyword (parser
, RID_WHILE
, "expected %<while%>");
8202 in_statement
= save_in_statement
;
8203 cond
= c_parser_paren_condition (parser
);
8204 if (ivdep
&& cond
!= error_mark_node
)
8205 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8206 build_int_cst (integer_type_node
,
8207 annot_expr_ivdep_kind
),
8209 if (unroll
&& cond
!= error_mark_node
)
8210 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8211 build_int_cst (integer_type_node
,
8212 annot_expr_unroll_kind
),
8213 build_int_cst (integer_type_node
, unroll
));
8214 if (novector
&& cond
!= error_mark_node
)
8215 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8216 build_int_cst (integer_type_node
,
8217 annot_expr_no_vector_kind
),
8219 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
8220 c_parser_skip_to_end_of_block_or_statement (parser
);
8222 add_stmt (build_stmt (loc
, DO_STMT
, cond
, body
));
8223 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
8226 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
8229 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
8230 for ( nested-declaration expression[opt] ; expression[opt] ) statement
8232 The form with a declaration is new in C99.
8234 ??? In accordance with the old parser, the declaration may be a
8235 nested function, which is then rejected in check_for_loop_decls,
8236 but does it make any sense for this to be included in the grammar?
8237 Note in particular that the nested function does not include a
8238 trailing ';', whereas the "declaration" production includes one.
8239 Also, can we reject bad declarations earlier and cheaper than
8240 check_for_loop_decls?
8242 In Objective-C, there are two additional variants:
8245 for ( expression in expresssion ) statement
8246 for ( declaration in expression ) statement
8248 This is inconsistent with C, because the second variant is allowed
8249 even if c99 is not enabled.
8251 The rest of the comment documents these Objective-C foreach-statement.
8253 Here is the canonical example of the first variant:
8254 for (object in array) { do something with object }
8255 we call the first expression ("object") the "object_expression" and
8256 the second expression ("array") the "collection_expression".
8257 object_expression must be an lvalue of type "id" (a generic Objective-C
8258 object) because the loop works by assigning to object_expression the
8259 various objects from the collection_expression. collection_expression
8260 must evaluate to something of type "id" which responds to the method
8261 countByEnumeratingWithState:objects:count:.
8263 The canonical example of the second variant is:
8264 for (id object in array) { do something with object }
8265 which is completely equivalent to
8268 for (object in array) { do something with object }
8270 Note that initizializing 'object' in some way (eg, "for ((object =
8271 xxx) in array) { do something with object }") is possibly
8272 technically valid, but completely pointless as 'object' will be
8273 assigned to something else as soon as the loop starts. We should
8274 most likely reject it (TODO).
8276 The beginning of the Objective-C foreach-statement looks exactly
8277 like the beginning of the for-statement, and we can tell it is a
8278 foreach-statement only because the initial declaration or
8279 expression is terminated by 'in' instead of ';'.
8281 IF_P is used to track whether there's a (possibly labeled) if statement
8282 which is not enclosed in braces and has an else clause. This is used to
8283 implement -Wparentheses. */
8286 c_parser_for_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
8287 bool novector
, bool *if_p
)
8289 tree block
, cond
, incr
, body
;
8290 unsigned char save_in_statement
;
8291 tree save_objc_foreach_break_label
, save_objc_foreach_continue_label
;
8292 /* The following are only used when parsing an ObjC foreach statement. */
8293 tree object_expression
;
8294 /* Silence the bogus uninitialized warning. */
8295 tree collection_expression
= NULL
;
8296 location_t loc
= c_parser_peek_token (parser
)->location
;
8297 location_t for_loc
= loc
;
8298 bool is_foreach_statement
= false;
8299 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
8300 token_indent_info for_tinfo
8301 = get_token_indent_info (c_parser_peek_token (parser
));
8303 if (parser
->omp_for_parse_state
)
8306 "loop not permitted in intervening code in OpenMP loop body");
8307 parser
->omp_for_parse_state
->fail
= true;
8310 c_parser_consume_token (parser
);
8311 /* Open a compound statement in Objective-C as well, just in case this is
8312 as foreach expression. */
8313 block
= c_begin_compound_stmt (flag_isoc99
|| c_dialect_objc ());
8314 cond
= error_mark_node
;
8315 incr
= error_mark_node
;
8316 matching_parens parens
;
8317 if (parens
.require_open (parser
))
8319 /* Parse the initialization declaration or expression. */
8320 object_expression
= error_mark_node
;
8321 parser
->objc_could_be_foreach_context
= c_dialect_objc ();
8322 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
8324 parser
->objc_could_be_foreach_context
= false;
8325 c_parser_consume_token (parser
);
8326 c_finish_expr_stmt (loc
, NULL_TREE
);
8328 else if (c_parser_next_tokens_start_declaration (parser
)
8329 || c_parser_nth_token_starts_std_attributes (parser
, 1))
8331 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
8332 &object_expression
);
8333 parser
->objc_could_be_foreach_context
= false;
8335 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
8337 c_parser_consume_token (parser
);
8338 is_foreach_statement
= true;
8339 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
8340 c_parser_error (parser
, "multiple iterating variables in "
8341 "fast enumeration");
8344 check_for_loop_decls (for_loc
, flag_isoc99
);
8346 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
8348 /* __extension__ can start a declaration, but is also an
8349 unary operator that can start an expression. Consume all
8350 but the last of a possible series of __extension__ to
8352 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
8353 && (c_parser_peek_2nd_token (parser
)->keyword
8355 c_parser_consume_token (parser
);
8356 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
8357 || c_parser_nth_token_starts_std_attributes (parser
, 2))
8360 ext
= disable_extension_diagnostics ();
8361 c_parser_consume_token (parser
);
8362 c_parser_declaration_or_fndef (parser
, true, true, true, true,
8363 true, &object_expression
);
8364 parser
->objc_could_be_foreach_context
= false;
8366 restore_extension_diagnostics (ext
);
8367 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
8369 c_parser_consume_token (parser
);
8370 is_foreach_statement
= true;
8371 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
8372 c_parser_error (parser
, "multiple iterating variables in "
8373 "fast enumeration");
8376 check_for_loop_decls (for_loc
, flag_isoc99
);
8386 tree init_expression
;
8387 ce
= c_parser_expression (parser
);
8388 init_expression
= ce
.value
;
8389 parser
->objc_could_be_foreach_context
= false;
8390 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
8392 c_parser_consume_token (parser
);
8393 is_foreach_statement
= true;
8394 if (! lvalue_p (init_expression
))
8395 c_parser_error (parser
, "invalid iterating variable in "
8396 "fast enumeration");
8398 = c_fully_fold (init_expression
, false, NULL
);
8402 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
8403 init_expression
= ce
.value
;
8404 c_finish_expr_stmt (loc
, init_expression
);
8405 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
8410 /* Parse the loop condition. In the case of a foreach
8411 statement, there is no loop condition. */
8412 gcc_assert (!parser
->objc_could_be_foreach_context
);
8413 if (!is_foreach_statement
)
8415 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
8419 c_parser_error (parser
, "missing loop condition in loop "
8420 "with %<GCC ivdep%> pragma");
8421 cond
= error_mark_node
;
8425 c_parser_error (parser
, "missing loop condition in loop "
8426 "with %<GCC unroll%> pragma");
8427 cond
= error_mark_node
;
8431 c_parser_consume_token (parser
);
8437 cond
= c_parser_condition (parser
);
8438 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
8441 if (ivdep
&& cond
!= error_mark_node
)
8442 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8443 build_int_cst (integer_type_node
,
8444 annot_expr_ivdep_kind
),
8446 if (unroll
&& cond
!= error_mark_node
)
8447 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8448 build_int_cst (integer_type_node
,
8449 annot_expr_unroll_kind
),
8450 build_int_cst (integer_type_node
, unroll
));
8451 if (novector
&& cond
&& cond
!= error_mark_node
)
8452 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
8453 build_int_cst (integer_type_node
,
8454 annot_expr_no_vector_kind
),
8457 /* Parse the increment expression (the third expression in a
8458 for-statement). In the case of a foreach-statement, this is
8459 the expression that follows the 'in'. */
8460 loc
= c_parser_peek_token (parser
)->location
;
8461 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8463 if (is_foreach_statement
)
8465 c_parser_error (parser
,
8466 "missing collection in fast enumeration");
8467 collection_expression
= error_mark_node
;
8470 incr
= c_process_expr_stmt (loc
, NULL_TREE
);
8474 if (is_foreach_statement
)
8475 collection_expression
8476 = c_fully_fold (c_parser_expression (parser
).value
, false, NULL
);
8479 struct c_expr ce
= c_parser_expression (parser
);
8480 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
8481 incr
= c_process_expr_stmt (loc
, ce
.value
);
8484 parens
.skip_until_found_close (parser
);
8486 save_in_statement
= in_statement
;
8487 if (is_foreach_statement
)
8489 in_statement
= IN_OBJC_FOREACH
;
8490 save_objc_foreach_break_label
= objc_foreach_break_label
;
8491 save_objc_foreach_continue_label
= objc_foreach_continue_label
;
8492 objc_foreach_break_label
= create_artificial_label (loc
);
8493 objc_foreach_continue_label
= create_artificial_label (loc
);
8496 in_statement
= IN_ITERATION_STMT
;
8498 token_indent_info body_tinfo
8499 = get_token_indent_info (c_parser_peek_token (parser
));
8501 location_t loc_after_labels
;
8502 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
8503 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
8505 if (is_foreach_statement
)
8506 objc_finish_foreach_loop (for_loc
, object_expression
,
8507 collection_expression
, body
,
8508 objc_foreach_break_label
,
8509 objc_foreach_continue_label
);
8511 add_stmt (build_stmt (for_loc
, FOR_STMT
, NULL_TREE
, cond
, incr
,
8513 add_stmt (c_end_compound_stmt (for_loc
, block
,
8514 flag_isoc99
|| c_dialect_objc ()));
8515 c_parser_maybe_reclassify_token (parser
);
8517 token_indent_info next_tinfo
8518 = get_token_indent_info (c_parser_peek_token (parser
));
8519 warn_for_misleading_indentation (for_tinfo
, body_tinfo
, next_tinfo
);
8521 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
8522 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
8523 for_tinfo
.location
, RID_FOR
);
8525 in_statement
= save_in_statement
;
8526 if (is_foreach_statement
)
8528 objc_foreach_break_label
= save_objc_foreach_break_label
;
8529 objc_foreach_continue_label
= save_objc_foreach_continue_label
;
8533 /* Parse an asm statement, a GNU extension. This is a full-blown asm
8534 statement with inputs, outputs, clobbers, and volatile, inline, and goto
8543 asm-qualifier-list asm-qualifier
8547 asm asm-qualifier-list[opt] ( asm-argument ) ;
8551 asm-string-literal : asm-operands[opt]
8552 asm-string-literal : asm-operands[opt] : asm-operands[opt]
8553 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
8555 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
8558 The form with asm-goto-operands is valid if and only if the
8559 asm-qualifier-list contains goto, and is the only allowed form in that case.
8560 Duplicate asm-qualifiers are not allowed.
8562 The :: token is considered equivalent to two consecutive : tokens. */
8565 c_parser_asm_statement (c_parser
*parser
)
8567 tree str
, outputs
, inputs
, clobbers
, labels
, ret
;
8569 location_t asm_loc
= c_parser_peek_token (parser
)->location
;
8570 int section
, nsections
;
8572 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
8573 c_parser_consume_token (parser
);
8575 /* Handle the asm-qualifier-list. */
8576 location_t volatile_loc
= UNKNOWN_LOCATION
;
8577 location_t inline_loc
= UNKNOWN_LOCATION
;
8578 location_t goto_loc
= UNKNOWN_LOCATION
;
8581 c_token
*token
= c_parser_peek_token (parser
);
8582 location_t loc
= token
->location
;
8583 switch (token
->keyword
)
8588 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
8589 inform (volatile_loc
, "first seen here");
8593 c_parser_consume_token (parser
);
8599 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
8600 inform (inline_loc
, "first seen here");
8604 c_parser_consume_token (parser
);
8610 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
8611 inform (goto_loc
, "first seen here");
8615 c_parser_consume_token (parser
);
8620 error_at (loc
, "%qE is not a valid %<asm%> qualifier", token
->value
);
8621 c_parser_consume_token (parser
);
8630 bool is_volatile
= (volatile_loc
!= UNKNOWN_LOCATION
);
8631 bool is_inline
= (inline_loc
!= UNKNOWN_LOCATION
);
8632 bool is_goto
= (goto_loc
!= UNKNOWN_LOCATION
);
8636 matching_parens parens
;
8637 if (!parens
.require_open (parser
))
8640 str
= c_parser_asm_string_literal (parser
);
8641 if (str
== NULL_TREE
)
8642 goto error_close_paren
;
8645 outputs
= NULL_TREE
;
8647 clobbers
= NULL_TREE
;
8650 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
8653 /* Parse each colon-delimited section of operands. */
8654 nsections
= 3 + is_goto
;
8655 for (section
= 0; section
< nsections
; ++section
)
8657 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
8660 if (section
== nsections
)
8662 c_parser_error (parser
, "expected %<)%>");
8663 goto error_close_paren
;
8665 c_parser_consume_token (parser
);
8667 else if (!c_parser_require (parser
, CPP_COLON
,
8669 ? G_("expected %<:%>")
8670 : G_("expected %<:%> or %<)%>"),
8671 UNKNOWN_LOCATION
, is_goto
))
8672 goto error_close_paren
;
8674 /* Once past any colon, we're no longer a simple asm. */
8677 if ((!c_parser_next_token_is (parser
, CPP_COLON
)
8678 && !c_parser_next_token_is (parser
, CPP_SCOPE
)
8679 && !c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8684 outputs
= c_parser_asm_operands (parser
);
8687 inputs
= c_parser_asm_operands (parser
);
8690 clobbers
= c_parser_asm_clobbers (parser
);
8693 labels
= c_parser_asm_goto_operands (parser
);
8699 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
8704 if (!parens
.require_close (parser
))
8706 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8710 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
8711 c_parser_skip_to_end_of_block_or_statement (parser
);
8713 ret
= build_asm_stmt (is_volatile
,
8714 build_asm_expr (asm_loc
, str
, outputs
, inputs
,
8715 clobbers
, labels
, simple
, is_inline
));
8721 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8725 /* Parse asm operands, a GNU extension.
8729 asm-operands , asm-operand
8732 asm-string-literal ( expression )
8733 [ identifier ] asm-string-literal ( expression )
8737 c_parser_asm_operands (c_parser
*parser
)
8739 tree list
= NULL_TREE
;
8744 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
8746 c_parser_consume_token (parser
);
8747 if (c_parser_next_token_is (parser
, CPP_NAME
))
8749 tree id
= c_parser_peek_token (parser
)->value
;
8750 c_parser_consume_token (parser
);
8751 name
= build_string (IDENTIFIER_LENGTH (id
),
8752 IDENTIFIER_POINTER (id
));
8756 c_parser_error (parser
, "expected identifier");
8757 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
8760 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
8765 str
= c_parser_asm_string_literal (parser
);
8766 if (str
== NULL_TREE
)
8768 matching_parens parens
;
8769 if (!parens
.require_open (parser
))
8771 expr
= c_parser_expression (parser
);
8772 mark_exp_read (expr
.value
);
8773 if (!parens
.require_close (parser
))
8775 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8778 list
= chainon (list
, build_tree_list (build_tree_list (name
, str
),
8780 if (c_parser_next_token_is (parser
, CPP_COMMA
))
8781 c_parser_consume_token (parser
);
8788 /* Parse asm clobbers, a GNU extension.
8792 asm-clobbers , asm-string-literal
8796 c_parser_asm_clobbers (c_parser
*parser
)
8798 tree list
= NULL_TREE
;
8801 tree str
= c_parser_asm_string_literal (parser
);
8803 list
= tree_cons (NULL_TREE
, str
, list
);
8806 if (c_parser_next_token_is (parser
, CPP_COMMA
))
8807 c_parser_consume_token (parser
);
8814 /* Parse asm goto labels, a GNU extension.
8818 asm-goto-operands , identifier
8822 c_parser_asm_goto_operands (c_parser
*parser
)
8824 tree list
= NULL_TREE
;
8829 if (c_parser_next_token_is (parser
, CPP_NAME
))
8831 c_token
*tok
= c_parser_peek_token (parser
);
8833 label
= lookup_label_for_goto (tok
->location
, name
);
8834 c_parser_consume_token (parser
);
8835 TREE_USED (label
) = 1;
8839 c_parser_error (parser
, "expected identifier");
8843 name
= build_string (IDENTIFIER_LENGTH (name
),
8844 IDENTIFIER_POINTER (name
));
8845 list
= tree_cons (name
, label
, list
);
8846 if (c_parser_next_token_is (parser
, CPP_COMMA
))
8847 c_parser_consume_token (parser
);
8849 return nreverse (list
);
8853 /* Parse a possibly concatenated sequence of string literals.
8854 TRANSLATE says whether to translate them to the execution character
8855 set; WIDE_OK says whether any kind of prefixed string literal is
8856 permitted in this context. This code is based on that in
8860 c_parser_string_literal (c_parser
*parser
, bool translate
, bool wide_ok
)
8864 struct obstack str_ob
;
8865 struct obstack loc_ob
;
8866 cpp_string str
, istr
, *strs
;
8868 location_t loc
, last_tok_loc
;
8869 enum cpp_ttype type
;
8870 tree value
, string_tree
;
8872 tok
= c_parser_peek_token (parser
);
8873 loc
= tok
->location
;
8874 last_tok_loc
= linemap_resolve_location (line_table
, loc
,
8875 LRK_MACRO_DEFINITION_LOCATION
,
8884 case CPP_UTF8STRING
:
8885 string_tree
= tok
->value
;
8889 c_parser_error (parser
, "expected string literal");
8891 ret
.value
= NULL_TREE
;
8892 ret
.original_code
= ERROR_MARK
;
8893 ret
.original_type
= NULL_TREE
;
8897 /* Try to avoid the overhead of creating and destroying an obstack
8898 for the common case of just one string. */
8899 switch (c_parser_peek_2nd_token (parser
)->type
)
8902 c_parser_consume_token (parser
);
8903 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
8904 str
.len
= TREE_STRING_LENGTH (string_tree
);
8913 case CPP_UTF8STRING
:
8914 gcc_obstack_init (&str_ob
);
8915 gcc_obstack_init (&loc_ob
);
8919 c_parser_consume_token (parser
);
8921 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
8922 str
.len
= TREE_STRING_LENGTH (string_tree
);
8923 if (type
!= tok
->type
)
8925 if (type
== CPP_STRING
)
8927 else if (tok
->type
!= CPP_STRING
)
8928 error ("unsupported non-standard concatenation "
8929 "of string literals");
8931 obstack_grow (&str_ob
, &str
, sizeof (cpp_string
));
8932 obstack_grow (&loc_ob
, &last_tok_loc
, sizeof (location_t
));
8933 tok
= c_parser_peek_token (parser
);
8934 string_tree
= tok
->value
;
8936 = linemap_resolve_location (line_table
, tok
->location
,
8937 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
8939 while (tok
->type
== CPP_STRING
8940 || tok
->type
== CPP_WSTRING
8941 || tok
->type
== CPP_STRING16
8942 || tok
->type
== CPP_STRING32
8943 || tok
->type
== CPP_UTF8STRING
);
8944 strs
= (cpp_string
*) obstack_finish (&str_ob
);
8947 if (count
> 1 && !in_system_header_at (input_location
))
8948 warning (OPT_Wtraditional
,
8949 "traditional C rejects string constant concatenation");
8951 if ((type
== CPP_STRING
|| wide_ok
)
8953 ? cpp_interpret_string
: cpp_interpret_string_notranslate
)
8954 (parse_in
, strs
, count
, &istr
, type
)))
8956 value
= build_string (istr
.len
, (const char *) istr
.text
);
8957 free (CONST_CAST (unsigned char *, istr
.text
));
8960 location_t
*locs
= (location_t
*) obstack_finish (&loc_ob
);
8961 gcc_assert (g_string_concat_db
);
8962 g_string_concat_db
->record_string_concatenation (count
, locs
);
8967 if (type
!= CPP_STRING
&& !wide_ok
)
8969 error_at (loc
, "a wide string is invalid in this context");
8972 /* Callers cannot generally handle error_mark_node in this
8973 context, so return the empty string instead. An error has
8974 been issued, either above or from cpp_interpret_string. */
8979 case CPP_UTF8STRING
:
8980 if (type
== CPP_UTF8STRING
&& flag_char8_t
)
8982 value
= build_string (TYPE_PRECISION (char8_type_node
)
8983 / TYPE_PRECISION (char_type_node
),
8984 ""); /* char8_t is 8 bits */
8987 value
= build_string (1, "");
8990 value
= build_string (TYPE_PRECISION (char16_type_node
)
8991 / TYPE_PRECISION (char_type_node
),
8992 "\0"); /* char16_t is 16 bits */
8995 value
= build_string (TYPE_PRECISION (char32_type_node
)
8996 / TYPE_PRECISION (char_type_node
),
8997 "\0\0\0"); /* char32_t is 32 bits */
9000 value
= build_string (TYPE_PRECISION (wchar_type_node
)
9001 / TYPE_PRECISION (char_type_node
),
9002 "\0\0\0"); /* widest supported wchar_t
9012 TREE_TYPE (value
) = char_array_type_node
;
9014 case CPP_UTF8STRING
:
9016 TREE_TYPE (value
) = char8_array_type_node
;
9018 TREE_TYPE (value
) = char_array_type_node
;
9021 TREE_TYPE (value
) = char16_array_type_node
;
9024 TREE_TYPE (value
) = char32_array_type_node
;
9027 TREE_TYPE (value
) = wchar_array_type_node
;
9029 value
= fix_string_type (value
);
9033 obstack_free (&str_ob
, 0);
9034 obstack_free (&loc_ob
, 0);
9038 ret
.original_code
= STRING_CST
;
9039 ret
.original_type
= NULL_TREE
;
9040 set_c_expr_source_range (&ret
, get_range_from_loc (line_table
, loc
));
9042 parser
->seen_string_literal
= true;
9046 /* Parse an expression other than a compound expression; that is, an
9047 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
9048 AFTER is not NULL then it is an Objective-C message expression which
9049 is the primary-expression starting the expression as an initializer.
9051 assignment-expression:
9052 conditional-expression
9053 unary-expression assignment-operator assignment-expression
9055 assignment-operator: one of
9056 = *= /= %= += -= <<= >>= &= ^= |=
9058 In GNU C we accept any conditional expression on the LHS and
9059 diagnose the invalid lvalue rather than producing a syntax
9062 static struct c_expr
9063 c_parser_expr_no_commas (c_parser
*parser
, struct c_expr
*after
,
9064 tree omp_atomic_lhs
)
9066 struct c_expr lhs
, rhs
, ret
;
9067 enum tree_code code
;
9068 location_t op_location
, exp_location
;
9069 bool save_in_omp_for
= c_in_omp_for
;
9070 c_in_omp_for
= false;
9071 gcc_assert (!after
|| c_dialect_objc ());
9072 lhs
= c_parser_conditional_expression (parser
, after
, omp_atomic_lhs
);
9073 op_location
= c_parser_peek_token (parser
)->location
;
9074 switch (c_parser_peek_token (parser
)->type
)
9083 code
= TRUNC_DIV_EXPR
;
9086 code
= TRUNC_MOD_EXPR
;
9101 code
= BIT_AND_EXPR
;
9104 code
= BIT_XOR_EXPR
;
9107 code
= BIT_IOR_EXPR
;
9110 c_in_omp_for
= save_in_omp_for
;
9113 c_parser_consume_token (parser
);
9114 exp_location
= c_parser_peek_token (parser
)->location
;
9115 rhs
= c_parser_expr_no_commas (parser
, NULL
);
9116 rhs
= convert_lvalue_to_rvalue (exp_location
, rhs
, true, true);
9118 ret
.value
= build_modify_expr (op_location
, lhs
.value
, lhs
.original_type
,
9119 code
, exp_location
, rhs
.value
,
9122 set_c_expr_source_range (&ret
, lhs
.get_start (), rhs
.get_finish ());
9123 if (code
== NOP_EXPR
)
9124 ret
.original_code
= MODIFY_EXPR
;
9127 suppress_warning (ret
.value
, OPT_Wparentheses
);
9128 ret
.original_code
= ERROR_MARK
;
9130 ret
.original_type
= NULL
;
9131 c_in_omp_for
= save_in_omp_for
;
9135 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
9136 AFTER is not NULL then it is an Objective-C message expression which is
9137 the primary-expression starting the expression as an initializer.
9139 conditional-expression:
9140 logical-OR-expression
9141 logical-OR-expression ? expression : conditional-expression
9145 conditional-expression:
9146 logical-OR-expression ? : conditional-expression
9149 static struct c_expr
9150 c_parser_conditional_expression (c_parser
*parser
, struct c_expr
*after
,
9151 tree omp_atomic_lhs
)
9153 struct c_expr cond
, exp1
, exp2
, ret
;
9154 location_t start
, cond_loc
, colon_loc
;
9155 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
9157 gcc_assert (!after
|| c_dialect_objc ());
9159 cond
= c_parser_binary_expression (parser
, after
, omp_atomic_lhs
);
9161 if (c_parser_next_token_is_not (parser
, CPP_QUERY
))
9163 c_omp_array_section_p
= false;
9164 if (cond
.value
!= error_mark_node
)
9165 start
= cond
.get_start ();
9167 start
= UNKNOWN_LOCATION
;
9168 cond_loc
= c_parser_peek_token (parser
)->location
;
9169 cond
= convert_lvalue_to_rvalue (cond_loc
, cond
, true, true);
9170 c_parser_consume_token (parser
);
9171 if (c_parser_next_token_is (parser
, CPP_COLON
))
9173 tree eptype
= NULL_TREE
;
9175 location_t middle_loc
= c_parser_peek_token (parser
)->location
;
9176 pedwarn (middle_loc
, OPT_Wpedantic
,
9177 "ISO C forbids omitting the middle term of a %<?:%> expression");
9178 if (TREE_CODE (cond
.value
) == EXCESS_PRECISION_EXPR
)
9180 eptype
= TREE_TYPE (cond
.value
);
9181 cond
.value
= TREE_OPERAND (cond
.value
, 0);
9183 tree e
= cond
.value
;
9184 while (TREE_CODE (e
) == COMPOUND_EXPR
)
9185 e
= TREE_OPERAND (e
, 1);
9186 warn_for_omitted_condop (middle_loc
, e
);
9187 /* Make sure first operand is calculated only once. */
9188 exp1
.value
= save_expr (default_conversion (cond
.value
));
9190 exp1
.value
= build1 (EXCESS_PRECISION_EXPR
, eptype
, exp1
.value
);
9191 exp1
.original_type
= NULL
;
9192 exp1
.src_range
= cond
.src_range
;
9193 cond
.value
= c_objc_common_truthvalue_conversion (cond_loc
, exp1
.value
);
9194 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_true_node
;
9199 = c_objc_common_truthvalue_conversion
9200 (cond_loc
, default_conversion (cond
.value
));
9201 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_false_node
;
9202 exp1
= c_parser_expression_conv (parser
);
9203 mark_exp_read (exp1
.value
);
9204 c_inhibit_evaluation_warnings
+=
9205 ((cond
.value
== truthvalue_true_node
)
9206 - (cond
.value
== truthvalue_false_node
));
9209 colon_loc
= c_parser_peek_token (parser
)->location
;
9210 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
9212 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
9214 ret
.original_code
= ERROR_MARK
;
9215 ret
.original_type
= NULL
;
9216 c_omp_array_section_p
= save_c_omp_array_section_p
;
9220 location_t exp2_loc
= c_parser_peek_token (parser
)->location
;
9221 exp2
= c_parser_conditional_expression (parser
, NULL
, NULL_TREE
);
9222 exp2
= convert_lvalue_to_rvalue (exp2_loc
, exp2
, true, true);
9224 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
9225 location_t loc1
= make_location (exp1
.get_start (), exp1
.src_range
);
9226 location_t loc2
= make_location (exp2
.get_start (), exp2
.src_range
);
9227 if (UNLIKELY (omp_atomic_lhs
!= NULL
)
9228 && (TREE_CODE (cond
.value
) == GT_EXPR
9229 || TREE_CODE (cond
.value
) == LT_EXPR
9230 || TREE_CODE (cond
.value
) == EQ_EXPR
)
9231 && c_tree_equal (exp2
.value
, omp_atomic_lhs
)
9232 && (c_tree_equal (TREE_OPERAND (cond
.value
, 0), omp_atomic_lhs
)
9233 || c_tree_equal (TREE_OPERAND (cond
.value
, 1), omp_atomic_lhs
)))
9234 ret
.value
= build3_loc (colon_loc
, COND_EXPR
, TREE_TYPE (omp_atomic_lhs
),
9235 cond
.value
, exp1
.value
, exp2
.value
);
9238 = build_conditional_expr (colon_loc
, cond
.value
,
9239 cond
.original_code
== C_MAYBE_CONST_EXPR
,
9240 exp1
.value
, exp1
.original_type
, loc1
,
9241 exp2
.value
, exp2
.original_type
, loc2
);
9242 ret
.original_code
= ERROR_MARK
;
9243 if (exp1
.value
== error_mark_node
|| exp2
.value
== error_mark_node
)
9244 ret
.original_type
= NULL
;
9249 /* If both sides are enum type, the default conversion will have
9250 made the type of the result be an integer type. We want to
9251 remember the enum types we started with. */
9252 t1
= exp1
.original_type
? exp1
.original_type
: TREE_TYPE (exp1
.value
);
9253 t2
= exp2
.original_type
? exp2
.original_type
: TREE_TYPE (exp2
.value
);
9254 ret
.original_type
= ((t1
!= error_mark_node
9255 && t2
!= error_mark_node
9256 && (TYPE_MAIN_VARIANT (t1
)
9257 == TYPE_MAIN_VARIANT (t2
)))
9261 set_c_expr_source_range (&ret
, start
, exp2
.get_finish ());
9263 c_omp_array_section_p
= save_c_omp_array_section_p
;
9267 /* Parse a binary expression; that is, a logical-OR-expression (C90
9268 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
9269 NULL then it is an Objective-C message expression which is the
9270 primary-expression starting the expression as an initializer.
9272 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
9273 when it should be the unfolded lhs. In a valid OpenMP source,
9274 one of the operands of the toplevel binary expression must be equal
9275 to it. In that case, just return a build2 created binary operation
9276 rather than result of parser_build_binary_op.
9278 multiplicative-expression:
9280 multiplicative-expression * cast-expression
9281 multiplicative-expression / cast-expression
9282 multiplicative-expression % cast-expression
9284 additive-expression:
9285 multiplicative-expression
9286 additive-expression + multiplicative-expression
9287 additive-expression - multiplicative-expression
9291 shift-expression << additive-expression
9292 shift-expression >> additive-expression
9294 relational-expression:
9296 relational-expression < shift-expression
9297 relational-expression > shift-expression
9298 relational-expression <= shift-expression
9299 relational-expression >= shift-expression
9301 equality-expression:
9302 relational-expression
9303 equality-expression == relational-expression
9304 equality-expression != relational-expression
9308 AND-expression & equality-expression
9310 exclusive-OR-expression:
9312 exclusive-OR-expression ^ AND-expression
9314 inclusive-OR-expression:
9315 exclusive-OR-expression
9316 inclusive-OR-expression | exclusive-OR-expression
9318 logical-AND-expression:
9319 inclusive-OR-expression
9320 logical-AND-expression && inclusive-OR-expression
9322 logical-OR-expression:
9323 logical-AND-expression
9324 logical-OR-expression || logical-AND-expression
9327 static struct c_expr
9328 c_parser_binary_expression (c_parser
*parser
, struct c_expr
*after
,
9329 tree omp_atomic_lhs
)
9331 /* A binary expression is parsed using operator-precedence parsing,
9332 with the operands being cast expressions. All the binary
9333 operators are left-associative. Thus a binary expression is of
9336 E0 op1 E1 op2 E2 ...
9338 which we represent on a stack. On the stack, the precedence
9339 levels are strictly increasing. When a new operator is
9340 encountered of higher precedence than that at the top of the
9341 stack, it is pushed; its LHS is the top expression, and its RHS
9342 is everything parsed until it is popped. When a new operator is
9343 encountered with precedence less than or equal to that at the top
9344 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
9345 by the result of the operation until the operator at the top of
9346 the stack has lower precedence than the new operator or there is
9347 only one element on the stack; then the top expression is the LHS
9348 of the new operator. In the case of logical AND and OR
9349 expressions, we also need to adjust c_inhibit_evaluation_warnings
9350 as appropriate when the operators are pushed and popped. */
9353 /* The expression at this stack level. */
9355 /* The precedence of the operator on its left, PREC_NONE at the
9356 bottom of the stack. */
9357 enum c_parser_prec prec
;
9358 /* The operation on its left. */
9360 /* The source location of this operation. */
9362 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
9366 /* Location of the binary operator. */
9367 location_t binary_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
9370 switch (stack[sp].op) \
9372 case TRUTH_ANDIF_EXPR: \
9373 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9374 == truthvalue_false_node); \
9376 case TRUTH_ORIF_EXPR: \
9377 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
9378 == truthvalue_true_node); \
9380 case TRUNC_DIV_EXPR: \
9381 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
9382 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
9383 && (stack[sp].expr.original_code == SIZEOF_EXPR \
9384 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
9386 tree type0 = stack[sp - 1].sizeof_arg; \
9387 tree type1 = stack[sp].sizeof_arg; \
9388 tree first_arg = type0; \
9389 if (!TYPE_P (type0)) \
9390 type0 = TREE_TYPE (type0); \
9391 if (!TYPE_P (type1)) \
9392 type1 = TREE_TYPE (type1); \
9393 if (POINTER_TYPE_P (type0) \
9394 && comptypes (TREE_TYPE (type0), type1) \
9395 && !(TREE_CODE (first_arg) == PARM_DECL \
9396 && C_ARRAY_PARAMETER (first_arg) \
9397 && warn_sizeof_array_argument)) \
9399 auto_diagnostic_group d; \
9400 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
9401 "division %<sizeof (%T) / sizeof (%T)%> " \
9402 "does not compute the number of array " \
9405 if (DECL_P (first_arg)) \
9406 inform (DECL_SOURCE_LOCATION (first_arg), \
9407 "first %<sizeof%> operand was declared here"); \
9409 else if (TREE_CODE (type0) == ARRAY_TYPE \
9410 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
9411 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
9412 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
9413 stack[sp].sizeof_arg, type1); \
9419 stack[sp - 1].expr \
9420 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
9421 stack[sp - 1].expr, true, true); \
9423 = convert_lvalue_to_rvalue (stack[sp].loc, \
9424 stack[sp].expr, true, true); \
9425 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
9426 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
9427 && ((1 << stack[sp].prec) \
9428 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
9429 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
9430 | (1 << PREC_ADD) | (1 << PREC_MULT) \
9431 | (1 << PREC_EQ)))) \
9432 || ((c_parser_next_token_is (parser, CPP_QUERY) \
9433 || (omp_atomic_lhs == void_list_node \
9434 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
9435 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
9436 && stack[sp].op != TRUNC_MOD_EXPR \
9437 && stack[sp].op != GE_EXPR \
9438 && stack[sp].op != LE_EXPR \
9439 && stack[sp].op != NE_EXPR \
9440 && stack[0].expr.value != error_mark_node \
9441 && stack[1].expr.value != error_mark_node \
9442 && (omp_atomic_lhs == void_list_node \
9443 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
9444 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
9445 || (stack[sp].op == EQ_EXPR \
9446 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
9448 tree t = make_node (stack[1].op); \
9449 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
9450 TREE_OPERAND (t, 0) = stack[0].expr.value; \
9451 TREE_OPERAND (t, 1) = stack[1].expr.value; \
9452 stack[0].expr.value = t; \
9453 stack[0].expr.m_decimal = 0; \
9456 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
9458 stack[sp - 1].expr, \
9462 gcc_assert (!after
|| c_dialect_objc ());
9463 stack
[0].loc
= c_parser_peek_token (parser
)->location
;
9464 stack
[0].expr
= c_parser_cast_expression (parser
, after
);
9465 stack
[0].prec
= PREC_NONE
;
9466 stack
[0].sizeof_arg
= c_last_sizeof_arg
;
9470 enum c_parser_prec oprec
;
9471 enum tree_code ocode
;
9472 source_range src_range
;
9475 switch (c_parser_peek_token (parser
)->type
)
9483 ocode
= TRUNC_DIV_EXPR
;
9487 ocode
= TRUNC_MOD_EXPR
;
9499 ocode
= LSHIFT_EXPR
;
9503 ocode
= RSHIFT_EXPR
;
9517 case CPP_GREATER_EQ
:
9530 oprec
= PREC_BITAND
;
9531 ocode
= BIT_AND_EXPR
;
9534 oprec
= PREC_BITXOR
;
9535 ocode
= BIT_XOR_EXPR
;
9539 ocode
= BIT_IOR_EXPR
;
9542 oprec
= PREC_LOGAND
;
9543 ocode
= TRUTH_ANDIF_EXPR
;
9547 ocode
= TRUTH_ORIF_EXPR
;
9550 /* Not a binary operator, so end of the binary
9554 binary_loc
= c_parser_peek_token (parser
)->location
;
9555 while (oprec
<= stack
[sp
].prec
)
9557 c_parser_consume_token (parser
);
9560 case TRUTH_ANDIF_EXPR
:
9561 src_range
= stack
[sp
].expr
.src_range
;
9563 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
9564 stack
[sp
].expr
, true, true);
9565 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
9566 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
9567 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
9568 == truthvalue_false_node
);
9569 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
9571 case TRUTH_ORIF_EXPR
:
9572 src_range
= stack
[sp
].expr
.src_range
;
9574 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
9575 stack
[sp
].expr
, true, true);
9576 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
9577 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
9578 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
9579 == truthvalue_true_node
);
9580 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
9586 stack
[sp
].loc
= binary_loc
;
9587 stack
[sp
].expr
= c_parser_cast_expression (parser
, NULL
);
9588 stack
[sp
].prec
= oprec
;
9589 stack
[sp
].op
= ocode
;
9590 stack
[sp
].sizeof_arg
= c_last_sizeof_arg
;
9595 return stack
[0].expr
;
9599 /* Parse any storage class specifiers after an open parenthesis in a
9600 context where a compound literal is permitted. */
9602 static struct c_declspecs
*
9603 c_parser_compound_literal_scspecs (c_parser
*parser
)
9605 bool seen_scspec
= false;
9606 struct c_declspecs
*specs
= build_null_declspecs ();
9607 while (c_parser_next_token_is (parser
, CPP_KEYWORD
))
9609 switch (c_parser_peek_token (parser
)->keyword
)
9616 declspecs_add_scspec (c_parser_peek_token (parser
)->location
,
9617 specs
, c_parser_peek_token (parser
)->value
);
9618 c_parser_consume_token (parser
);
9625 return seen_scspec
? specs
: NULL
;
9628 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
9629 is not NULL then it is an Objective-C message expression which is the
9630 primary-expression starting the expression as an initializer.
9634 ( type-name ) unary-expression
9637 static struct c_expr
9638 c_parser_cast_expression (c_parser
*parser
, struct c_expr
*after
)
9640 location_t cast_loc
= c_parser_peek_token (parser
)->location
;
9641 gcc_assert (!after
|| c_dialect_objc ());
9643 return c_parser_postfix_expression_after_primary (parser
,
9645 /* If the expression begins with a parenthesized type name, it may
9646 be either a cast or a compound literal; we need to see whether
9647 the next character is '{' to tell the difference. If not, it is
9648 an unary expression. Full detection of unknown typenames here
9649 would require a 3-token lookahead. */
9650 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
9651 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
9653 struct c_declspecs
*scspecs
;
9654 struct c_type_name
*type_name
;
9657 matching_parens parens
;
9658 parens
.consume_open (parser
);
9659 scspecs
= c_parser_compound_literal_scspecs (parser
);
9660 type_name
= c_parser_type_name (parser
, true);
9661 parens
.skip_until_found_close (parser
);
9662 if (type_name
== NULL
)
9665 ret
.original_code
= ERROR_MARK
;
9666 ret
.original_type
= NULL
;
9670 /* Save casted types in the function's used types hash table. */
9671 used_types_insert (type_name
->specs
->type
);
9673 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
9674 return c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
9678 error_at (cast_loc
, "storage class specifier in cast");
9679 if (type_name
->specs
->alignas_p
)
9680 error_at (type_name
->specs
->locations
[cdw_alignas
],
9681 "alignment specified for type name in cast");
9683 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
9684 expr
= c_parser_cast_expression (parser
, NULL
);
9685 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
9687 ret
.value
= c_cast_expr (cast_loc
, type_name
, expr
.value
);
9688 if (ret
.value
&& expr
.value
)
9689 set_c_expr_source_range (&ret
, cast_loc
, expr
.get_finish ());
9690 ret
.original_code
= ERROR_MARK
;
9691 ret
.original_type
= NULL
;
9696 return c_parser_unary_expression (parser
);
9699 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
9705 unary-operator cast-expression
9706 sizeof unary-expression
9707 sizeof ( type-name )
9709 unary-operator: one of
9715 __alignof__ unary-expression
9716 __alignof__ ( type-name )
9719 (C11 permits _Alignof with type names only.)
9721 unary-operator: one of
9722 __extension__ __real__ __imag__
9724 Transactional Memory:
9727 transaction-expression
9729 In addition, the GNU syntax treats ++ and -- as unary operators, so
9730 they may be applied to cast expressions with errors for non-lvalues
9733 static struct c_expr
9734 c_parser_unary_expression (c_parser
*parser
)
9737 struct c_expr ret
, op
;
9738 location_t op_loc
= c_parser_peek_token (parser
)->location
;
9741 ret
.original_code
= ERROR_MARK
;
9742 ret
.original_type
= NULL
;
9743 switch (c_parser_peek_token (parser
)->type
)
9746 c_parser_consume_token (parser
);
9747 exp_loc
= c_parser_peek_token (parser
)->location
;
9748 op
= c_parser_cast_expression (parser
, NULL
);
9750 op
= default_function_array_read_conversion (exp_loc
, op
);
9751 return parser_build_unary_op (op_loc
, PREINCREMENT_EXPR
, op
);
9752 case CPP_MINUS_MINUS
:
9753 c_parser_consume_token (parser
);
9754 exp_loc
= c_parser_peek_token (parser
)->location
;
9755 op
= c_parser_cast_expression (parser
, NULL
);
9757 op
= default_function_array_read_conversion (exp_loc
, op
);
9758 return parser_build_unary_op (op_loc
, PREDECREMENT_EXPR
, op
);
9760 c_parser_consume_token (parser
);
9761 op
= c_parser_cast_expression (parser
, NULL
);
9762 mark_exp_read (op
.value
);
9763 return parser_build_unary_op (op_loc
, ADDR_EXPR
, op
);
9766 c_parser_consume_token (parser
);
9767 exp_loc
= c_parser_peek_token (parser
)->location
;
9768 op
= c_parser_cast_expression (parser
, NULL
);
9769 finish
= op
.get_finish ();
9770 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9771 location_t combined_loc
= make_location (op_loc
, op_loc
, finish
);
9772 ret
.value
= build_indirect_ref (combined_loc
, op
.value
, RO_UNARY_STAR
);
9773 ret
.src_range
.m_start
= op_loc
;
9774 ret
.src_range
.m_finish
= finish
;
9779 if (!c_dialect_objc () && !in_system_header_at (input_location
))
9782 "traditional C rejects the unary plus operator");
9783 c_parser_consume_token (parser
);
9784 exp_loc
= c_parser_peek_token (parser
)->location
;
9785 op
= c_parser_cast_expression (parser
, NULL
);
9786 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9787 return parser_build_unary_op (op_loc
, CONVERT_EXPR
, op
);
9789 c_parser_consume_token (parser
);
9790 exp_loc
= c_parser_peek_token (parser
)->location
;
9791 op
= c_parser_cast_expression (parser
, NULL
);
9792 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9793 return parser_build_unary_op (op_loc
, NEGATE_EXPR
, op
);
9795 c_parser_consume_token (parser
);
9796 exp_loc
= c_parser_peek_token (parser
)->location
;
9797 op
= c_parser_cast_expression (parser
, NULL
);
9798 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9799 return parser_build_unary_op (op_loc
, BIT_NOT_EXPR
, op
);
9801 c_parser_consume_token (parser
);
9802 exp_loc
= c_parser_peek_token (parser
)->location
;
9803 op
= c_parser_cast_expression (parser
, NULL
);
9804 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
9805 return parser_build_unary_op (op_loc
, TRUTH_NOT_EXPR
, op
);
9807 /* Refer to the address of a label as a pointer. */
9808 c_parser_consume_token (parser
);
9809 if (c_parser_next_token_is (parser
, CPP_NAME
))
9811 ret
.value
= finish_label_address_expr
9812 (c_parser_peek_token (parser
)->value
, op_loc
);
9813 set_c_expr_source_range (&ret
, op_loc
,
9814 c_parser_peek_token (parser
)->get_finish ());
9815 c_parser_consume_token (parser
);
9819 c_parser_error (parser
, "expected identifier");
9824 switch (c_parser_peek_token (parser
)->keyword
)
9827 return c_parser_sizeof_expression (parser
);
9829 return c_parser_alignof_expression (parser
);
9830 case RID_BUILTIN_HAS_ATTRIBUTE
:
9831 return c_parser_has_attribute_expression (parser
);
9833 c_parser_consume_token (parser
);
9834 ext
= disable_extension_diagnostics ();
9835 ret
= c_parser_cast_expression (parser
, NULL
);
9836 restore_extension_diagnostics (ext
);
9839 c_parser_consume_token (parser
);
9840 exp_loc
= c_parser_peek_token (parser
)->location
;
9841 op
= c_parser_cast_expression (parser
, NULL
);
9842 op
= default_function_array_conversion (exp_loc
, op
);
9843 return parser_build_unary_op (op_loc
, REALPART_EXPR
, op
);
9845 c_parser_consume_token (parser
);
9846 exp_loc
= c_parser_peek_token (parser
)->location
;
9847 op
= c_parser_cast_expression (parser
, NULL
);
9848 op
= default_function_array_conversion (exp_loc
, op
);
9849 return parser_build_unary_op (op_loc
, IMAGPART_EXPR
, op
);
9850 case RID_TRANSACTION_ATOMIC
:
9851 case RID_TRANSACTION_RELAXED
:
9852 return c_parser_transaction_expression (parser
,
9853 c_parser_peek_token (parser
)->keyword
);
9855 return c_parser_postfix_expression (parser
);
9858 return c_parser_postfix_expression (parser
);
9862 /* Parse a sizeof expression. */
9864 static struct c_expr
9865 c_parser_sizeof_expression (c_parser
*parser
)
9868 struct c_expr result
;
9869 location_t expr_loc
;
9870 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SIZEOF
));
9873 location_t finish
= UNKNOWN_LOCATION
;
9875 start
= c_parser_peek_token (parser
)->location
;
9877 c_parser_consume_token (parser
);
9878 c_inhibit_evaluation_warnings
++;
9880 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
9881 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
9883 /* Either sizeof ( type-name ) or sizeof unary-expression
9884 starting with a compound literal. */
9885 struct c_declspecs
*scspecs
;
9886 struct c_type_name
*type_name
;
9887 matching_parens parens
;
9888 parens
.consume_open (parser
);
9889 expr_loc
= c_parser_peek_token (parser
)->location
;
9890 scspecs
= c_parser_compound_literal_scspecs (parser
);
9891 type_name
= c_parser_type_name (parser
, true);
9892 parens
.skip_until_found_close (parser
);
9893 finish
= parser
->tokens_buf
[0].location
;
9894 if (type_name
== NULL
)
9897 c_inhibit_evaluation_warnings
--;
9900 ret
.original_code
= ERROR_MARK
;
9901 ret
.original_type
= NULL
;
9904 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
9906 expr
= c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
9909 finish
= expr
.get_finish ();
9912 /* sizeof ( type-name ). */
9914 error_at (expr_loc
, "storage class specifier in %<sizeof%>");
9915 if (type_name
->specs
->alignas_p
)
9916 error_at (type_name
->specs
->locations
[cdw_alignas
],
9917 "alignment specified for type name in %<sizeof%>");
9918 c_inhibit_evaluation_warnings
--;
9920 result
= c_expr_sizeof_type (expr_loc
, type_name
);
9924 expr_loc
= c_parser_peek_token (parser
)->location
;
9925 expr
= c_parser_unary_expression (parser
);
9926 finish
= expr
.get_finish ();
9928 c_inhibit_evaluation_warnings
--;
9930 mark_exp_read (expr
.value
);
9931 if (TREE_CODE (expr
.value
) == COMPONENT_REF
9932 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
9933 error_at (expr_loc
, "%<sizeof%> applied to a bit-field");
9934 result
= c_expr_sizeof_expr (expr_loc
, expr
);
9936 if (finish
== UNKNOWN_LOCATION
)
9938 set_c_expr_source_range (&result
, start
, finish
);
9942 /* Parse an alignof expression. */
9944 static struct c_expr
9945 c_parser_alignof_expression (c_parser
*parser
)
9948 location_t start_loc
= c_parser_peek_token (parser
)->location
;
9950 tree alignof_spelling
= c_parser_peek_token (parser
)->value
;
9951 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNOF
));
9952 bool is_c11_alignof
= (strcmp (IDENTIFIER_POINTER (alignof_spelling
),
9954 || strcmp (IDENTIFIER_POINTER (alignof_spelling
),
9956 /* A diagnostic is not required for the use of this identifier in
9957 the implementation namespace; only diagnose it for the C11 or C23
9958 spelling because of existing code using the other spellings. */
9962 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C99 does not support %qE",
9965 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C90 does not support %qE",
9968 c_parser_consume_token (parser
);
9969 c_inhibit_evaluation_warnings
++;
9971 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
9972 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
9974 /* Either __alignof__ ( type-name ) or __alignof__
9975 unary-expression starting with a compound literal. */
9977 struct c_declspecs
*scspecs
;
9978 struct c_type_name
*type_name
;
9980 matching_parens parens
;
9981 parens
.consume_open (parser
);
9982 loc
= c_parser_peek_token (parser
)->location
;
9983 scspecs
= c_parser_compound_literal_scspecs (parser
);
9984 type_name
= c_parser_type_name (parser
, true);
9985 end_loc
= c_parser_peek_token (parser
)->location
;
9986 parens
.skip_until_found_close (parser
);
9987 if (type_name
== NULL
)
9990 c_inhibit_evaluation_warnings
--;
9993 ret
.original_code
= ERROR_MARK
;
9994 ret
.original_type
= NULL
;
9997 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
9999 expr
= c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
10004 /* alignof ( type-name ). */
10006 error_at (loc
, "storage class specifier in %qE", alignof_spelling
);
10007 if (type_name
->specs
->alignas_p
)
10008 error_at (type_name
->specs
->locations
[cdw_alignas
],
10009 "alignment specified for type name in %qE",
10011 c_inhibit_evaluation_warnings
--;
10013 ret
.value
= c_sizeof_or_alignof_type (loc
, groktypename (type_name
,
10015 false, is_c11_alignof
, 1);
10016 ret
.original_code
= ERROR_MARK
;
10017 ret
.original_type
= NULL
;
10018 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
10025 expr
= c_parser_unary_expression (parser
);
10026 end_loc
= expr
.src_range
.m_finish
;
10028 mark_exp_read (expr
.value
);
10029 c_inhibit_evaluation_warnings
--;
10031 if (is_c11_alignof
)
10032 pedwarn (start_loc
,
10033 OPT_Wpedantic
, "ISO C does not allow %<%E (expression)%>",
10035 ret
.value
= c_alignof_expr (start_loc
, expr
.value
);
10036 ret
.original_code
= ERROR_MARK
;
10037 ret
.original_type
= NULL
;
10038 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
10044 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
10047 static struct c_expr
10048 c_parser_has_attribute_expression (c_parser
*parser
)
10050 gcc_assert (c_parser_next_token_is_keyword (parser
,
10051 RID_BUILTIN_HAS_ATTRIBUTE
));
10052 location_t start
= c_parser_peek_token (parser
)->location
;
10053 c_parser_consume_token (parser
);
10055 c_inhibit_evaluation_warnings
++;
10057 matching_parens parens
;
10058 if (!parens
.require_open (parser
))
10060 c_inhibit_evaluation_warnings
--;
10063 struct c_expr result
;
10064 result
.set_error ();
10065 result
.original_code
= ERROR_MARK
;
10066 result
.original_type
= NULL
;
10070 /* Treat the type argument the same way as in typeof for the purposes
10071 of warnings. FIXME: Generalize this so the warning refers to
10072 __builtin_has_attribute rather than typeof. */
10075 /* The first operand: one of DECL, EXPR, or TYPE. */
10076 tree oper
= NULL_TREE
;
10077 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
10079 struct c_type_name
*tname
= c_parser_type_name (parser
);
10083 oper
= groktypename (tname
, NULL
, NULL
);
10084 pop_maybe_used (c_type_variably_modified_p (oper
));
10089 struct c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
10090 c_inhibit_evaluation_warnings
--;
10092 if (cexpr
.value
!= error_mark_node
)
10094 mark_exp_read (cexpr
.value
);
10095 oper
= cexpr
.value
;
10096 tree etype
= TREE_TYPE (oper
);
10097 bool was_vm
= c_type_variably_modified_p (etype
);
10098 /* This is returned with the type so that when the type is
10099 evaluated, this can be evaluated. */
10101 oper
= c_fully_fold (oper
, false, NULL
);
10102 pop_maybe_used (was_vm
);
10106 struct c_expr result
;
10107 result
.original_code
= ERROR_MARK
;
10108 result
.original_type
= NULL
;
10110 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10112 /* Consume the closing parenthesis if that's the next token
10113 in the likely case the built-in was invoked with fewer
10114 than two arguments. */
10115 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10116 c_parser_consume_token (parser
);
10117 c_inhibit_evaluation_warnings
--;
10118 result
.set_error ();
10122 bool save_translate_strings_p
= parser
->translate_strings_p
;
10124 location_t atloc
= c_parser_peek_token (parser
)->location
;
10125 /* Parse a single attribute. Require no leading comma and do not
10126 allow empty attributes. */
10127 tree attr
= c_parser_gnu_attribute (parser
, NULL_TREE
, false, false);
10129 parser
->translate_strings_p
= save_translate_strings_p
;
10131 location_t finish
= c_parser_peek_token (parser
)->location
;
10132 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10133 c_parser_consume_token (parser
);
10136 c_parser_error (parser
, "expected identifier");
10137 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10139 result
.set_error ();
10145 error_at (atloc
, "expected identifier");
10146 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10148 result
.set_error ();
10152 result
.original_code
= INTEGER_CST
;
10153 result
.original_type
= boolean_type_node
;
10155 if (has_attribute (atloc
, oper
, attr
, default_conversion
))
10156 result
.value
= boolean_true_node
;
10158 result
.value
= boolean_false_node
;
10160 set_c_expr_source_range (&result
, start
, finish
);
10161 result
.m_decimal
= 0;
10165 /* Helper function to read arguments of builtins which are interfaces
10166 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
10167 others. The name of the builtin is passed using BNAME parameter.
10168 Function returns true if there were no errors while parsing and
10169 stores the arguments in CEXPR_LIST. If it returns true,
10170 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
10173 c_parser_get_builtin_args (c_parser
*parser
, const char *bname
,
10174 vec
<c_expr_t
, va_gc
> **ret_cexpr_list
,
10175 bool choose_expr_p
,
10176 location_t
*out_close_paren_loc
)
10178 location_t loc
= c_parser_peek_token (parser
)->location
;
10179 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10181 bool saved_force_folding_builtin_constant_p
;
10183 *ret_cexpr_list
= NULL
;
10184 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
10186 error_at (loc
, "cannot take address of %qs", bname
);
10190 c_parser_consume_token (parser
);
10192 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10194 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
10195 c_parser_consume_token (parser
);
10199 saved_force_folding_builtin_constant_p
10200 = force_folding_builtin_constant_p
;
10201 force_folding_builtin_constant_p
|= choose_expr_p
;
10202 expr
= c_parser_expr_no_commas (parser
, NULL
);
10203 force_folding_builtin_constant_p
10204 = saved_force_folding_builtin_constant_p
;
10205 vec_alloc (cexpr_list
, 1);
10206 vec_safe_push (cexpr_list
, expr
);
10207 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10209 c_parser_consume_token (parser
);
10210 expr
= c_parser_expr_no_commas (parser
, NULL
);
10211 vec_safe_push (cexpr_list
, expr
);
10214 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
10215 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
10218 *ret_cexpr_list
= cexpr_list
;
10222 /* This represents a single generic-association. */
10224 struct c_generic_association
10226 /* The location of the starting token of the type. */
10227 location_t type_location
;
10228 /* The association's type, or NULL_TREE for 'default'. */
10230 /* The association's expression. */
10231 struct c_expr expression
;
10234 /* Parse a generic-selection. (C11 6.5.1.1).
10237 _Generic ( assignment-expression , generic-assoc-list )
10239 generic-assoc-list:
10240 generic-association
10241 generic-assoc-list , generic-association
10243 generic-association:
10244 type-name : assignment-expression
10245 default : assignment-expression
10248 static struct c_expr
10249 c_parser_generic_selection (c_parser
*parser
)
10251 struct c_expr selector
, error_expr
;
10252 tree selector_type
;
10253 struct c_generic_association matched_assoc
;
10254 int match_found
= -1;
10255 location_t generic_loc
, selector_loc
;
10257 error_expr
.original_code
= ERROR_MARK
;
10258 error_expr
.original_type
= NULL
;
10259 error_expr
.set_error ();
10260 matched_assoc
.type_location
= UNKNOWN_LOCATION
;
10261 matched_assoc
.type
= NULL_TREE
;
10262 matched_assoc
.expression
= error_expr
;
10264 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_GENERIC
));
10265 generic_loc
= c_parser_peek_token (parser
)->location
;
10266 c_parser_consume_token (parser
);
10268 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
10269 "ISO C99 does not support %<_Generic%>");
10271 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
10272 "ISO C90 does not support %<_Generic%>");
10274 matching_parens parens
;
10275 if (!parens
.require_open (parser
))
10278 c_inhibit_evaluation_warnings
++;
10279 selector_loc
= c_parser_peek_token (parser
)->location
;
10280 selector
= c_parser_expr_no_commas (parser
, NULL
);
10281 selector
= default_function_array_conversion (selector_loc
, selector
);
10282 c_inhibit_evaluation_warnings
--;
10284 if (selector
.value
== error_mark_node
)
10286 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10289 mark_exp_read (selector
.value
);
10290 selector_type
= TREE_TYPE (selector
.value
);
10291 /* In ISO C terms, rvalues (including the controlling expression of
10292 _Generic) do not have qualified types. */
10293 if (TREE_CODE (selector_type
) != ARRAY_TYPE
)
10294 selector_type
= TYPE_MAIN_VARIANT (selector_type
);
10295 /* In ISO C terms, _Noreturn is not part of the type of expressions
10296 such as &abort, but in GCC it is represented internally as a type
10298 if (FUNCTION_POINTER_TYPE_P (selector_type
)
10299 && TYPE_QUALS (TREE_TYPE (selector_type
)) != TYPE_UNQUALIFIED
)
10301 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type
)));
10303 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10305 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10309 auto_vec
<c_generic_association
> associations
;
10312 struct c_generic_association assoc
, *iter
;
10314 c_token
*token
= c_parser_peek_token (parser
);
10316 assoc
.type_location
= token
->location
;
10317 if (token
->type
== CPP_KEYWORD
&& token
->keyword
== RID_DEFAULT
)
10319 c_parser_consume_token (parser
);
10320 assoc
.type
= NULL_TREE
;
10324 struct c_type_name
*type_name
;
10326 type_name
= c_parser_type_name (parser
);
10327 if (type_name
== NULL
)
10329 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10332 assoc
.type
= groktypename (type_name
, NULL
, NULL
);
10333 if (assoc
.type
== error_mark_node
)
10335 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10339 if (TREE_CODE (assoc
.type
) == FUNCTION_TYPE
)
10340 error_at (assoc
.type_location
,
10341 "%<_Generic%> association has function type");
10342 else if (!COMPLETE_TYPE_P (assoc
.type
))
10343 error_at (assoc
.type_location
,
10344 "%<_Generic%> association has incomplete type");
10346 if (c_type_variably_modified_p (assoc
.type
))
10347 error_at (assoc
.type_location
,
10348 "%<_Generic%> association has "
10349 "variable length type");
10352 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
10354 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10358 bool match
= assoc
.type
== NULL_TREE
10359 || comptypes (assoc
.type
, selector_type
);
10362 c_inhibit_evaluation_warnings
++;
10364 assoc
.expression
= c_parser_expr_no_commas (parser
, NULL
);
10367 c_inhibit_evaluation_warnings
--;
10369 if (assoc
.expression
.value
== error_mark_node
)
10371 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10375 for (ix
= 0; associations
.iterate (ix
, &iter
); ++ix
)
10377 if (assoc
.type
== NULL_TREE
)
10379 if (iter
->type
== NULL_TREE
)
10381 error_at (assoc
.type_location
,
10382 "duplicate %<default%> case in %<_Generic%>");
10383 inform (iter
->type_location
, "original %<default%> is here");
10386 else if (iter
->type
!= NULL_TREE
)
10388 if (comptypes (assoc
.type
, iter
->type
))
10390 error_at (assoc
.type_location
,
10391 "%<_Generic%> specifies two compatible types");
10392 inform (iter
->type_location
, "compatible type is here");
10397 if (assoc
.type
== NULL_TREE
)
10399 if (match_found
< 0)
10401 matched_assoc
= assoc
;
10402 match_found
= associations
.length ();
10407 if (match_found
< 0 || matched_assoc
.type
== NULL_TREE
)
10409 matched_assoc
= assoc
;
10410 match_found
= associations
.length ();
10414 error_at (assoc
.type_location
,
10415 "%<_Generic%> selector matches multiple associations");
10416 inform (matched_assoc
.type_location
,
10417 "other match is here");
10421 associations
.safe_push (assoc
);
10423 if (c_parser_peek_token (parser
)->type
!= CPP_COMMA
)
10425 c_parser_consume_token (parser
);
10429 struct c_generic_association
*iter
;
10430 FOR_EACH_VEC_ELT (associations
, ix
, iter
)
10431 if (ix
!= (unsigned) match_found
)
10432 mark_exp_read (iter
->expression
.value
);
10434 if (!parens
.require_close (parser
))
10436 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10440 if (match_found
< 0)
10442 error_at (selector_loc
, "%<_Generic%> selector of type %qT is not "
10443 "compatible with any association",
10448 return matched_assoc
.expression
;
10451 /* Check the validity of a function pointer argument *EXPR (argument
10452 position POS) to __builtin_tgmath. Return the number of function
10453 arguments if possibly valid; return 0 having reported an error if
10456 static unsigned int
10457 check_tgmath_function (c_expr
*expr
, unsigned int pos
)
10459 tree type
= TREE_TYPE (expr
->value
);
10460 if (!FUNCTION_POINTER_TYPE_P (type
))
10462 error_at (expr
->get_location (),
10463 "argument %u of %<__builtin_tgmath%> is not a function pointer",
10467 type
= TREE_TYPE (type
);
10468 if (!prototype_p (type
))
10470 error_at (expr
->get_location (),
10471 "argument %u of %<__builtin_tgmath%> is unprototyped", pos
);
10474 if (stdarg_p (type
))
10476 error_at (expr
->get_location (),
10477 "argument %u of %<__builtin_tgmath%> has variable arguments",
10481 unsigned int nargs
= 0;
10482 function_args_iterator iter
;
10484 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
10486 if (t
== void_type_node
)
10492 error_at (expr
->get_location (),
10493 "argument %u of %<__builtin_tgmath%> has no arguments", pos
);
10499 /* Ways in which a parameter or return value of a type-generic macro
10500 may vary between the different functions the macro may call. */
10501 enum tgmath_parm_kind
10503 tgmath_fixed
, tgmath_real
, tgmath_complex
10506 /* Helper function for c_parser_postfix_expression. Parse predefined
10509 static struct c_expr
10510 c_parser_predefined_identifier (c_parser
*parser
)
10512 location_t loc
= c_parser_peek_token (parser
)->location
;
10513 switch (c_parser_peek_token (parser
)->keyword
)
10515 case RID_FUNCTION_NAME
:
10516 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
10517 "identifier", "__FUNCTION__");
10519 case RID_PRETTY_FUNCTION_NAME
:
10520 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
10521 "identifier", "__PRETTY_FUNCTION__");
10523 case RID_C99_FUNCTION_NAME
:
10524 pedwarn_c90 (loc
, OPT_Wpedantic
, "ISO C90 does not support "
10525 "%<__func__%> predefined identifier");
10528 gcc_unreachable ();
10531 struct c_expr expr
;
10532 expr
.original_code
= ERROR_MARK
;
10533 expr
.original_type
= NULL
;
10534 expr
.value
= fname_decl (loc
, c_parser_peek_token (parser
)->keyword
,
10535 c_parser_peek_token (parser
)->value
);
10536 set_c_expr_source_range (&expr
, loc
, loc
);
10537 expr
.m_decimal
= 0;
10538 c_parser_consume_token (parser
);
10542 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
10543 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
10544 call c_parser_postfix_expression_after_paren_type on encountering them.
10546 postfix-expression:
10548 postfix-expression [ expression ]
10549 postfix-expression ( argument-expression-list[opt] )
10550 postfix-expression . identifier
10551 postfix-expression -> identifier
10552 postfix-expression ++
10553 postfix-expression --
10554 ( storage-class-specifiers[opt] type-name ) { initializer-list[opt] }
10555 ( storage-class-specifiers[opt] type-name ) { initializer-list , }
10557 argument-expression-list:
10558 argument-expression
10559 argument-expression-list , argument-expression
10561 primary-expression:
10570 primary-expression:
10572 (treated as a keyword in GNU C)
10574 __PRETTY_FUNCTION__
10575 ( compound-statement )
10576 __builtin_va_arg ( assignment-expression , type-name )
10577 __builtin_offsetof ( type-name , offsetof-member-designator )
10578 __builtin_choose_expr ( assignment-expression ,
10579 assignment-expression ,
10580 assignment-expression )
10581 __builtin_types_compatible_p ( type-name , type-name )
10582 __builtin_tgmath ( expr-list )
10583 __builtin_complex ( assignment-expression , assignment-expression )
10584 __builtin_shuffle ( assignment-expression , assignment-expression )
10585 __builtin_shuffle ( assignment-expression ,
10586 assignment-expression ,
10587 assignment-expression, )
10588 __builtin_convertvector ( assignment-expression , type-name )
10589 __builtin_assoc_barrier ( assignment-expression )
10591 offsetof-member-designator:
10593 offsetof-member-designator . identifier
10594 offsetof-member-designator [ expression ]
10598 primary-expression:
10599 [ objc-receiver objc-message-args ]
10600 @selector ( objc-selector-arg )
10601 @protocol ( identifier )
10602 @encode ( type-name )
10603 objc-string-literal
10604 Classname . identifier
10607 static struct c_expr
10608 c_parser_postfix_expression (c_parser
*parser
)
10610 struct c_expr expr
, e1
;
10611 struct c_type_name
*t1
, *t2
;
10612 location_t loc
= c_parser_peek_token (parser
)->location
;
10613 source_range tok_range
= c_parser_peek_token (parser
)->get_range ();
10614 expr
.original_code
= ERROR_MARK
;
10615 expr
.original_type
= NULL
;
10616 expr
.m_decimal
= 0;
10617 switch (c_parser_peek_token (parser
)->type
)
10620 expr
.value
= c_parser_peek_token (parser
)->value
;
10621 set_c_expr_source_range (&expr
, tok_range
);
10622 loc
= c_parser_peek_token (parser
)->location
;
10623 expr
.m_decimal
= c_parser_peek_token (parser
)->flags
& DECIMAL_INT
;
10624 c_parser_consume_token (parser
);
10625 if (TREE_CODE (expr
.value
) == FIXED_CST
10626 && !targetm
.fixed_point_supported_p ())
10628 error_at (loc
, "fixed-point types not supported for this target");
10637 expr
.value
= c_parser_peek_token (parser
)->value
;
10638 /* For the purpose of warning when a pointer is compared with
10639 a zero character constant. */
10640 expr
.original_type
= char_type_node
;
10641 set_c_expr_source_range (&expr
, tok_range
);
10642 c_parser_consume_token (parser
);
10648 case CPP_UTF8STRING
:
10649 expr
= c_parser_string_literal (parser
, parser
->translate_strings_p
,
10652 case CPP_OBJC_STRING
:
10653 gcc_assert (c_dialect_objc ());
10655 = objc_build_string_object (c_parser_peek_token (parser
)->value
);
10656 set_c_expr_source_range (&expr
, tok_range
);
10657 c_parser_consume_token (parser
);
10660 switch (c_parser_peek_token (parser
)->id_kind
)
10664 tree id
= c_parser_peek_token (parser
)->value
;
10665 c_parser_consume_token (parser
);
10666 expr
.value
= build_external_ref (loc
, id
,
10667 (c_parser_peek_token (parser
)->type
10668 == CPP_OPEN_PAREN
),
10669 &expr
.original_type
);
10670 set_c_expr_source_range (&expr
, tok_range
);
10673 case C_ID_CLASSNAME
:
10675 /* Here we parse the Objective-C 2.0 Class.name dot
10677 tree class_name
= c_parser_peek_token (parser
)->value
;
10679 c_parser_consume_token (parser
);
10680 gcc_assert (c_dialect_objc ());
10681 if (!c_parser_require (parser
, CPP_DOT
, "expected %<.%>"))
10686 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10688 c_parser_error (parser
, "expected identifier");
10692 c_token
*component_tok
= c_parser_peek_token (parser
);
10693 component
= component_tok
->value
;
10694 location_t end_loc
= component_tok
->get_finish ();
10695 c_parser_consume_token (parser
);
10696 expr
.value
= objc_build_class_component_ref (class_name
,
10698 set_c_expr_source_range (&expr
, loc
, end_loc
);
10702 c_parser_error (parser
, "expected expression");
10707 case CPP_OPEN_PAREN
:
10708 /* A parenthesized expression, statement expression or compound
10710 if (c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_BRACE
)
10712 /* A statement expression. */
10714 location_t brace_loc
;
10715 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
10716 c_parser_consume_token (parser
);
10717 brace_loc
= c_parser_peek_token (parser
)->location
;
10718 c_parser_consume_token (parser
);
10719 /* If we've not yet started the current function's statement list,
10720 or we're in the parameter scope of an old-style function
10721 declaration, statement expressions are not allowed. */
10722 if (!building_stmt_list_p () || old_style_parameter_scope ())
10724 error_at (loc
, "braced-group within expression allowed "
10725 "only inside a function");
10726 parser
->error
= true;
10727 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
10728 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10732 c_omp_array_section_p
= false;
10733 stmt
= c_begin_stmt_expr ();
10734 c_parser_compound_statement_nostart (parser
);
10735 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10736 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10738 pedwarn (loc
, OPT_Wpedantic
,
10739 "ISO C forbids braced-groups within expressions");
10740 expr
.value
= c_finish_stmt_expr (brace_loc
, stmt
);
10741 set_c_expr_source_range (&expr
, loc
, close_loc
);
10742 mark_exp_read (expr
.value
);
10743 c_omp_array_section_p
= save_c_omp_array_section_p
;
10747 /* A parenthesized expression. */
10748 location_t loc_open_paren
= c_parser_peek_token (parser
)->location
;
10749 c_parser_consume_token (parser
);
10750 expr
= c_parser_expression (parser
);
10751 if (TREE_CODE (expr
.value
) == MODIFY_EXPR
)
10752 suppress_warning (expr
.value
, OPT_Wparentheses
);
10753 if (expr
.original_code
!= C_MAYBE_CONST_EXPR
10754 && expr
.original_code
!= SIZEOF_EXPR
)
10755 expr
.original_code
= ERROR_MARK
;
10756 /* Remember that we saw ( ) around the sizeof. */
10757 if (expr
.original_code
== SIZEOF_EXPR
)
10758 expr
.original_code
= PAREN_SIZEOF_EXPR
;
10759 /* Don't change EXPR.ORIGINAL_TYPE. */
10760 location_t loc_close_paren
= c_parser_peek_token (parser
)->location
;
10761 set_c_expr_source_range (&expr
, loc_open_paren
, loc_close_paren
);
10762 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10763 "expected %<)%>", loc_open_paren
);
10767 switch (c_parser_peek_token (parser
)->keyword
)
10769 case RID_FUNCTION_NAME
:
10770 case RID_PRETTY_FUNCTION_NAME
:
10771 case RID_C99_FUNCTION_NAME
:
10772 expr
= c_parser_predefined_identifier (parser
);
10776 location_t start_loc
= loc
;
10777 c_parser_consume_token (parser
);
10778 matching_parens parens
;
10779 if (!parens
.require_open (parser
))
10784 e1
= c_parser_expr_no_commas (parser
, NULL
);
10785 mark_exp_read (e1
.value
);
10786 e1
.value
= c_fully_fold (e1
.value
, false, NULL
);
10787 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10789 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10793 loc
= c_parser_peek_token (parser
)->location
;
10794 t1
= c_parser_type_name (parser
);
10795 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10796 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10804 tree type_expr
= NULL_TREE
;
10805 expr
.value
= c_build_va_arg (start_loc
, e1
.value
, loc
,
10806 groktypename (t1
, &type_expr
, NULL
));
10809 expr
.value
= build2 (C_MAYBE_CONST_EXPR
,
10810 TREE_TYPE (expr
.value
), type_expr
,
10812 C_MAYBE_CONST_EXPR_NON_CONST (expr
.value
) = true;
10814 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10820 c_parser_consume_token (parser
);
10821 matching_parens parens
;
10822 if (!parens
.require_open (parser
))
10827 t1
= c_parser_type_name (parser
);
10829 parser
->error
= true;
10830 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10831 gcc_assert (parser
->error
);
10834 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10838 tree type
= groktypename (t1
, NULL
, NULL
);
10840 if (type
== error_mark_node
)
10841 offsetof_ref
= error_mark_node
;
10844 offsetof_ref
= build1 (INDIRECT_REF
, type
, null_pointer_node
);
10845 SET_EXPR_LOCATION (offsetof_ref
, loc
);
10847 /* Parse the second argument to __builtin_offsetof. We
10848 must have one identifier, and beyond that we want to
10849 accept sub structure and sub array references. */
10850 if (c_parser_next_token_is (parser
, CPP_NAME
))
10852 c_token
*comp_tok
= c_parser_peek_token (parser
);
10854 = build_component_ref (loc
, offsetof_ref
, comp_tok
->value
,
10855 comp_tok
->location
, UNKNOWN_LOCATION
);
10856 c_parser_consume_token (parser
);
10857 while (c_parser_next_token_is (parser
, CPP_DOT
)
10858 || c_parser_next_token_is (parser
,
10860 || c_parser_next_token_is (parser
,
10863 if (c_parser_next_token_is (parser
, CPP_DEREF
))
10865 loc
= c_parser_peek_token (parser
)->location
;
10866 offsetof_ref
= build_array_ref (loc
,
10868 integer_zero_node
);
10871 else if (c_parser_next_token_is (parser
, CPP_DOT
))
10874 c_parser_consume_token (parser
);
10875 if (c_parser_next_token_is_not (parser
,
10878 c_parser_error (parser
, "expected identifier");
10881 c_token
*comp_tok
= c_parser_peek_token (parser
);
10883 = build_component_ref (loc
, offsetof_ref
,
10885 comp_tok
->location
,
10887 c_parser_consume_token (parser
);
10893 loc
= c_parser_peek_token (parser
)->location
;
10894 c_parser_consume_token (parser
);
10895 ce
= c_parser_expression (parser
);
10896 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
10898 idx
= c_fully_fold (idx
, false, NULL
);
10899 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10901 offsetof_ref
= build_array_ref (loc
, offsetof_ref
, idx
);
10906 c_parser_error (parser
, "expected identifier");
10907 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10908 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10910 expr
.value
= fold_offsetof (offsetof_ref
);
10911 set_c_expr_source_range (&expr
, loc
, end_loc
);
10914 case RID_CHOOSE_EXPR
:
10916 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10917 c_expr_t
*e1_p
, *e2_p
, *e3_p
;
10919 location_t close_paren_loc
;
10921 c_parser_consume_token (parser
);
10922 if (!c_parser_get_builtin_args (parser
,
10923 "__builtin_choose_expr",
10931 if (vec_safe_length (cexpr_list
) != 3)
10933 error_at (loc
, "wrong number of arguments to "
10934 "%<__builtin_choose_expr%>");
10939 e1_p
= &(*cexpr_list
)[0];
10940 e2_p
= &(*cexpr_list
)[1];
10941 e3_p
= &(*cexpr_list
)[2];
10944 mark_exp_read (e2_p
->value
);
10945 mark_exp_read (e3_p
->value
);
10946 if (TREE_CODE (c
) != INTEGER_CST
10947 || !INTEGRAL_TYPE_P (TREE_TYPE (c
)))
10949 "first argument to %<__builtin_choose_expr%> not"
10951 constant_expression_warning (c
);
10952 expr
= integer_zerop (c
) ? *e3_p
: *e2_p
;
10953 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10956 case RID_TYPES_COMPATIBLE_P
:
10958 c_parser_consume_token (parser
);
10959 matching_parens parens
;
10960 if (!parens
.require_open (parser
))
10965 t1
= c_parser_type_name (parser
);
10971 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10973 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10977 t2
= c_parser_type_name (parser
);
10983 location_t close_paren_loc
= c_parser_peek_token (parser
)->location
;
10984 parens
.skip_until_found_close (parser
);
10986 e1
= groktypename (t1
, NULL
, NULL
);
10987 e2
= groktypename (t2
, NULL
, NULL
);
10988 if (e1
== error_mark_node
|| e2
== error_mark_node
)
10994 e1
= TYPE_MAIN_VARIANT (e1
);
10995 e2
= TYPE_MAIN_VARIANT (e2
);
10998 = comptypes (e1
, e2
) ? integer_one_node
: integer_zero_node
;
10999 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11002 case RID_BUILTIN_TGMATH
:
11004 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11005 location_t close_paren_loc
;
11007 c_parser_consume_token (parser
);
11008 if (!c_parser_get_builtin_args (parser
,
11009 "__builtin_tgmath",
11010 &cexpr_list
, false,
11017 if (vec_safe_length (cexpr_list
) < 3)
11019 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
11026 FOR_EACH_VEC_ELT (*cexpr_list
, i
, p
)
11027 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
11028 unsigned int nargs
= check_tgmath_function (&(*cexpr_list
)[0], 1);
11034 if (vec_safe_length (cexpr_list
) < nargs
)
11036 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
11040 unsigned int num_functions
= vec_safe_length (cexpr_list
) - nargs
;
11041 if (num_functions
< 2)
11043 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
11048 /* The first NUM_FUNCTIONS expressions are the function
11049 pointers. The remaining NARGS expressions are the
11050 arguments that are to be passed to one of those
11051 functions, chosen following <tgmath.h> rules. */
11052 for (unsigned int j
= 1; j
< num_functions
; j
++)
11054 unsigned int this_nargs
11055 = check_tgmath_function (&(*cexpr_list
)[j
], j
+ 1);
11056 if (this_nargs
== 0)
11061 if (this_nargs
!= nargs
)
11063 error_at ((*cexpr_list
)[j
].get_location (),
11064 "argument %u of %<__builtin_tgmath%> has "
11065 "wrong number of arguments", j
+ 1);
11071 /* The functions all have the same number of arguments.
11072 Determine whether arguments and return types vary in
11073 ways permitted for <tgmath.h> functions. */
11074 /* The first entry in each of these vectors is for the
11075 return type, subsequent entries for parameter
11077 auto_vec
<enum tgmath_parm_kind
> parm_kind (nargs
+ 1);
11078 auto_vec
<tree
> parm_first (nargs
+ 1);
11079 auto_vec
<bool> parm_complex (nargs
+ 1);
11080 auto_vec
<bool> parm_varies (nargs
+ 1);
11081 tree first_type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[0].value
));
11082 tree first_ret
= TYPE_MAIN_VARIANT (TREE_TYPE (first_type
));
11083 parm_first
.quick_push (first_ret
);
11084 parm_complex
.quick_push (TREE_CODE (first_ret
) == COMPLEX_TYPE
);
11085 parm_varies
.quick_push (false);
11086 function_args_iterator iter
;
11088 unsigned int argpos
;
11089 FOREACH_FUNCTION_ARGS (first_type
, t
, iter
)
11091 if (t
== void_type_node
)
11093 parm_first
.quick_push (TYPE_MAIN_VARIANT (t
));
11094 parm_complex
.quick_push (TREE_CODE (t
) == COMPLEX_TYPE
);
11095 parm_varies
.quick_push (false);
11097 for (unsigned int j
= 1; j
< num_functions
; j
++)
11099 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
11100 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
11101 if (ret
!= parm_first
[0])
11103 parm_varies
[0] = true;
11104 if (!SCALAR_FLOAT_TYPE_P (parm_first
[0])
11105 && !COMPLEX_FLOAT_TYPE_P (parm_first
[0]))
11107 error_at ((*cexpr_list
)[0].get_location (),
11108 "invalid type-generic return type for "
11109 "argument %u of %<__builtin_tgmath%>",
11114 if (!SCALAR_FLOAT_TYPE_P (ret
)
11115 && !COMPLEX_FLOAT_TYPE_P (ret
))
11117 error_at ((*cexpr_list
)[j
].get_location (),
11118 "invalid type-generic return type for "
11119 "argument %u of %<__builtin_tgmath%>",
11125 if (TREE_CODE (ret
) == COMPLEX_TYPE
)
11126 parm_complex
[0] = true;
11128 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
11130 if (t
== void_type_node
)
11132 t
= TYPE_MAIN_VARIANT (t
);
11133 if (t
!= parm_first
[argpos
])
11135 parm_varies
[argpos
] = true;
11136 if (!SCALAR_FLOAT_TYPE_P (parm_first
[argpos
])
11137 && !COMPLEX_FLOAT_TYPE_P (parm_first
[argpos
]))
11139 error_at ((*cexpr_list
)[0].get_location (),
11140 "invalid type-generic type for "
11141 "argument %u of argument %u of "
11142 "%<__builtin_tgmath%>", argpos
, 1);
11146 if (!SCALAR_FLOAT_TYPE_P (t
)
11147 && !COMPLEX_FLOAT_TYPE_P (t
))
11149 error_at ((*cexpr_list
)[j
].get_location (),
11150 "invalid type-generic type for "
11151 "argument %u of argument %u of "
11152 "%<__builtin_tgmath%>", argpos
, j
+ 1);
11157 if (TREE_CODE (t
) == COMPLEX_TYPE
)
11158 parm_complex
[argpos
] = true;
11162 enum tgmath_parm_kind max_variation
= tgmath_fixed
;
11163 for (unsigned int j
= 0; j
<= nargs
; j
++)
11165 enum tgmath_parm_kind this_kind
;
11166 if (parm_varies
[j
])
11168 if (parm_complex
[j
])
11169 max_variation
= this_kind
= tgmath_complex
;
11172 this_kind
= tgmath_real
;
11173 if (max_variation
!= tgmath_complex
)
11174 max_variation
= tgmath_real
;
11178 this_kind
= tgmath_fixed
;
11179 parm_kind
.quick_push (this_kind
);
11181 if (max_variation
== tgmath_fixed
)
11183 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
11184 "all have the same type");
11189 /* Identify a parameter (not the return type) that varies,
11190 including with complex types if any variation includes
11191 complex types; there must be at least one such
11193 unsigned int tgarg
= 0;
11194 for (unsigned int j
= 1; j
<= nargs
; j
++)
11195 if (parm_kind
[j
] == max_variation
)
11202 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
11203 "lack type-generic parameter");
11208 /* Determine the type of the relevant parameter for each
11210 auto_vec
<tree
> tg_type (num_functions
);
11211 for (unsigned int j
= 0; j
< num_functions
; j
++)
11213 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
11215 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
11217 if (argpos
== tgarg
)
11219 tg_type
.quick_push (TYPE_MAIN_VARIANT (t
));
11226 /* Verify that the corresponding types are different for
11227 all the listed functions. Also determine whether all
11228 the types are complex, whether all the types are
11229 standard or binary, and whether all the types are
11231 bool all_complex
= true;
11232 bool all_binary
= true;
11233 bool all_decimal
= true;
11234 hash_set
<tree
> tg_types
;
11235 FOR_EACH_VEC_ELT (tg_type
, i
, t
)
11237 if (TREE_CODE (t
) == COMPLEX_TYPE
)
11238 all_decimal
= false;
11241 all_complex
= false;
11242 if (DECIMAL_FLOAT_TYPE_P (t
))
11243 all_binary
= false;
11245 all_decimal
= false;
11247 if (tg_types
.add (t
))
11249 error_at ((*cexpr_list
)[i
].get_location (),
11250 "duplicate type-generic parameter type for "
11251 "function argument %u of %<__builtin_tgmath%>",
11258 /* Verify that other parameters and the return type whose
11259 types vary have their types varying in the correct
11261 for (unsigned int j
= 0; j
< num_functions
; j
++)
11263 tree exp_type
= tg_type
[j
];
11264 tree exp_real_type
= exp_type
;
11265 if (TREE_CODE (exp_type
) == COMPLEX_TYPE
)
11266 exp_real_type
= TREE_TYPE (exp_type
);
11267 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
11268 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
11269 if ((parm_kind
[0] == tgmath_complex
&& ret
!= exp_type
)
11270 || (parm_kind
[0] == tgmath_real
&& ret
!= exp_real_type
))
11272 error_at ((*cexpr_list
)[j
].get_location (),
11273 "bad return type for function argument %u "
11274 "of %<__builtin_tgmath%>", j
+ 1);
11279 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
11281 if (t
== void_type_node
)
11283 t
= TYPE_MAIN_VARIANT (t
);
11284 if ((parm_kind
[argpos
] == tgmath_complex
11286 || (parm_kind
[argpos
] == tgmath_real
11287 && t
!= exp_real_type
))
11289 error_at ((*cexpr_list
)[j
].get_location (),
11290 "bad type for argument %u of "
11291 "function argument %u of "
11292 "%<__builtin_tgmath%>", argpos
, j
+ 1);
11300 /* The functions listed are a valid set of functions for a
11301 <tgmath.h> macro to select between. Identify the
11302 matching function, if any. First, the argument types
11303 must be combined following <tgmath.h> rules. Integer
11304 types are treated as _Decimal64 if any type-generic
11305 argument is decimal, or if the only alternatives for
11306 type-generic arguments are of decimal types, and are
11307 otherwise treated as _Float32x (or _Complex _Float32x
11308 for complex integer types) if any type-generic argument
11309 has _FloatNx type, otherwise as double (or _Complex
11310 double for complex integer types). After that
11311 adjustment, types are combined following the usual
11312 arithmetic conversions. If the function only accepts
11313 complex arguments, a complex type is produced. */
11314 bool arg_complex
= all_complex
;
11315 bool arg_binary
= all_binary
;
11316 bool arg_int_decimal
= all_decimal
;
11317 bool arg_int_floatnx
= false;
11318 for (unsigned int j
= 1; j
<= nargs
; j
++)
11320 if (parm_kind
[j
] == tgmath_fixed
)
11322 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
11323 tree type
= TREE_TYPE (ce
->value
);
11324 if (!INTEGRAL_TYPE_P (type
)
11325 && !SCALAR_FLOAT_TYPE_P (type
)
11326 && TREE_CODE (type
) != COMPLEX_TYPE
)
11328 error_at (ce
->get_location (),
11329 "invalid type of argument %u of type-generic "
11334 if (DECIMAL_FLOAT_TYPE_P (type
))
11336 arg_int_decimal
= true;
11339 error_at (ce
->get_location (),
11340 "decimal floating-point argument %u to "
11341 "complex-only type-generic function", j
);
11345 else if (all_binary
)
11347 error_at (ce
->get_location (),
11348 "decimal floating-point argument %u to "
11349 "binary-only type-generic function", j
);
11353 else if (arg_complex
)
11355 error_at (ce
->get_location (),
11356 "both complex and decimal floating-point "
11357 "arguments to type-generic function");
11361 else if (arg_binary
)
11363 error_at (ce
->get_location (),
11364 "both binary and decimal floating-point "
11365 "arguments to type-generic function");
11370 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
11372 arg_complex
= true;
11373 if (COMPLEX_FLOAT_TYPE_P (type
))
11377 error_at (ce
->get_location (),
11378 "complex argument %u to "
11379 "decimal-only type-generic function", j
);
11383 else if (arg_int_decimal
)
11385 error_at (ce
->get_location (),
11386 "both complex and decimal floating-point "
11387 "arguments to type-generic function");
11392 else if (SCALAR_FLOAT_TYPE_P (type
))
11397 error_at (ce
->get_location (),
11398 "binary argument %u to "
11399 "decimal-only type-generic function", j
);
11403 else if (arg_int_decimal
)
11405 error_at (ce
->get_location (),
11406 "both binary and decimal floating-point "
11407 "arguments to type-generic function");
11412 tree rtype
= TYPE_MAIN_VARIANT (type
);
11413 if (TREE_CODE (rtype
) == COMPLEX_TYPE
)
11414 rtype
= TREE_TYPE (rtype
);
11415 if (SCALAR_FLOAT_TYPE_P (rtype
))
11416 for (unsigned int j
= 0; j
< NUM_FLOATNX_TYPES
; j
++)
11417 if (rtype
== FLOATNX_TYPE_NODE (j
))
11419 arg_int_floatnx
= true;
11423 tree arg_real
= NULL_TREE
;
11424 for (unsigned int j
= 1; j
<= nargs
; j
++)
11426 if (parm_kind
[j
] == tgmath_fixed
)
11428 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
11429 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (ce
->value
));
11430 if (TREE_CODE (type
) == COMPLEX_TYPE
)
11431 type
= TREE_TYPE (type
);
11432 if (INTEGRAL_TYPE_P (type
))
11433 type
= (arg_int_decimal
11434 ? dfloat64_type_node
11436 ? float32x_type_node
11437 : double_type_node
);
11438 if (arg_real
== NULL_TREE
)
11441 arg_real
= common_type (arg_real
, type
);
11442 if (arg_real
== error_mark_node
)
11448 tree arg_type
= (arg_complex
11449 ? build_complex_type (arg_real
)
11452 /* Look for a function to call with type-generic parameter
11454 c_expr_t
*fn
= NULL
;
11455 for (unsigned int j
= 0; j
< num_functions
; j
++)
11457 if (tg_type
[j
] == arg_type
)
11459 fn
= &(*cexpr_list
)[j
];
11464 && parm_kind
[0] == tgmath_fixed
11465 && SCALAR_FLOAT_TYPE_P (parm_first
[0]))
11467 /* Presume this is a macro that rounds its result to a
11468 narrower type, and look for the first function with
11469 at least the range and precision of the argument
11471 for (unsigned int j
= 0; j
< num_functions
; j
++)
11474 != (TREE_CODE (tg_type
[j
]) == COMPLEX_TYPE
))
11476 tree real_tg_type
= (arg_complex
11477 ? TREE_TYPE (tg_type
[j
])
11479 if (DECIMAL_FLOAT_TYPE_P (arg_real
)
11480 != DECIMAL_FLOAT_TYPE_P (real_tg_type
))
11482 scalar_float_mode arg_mode
11483 = SCALAR_FLOAT_TYPE_MODE (arg_real
);
11484 scalar_float_mode tg_mode
11485 = SCALAR_FLOAT_TYPE_MODE (real_tg_type
);
11486 const real_format
*arg_fmt
= REAL_MODE_FORMAT (arg_mode
);
11487 const real_format
*tg_fmt
= REAL_MODE_FORMAT (tg_mode
);
11488 if (arg_fmt
->b
== tg_fmt
->b
11489 && arg_fmt
->p
<= tg_fmt
->p
11490 && arg_fmt
->emax
<= tg_fmt
->emax
11491 && (arg_fmt
->emin
- arg_fmt
->p
11492 >= tg_fmt
->emin
- tg_fmt
->p
))
11494 fn
= &(*cexpr_list
)[j
];
11501 error_at (loc
, "no matching function for type-generic call");
11506 /* Construct a call to FN. */
11507 vec
<tree
, va_gc
> *args
;
11508 vec_alloc (args
, nargs
);
11509 vec
<tree
, va_gc
> *origtypes
;
11510 vec_alloc (origtypes
, nargs
);
11511 auto_vec
<location_t
> arg_loc (nargs
);
11512 for (unsigned int j
= 0; j
< nargs
; j
++)
11514 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
];
11515 args
->quick_push (ce
->value
);
11516 arg_loc
.quick_push (ce
->get_location ());
11517 origtypes
->quick_push (ce
->original_type
);
11519 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fn
->value
,
11521 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11524 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN
:
11526 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11529 location_t close_paren_loc
;
11531 c_parser_consume_token (parser
);
11532 if (!c_parser_get_builtin_args (parser
,
11533 "__builtin_call_with_static_chain",
11534 &cexpr_list
, false,
11540 if (vec_safe_length (cexpr_list
) != 2)
11542 error_at (loc
, "wrong number of arguments to "
11543 "%<__builtin_call_with_static_chain%>");
11548 expr
= (*cexpr_list
)[0];
11549 e2_p
= &(*cexpr_list
)[1];
11550 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
11551 chain_value
= e2_p
->value
;
11552 mark_exp_read (chain_value
);
11554 if (TREE_CODE (expr
.value
) != CALL_EXPR
)
11555 error_at (loc
, "first argument to "
11556 "%<__builtin_call_with_static_chain%> "
11557 "must be a call expression");
11558 else if (TREE_CODE (TREE_TYPE (chain_value
)) != POINTER_TYPE
)
11559 error_at (loc
, "second argument to "
11560 "%<__builtin_call_with_static_chain%> "
11561 "must be a pointer type");
11563 CALL_EXPR_STATIC_CHAIN (expr
.value
) = chain_value
;
11564 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11567 case RID_BUILTIN_COMPLEX
:
11569 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11570 c_expr_t
*e1_p
, *e2_p
;
11571 location_t close_paren_loc
;
11573 c_parser_consume_token (parser
);
11574 if (!c_parser_get_builtin_args (parser
,
11575 "__builtin_complex",
11576 &cexpr_list
, false,
11583 if (vec_safe_length (cexpr_list
) != 2)
11585 error_at (loc
, "wrong number of arguments to "
11586 "%<__builtin_complex%>");
11591 e1_p
= &(*cexpr_list
)[0];
11592 e2_p
= &(*cexpr_list
)[1];
11594 *e1_p
= convert_lvalue_to_rvalue (loc
, *e1_p
, true, true);
11595 if (TREE_CODE (e1_p
->value
) == EXCESS_PRECISION_EXPR
)
11596 e1_p
->value
= convert (TREE_TYPE (e1_p
->value
),
11597 TREE_OPERAND (e1_p
->value
, 0));
11598 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
11599 if (TREE_CODE (e2_p
->value
) == EXCESS_PRECISION_EXPR
)
11600 e2_p
->value
= convert (TREE_TYPE (e2_p
->value
),
11601 TREE_OPERAND (e2_p
->value
, 0));
11602 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
11603 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
11604 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
))
11605 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
)))
11607 error_at (loc
, "%<__builtin_complex%> operand "
11608 "not of real binary floating-point type");
11612 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p
->value
))
11613 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p
->value
)))
11616 "%<__builtin_complex%> operands of different types");
11620 pedwarn_c90 (loc
, OPT_Wpedantic
,
11621 "ISO C90 does not support complex types");
11622 expr
.value
= build2_loc (loc
, COMPLEX_EXPR
,
11625 (TREE_TYPE (e1_p
->value
))),
11626 e1_p
->value
, e2_p
->value
);
11627 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11630 case RID_BUILTIN_SHUFFLE
:
11632 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11635 location_t close_paren_loc
;
11637 c_parser_consume_token (parser
);
11638 if (!c_parser_get_builtin_args (parser
,
11639 "__builtin_shuffle",
11640 &cexpr_list
, false,
11647 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
11648 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
11650 if (vec_safe_length (cexpr_list
) == 2)
11651 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
11653 (*cexpr_list
)[1].value
);
11655 else if (vec_safe_length (cexpr_list
) == 3)
11656 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
11657 (*cexpr_list
)[1].value
,
11658 (*cexpr_list
)[2].value
);
11661 error_at (loc
, "wrong number of arguments to "
11662 "%<__builtin_shuffle%>");
11665 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11668 case RID_BUILTIN_SHUFFLEVECTOR
:
11670 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11673 location_t close_paren_loc
;
11675 c_parser_consume_token (parser
);
11676 if (!c_parser_get_builtin_args (parser
,
11677 "__builtin_shufflevector",
11678 &cexpr_list
, false,
11685 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
11686 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
11688 if (vec_safe_length (cexpr_list
) < 3)
11690 error_at (loc
, "wrong number of arguments to "
11691 "%<__builtin_shuffle%>");
11696 auto_vec
<tree
, 16> mask
;
11697 for (i
= 2; i
< cexpr_list
->length (); ++i
)
11698 mask
.safe_push ((*cexpr_list
)[i
].value
);
11699 expr
.value
= c_build_shufflevector (loc
, (*cexpr_list
)[0].value
,
11700 (*cexpr_list
)[1].value
,
11703 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11706 case RID_BUILTIN_CONVERTVECTOR
:
11708 location_t start_loc
= loc
;
11709 c_parser_consume_token (parser
);
11710 matching_parens parens
;
11711 if (!parens
.require_open (parser
))
11716 e1
= c_parser_expr_no_commas (parser
, NULL
);
11717 mark_exp_read (e1
.value
);
11718 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
11720 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
11724 loc
= c_parser_peek_token (parser
)->location
;
11725 t1
= c_parser_type_name (parser
);
11726 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
11727 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
11733 tree type_expr
= NULL_TREE
;
11734 expr
.value
= c_build_vec_convert (start_loc
, e1
.value
, loc
,
11735 groktypename (t1
, &type_expr
,
11737 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
11741 case RID_BUILTIN_ASSOC_BARRIER
:
11743 location_t start_loc
= loc
;
11744 c_parser_consume_token (parser
);
11745 matching_parens parens
;
11746 if (!parens
.require_open (parser
))
11751 e1
= c_parser_expr_no_commas (parser
, NULL
);
11752 mark_exp_read (e1
.value
);
11753 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
11754 parens
.skip_until_found_close (parser
);
11755 expr
= parser_build_unary_op (loc
, PAREN_EXPR
, e1
);
11756 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
11759 case RID_BUILTIN_STDC
:
11761 vec
<c_expr_t
, va_gc
> *cexpr_list
;
11763 location_t close_paren_loc
;
11764 enum c_builtin_stdc
{
11765 C_BUILTIN_STDC_BIT_CEIL
,
11766 C_BUILTIN_STDC_BIT_FLOOR
,
11767 C_BUILTIN_STDC_BIT_WIDTH
,
11768 C_BUILTIN_STDC_COUNT_ONES
,
11769 C_BUILTIN_STDC_COUNT_ZEROS
,
11770 C_BUILTIN_STDC_FIRST_LEADING_ONE
,
11771 C_BUILTIN_STDC_FIRST_LEADING_ZERO
,
11772 C_BUILTIN_STDC_FIRST_TRAILING_ONE
,
11773 C_BUILTIN_STDC_FIRST_TRAILING_ZERO
,
11774 C_BUILTIN_STDC_HAS_SINGLE_BIT
,
11775 C_BUILTIN_STDC_LEADING_ONES
,
11776 C_BUILTIN_STDC_LEADING_ZEROS
,
11777 C_BUILTIN_STDC_TRAILING_ONES
,
11778 C_BUILTIN_STDC_TRAILING_ZEROS
,
11780 } stdc_rid
= C_BUILTIN_STDC_MAX
;
11782 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
11783 switch (name
[sizeof ("__builtin_stdc_") - 1])
11786 switch (name
[sizeof ("__builtin_stdc_bit_") - 1])
11789 stdc_rid
= C_BUILTIN_STDC_BIT_CEIL
;
11792 stdc_rid
= C_BUILTIN_STDC_BIT_FLOOR
;
11795 stdc_rid
= C_BUILTIN_STDC_BIT_WIDTH
;
11800 if (name
[sizeof ("__builtin_stdc_count_") - 1] == 'o')
11801 stdc_rid
= C_BUILTIN_STDC_COUNT_ONES
;
11803 stdc_rid
= C_BUILTIN_STDC_COUNT_ZEROS
;
11806 switch (name
[sizeof ("__builtin_stdc_first_trailing_") - 1])
11809 stdc_rid
= C_BUILTIN_STDC_FIRST_LEADING_ONE
;
11812 stdc_rid
= C_BUILTIN_STDC_FIRST_LEADING_ZERO
;
11815 stdc_rid
= C_BUILTIN_STDC_FIRST_TRAILING_ONE
;
11818 stdc_rid
= C_BUILTIN_STDC_FIRST_TRAILING_ZERO
;
11823 stdc_rid
= C_BUILTIN_STDC_HAS_SINGLE_BIT
;
11826 if (name
[sizeof ("__builtin_stdc_leading_") - 1] == 'o')
11827 stdc_rid
= C_BUILTIN_STDC_LEADING_ONES
;
11829 stdc_rid
= C_BUILTIN_STDC_LEADING_ZEROS
;
11832 if (name
[sizeof ("__builtin_stdc_trailing_") - 1] == 'o')
11833 stdc_rid
= C_BUILTIN_STDC_TRAILING_ONES
;
11835 stdc_rid
= C_BUILTIN_STDC_TRAILING_ZEROS
;
11838 gcc_checking_assert (stdc_rid
!= C_BUILTIN_STDC_MAX
);
11840 c_parser_consume_token (parser
);
11841 if (!c_parser_get_builtin_args (parser
, name
,
11842 &cexpr_list
, false,
11849 if (vec_safe_length (cexpr_list
) != 1)
11851 error_at (loc
, "wrong number of arguments to %qs", name
);
11856 arg_p
= &(*cexpr_list
)[0];
11857 *arg_p
= convert_lvalue_to_rvalue (loc
, *arg_p
, true, true);
11858 if (!INTEGRAL_TYPE_P (TREE_TYPE (arg_p
->value
)))
11860 error_at (loc
, "%qs operand not an integral type", name
);
11864 tree arg
= arg_p
->value
;
11865 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (arg
));
11867 __builtin_stdc_leading_zeros (arg) as
11868 (unsigned int) __builtin_clzg (arg, prec)
11869 __builtin_stdc_leading_ones (arg) as
11870 (unsigned int) __builtin_clzg ((type) ~arg, prec)
11871 __builtin_stdc_trailing_zeros (arg) as
11872 (unsigned int) __builtin_ctzg (arg, prec)
11873 __builtin_stdc_trailing_ones (arg) as
11874 (unsigned int) __builtin_ctzg ((type) ~arg, prec)
11875 __builtin_stdc_first_leading_zero (arg) as
11876 __builtin_clzg ((type) ~arg, -1) + 1U
11877 __builtin_stdc_first_leading_one (arg) as
11878 __builtin_clzg (arg, -1) + 1U
11879 __builtin_stdc_first_trailing_zero (arg) as
11880 __builtin_ctzg ((type) ~arg, -1) + 1U
11881 __builtin_stdc_first_trailing_one (arg) as
11882 __builtin_ctzg (arg, -1) + 1U
11883 __builtin_stdc_count_zeros (arg) as
11884 (unsigned int) __builtin_popcountg ((type) ~arg)
11885 __builtin_stdc_count_ones (arg) as
11886 (unsigned int) __builtin_popcountg (arg)
11887 __builtin_stdc_has_single_bit (arg) as
11888 (_Bool) (__builtin_popcountg (arg) == 1)
11889 __builtin_stdc_bit_width (arg) as
11890 (unsigned int) (prec - __builtin_clzg (arg, prec))
11891 __builtin_stdc_bit_floor (arg) as
11892 arg == 0 ? (type) 0
11893 : (type) 1 << (prec - 1 - __builtin_clzg (arg))
11894 __builtin_stdc_bit_ceil (arg) as
11895 arg <= 1 ? (type) 1
11896 : (type) 2 << (prec - 1 - __builtin_clzg (arg - 1))
11897 without evaluating arg multiple times, type being
11898 __typeof (arg) and prec __builtin_popcountg ((type) ~0)). */
11899 int prec
= TYPE_PRECISION (type
);
11903 case C_BUILTIN_STDC_BIT_CEIL
:
11904 arg
= save_expr (arg
);
11905 barg1
= build2_loc (loc
, PLUS_EXPR
, type
, arg
,
11906 build_int_cst (type
, -1));
11908 case C_BUILTIN_STDC_BIT_FLOOR
:
11909 barg1
= arg
= save_expr (arg
);
11911 case C_BUILTIN_STDC_COUNT_ZEROS
:
11912 case C_BUILTIN_STDC_FIRST_LEADING_ZERO
:
11913 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO
:
11914 case C_BUILTIN_STDC_LEADING_ONES
:
11915 case C_BUILTIN_STDC_TRAILING_ONES
:
11916 barg1
= build1_loc (loc
, BIT_NOT_EXPR
, type
, arg
);
11921 tree barg2
= NULL_TREE
;
11924 case C_BUILTIN_STDC_BIT_WIDTH
:
11925 case C_BUILTIN_STDC_LEADING_ONES
:
11926 case C_BUILTIN_STDC_LEADING_ZEROS
:
11927 case C_BUILTIN_STDC_TRAILING_ONES
:
11928 case C_BUILTIN_STDC_TRAILING_ZEROS
:
11929 barg2
= build_int_cst (integer_type_node
, prec
);
11931 case C_BUILTIN_STDC_FIRST_LEADING_ONE
:
11932 case C_BUILTIN_STDC_FIRST_LEADING_ZERO
:
11933 case C_BUILTIN_STDC_FIRST_TRAILING_ONE
:
11934 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO
:
11935 barg2
= integer_minus_one_node
;
11940 tree fndecl
= NULL_TREE
;
11943 case C_BUILTIN_STDC_BIT_CEIL
:
11944 case C_BUILTIN_STDC_BIT_FLOOR
:
11945 case C_BUILTIN_STDC_BIT_WIDTH
:
11946 case C_BUILTIN_STDC_FIRST_LEADING_ONE
:
11947 case C_BUILTIN_STDC_FIRST_LEADING_ZERO
:
11948 case C_BUILTIN_STDC_LEADING_ONES
:
11949 case C_BUILTIN_STDC_LEADING_ZEROS
:
11950 fndecl
= builtin_decl_explicit (BUILT_IN_CLZG
);
11952 case C_BUILTIN_STDC_FIRST_TRAILING_ONE
:
11953 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO
:
11954 case C_BUILTIN_STDC_TRAILING_ONES
:
11955 case C_BUILTIN_STDC_TRAILING_ZEROS
:
11956 fndecl
= builtin_decl_explicit (BUILT_IN_CTZG
);
11958 case C_BUILTIN_STDC_COUNT_ONES
:
11959 case C_BUILTIN_STDC_COUNT_ZEROS
:
11960 case C_BUILTIN_STDC_HAS_SINGLE_BIT
:
11961 fndecl
= builtin_decl_explicit (BUILT_IN_POPCOUNTG
);
11964 gcc_unreachable ();
11966 /* Construct a call to __builtin_{clz,ctz,popcount}g. */
11967 int nargs
= barg2
!= NULL_TREE
? 2 : 1;
11968 vec
<tree
, va_gc
> *args
;
11969 vec_alloc (args
, nargs
);
11970 vec
<tree
, va_gc
> *origtypes
;
11971 vec_alloc (origtypes
, nargs
);
11972 auto_vec
<location_t
> arg_loc (nargs
);
11973 args
->quick_push (barg1
);
11974 arg_loc
.quick_push (arg_p
->get_location ());
11975 origtypes
->quick_push (arg_p
->original_type
);
11978 args
->quick_push (barg2
);
11979 arg_loc
.quick_push (loc
);
11980 origtypes
->quick_push (integer_type_node
);
11982 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fndecl
,
11984 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
11985 if (expr
.value
== error_mark_node
)
11989 case C_BUILTIN_STDC_BIT_CEIL
:
11990 case C_BUILTIN_STDC_BIT_FLOOR
:
11993 case C_BUILTIN_STDC_BIT_WIDTH
:
11994 expr
.value
= build2_loc (loc
, MINUS_EXPR
, integer_type_node
,
11995 build_int_cst (integer_type_node
,
11996 prec
), expr
.value
);
11998 case C_BUILTIN_STDC_FIRST_LEADING_ONE
:
11999 case C_BUILTIN_STDC_FIRST_LEADING_ZERO
:
12000 case C_BUILTIN_STDC_FIRST_TRAILING_ONE
:
12001 case C_BUILTIN_STDC_FIRST_TRAILING_ZERO
:
12002 expr
.value
= build2_loc (loc
, PLUS_EXPR
, integer_type_node
,
12003 expr
.value
, integer_one_node
);
12005 case C_BUILTIN_STDC_HAS_SINGLE_BIT
:
12006 expr
.value
= build2_loc (loc
, EQ_EXPR
, boolean_type_node
,
12007 expr
.value
, integer_one_node
);
12013 if (stdc_rid
!= C_BUILTIN_STDC_BIT_CEIL
12014 && stdc_rid
!= C_BUILTIN_STDC_BIT_FLOOR
)
12016 if (stdc_rid
!= C_BUILTIN_STDC_HAS_SINGLE_BIT
)
12017 expr
.value
= fold_convert_loc (loc
, unsigned_type_node
,
12021 /* For __builtin_stdc_bit_ceil (0U) or __builtin_stdc_bit_ceil (1U)
12022 or __builtin_stdc_bit_floor (0U) avoid bogus -Wshift-count-*
12023 warnings. The LSHIFT_EXPR is in dead code in that case. */
12024 if (integer_zerop (arg
)
12025 || (stdc_rid
== C_BUILTIN_STDC_BIT_CEIL
&& integer_onep (arg
)))
12026 expr
.value
= build_int_cst (type
, 0);
12029 = build2_loc (loc
, LSHIFT_EXPR
, type
,
12030 build_int_cst (type
,
12032 == C_BUILTIN_STDC_BIT_CEIL
12033 ? 2 : 1)), expr
.value
);
12034 if (stdc_rid
== C_BUILTIN_STDC_BIT_CEIL
)
12035 expr
.value
= build3_loc (loc
, COND_EXPR
, type
,
12036 build2_loc (loc
, LE_EXPR
,
12037 boolean_type_node
, arg
,
12038 build_int_cst (type
, 1)),
12039 build_int_cst (type
, 1),
12042 expr
.value
= build3_loc (loc
, COND_EXPR
, type
,
12043 build2_loc (loc
, EQ_EXPR
,
12044 boolean_type_node
, arg
,
12045 build_int_cst (type
, 0)),
12046 build_int_cst (type
, 0),
12050 case RID_AT_SELECTOR
:
12052 gcc_assert (c_dialect_objc ());
12053 c_parser_consume_token (parser
);
12054 matching_parens parens
;
12055 if (!parens
.require_open (parser
))
12060 tree sel
= c_parser_objc_selector_arg (parser
);
12061 location_t close_loc
= c_parser_peek_token (parser
)->location
;
12062 parens
.skip_until_found_close (parser
);
12063 expr
.value
= objc_build_selector_expr (loc
, sel
);
12064 set_c_expr_source_range (&expr
, loc
, close_loc
);
12067 case RID_AT_PROTOCOL
:
12069 gcc_assert (c_dialect_objc ());
12070 c_parser_consume_token (parser
);
12071 matching_parens parens
;
12072 if (!parens
.require_open (parser
))
12077 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12079 c_parser_error (parser
, "expected identifier");
12080 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
12084 tree id
= c_parser_peek_token (parser
)->value
;
12085 c_parser_consume_token (parser
);
12086 location_t close_loc
= c_parser_peek_token (parser
)->location
;
12087 parens
.skip_until_found_close (parser
);
12088 expr
.value
= objc_build_protocol_expr (id
);
12089 set_c_expr_source_range (&expr
, loc
, close_loc
);
12092 case RID_AT_ENCODE
:
12094 /* Extension to support C-structures in the archiver. */
12095 gcc_assert (c_dialect_objc ());
12096 c_parser_consume_token (parser
);
12097 matching_parens parens
;
12098 if (!parens
.require_open (parser
))
12103 t1
= c_parser_type_name (parser
);
12107 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
12110 location_t close_loc
= c_parser_peek_token (parser
)->location
;
12111 parens
.skip_until_found_close (parser
);
12112 tree type
= groktypename (t1
, NULL
, NULL
);
12113 expr
.value
= objc_build_encode_expr (type
);
12114 set_c_expr_source_range (&expr
, loc
, close_loc
);
12118 expr
= c_parser_generic_selection (parser
);
12120 case RID_OMP_ALL_MEMORY
:
12121 gcc_assert (flag_openmp
);
12122 c_parser_consume_token (parser
);
12123 error_at (loc
, "%<omp_all_memory%> may only be used in OpenMP "
12124 "%<depend%> clause");
12127 /* C23 'nullptr' literal. */
12129 c_parser_consume_token (parser
);
12130 expr
.value
= nullptr_node
;
12131 set_c_expr_source_range (&expr
, tok_range
);
12132 pedwarn_c11 (loc
, OPT_Wpedantic
,
12133 "ISO C does not support %qs before C23", "nullptr");
12136 c_parser_consume_token (parser
);
12137 expr
.value
= boolean_true_node
;
12138 set_c_expr_source_range (&expr
, tok_range
);
12141 c_parser_consume_token (parser
);
12142 expr
.value
= boolean_false_node
;
12143 set_c_expr_source_range (&expr
, tok_range
);
12146 c_parser_error (parser
, "expected expression");
12151 case CPP_OPEN_SQUARE
:
12152 if (c_dialect_objc ())
12154 tree receiver
, args
;
12155 c_parser_consume_token (parser
);
12156 receiver
= c_parser_objc_receiver (parser
);
12157 args
= c_parser_objc_message_args (parser
);
12158 location_t close_loc
= c_parser_peek_token (parser
)->location
;
12159 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
12161 expr
.value
= objc_build_message_expr (receiver
, args
);
12162 set_c_expr_source_range (&expr
, loc
, close_loc
);
12165 /* Else fall through to report error. */
12168 c_parser_error (parser
, "expected expression");
12173 return c_parser_postfix_expression_after_primary
12174 (parser
, EXPR_LOC_OR_LOC (expr
.value
, loc
), expr
);
12177 /* Parse a postfix expression after a parenthesized type name: the
12178 brace-enclosed initializer of a compound literal, possibly followed
12179 by some postfix operators. This is separate because it is not
12180 possible to tell until after the type name whether a cast
12181 expression has a cast or a compound literal, or whether the operand
12182 of sizeof is a parenthesized type name or starts with a compound
12183 literal. TYPE_LOC is the location where TYPE_NAME starts--the
12184 location of the first token after the parentheses around the type
12187 static struct c_expr
12188 c_parser_postfix_expression_after_paren_type (c_parser
*parser
,
12189 struct c_declspecs
*scspecs
,
12190 struct c_type_name
*type_name
,
12191 location_t type_loc
)
12194 struct c_expr init
;
12196 struct c_expr expr
;
12197 location_t start_loc
;
12198 tree type_expr
= NULL_TREE
;
12199 bool type_expr_const
= true;
12200 bool constexpr_p
= scspecs
? scspecs
->constexpr_p
: false;
12201 unsigned int underspec_state
= 0;
12202 check_compound_literal_type (type_loc
, type_name
);
12203 rich_location
richloc (line_table
, type_loc
);
12204 start_loc
= c_parser_peek_token (parser
)->location
;
12207 underspec_state
= start_underspecified_init (start_loc
, NULL_TREE
);
12208 /* A constexpr compound literal is subject to the constraints on
12209 underspecified declarations, which may not declare tags or
12210 members or structures or unions; it is undefined behavior to
12211 declare the members of an enumeration. Where the structure,
12212 union or enumeration type is declared within the compound
12213 literal initializer, this is diagnosed elsewhere as a result
12214 of the above call to start_underspecified_init. Diagnose
12215 here the case of declaring such a type in the type specifiers
12216 of the compound literal. */
12217 switch (type_name
->specs
->typespec_kind
)
12219 case ctsk_tagfirstref
:
12220 case ctsk_tagfirstref_attrs
:
12221 error_at (type_loc
, "%qT declared in %<constexpr%> compound literal",
12222 type_name
->specs
->type
);
12226 error_at (type_loc
, "%qT defined in %<constexpr%> compound literal",
12227 type_name
->specs
->type
);
12234 start_init (NULL_TREE
, NULL
,
12235 (global_bindings_p ()
12236 || (scspecs
&& scspecs
->storage_class
== csc_static
)
12237 || constexpr_p
), constexpr_p
, &richloc
);
12238 type
= groktypename (type_name
, &type_expr
, &type_expr_const
);
12239 if (type
!= error_mark_node
&& C_TYPE_VARIABLE_SIZE (type
))
12241 error_at (type_loc
, "compound literal has variable size");
12242 type
= error_mark_node
;
12244 else if (TREE_CODE (type
) == FUNCTION_TYPE
)
12246 error_at (type_loc
, "compound literal has function type");
12247 type
= error_mark_node
;
12249 if (constexpr_p
&& type
!= error_mark_node
)
12251 tree type_no_array
= strip_array_types (type
);
12252 /* The type of a constexpr object must not be variably modified
12253 (which applies to all compound literals), volatile, atomic or
12254 restrict qualified or have a member with such a qualifier.
12255 const qualification is implicitly added. */
12256 if (TYPE_QUALS (type_no_array
)
12257 & (TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
| TYPE_QUAL_ATOMIC
))
12258 error_at (type_loc
, "invalid qualifiers for %<constexpr%> object");
12259 else if (RECORD_OR_UNION_TYPE_P (type_no_array
)
12260 && C_TYPE_FIELDS_NON_CONSTEXPR (type_no_array
))
12261 error_at (type_loc
, "invalid qualifiers for field of "
12262 "%<constexpr%> object");
12263 type
= c_build_qualified_type (type
,
12264 (TYPE_QUALS (type_no_array
)
12265 | TYPE_QUAL_CONST
));
12267 init
= c_parser_braced_init (parser
, type
, false, NULL
, NULL_TREE
);
12269 finish_underspecified_init (NULL_TREE
, underspec_state
);
12271 maybe_warn_string_init (type_loc
, type
, init
);
12273 if (type
!= error_mark_node
12274 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type
))
12275 && current_function_decl
)
12277 error ("compound literal qualified by address-space qualifier");
12278 type
= error_mark_node
;
12281 if (!pedwarn_c90 (start_loc
, OPT_Wpedantic
,
12282 "ISO C90 forbids compound literals") && scspecs
)
12283 pedwarn_c11 (start_loc
, OPT_Wpedantic
,
12284 "ISO C forbids storage class specifiers in compound literals "
12286 non_const
= ((init
.value
&& TREE_CODE (init
.value
) == CONSTRUCTOR
)
12287 ? CONSTRUCTOR_NON_CONST (init
.value
)
12288 : init
.original_code
== C_MAYBE_CONST_EXPR
);
12289 non_const
|= !type_expr_const
;
12290 unsigned int alignas_align
= 0;
12291 if (type
!= error_mark_node
12292 && type_name
->specs
->align_log
!= -1)
12294 alignas_align
= 1U << type_name
->specs
->align_log
;
12295 if (alignas_align
< min_align_of_type (type
))
12297 error_at (type_name
->specs
->locations
[cdw_alignas
],
12298 "%<_Alignas%> specifiers cannot reduce "
12299 "alignment of compound literal");
12303 expr
.value
= build_compound_literal (start_loc
, type
, init
.value
, non_const
,
12304 alignas_align
, scspecs
);
12305 set_c_expr_source_range (&expr
, init
.src_range
);
12306 expr
.m_decimal
= 0;
12307 expr
.original_code
= ERROR_MARK
;
12308 expr
.original_type
= NULL
;
12309 if (type
!= error_mark_node
12310 && expr
.value
!= error_mark_node
12313 if (TREE_CODE (expr
.value
) == C_MAYBE_CONST_EXPR
)
12315 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr
.value
) == NULL_TREE
);
12316 C_MAYBE_CONST_EXPR_PRE (expr
.value
) = type_expr
;
12320 gcc_assert (!non_const
);
12321 expr
.value
= build2 (C_MAYBE_CONST_EXPR
, type
,
12322 type_expr
, expr
.value
);
12325 return c_parser_postfix_expression_after_primary (parser
, start_loc
, expr
);
12328 /* Callback function for sizeof_pointer_memaccess_warning to compare
12332 sizeof_ptr_memacc_comptypes (tree type1
, tree type2
)
12334 return comptypes (type1
, type2
) == 1;
12337 /* Warn for patterns where abs-like function appears to be used incorrectly,
12338 gracefully ignore any non-abs-like function. The warning location should
12339 be LOC. FNDECL is the declaration of called function, it must be a
12340 BUILT_IN_NORMAL function. ARG is the first and only argument of the
12344 warn_for_abs (location_t loc
, tree fndecl
, tree arg
)
12346 /* Avoid warning in unreachable subexpressions. */
12347 if (c_inhibit_evaluation_warnings
)
12350 tree atype
= TREE_TYPE (arg
);
12352 /* Casts from pointers (and thus arrays and fndecls) will generate
12353 -Wint-conversion warnings. Most other wrong types hopefully lead to type
12354 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
12355 types and possibly other exotic types. */
12356 if (!INTEGRAL_TYPE_P (atype
)
12357 && !SCALAR_FLOAT_TYPE_P (atype
)
12358 && TREE_CODE (atype
) != COMPLEX_TYPE
)
12361 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
12366 case BUILT_IN_LABS
:
12367 case BUILT_IN_LLABS
:
12368 case BUILT_IN_IMAXABS
:
12369 if (!INTEGRAL_TYPE_P (atype
))
12371 if (SCALAR_FLOAT_TYPE_P (atype
))
12372 warning_at (loc
, OPT_Wabsolute_value
,
12373 "using integer absolute value function %qD when "
12374 "argument is of floating-point type %qT",
12376 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12377 warning_at (loc
, OPT_Wabsolute_value
,
12378 "using integer absolute value function %qD when "
12379 "argument is of complex type %qT", fndecl
, atype
);
12381 gcc_unreachable ();
12384 if (TYPE_UNSIGNED (atype
))
12385 warning_at (loc
, OPT_Wabsolute_value
,
12386 "taking the absolute value of unsigned type %qT "
12387 "has no effect", atype
);
12390 CASE_FLT_FN (BUILT_IN_FABS
):
12391 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS
):
12392 if (!SCALAR_FLOAT_TYPE_P (atype
)
12393 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype
)))
12395 if (INTEGRAL_TYPE_P (atype
))
12396 warning_at (loc
, OPT_Wabsolute_value
,
12397 "using floating-point absolute value function %qD "
12398 "when argument is of integer type %qT", fndecl
, atype
);
12399 else if (DECIMAL_FLOAT_TYPE_P (atype
))
12400 warning_at (loc
, OPT_Wabsolute_value
,
12401 "using floating-point absolute value function %qD "
12402 "when argument is of decimal floating-point type %qT",
12404 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12405 warning_at (loc
, OPT_Wabsolute_value
,
12406 "using floating-point absolute value function %qD when "
12407 "argument is of complex type %qT", fndecl
, atype
);
12409 gcc_unreachable ();
12414 CASE_FLT_FN (BUILT_IN_CABS
):
12415 if (TREE_CODE (atype
) != COMPLEX_TYPE
)
12417 if (INTEGRAL_TYPE_P (atype
))
12418 warning_at (loc
, OPT_Wabsolute_value
,
12419 "using complex absolute value function %qD when "
12420 "argument is of integer type %qT", fndecl
, atype
);
12421 else if (SCALAR_FLOAT_TYPE_P (atype
))
12422 warning_at (loc
, OPT_Wabsolute_value
,
12423 "using complex absolute value function %qD when "
12424 "argument is of floating-point type %qT",
12427 gcc_unreachable ();
12433 case BUILT_IN_FABSD32
:
12434 case BUILT_IN_FABSD64
:
12435 case BUILT_IN_FABSD128
:
12436 if (!DECIMAL_FLOAT_TYPE_P (atype
))
12438 if (INTEGRAL_TYPE_P (atype
))
12439 warning_at (loc
, OPT_Wabsolute_value
,
12440 "using decimal floating-point absolute value "
12441 "function %qD when argument is of integer type %qT",
12443 else if (SCALAR_FLOAT_TYPE_P (atype
))
12444 warning_at (loc
, OPT_Wabsolute_value
,
12445 "using decimal floating-point absolute value "
12446 "function %qD when argument is of floating-point "
12447 "type %qT", fndecl
, atype
);
12448 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12449 warning_at (loc
, OPT_Wabsolute_value
,
12450 "using decimal floating-point absolute value "
12451 "function %qD when argument is of complex type %qT",
12454 gcc_unreachable ();
12463 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl
)))
12466 tree ftype
= TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
12467 if (TREE_CODE (atype
) == COMPLEX_TYPE
)
12469 gcc_assert (TREE_CODE (ftype
) == COMPLEX_TYPE
);
12470 atype
= TREE_TYPE (atype
);
12471 ftype
= TREE_TYPE (ftype
);
12474 if (TYPE_PRECISION (ftype
) < TYPE_PRECISION (atype
))
12475 warning_at (loc
, OPT_Wabsolute_value
,
12476 "absolute value function %qD given an argument of type %qT "
12477 "but has parameter of type %qT which may cause truncation "
12478 "of value", fndecl
, atype
, ftype
);
12482 /* Parse a postfix expression after the initial primary or compound
12483 literal; that is, parse a series of postfix operators.
12485 EXPR_LOC is the location of the primary expression. */
12487 static struct c_expr
12488 c_parser_postfix_expression_after_primary (c_parser
*parser
,
12489 location_t expr_loc
,
12490 struct c_expr expr
)
12492 struct c_expr orig_expr
;
12493 tree ident
, idx
, len
;
12494 location_t sizeof_arg_loc
[6], comp_loc
;
12495 tree sizeof_arg
[6];
12496 unsigned int literal_zero_mask
;
12498 vec
<tree
, va_gc
> *exprlist
;
12499 vec
<tree
, va_gc
> *origtypes
= NULL
;
12500 vec
<location_t
> arg_loc
= vNULL
;
12506 location_t op_loc
= c_parser_peek_token (parser
)->location
;
12507 switch (c_parser_peek_token (parser
)->type
)
12509 case CPP_OPEN_SQUARE
:
12510 /* Array reference. */
12511 c_parser_consume_token (parser
);
12512 idx
= len
= NULL_TREE
;
12513 if (!c_omp_array_section_p
12514 || c_parser_next_token_is_not (parser
, CPP_COLON
))
12515 idx
= c_parser_expression (parser
).value
;
12517 if (c_omp_array_section_p
12518 && c_parser_next_token_is (parser
, CPP_COLON
))
12520 c_parser_consume_token (parser
);
12521 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_SQUARE
))
12522 len
= c_parser_expression (parser
).value
;
12524 expr
.value
= build_omp_array_section (op_loc
, expr
.value
, idx
,
12528 expr
.value
= build_array_ref (op_loc
, expr
.value
, idx
);
12530 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
12533 start
= expr
.get_start ();
12534 finish
= parser
->tokens_buf
[0].location
;
12535 set_c_expr_source_range (&expr
, start
, finish
);
12536 expr
.original_code
= ERROR_MARK
;
12537 expr
.original_type
= NULL
;
12538 expr
.m_decimal
= 0;
12540 case CPP_OPEN_PAREN
:
12541 /* Function call. */
12543 matching_parens parens
;
12544 parens
.consume_open (parser
);
12545 for (i
= 0; i
< 6; i
++)
12547 sizeof_arg
[i
] = NULL_TREE
;
12548 sizeof_arg_loc
[i
] = UNKNOWN_LOCATION
;
12550 literal_zero_mask
= 0;
12551 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
12553 else if (TREE_CODE (expr
.value
) == FUNCTION_DECL
12554 && fndecl_built_in_p (expr
.value
, BUILT_IN_CLASSIFY_TYPE
)
12555 && c_parser_next_tokens_start_typename (parser
,
12558 /* __builtin_classify_type (type) */
12559 c_inhibit_evaluation_warnings
++;
12561 struct c_type_name
*type
= c_parser_type_name (parser
);
12562 c_inhibit_evaluation_warnings
--;
12564 struct c_typespec ret
;
12565 ret
.expr
= NULL_TREE
;
12566 ret
.spec
= error_mark_node
;
12567 ret
.expr_const_operands
= false;
12569 ret
.spec
= groktypename (type
, &ret
.expr
,
12570 &ret
.expr_const_operands
);
12571 parens
.skip_until_found_close (parser
);
12572 expr
.value
= build_int_cst (integer_type_node
,
12573 type_to_class (ret
.spec
));
12577 exprlist
= c_parser_expr_list (parser
, true, false, &origtypes
,
12578 sizeof_arg_loc
, sizeof_arg
,
12579 &arg_loc
, &literal_zero_mask
);
12580 parens
.skip_until_found_close (parser
);
12583 mark_exp_read (expr
.value
);
12584 if (warn_sizeof_pointer_memaccess
)
12585 sizeof_pointer_memaccess_warning (sizeof_arg_loc
,
12586 expr
.value
, exprlist
,
12588 sizeof_ptr_memacc_comptypes
);
12589 if (TREE_CODE (expr
.value
) == FUNCTION_DECL
)
12591 if (fndecl_built_in_p (expr
.value
, BUILT_IN_MEMSET
)
12592 && vec_safe_length (exprlist
) == 3)
12594 tree arg0
= (*exprlist
)[0];
12595 tree arg2
= (*exprlist
)[2];
12596 warn_for_memset (expr_loc
, arg0
, arg2
, literal_zero_mask
);
12598 if (warn_absolute_value
12599 && fndecl_built_in_p (expr
.value
, BUILT_IN_NORMAL
)
12600 && vec_safe_length (exprlist
) == 1)
12601 warn_for_abs (expr_loc
, expr
.value
, (*exprlist
)[0]);
12602 if (parser
->omp_for_parse_state
12603 && parser
->omp_for_parse_state
->in_intervening_code
12604 && omp_runtime_api_call (expr
.value
))
12606 error_at (expr_loc
, "calls to the OpenMP runtime API are "
12607 "not permitted in intervening code");
12608 parser
->omp_for_parse_state
->fail
= true;
12610 if (warn_calloc_transposed_args
)
12611 if (tree attr
= lookup_attribute ("alloc_size",
12613 (TREE_TYPE (expr
.value
))))
12614 if (TREE_VALUE (attr
) && TREE_CHAIN (TREE_VALUE (attr
)))
12615 warn_for_calloc (sizeof_arg_loc
, expr
.value
, exprlist
,
12619 start
= expr
.get_start ();
12620 finish
= parser
->tokens_buf
[0].get_finish ();
12622 = c_build_function_call_vec (expr_loc
, arg_loc
, expr
.value
,
12623 exprlist
, origtypes
);
12624 set_c_expr_source_range (&expr
, start
, finish
);
12625 expr
.m_decimal
= 0;
12627 expr
.original_code
= ERROR_MARK
;
12628 if (TREE_CODE (expr
.value
) == INTEGER_CST
12629 && TREE_CODE (orig_expr
.value
) == FUNCTION_DECL
12630 && fndecl_built_in_p (orig_expr
.value
, BUILT_IN_CONSTANT_P
))
12631 expr
.original_code
= C_MAYBE_CONST_EXPR
;
12632 expr
.original_type
= NULL
;
12635 release_tree_vector (exprlist
);
12636 release_tree_vector (origtypes
);
12638 arg_loc
.release ();
12641 /* Structure element reference. */
12642 c_parser_consume_token (parser
);
12643 expr
= default_function_array_conversion (expr_loc
, expr
);
12644 if (c_parser_next_token_is (parser
, CPP_NAME
))
12646 c_token
*comp_tok
= c_parser_peek_token (parser
);
12647 ident
= comp_tok
->value
;
12648 comp_loc
= comp_tok
->location
;
12652 c_parser_error (parser
, "expected identifier");
12654 expr
.original_code
= ERROR_MARK
;
12655 expr
.original_type
= NULL
;
12658 start
= expr
.get_start ();
12659 finish
= c_parser_peek_token (parser
)->get_finish ();
12660 c_parser_consume_token (parser
);
12661 expr
.value
= build_component_ref (op_loc
, expr
.value
, ident
,
12662 comp_loc
, UNKNOWN_LOCATION
);
12663 set_c_expr_source_range (&expr
, start
, finish
);
12664 expr
.original_code
= ERROR_MARK
;
12665 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
12666 expr
.original_type
= NULL
;
12669 /* Remember the original type of a bitfield. */
12670 tree field
= TREE_OPERAND (expr
.value
, 1);
12671 if (TREE_CODE (field
) != FIELD_DECL
)
12672 expr
.original_type
= NULL
;
12674 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
12676 expr
.m_decimal
= 0;
12679 /* Structure element reference. */
12680 c_parser_consume_token (parser
);
12681 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, false);
12682 if (c_parser_next_token_is (parser
, CPP_NAME
))
12684 c_token
*comp_tok
= c_parser_peek_token (parser
);
12685 ident
= comp_tok
->value
;
12686 comp_loc
= comp_tok
->location
;
12690 c_parser_error (parser
, "expected identifier");
12692 expr
.original_code
= ERROR_MARK
;
12693 expr
.original_type
= NULL
;
12696 start
= expr
.get_start ();
12697 finish
= c_parser_peek_token (parser
)->get_finish ();
12698 c_parser_consume_token (parser
);
12699 expr
.value
= build_component_ref (op_loc
,
12700 build_indirect_ref (op_loc
,
12704 expr
.get_location ());
12705 set_c_expr_source_range (&expr
, start
, finish
);
12706 expr
.original_code
= ERROR_MARK
;
12707 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
12708 expr
.original_type
= NULL
;
12711 /* Remember the original type of a bitfield. */
12712 tree field
= TREE_OPERAND (expr
.value
, 1);
12713 if (TREE_CODE (field
) != FIELD_DECL
)
12714 expr
.original_type
= NULL
;
12716 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
12718 expr
.m_decimal
= 0;
12720 case CPP_PLUS_PLUS
:
12721 /* Postincrement. */
12722 start
= expr
.get_start ();
12723 finish
= c_parser_peek_token (parser
)->get_finish ();
12724 c_parser_consume_token (parser
);
12725 expr
= default_function_array_read_conversion (expr_loc
, expr
);
12726 expr
.value
= build_unary_op (op_loc
, POSTINCREMENT_EXPR
,
12727 expr
.value
, false);
12728 set_c_expr_source_range (&expr
, start
, finish
);
12729 expr
.original_code
= ERROR_MARK
;
12730 expr
.original_type
= NULL
;
12732 case CPP_MINUS_MINUS
:
12733 /* Postdecrement. */
12734 start
= expr
.get_start ();
12735 finish
= c_parser_peek_token (parser
)->get_finish ();
12736 c_parser_consume_token (parser
);
12737 expr
= default_function_array_read_conversion (expr_loc
, expr
);
12738 expr
.value
= build_unary_op (op_loc
, POSTDECREMENT_EXPR
,
12739 expr
.value
, false);
12740 set_c_expr_source_range (&expr
, start
, finish
);
12741 expr
.original_code
= ERROR_MARK
;
12742 expr
.original_type
= NULL
;
12750 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
12753 assignment-expression
12754 expression , assignment-expression
12757 static struct c_expr
12758 c_parser_expression (c_parser
*parser
)
12760 location_t tloc
= c_parser_peek_token (parser
)->location
;
12761 struct c_expr expr
;
12762 expr
= c_parser_expr_no_commas (parser
, NULL
);
12763 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12764 expr
= convert_lvalue_to_rvalue (tloc
, expr
, true, false);
12765 while (c_parser_next_token_is (parser
, CPP_COMMA
))
12767 struct c_expr next
;
12769 location_t loc
= c_parser_peek_token (parser
)->location
;
12770 location_t expr_loc
;
12771 c_parser_consume_token (parser
);
12772 expr_loc
= c_parser_peek_token (parser
)->location
;
12773 lhsval
= expr
.value
;
12774 while (TREE_CODE (lhsval
) == COMPOUND_EXPR
12775 || TREE_CODE (lhsval
) == NOP_EXPR
)
12777 if (TREE_CODE (lhsval
) == COMPOUND_EXPR
)
12778 lhsval
= TREE_OPERAND (lhsval
, 1);
12780 lhsval
= TREE_OPERAND (lhsval
, 0);
12782 if (DECL_P (lhsval
) || handled_component_p (lhsval
))
12783 mark_exp_read (lhsval
);
12784 next
= c_parser_expr_no_commas (parser
, NULL
);
12785 next
= convert_lvalue_to_rvalue (expr_loc
, next
, true, false);
12786 expr
.value
= build_compound_expr (loc
, expr
.value
, next
.value
);
12787 expr
.original_code
= COMPOUND_EXPR
;
12788 expr
.original_type
= next
.original_type
;
12789 expr
.m_decimal
= 0;
12794 /* Parse an expression and convert functions or arrays to pointers and
12795 lvalues to rvalues. */
12797 static struct c_expr
12798 c_parser_expression_conv (c_parser
*parser
)
12800 struct c_expr expr
;
12801 location_t loc
= c_parser_peek_token (parser
)->location
;
12802 expr
= c_parser_expression (parser
);
12803 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, false);
12807 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
12808 argument is a literal zero alone and if so, set it in literal_zero_mask. */
12811 c_parser_check_literal_zero (c_parser
*parser
, unsigned *literal_zero_mask
,
12814 if (idx
>= HOST_BITS_PER_INT
)
12817 c_token
*tok
= c_parser_peek_token (parser
);
12826 /* If a parameter is literal zero alone, remember it
12827 for -Wmemset-transposed-args warning. */
12828 if (integer_zerop (tok
->value
)
12829 && !TREE_OVERFLOW (tok
->value
)
12830 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
12831 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
12832 *literal_zero_mask
|= 1U << idx
;
12838 /* Parse a non-empty list of expressions. If CONVERT_P, convert
12839 functions and arrays to pointers and lvalues to rvalues. If
12840 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
12841 locations of function arguments into this vector.
12843 nonempty-expr-list:
12844 assignment-expression
12845 nonempty-expr-list , assignment-expression
12848 static vec
<tree
, va_gc
> *
12849 c_parser_expr_list (c_parser
*parser
, bool convert_p
, bool fold_p
,
12850 vec
<tree
, va_gc
> **p_orig_types
,
12851 location_t
*sizeof_arg_loc
, tree
*sizeof_arg
,
12852 vec
<location_t
> *locations
,
12853 unsigned int *literal_zero_mask
)
12855 vec
<tree
, va_gc
> *ret
;
12856 vec
<tree
, va_gc
> *orig_types
;
12857 struct c_expr expr
;
12858 unsigned int idx
= 0;
12859 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
12860 c_omp_array_section_p
= false;
12862 ret
= make_tree_vector ();
12863 if (p_orig_types
== NULL
)
12866 orig_types
= make_tree_vector ();
12868 if (literal_zero_mask
)
12869 c_parser_check_literal_zero (parser
, literal_zero_mask
, 0);
12870 expr
= c_parser_expr_no_commas (parser
, NULL
);
12872 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true, true);
12874 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
12875 ret
->quick_push (expr
.value
);
12877 orig_types
->quick_push (expr
.original_type
);
12879 locations
->safe_push (expr
.get_location ());
12880 if (sizeof_arg
!= NULL
12881 && (expr
.original_code
== SIZEOF_EXPR
12882 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
12884 sizeof_arg
[0] = c_last_sizeof_arg
;
12885 sizeof_arg_loc
[0] = c_last_sizeof_loc
;
12887 while (c_parser_next_token_is (parser
, CPP_COMMA
))
12889 c_parser_consume_token (parser
);
12890 if (literal_zero_mask
)
12891 c_parser_check_literal_zero (parser
, literal_zero_mask
, idx
+ 1);
12892 expr
= c_parser_expr_no_commas (parser
, NULL
);
12894 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true,
12897 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
12898 vec_safe_push (ret
, expr
.value
);
12900 vec_safe_push (orig_types
, expr
.original_type
);
12902 locations
->safe_push (expr
.get_location ());
12904 && sizeof_arg
!= NULL
12905 && (expr
.original_code
== SIZEOF_EXPR
12906 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
12908 sizeof_arg
[idx
] = c_last_sizeof_arg
;
12909 sizeof_arg_loc
[idx
] = c_last_sizeof_loc
;
12913 *p_orig_types
= orig_types
;
12914 c_omp_array_section_p
= save_c_omp_array_section_p
;
12918 /* Parse Objective-C-specific constructs. */
12920 /* Parse an objc-class-definition.
12922 objc-class-definition:
12923 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
12924 objc-class-instance-variables[opt] objc-methodprotolist @end
12925 @implementation identifier objc-superclass[opt]
12926 objc-class-instance-variables[opt]
12927 @interface identifier ( identifier ) objc-protocol-refs[opt]
12928 objc-methodprotolist @end
12929 @interface identifier ( ) objc-protocol-refs[opt]
12930 objc-methodprotolist @end
12931 @implementation identifier ( identifier )
12936 "@interface identifier (" must start "@interface identifier (
12937 identifier ) ...": objc-methodprotolist in the first production may
12938 not start with a parenthesized identifier as a declarator of a data
12939 definition with no declaration specifiers if the objc-superclass,
12940 objc-protocol-refs and objc-class-instance-variables are omitted. */
12943 c_parser_objc_class_definition (c_parser
*parser
, tree attributes
)
12948 if (c_parser_next_token_is_keyword (parser
, RID_AT_INTERFACE
))
12950 else if (c_parser_next_token_is_keyword (parser
, RID_AT_IMPLEMENTATION
))
12953 gcc_unreachable ();
12955 c_parser_consume_token (parser
);
12956 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12958 c_parser_error (parser
, "expected identifier");
12961 id1
= c_parser_peek_token (parser
)->value
;
12962 location_t loc1
= c_parser_peek_token (parser
)->location
;
12963 c_parser_consume_token (parser
);
12964 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
12966 /* We have a category or class extension. */
12968 tree proto
= NULL_TREE
;
12969 matching_parens parens
;
12970 parens
.consume_open (parser
);
12971 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12973 if (iface_p
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
12975 /* We have a class extension. */
12980 c_parser_error (parser
, "expected identifier or %<)%>");
12981 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
12987 id2
= c_parser_peek_token (parser
)->value
;
12988 c_parser_consume_token (parser
);
12990 parens
.skip_until_found_close (parser
);
12993 objc_start_category_implementation (id1
, id2
);
12996 if (c_parser_next_token_is (parser
, CPP_LESS
))
12997 proto
= c_parser_objc_protocol_refs (parser
);
12998 objc_start_category_interface (id1
, id2
, proto
, attributes
);
12999 c_parser_objc_methodprotolist (parser
);
13000 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
13001 objc_finish_interface ();
13004 if (c_parser_next_token_is (parser
, CPP_COLON
))
13006 c_parser_consume_token (parser
);
13007 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13009 c_parser_error (parser
, "expected identifier");
13012 superclass
= c_parser_peek_token (parser
)->value
;
13013 c_parser_consume_token (parser
);
13016 superclass
= NULL_TREE
;
13019 tree proto
= NULL_TREE
;
13020 if (c_parser_next_token_is (parser
, CPP_LESS
))
13021 proto
= c_parser_objc_protocol_refs (parser
);
13022 objc_start_class_interface (id1
, loc1
, superclass
, proto
, attributes
);
13025 objc_start_class_implementation (id1
, superclass
);
13026 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
13027 c_parser_objc_class_instance_variables (parser
);
13030 objc_continue_interface ();
13031 c_parser_objc_methodprotolist (parser
);
13032 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
13033 objc_finish_interface ();
13037 objc_continue_implementation ();
13042 /* Parse objc-class-instance-variables.
13044 objc-class-instance-variables:
13045 { objc-instance-variable-decl-list[opt] }
13047 objc-instance-variable-decl-list:
13048 objc-visibility-spec
13049 objc-instance-variable-decl ;
13051 objc-instance-variable-decl-list objc-visibility-spec
13052 objc-instance-variable-decl-list objc-instance-variable-decl ;
13053 objc-instance-variable-decl-list ;
13055 objc-visibility-spec:
13060 objc-instance-variable-decl:
13065 c_parser_objc_class_instance_variables (c_parser
*parser
)
13067 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
13068 c_parser_consume_token (parser
);
13069 while (c_parser_next_token_is_not (parser
, CPP_EOF
))
13072 /* Parse any stray semicolon. */
13073 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
13075 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
13076 "extra semicolon");
13077 c_parser_consume_token (parser
);
13080 /* Stop if at the end of the instance variables. */
13081 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
13083 c_parser_consume_token (parser
);
13086 /* Parse any objc-visibility-spec. */
13087 if (c_parser_next_token_is_keyword (parser
, RID_AT_PRIVATE
))
13089 c_parser_consume_token (parser
);
13090 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE
);
13093 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROTECTED
))
13095 c_parser_consume_token (parser
);
13096 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED
);
13099 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PUBLIC
))
13101 c_parser_consume_token (parser
);
13102 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC
);
13105 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PACKAGE
))
13107 c_parser_consume_token (parser
);
13108 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE
);
13111 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
13113 c_parser_pragma (parser
, pragma_external
, NULL
);
13117 /* Parse some comma-separated declarations. */
13118 decls
= c_parser_struct_declaration (parser
, NULL
);
13121 /* There is a syntax error. We want to skip the offending
13122 tokens up to the next ';' (included) or '}'
13125 /* First, skip manually a ')' or ']'. This is because they
13126 reduce the nesting level, so c_parser_skip_until_found()
13127 wouldn't be able to skip past them. */
13128 c_token
*token
= c_parser_peek_token (parser
);
13129 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_CLOSE_SQUARE
)
13130 c_parser_consume_token (parser
);
13132 /* Then, do the standard skipping. */
13133 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
13135 /* We hopefully recovered. Start normal parsing again. */
13136 parser
->error
= false;
13141 /* Comma-separated instance variables are chained together
13142 in reverse order; add them one by one. */
13143 tree ivar
= nreverse (decls
);
13144 for (; ivar
; ivar
= DECL_CHAIN (ivar
))
13145 objc_add_instance_variable (copy_node (ivar
));
13147 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13151 /* Parse an objc-class-declaration.
13153 objc-class-declaration:
13154 @class identifier-list ;
13158 c_parser_objc_class_declaration (c_parser
*parser
)
13160 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_CLASS
));
13161 c_parser_consume_token (parser
);
13162 /* Any identifiers, including those declared as type names, are OK
13167 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13169 c_parser_error (parser
, "expected identifier");
13170 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
13171 parser
->error
= false;
13174 id
= c_parser_peek_token (parser
)->value
;
13175 objc_declare_class (id
);
13176 c_parser_consume_token (parser
);
13177 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13178 c_parser_consume_token (parser
);
13182 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13185 /* Parse an objc-alias-declaration.
13187 objc-alias-declaration:
13188 @compatibility_alias identifier identifier ;
13192 c_parser_objc_alias_declaration (c_parser
*parser
)
13195 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_ALIAS
));
13196 c_parser_consume_token (parser
);
13197 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13199 c_parser_error (parser
, "expected identifier");
13200 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
13203 id1
= c_parser_peek_token (parser
)->value
;
13204 c_parser_consume_token (parser
);
13205 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13207 c_parser_error (parser
, "expected identifier");
13208 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
13211 id2
= c_parser_peek_token (parser
)->value
;
13212 c_parser_consume_token (parser
);
13213 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13214 objc_declare_alias (id1
, id2
);
13217 /* Parse an objc-protocol-definition.
13219 objc-protocol-definition:
13220 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
13221 @protocol identifier-list ;
13223 "@protocol identifier ;" should be resolved as "@protocol
13224 identifier-list ;": objc-methodprotolist may not start with a
13225 semicolon in the first alternative if objc-protocol-refs are
13229 c_parser_objc_protocol_definition (c_parser
*parser
, tree attributes
)
13231 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROTOCOL
));
13233 c_parser_consume_token (parser
);
13234 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13236 c_parser_error (parser
, "expected identifier");
13239 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
13240 || c_parser_peek_2nd_token (parser
)->type
== CPP_SEMICOLON
)
13242 /* Any identifiers, including those declared as type names, are
13247 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13249 c_parser_error (parser
, "expected identifier");
13252 id
= c_parser_peek_token (parser
)->value
;
13253 objc_declare_protocol (id
, attributes
);
13254 c_parser_consume_token (parser
);
13255 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13256 c_parser_consume_token (parser
);
13260 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13264 tree id
= c_parser_peek_token (parser
)->value
;
13265 tree proto
= NULL_TREE
;
13266 c_parser_consume_token (parser
);
13267 if (c_parser_next_token_is (parser
, CPP_LESS
))
13268 proto
= c_parser_objc_protocol_refs (parser
);
13269 parser
->objc_pq_context
= true;
13270 objc_start_protocol (id
, proto
, attributes
);
13271 c_parser_objc_methodprotolist (parser
);
13272 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
13273 parser
->objc_pq_context
= false;
13274 objc_finish_interface ();
13278 /* Parse an objc-method-type.
13284 Return true if it is a class method (+) and false if it is
13285 an instance method (-).
13288 c_parser_objc_method_type (c_parser
*parser
)
13290 switch (c_parser_peek_token (parser
)->type
)
13293 c_parser_consume_token (parser
);
13296 c_parser_consume_token (parser
);
13299 gcc_unreachable ();
13303 /* Parse an objc-method-definition.
13305 objc-method-definition:
13306 objc-method-type objc-method-decl ;[opt] compound-statement
13310 c_parser_objc_method_definition (c_parser
*parser
)
13312 bool is_class_method
= c_parser_objc_method_type (parser
);
13313 tree decl
, attributes
= NULL_TREE
, expr
= NULL_TREE
;
13314 parser
->objc_pq_context
= true;
13315 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
13317 if (decl
== error_mark_node
)
13318 return; /* Bail here. */
13320 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
13322 c_parser_consume_token (parser
);
13323 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
13324 "extra semicolon in method definition specified");
13327 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
13329 c_parser_error (parser
, "expected %<{%>");
13333 parser
->objc_pq_context
= false;
13334 if (objc_start_method_definition (is_class_method
, decl
, attributes
, expr
))
13336 add_stmt (c_parser_compound_statement (parser
));
13337 objc_finish_method_definition (current_function_decl
);
13341 /* This code is executed when we find a method definition
13342 outside of an @implementation context (or invalid for other
13343 reasons). Parse the method (to keep going) but do not emit
13346 c_parser_compound_statement (parser
);
13350 /* Parse an objc-methodprotolist.
13352 objc-methodprotolist:
13354 objc-methodprotolist objc-methodproto
13355 objc-methodprotolist declaration
13356 objc-methodprotolist ;
13360 The declaration is a data definition, which may be missing
13361 declaration specifiers under the same rules and diagnostics as
13362 other data definitions outside functions, and the stray semicolon
13363 is diagnosed the same way as a stray semicolon outside a
13367 c_parser_objc_methodprotolist (c_parser
*parser
)
13371 /* The list is terminated by @end. */
13372 switch (c_parser_peek_token (parser
)->type
)
13374 case CPP_SEMICOLON
:
13375 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
13376 "ISO C does not allow extra %<;%> outside of a function");
13377 c_parser_consume_token (parser
);
13381 c_parser_objc_methodproto (parser
);
13384 c_parser_pragma (parser
, pragma_external
, NULL
);
13389 if (c_parser_next_token_is_keyword (parser
, RID_AT_END
))
13391 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
))
13392 c_parser_objc_at_property_declaration (parser
);
13393 else if (c_parser_next_token_is_keyword (parser
, RID_AT_OPTIONAL
))
13395 objc_set_method_opt (true);
13396 c_parser_consume_token (parser
);
13398 else if (c_parser_next_token_is_keyword (parser
, RID_AT_REQUIRED
))
13400 objc_set_method_opt (false);
13401 c_parser_consume_token (parser
);
13404 c_parser_declaration_or_fndef (parser
, false, false, true,
13411 /* Parse an objc-methodproto.
13414 objc-method-type objc-method-decl ;
13418 c_parser_objc_methodproto (c_parser
*parser
)
13420 bool is_class_method
= c_parser_objc_method_type (parser
);
13421 tree decl
, attributes
= NULL_TREE
;
13423 /* Remember protocol qualifiers in prototypes. */
13424 parser
->objc_pq_context
= true;
13425 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
13427 /* Forget protocol qualifiers now. */
13428 parser
->objc_pq_context
= false;
13430 /* Do not allow the presence of attributes to hide an erroneous
13431 method implementation in the interface section. */
13432 if (!c_parser_next_token_is (parser
, CPP_SEMICOLON
))
13434 c_parser_error (parser
, "expected %<;%>");
13438 if (decl
!= error_mark_node
)
13439 objc_add_method_declaration (is_class_method
, decl
, attributes
);
13441 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13444 /* If we are at a position that method attributes may be present, check that
13445 there are not any parsed already (a syntax error) and then collect any
13446 specified at the current location. Finally, if new attributes were present,
13447 check that the next token is legal ( ';' for decls and '{' for defs). */
13450 c_parser_objc_maybe_method_attributes (c_parser
* parser
, tree
* attributes
)
13455 c_parser_error (parser
,
13456 "method attributes must be specified at the end only");
13457 *attributes
= NULL_TREE
;
13461 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
13462 *attributes
= c_parser_gnu_attributes (parser
);
13464 /* If there were no attributes here, just report any earlier error. */
13465 if (*attributes
== NULL_TREE
|| bad
)
13468 /* If the attributes are followed by a ; or {, then just report any earlier
13470 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
13471 || c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
13474 /* We've got attributes, but not at the end. */
13475 c_parser_error (parser
,
13476 "expected %<;%> or %<{%> after method attribute definition");
13480 /* Parse an objc-method-decl.
13483 ( objc-type-name ) objc-selector
13485 ( objc-type-name ) objc-keyword-selector objc-optparmlist
13486 objc-keyword-selector objc-optparmlist
13489 objc-keyword-selector:
13491 objc-keyword-selector objc-keyword-decl
13494 objc-selector : ( objc-type-name ) identifier
13495 objc-selector : identifier
13496 : ( objc-type-name ) identifier
13500 objc-optparms objc-optellipsis
13504 objc-opt-parms , parameter-declaration
13512 c_parser_objc_method_decl (c_parser
*parser
, bool is_class_method
,
13513 tree
*attributes
, tree
*expr
)
13515 tree type
= NULL_TREE
;
13517 tree parms
= NULL_TREE
;
13518 bool ellipsis
= false;
13519 bool attr_err
= false;
13521 *attributes
= NULL_TREE
;
13522 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13524 matching_parens parens
;
13525 parens
.consume_open (parser
);
13526 type
= c_parser_objc_type_name (parser
);
13527 parens
.skip_until_found_close (parser
);
13529 sel
= c_parser_objc_selector (parser
);
13530 /* If there is no selector, or a colon follows, we have an
13531 objc-keyword-selector. If there is a selector, and a colon does
13532 not follow, that selector ends the objc-method-decl. */
13533 if (!sel
|| c_parser_next_token_is (parser
, CPP_COLON
))
13536 tree list
= NULL_TREE
;
13539 tree atype
= NULL_TREE
, id
, keyworddecl
;
13540 tree param_attr
= NULL_TREE
;
13541 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
13543 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13545 c_parser_consume_token (parser
);
13546 atype
= c_parser_objc_type_name (parser
);
13547 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
13550 /* New ObjC allows attributes on method parameters. */
13551 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
13552 param_attr
= c_parser_gnu_attributes (parser
);
13553 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13555 c_parser_error (parser
, "expected identifier");
13556 return error_mark_node
;
13558 id
= c_parser_peek_token (parser
)->value
;
13559 c_parser_consume_token (parser
);
13560 keyworddecl
= objc_build_keyword_decl (tsel
, atype
, id
, param_attr
);
13561 list
= chainon (list
, keyworddecl
);
13562 tsel
= c_parser_objc_selector (parser
);
13563 if (!tsel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
13567 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
13569 /* Parse the optional parameter list. Optional Objective-C
13570 method parameters follow the C syntax, and may include '...'
13571 to denote a variable number of arguments. */
13572 parms
= make_node (TREE_LIST
);
13573 while (c_parser_next_token_is (parser
, CPP_COMMA
))
13575 struct c_parm
*parm
;
13576 c_parser_consume_token (parser
);
13577 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
13580 c_parser_consume_token (parser
);
13581 attr_err
|= c_parser_objc_maybe_method_attributes
13582 (parser
, attributes
) ;
13585 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
13588 parms
= chainon (parms
,
13589 build_tree_list (NULL_TREE
, grokparm (parm
, expr
)));
13594 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
13598 c_parser_error (parser
, "objective-c method declaration is expected");
13599 return error_mark_node
;
13603 return error_mark_node
;
13605 return objc_build_method_signature (is_class_method
, type
, sel
, parms
, ellipsis
);
13608 /* Parse an objc-type-name.
13611 objc-type-qualifiers[opt] type-name
13612 objc-type-qualifiers[opt]
13614 objc-type-qualifiers:
13615 objc-type-qualifier
13616 objc-type-qualifiers objc-type-qualifier
13618 objc-type-qualifier: one of
13619 in out inout bycopy byref oneway
13623 c_parser_objc_type_name (c_parser
*parser
)
13625 tree quals
= NULL_TREE
;
13626 struct c_type_name
*type_name
= NULL
;
13627 tree type
= NULL_TREE
;
13630 c_token
*token
= c_parser_peek_token (parser
);
13631 if (token
->type
== CPP_KEYWORD
13632 && (token
->keyword
== RID_IN
13633 || token
->keyword
== RID_OUT
13634 || token
->keyword
== RID_INOUT
13635 || token
->keyword
== RID_BYCOPY
13636 || token
->keyword
== RID_BYREF
13637 || token
->keyword
== RID_ONEWAY
))
13639 quals
= chainon (build_tree_list (NULL_TREE
, token
->value
), quals
);
13640 c_parser_consume_token (parser
);
13645 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
13646 type_name
= c_parser_type_name (parser
);
13648 type
= groktypename (type_name
, NULL
, NULL
);
13650 /* If the type is unknown, and error has already been produced and
13651 we need to recover from the error. In that case, use NULL_TREE
13652 for the type, as if no type had been specified; this will use the
13653 default type ('id') which is good for error recovery. */
13654 if (type
== error_mark_node
)
13657 return build_tree_list (quals
, type
);
13660 /* Parse objc-protocol-refs.
13662 objc-protocol-refs:
13663 < identifier-list >
13667 c_parser_objc_protocol_refs (c_parser
*parser
)
13669 tree list
= NULL_TREE
;
13670 gcc_assert (c_parser_next_token_is (parser
, CPP_LESS
));
13671 c_parser_consume_token (parser
);
13672 /* Any identifiers, including those declared as type names, are OK
13677 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
13679 c_parser_error (parser
, "expected identifier");
13682 id
= c_parser_peek_token (parser
)->value
;
13683 list
= chainon (list
, build_tree_list (NULL_TREE
, id
));
13684 c_parser_consume_token (parser
);
13685 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13686 c_parser_consume_token (parser
);
13690 c_parser_require (parser
, CPP_GREATER
, "expected %<>%>");
13694 /* Parse an objc-try-catch-finally-statement.
13696 objc-try-catch-finally-statement:
13697 @try compound-statement objc-catch-list[opt]
13698 @try compound-statement objc-catch-list[opt] @finally compound-statement
13701 @catch ( objc-catch-parameter-declaration ) compound-statement
13702 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
13704 objc-catch-parameter-declaration:
13705 parameter-declaration
13708 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
13710 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
13711 for C++. Keep them in sync. */
13714 c_parser_objc_try_catch_finally_statement (c_parser
*parser
)
13716 location_t location
;
13719 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_TRY
));
13720 c_parser_consume_token (parser
);
13721 location
= c_parser_peek_token (parser
)->location
;
13722 objc_maybe_warn_exceptions (location
);
13723 stmt
= c_parser_compound_statement (parser
);
13724 objc_begin_try_stmt (location
, stmt
);
13726 while (c_parser_next_token_is_keyword (parser
, RID_AT_CATCH
))
13728 struct c_parm
*parm
;
13729 tree parameter_declaration
= error_mark_node
;
13730 bool seen_open_paren
= false;
13732 c_parser_consume_token (parser
);
13733 matching_parens parens
;
13734 if (!parens
.require_open (parser
))
13735 seen_open_paren
= true;
13736 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
13738 /* We have "@catch (...)" (where the '...' are literally
13739 what is in the code). Skip the '...'.
13740 parameter_declaration is set to NULL_TREE, and
13741 objc_being_catch_clauses() knows that that means
13743 c_parser_consume_token (parser
);
13744 parameter_declaration
= NULL_TREE
;
13748 /* We have "@catch (NSException *exception)" or something
13749 like that. Parse the parameter declaration. */
13750 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
13752 parameter_declaration
= error_mark_node
;
13754 parameter_declaration
= grokparm (parm
, NULL
);
13756 if (seen_open_paren
)
13757 parens
.require_close (parser
);
13760 /* If there was no open parenthesis, we are recovering from
13761 an error, and we are trying to figure out what mistake
13762 the user has made. */
13764 /* If there is an immediate closing parenthesis, the user
13765 probably forgot the opening one (ie, they typed "@catch
13766 NSException *e)". Parse the closing parenthesis and keep
13768 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
13769 c_parser_consume_token (parser
);
13771 /* If these is no immediate closing parenthesis, the user
13772 probably doesn't know that parenthesis are required at
13773 all (ie, they typed "@catch NSException *e"). So, just
13774 forget about the closing parenthesis and keep going. */
13776 objc_begin_catch_clause (parameter_declaration
);
13777 if (c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
13778 c_parser_compound_statement_nostart (parser
);
13779 objc_finish_catch_clause ();
13781 if (c_parser_next_token_is_keyword (parser
, RID_AT_FINALLY
))
13783 c_parser_consume_token (parser
);
13784 location
= c_parser_peek_token (parser
)->location
;
13785 stmt
= c_parser_compound_statement (parser
);
13786 objc_build_finally_clause (location
, stmt
);
13788 objc_finish_try_stmt ();
13791 /* Parse an objc-synchronized-statement.
13793 objc-synchronized-statement:
13794 @synchronized ( expression ) compound-statement
13798 c_parser_objc_synchronized_statement (c_parser
*parser
)
13802 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNCHRONIZED
));
13803 c_parser_consume_token (parser
);
13804 loc
= c_parser_peek_token (parser
)->location
;
13805 objc_maybe_warn_exceptions (loc
);
13806 matching_parens parens
;
13807 if (parens
.require_open (parser
))
13809 struct c_expr ce
= c_parser_expression (parser
);
13810 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
13812 expr
= c_fully_fold (expr
, false, NULL
);
13813 parens
.skip_until_found_close (parser
);
13816 expr
= error_mark_node
;
13817 stmt
= c_parser_compound_statement (parser
);
13818 objc_build_synchronized (loc
, expr
, stmt
);
13821 /* Parse an objc-selector; return NULL_TREE without an error if the
13822 next token is not an objc-selector.
13827 enum struct union if else while do for switch case default
13828 break continue return goto asm sizeof typeof typeof_unqual __alignof
13829 unsigned long const short volatile signed restrict _Complex
13830 in out inout bycopy byref oneway int char float double void _Bool
13833 ??? Why this selection of keywords but not, for example, storage
13834 class specifiers? */
13837 c_parser_objc_selector (c_parser
*parser
)
13839 c_token
*token
= c_parser_peek_token (parser
);
13840 tree value
= token
->value
;
13841 if (token
->type
== CPP_NAME
)
13843 c_parser_consume_token (parser
);
13846 if (token
->type
!= CPP_KEYWORD
)
13848 switch (token
->keyword
)
13868 case RID_TYPEOF_UNQUAL
:
13888 CASE_RID_FLOATN_NX
:
13892 case RID_AUTO_TYPE
:
13897 c_parser_consume_token (parser
);
13904 /* Parse an objc-selector-arg.
13908 objc-keywordname-list
13910 objc-keywordname-list:
13912 objc-keywordname-list objc-keywordname
13920 c_parser_objc_selector_arg (c_parser
*parser
)
13922 tree sel
= c_parser_objc_selector (parser
);
13923 tree list
= NULL_TREE
;
13925 && c_parser_next_token_is_not (parser
, CPP_COLON
)
13926 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
13930 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
13932 c_parser_consume_token (parser
);
13933 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
13934 list
= chainon (list
, build_tree_list (NULL_TREE
, NULL_TREE
));
13938 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
13940 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
13942 sel
= c_parser_objc_selector (parser
);
13944 && c_parser_next_token_is_not (parser
, CPP_COLON
)
13945 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
13951 /* Parse an objc-receiver.
13960 c_parser_objc_receiver (c_parser
*parser
)
13962 location_t loc
= c_parser_peek_token (parser
)->location
;
13964 if (c_parser_peek_token (parser
)->type
== CPP_NAME
13965 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
13966 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
13968 tree id
= c_parser_peek_token (parser
)->value
;
13969 c_parser_consume_token (parser
);
13970 return objc_get_class_reference (id
);
13972 struct c_expr ce
= c_parser_expression (parser
);
13973 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
13974 return c_fully_fold (ce
.value
, false, NULL
);
13977 /* Parse objc-message-args.
13981 objc-keywordarg-list
13983 objc-keywordarg-list:
13985 objc-keywordarg-list objc-keywordarg
13988 objc-selector : objc-keywordexpr
13993 c_parser_objc_message_args (c_parser
*parser
)
13995 tree sel
= c_parser_objc_selector (parser
);
13996 tree list
= NULL_TREE
;
13997 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
14002 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14003 return error_mark_node
;
14004 keywordexpr
= c_parser_objc_keywordexpr (parser
);
14005 list
= chainon (list
, build_tree_list (sel
, keywordexpr
));
14006 sel
= c_parser_objc_selector (parser
);
14007 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
14013 /* Parse an objc-keywordexpr.
14020 c_parser_objc_keywordexpr (c_parser
*parser
)
14023 vec
<tree
, va_gc
> *expr_list
= c_parser_expr_list (parser
, true, true,
14024 NULL
, NULL
, NULL
, NULL
);
14025 if (vec_safe_length (expr_list
) == 1)
14027 /* Just return the expression, remove a level of
14029 ret
= (*expr_list
)[0];
14033 /* We have a comma expression, we will collapse later. */
14034 ret
= build_tree_list_vec (expr_list
);
14036 release_tree_vector (expr_list
);
14040 /* A check, needed in several places, that ObjC interface, implementation or
14041 method definitions are not prefixed by incorrect items. */
14043 c_parser_objc_diagnose_bad_element_prefix (c_parser
*parser
,
14044 struct c_declspecs
*specs
)
14046 if (!specs
->declspecs_seen_p
|| specs
->non_sc_seen_p
14047 || specs
->typespec_kind
!= ctsk_none
)
14049 c_parser_error (parser
,
14050 "no type or storage class may be specified here,");
14051 c_parser_skip_to_end_of_block_or_statement (parser
);
14057 /* Parse an Objective-C @property declaration. The syntax is:
14059 objc-property-declaration:
14060 '@property' objc-property-attributes[opt] struct-declaration ;
14062 objc-property-attributes:
14063 '(' objc-property-attribute-list ')'
14065 objc-property-attribute-list:
14066 objc-property-attribute
14067 objc-property-attribute-list, objc-property-attribute
14069 objc-property-attribute
14070 'getter' = identifier
14071 'setter' = identifier
14080 @property NSString *name;
14081 @property (readonly) id object;
14082 @property (retain, nonatomic, getter=getTheName) id name;
14083 @property int a, b, c;
14085 PS: This function is identical to cp_parser_objc_at_propery_declaration
14086 for C++. Keep them in sync. */
14088 c_parser_objc_at_property_declaration (c_parser
*parser
)
14090 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
));
14091 location_t loc
= c_parser_peek_token (parser
)->location
;
14092 c_parser_consume_token (parser
); /* Eat '@property'. */
14094 /* Parse the optional attribute list.
14096 A list of parsed, but not verified, attributes. */
14097 vec
<property_attribute_info
*> prop_attr_list
= vNULL
;
14099 bool syntax_error
= false;
14100 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14102 matching_parens parens
;
14104 location_t attr_start
= c_parser_peek_token (parser
)->location
;
14106 parens
.consume_open (parser
);
14108 /* Property attribute keywords are valid now. */
14109 parser
->objc_property_attr_context
= true;
14111 /* Allow @property (), with a warning. */
14112 location_t attr_end
= c_parser_peek_token (parser
)->location
;
14114 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
14116 location_t attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
14117 warning_at (attr_comb
, OPT_Wattributes
,
14118 "empty property attribute list");
14123 c_token
*token
= c_parser_peek_token (parser
);
14124 attr_start
= token
->location
;
14125 attr_end
= get_finish (token
->location
);
14126 location_t attr_comb
= make_location (attr_start
, attr_start
,
14129 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_COMMA
)
14131 warning_at (attr_comb
, OPT_Wattributes
,
14132 "missing property attribute");
14133 if (token
->type
== CPP_CLOSE_PAREN
)
14135 c_parser_consume_token (parser
);
14139 tree attr_name
= NULL_TREE
;
14140 enum rid keyword
= RID_MAX
; /* Not a valid property attribute. */
14141 bool add_at
= false;
14142 if (token
->type
== CPP_KEYWORD
)
14144 keyword
= token
->keyword
;
14145 if (OBJC_IS_AT_KEYWORD (keyword
))
14147 /* For '@' keywords the token value has the keyword,
14148 prepend the '@' for diagnostics. */
14149 attr_name
= token
->value
;
14153 attr_name
= ridpointers
[(int)keyword
];
14155 else if (token
->type
== CPP_NAME
)
14156 attr_name
= token
->value
;
14157 c_parser_consume_token (parser
);
14159 enum objc_property_attribute_kind prop_kind
14160 = objc_prop_attr_kind_for_rid (keyword
);
14161 property_attribute_info
*prop
14162 = new property_attribute_info (attr_name
, attr_comb
, prop_kind
);
14163 prop_attr_list
.safe_push (prop
);
14166 switch (prop
->prop_kind
)
14169 case OBJC_PROPERTY_ATTR_UNKNOWN
:
14171 error_at (attr_comb
, "unknown property attribute %<%s%s%>",
14172 add_at
? "@" : "", IDENTIFIER_POINTER (attr_name
));
14174 error_at (attr_comb
, "unknown property attribute");
14175 prop
->parse_error
= syntax_error
= true;
14178 case OBJC_PROPERTY_ATTR_GETTER
:
14179 case OBJC_PROPERTY_ATTR_SETTER
:
14180 if (c_parser_next_token_is_not (parser
, CPP_EQ
))
14182 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
14183 error_at (attr_comb
, "expected %<=%> after Objective-C %qE",
14185 prop
->parse_error
= syntax_error
= true;
14188 token
= c_parser_peek_token (parser
);
14189 attr_end
= token
->location
;
14190 c_parser_consume_token (parser
); /* eat the = */
14191 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14193 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
14194 error_at (attr_comb
, "expected %qE selector name",
14196 prop
->parse_error
= syntax_error
= true;
14199 /* Get the end of the method name, and consume the name. */
14200 token
= c_parser_peek_token (parser
);
14201 attr_end
= get_finish (token
->location
);
14202 meth_name
= token
->value
;
14203 c_parser_consume_token (parser
);
14204 if (prop
->prop_kind
== OBJC_PROPERTY_ATTR_SETTER
)
14206 if (c_parser_next_token_is_not (parser
, CPP_COLON
))
14208 attr_comb
= make_location (attr_end
, attr_start
,
14210 error_at (attr_comb
, "setter method names must"
14211 " terminate with %<:%>");
14212 prop
->parse_error
= syntax_error
= true;
14216 attr_end
= get_finish (c_parser_peek_token
14217 (parser
)->location
);
14218 c_parser_consume_token (parser
);
14220 attr_comb
= make_location (attr_start
, attr_start
,
14224 attr_comb
= make_location (attr_start
, attr_start
,
14226 prop
->ident
= meth_name
;
14227 /* Updated location including all that was successfully
14229 prop
->prop_loc
= attr_comb
;
14233 /* If we see a comma here, then keep going - even if we already
14234 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
14235 this makes a more useful output and avoid spurious warnings about
14236 missing attributes that are, in fact, specified after the one with
14237 the syntax error. */
14238 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14239 c_parser_consume_token (parser
);
14243 parser
->objc_property_attr_context
= false;
14245 if (syntax_error
&& c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
14246 /* We don't really want to chew the whole of the file looking for a
14247 matching closing parenthesis, so we will try to read the decl and
14248 let the error handling for that close out the statement. */
14251 syntax_error
= false, parens
.skip_until_found_close (parser
);
14254 /* 'properties' is the list of properties that we read. Usually a
14255 single one, but maybe more (eg, in "@property int a, b, c;" there
14257 tree properties
= c_parser_struct_declaration (parser
, NULL
);
14259 if (properties
== error_mark_node
)
14260 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
14263 if (properties
== NULL_TREE
)
14264 c_parser_error (parser
, "expected identifier");
14267 /* Comma-separated properties are chained together in reverse order;
14268 add them one by one. */
14269 properties
= nreverse (properties
);
14270 for (; properties
; properties
= TREE_CHAIN (properties
))
14271 objc_add_property_declaration (loc
, copy_node (properties
),
14274 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
14277 while (!prop_attr_list
.is_empty())
14278 delete prop_attr_list
.pop ();
14279 prop_attr_list
.release ();
14280 parser
->error
= false;
14283 /* Parse an Objective-C @synthesize declaration. The syntax is:
14285 objc-synthesize-declaration:
14286 @synthesize objc-synthesize-identifier-list ;
14288 objc-synthesize-identifier-list:
14289 objc-synthesize-identifier
14290 objc-synthesize-identifier-list, objc-synthesize-identifier
14292 objc-synthesize-identifier
14294 identifier = identifier
14297 @synthesize MyProperty;
14298 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
14300 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
14301 for C++. Keep them in sync.
14304 c_parser_objc_at_synthesize_declaration (c_parser
*parser
)
14306 tree list
= NULL_TREE
;
14308 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNTHESIZE
));
14309 loc
= c_parser_peek_token (parser
)->location
;
14311 c_parser_consume_token (parser
);
14314 tree property
, ivar
;
14315 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14317 c_parser_error (parser
, "expected identifier");
14318 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
14319 /* Once we find the semicolon, we can resume normal parsing.
14320 We have to reset parser->error manually because
14321 c_parser_skip_until_found() won't reset it for us if the
14322 next token is precisely a semicolon. */
14323 parser
->error
= false;
14326 property
= c_parser_peek_token (parser
)->value
;
14327 c_parser_consume_token (parser
);
14328 if (c_parser_next_token_is (parser
, CPP_EQ
))
14330 c_parser_consume_token (parser
);
14331 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14333 c_parser_error (parser
, "expected identifier");
14334 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
14335 parser
->error
= false;
14338 ivar
= c_parser_peek_token (parser
)->value
;
14339 c_parser_consume_token (parser
);
14343 list
= chainon (list
, build_tree_list (ivar
, property
));
14344 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14345 c_parser_consume_token (parser
);
14349 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
14350 objc_add_synthesize_declaration (loc
, list
);
14353 /* Parse an Objective-C @dynamic declaration. The syntax is:
14355 objc-dynamic-declaration:
14356 @dynamic identifier-list ;
14359 @dynamic MyProperty;
14360 @dynamic MyProperty, AnotherProperty;
14362 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
14363 for C++. Keep them in sync.
14366 c_parser_objc_at_dynamic_declaration (c_parser
*parser
)
14368 tree list
= NULL_TREE
;
14370 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_DYNAMIC
));
14371 loc
= c_parser_peek_token (parser
)->location
;
14373 c_parser_consume_token (parser
);
14377 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
14379 c_parser_error (parser
, "expected identifier");
14380 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
14381 parser
->error
= false;
14384 property
= c_parser_peek_token (parser
)->value
;
14385 list
= chainon (list
, build_tree_list (NULL_TREE
, property
));
14386 c_parser_consume_token (parser
);
14387 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14388 c_parser_consume_token (parser
);
14392 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
14393 objc_add_dynamic_declaration (loc
, list
);
14397 /* Parse a pragma GCC ivdep. */
14400 c_parse_pragma_ivdep (c_parser
*parser
)
14402 c_parser_consume_pragma (parser
);
14403 c_parser_skip_to_pragma_eol (parser
);
14407 /* Parse a pragma GCC novector. */
14410 c_parse_pragma_novector (c_parser
*parser
)
14412 c_parser_consume_pragma (parser
);
14413 c_parser_skip_to_pragma_eol (parser
);
14417 /* Parse a pragma GCC unroll. */
14419 static unsigned short
14420 c_parser_pragma_unroll (c_parser
*parser
)
14422 unsigned short unroll
;
14423 c_parser_consume_pragma (parser
);
14424 location_t location
= c_parser_peek_token (parser
)->location
;
14425 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
14426 mark_exp_read (expr
);
14427 expr
= c_fully_fold (expr
, false, NULL
);
14428 HOST_WIDE_INT lunroll
= 0;
14429 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
14430 || TREE_CODE (expr
) != INTEGER_CST
14431 || (lunroll
= tree_to_shwi (expr
)) < 0
14432 || lunroll
>= USHRT_MAX
)
14434 error_at (location
, "%<#pragma GCC unroll%> requires an"
14435 " assignment-expression that evaluates to a non-negative"
14436 " integral constant less than %u", USHRT_MAX
);
14441 unroll
= (unsigned short)lunroll
;
14446 c_parser_skip_to_pragma_eol (parser
);
14450 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
14451 should be considered, statements. ALLOW_STMT is true if we're within
14452 the context of a function and such pragmas are to be allowed. Returns
14453 true if we actually parsed such a pragma. */
14456 c_parser_pragma (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
14459 const char *construct
= NULL
;
14461 input_location
= c_parser_peek_token (parser
)->location
;
14462 id
= c_parser_peek_token (parser
)->pragma_kind
;
14463 gcc_assert (id
!= PRAGMA_NONE
);
14464 if (parser
->omp_for_parse_state
14465 && parser
->omp_for_parse_state
->in_intervening_code
14466 && id
>= PRAGMA_OMP__START_
14467 && id
<= PRAGMA_OMP__LAST_
)
14469 error_at (input_location
,
14470 "intervening code must not contain OpenMP directives");
14471 parser
->omp_for_parse_state
->fail
= true;
14472 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14478 case PRAGMA_OACC_DECLARE
:
14479 c_parser_oacc_declare (parser
);
14482 case PRAGMA_OACC_ENTER_DATA
:
14483 if (context
!= pragma_compound
)
14485 construct
= "acc enter data";
14487 if (context
== pragma_stmt
)
14489 error_at (c_parser_peek_token (parser
)->location
,
14490 "%<#pragma %s%> may only be used in compound "
14491 "statements", construct
);
14492 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14497 c_parser_oacc_enter_exit_data (parser
, true);
14500 case PRAGMA_OACC_EXIT_DATA
:
14501 if (context
!= pragma_compound
)
14503 construct
= "acc exit data";
14506 c_parser_oacc_enter_exit_data (parser
, false);
14509 case PRAGMA_OACC_ROUTINE
:
14510 if (context
!= pragma_external
)
14512 error_at (c_parser_peek_token (parser
)->location
,
14513 "%<#pragma acc routine%> must be at file scope");
14514 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14517 c_parser_oacc_routine (parser
, context
);
14520 case PRAGMA_OACC_UPDATE
:
14521 if (context
!= pragma_compound
)
14523 construct
= "acc update";
14526 c_parser_oacc_update (parser
);
14529 case PRAGMA_OMP_BARRIER
:
14530 if (context
!= pragma_compound
)
14532 construct
= "omp barrier";
14535 c_parser_omp_barrier (parser
);
14538 case PRAGMA_OMP_DEPOBJ
:
14539 if (context
!= pragma_compound
)
14541 construct
= "omp depobj";
14544 c_parser_omp_depobj (parser
);
14547 case PRAGMA_OMP_FLUSH
:
14548 if (context
!= pragma_compound
)
14550 construct
= "omp flush";
14553 c_parser_omp_flush (parser
);
14556 case PRAGMA_OMP_TASKWAIT
:
14557 if (context
!= pragma_compound
)
14559 construct
= "omp taskwait";
14562 c_parser_omp_taskwait (parser
);
14565 case PRAGMA_OMP_TASKYIELD
:
14566 if (context
!= pragma_compound
)
14568 construct
= "omp taskyield";
14571 c_parser_omp_taskyield (parser
);
14574 case PRAGMA_OMP_CANCEL
:
14575 if (context
!= pragma_compound
)
14577 construct
= "omp cancel";
14580 c_parser_omp_cancel (parser
);
14583 case PRAGMA_OMP_CANCELLATION_POINT
:
14584 return c_parser_omp_cancellation_point (parser
, context
);
14586 case PRAGMA_OMP_THREADPRIVATE
:
14587 c_parser_omp_threadprivate (parser
);
14590 case PRAGMA_OMP_TARGET
:
14591 return c_parser_omp_target (parser
, context
, if_p
);
14593 case PRAGMA_OMP_BEGIN
:
14594 c_parser_omp_begin (parser
);
14597 case PRAGMA_OMP_END
:
14598 c_parser_omp_end (parser
);
14601 case PRAGMA_OMP_SCAN
:
14602 error_at (c_parser_peek_token (parser
)->location
,
14603 "%<#pragma omp scan%> may only be used in "
14604 "a loop construct with %<inscan%> %<reduction%> clause");
14605 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14608 case PRAGMA_OMP_SECTION
:
14609 error_at (c_parser_peek_token (parser
)->location
,
14610 "%<#pragma omp section%> may only be used in "
14611 "%<#pragma omp sections%> construct");
14612 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14615 case PRAGMA_OMP_DECLARE
:
14616 return c_parser_omp_declare (parser
, context
);
14618 case PRAGMA_OMP_REQUIRES
:
14619 if (context
!= pragma_external
)
14621 error_at (c_parser_peek_token (parser
)->location
,
14622 "%<#pragma %s%> may only be used at file scope",
14624 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14627 c_parser_omp_requires (parser
);
14630 case PRAGMA_OMP_ALLOCATE
:
14631 c_parser_omp_allocate (parser
);
14634 case PRAGMA_OMP_ASSUMES
:
14635 if (context
!= pragma_external
)
14637 error_at (c_parser_peek_token (parser
)->location
,
14638 "%<#pragma %s%> may only be used at file scope",
14640 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14643 c_parser_omp_assumes (parser
);
14646 case PRAGMA_OMP_NOTHING
:
14647 c_parser_omp_nothing (parser
);
14650 case PRAGMA_OMP_ERROR
:
14651 return c_parser_omp_error (parser
, context
);
14653 case PRAGMA_OMP_ORDERED
:
14654 return c_parser_omp_ordered (parser
, context
, if_p
);
14656 case PRAGMA_NOVECTOR
:
14657 case PRAGMA_UNROLL
:
14660 bool novector
= false;
14661 unsigned short unroll
= 0;
14662 bool ivdep
= false;
14666 case PRAGMA_NOVECTOR
:
14667 novector
= c_parse_pragma_novector (parser
);
14669 case PRAGMA_UNROLL
:
14670 unroll
= c_parser_pragma_unroll (parser
);
14673 ivdep
= c_parse_pragma_ivdep (parser
);
14676 gcc_unreachable ();
14679 c_token
*tok
= c_parser_peek_token (parser
);
14680 bool has_more
= tok
->type
== CPP_PRAGMA
;
14683 switch (tok
->pragma_kind
)
14686 ivdep
= c_parse_pragma_ivdep (parser
);
14688 case PRAGMA_UNROLL
:
14689 unroll
= c_parser_pragma_unroll (parser
);
14691 case PRAGMA_NOVECTOR
:
14692 novector
= c_parse_pragma_novector (parser
);
14698 tok
= c_parser_peek_token (parser
);
14699 has_more
= has_more
&& tok
->type
== CPP_PRAGMA
;
14701 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
14702 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
14703 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
14705 c_parser_error (parser
, "for, while or do statement expected");
14708 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
14709 c_parser_for_statement (parser
, ivdep
, unroll
, novector
, if_p
);
14710 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
14711 c_parser_while_statement (parser
, ivdep
, unroll
, novector
, if_p
);
14713 c_parser_do_statement (parser
, ivdep
, unroll
, novector
);
14717 case PRAGMA_GCC_PCH_PREPROCESS
:
14718 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
14719 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14722 case PRAGMA_OACC_WAIT
:
14723 if (context
!= pragma_compound
)
14725 construct
= "acc wait";
14728 /* FALL THROUGH. */
14731 if (id
< PRAGMA_FIRST_EXTERNAL
)
14733 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
14736 c_parser_error (parser
, "expected declaration specifiers");
14737 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
14740 c_parser_omp_construct (parser
, if_p
);
14746 c_parser_consume_pragma (parser
);
14747 c_invoke_pragma_handler (id
);
14749 /* Skip to EOL, but suppress any error message. Those will have been
14750 generated by the handler routine through calling error, as opposed
14751 to calling c_parser_error. */
14752 parser
->error
= true;
14753 c_parser_skip_to_pragma_eol (parser
);
14758 /* The interface the pragma parsers have to the lexer. */
14761 pragma_lex (tree
*value
, location_t
*loc
)
14763 c_token
*tok
= c_parser_peek_token (the_parser
);
14764 enum cpp_ttype ret
= tok
->type
;
14766 *value
= tok
->value
;
14768 *loc
= tok
->location
;
14770 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
14772 else if (ret
== CPP_STRING
)
14773 *value
= c_parser_string_literal (the_parser
, false, false).value
;
14776 if (ret
== CPP_KEYWORD
)
14778 c_parser_consume_token (the_parser
);
14785 pragma_lex_discard_to_eol ()
14790 type
= c_parser_peek_token (the_parser
)->type
;
14791 gcc_assert (type
!= CPP_EOF
);
14792 c_parser_consume_token (the_parser
);
14793 } while (type
!= CPP_PRAGMA_EOL
);
14797 c_parser_pragma_pch_preprocess (c_parser
*parser
)
14801 parser
->lex_joined_string
= true;
14802 c_parser_consume_pragma (parser
);
14803 if (c_parser_next_token_is (parser
, CPP_STRING
))
14805 name
= c_parser_peek_token (parser
)->value
;
14806 c_parser_consume_token (parser
);
14809 c_parser_error (parser
, "expected string literal");
14810 c_parser_skip_to_pragma_eol (parser
);
14811 parser
->lex_joined_string
= false;
14814 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
14817 /* OpenACC and OpenMP parsing routines. */
14819 /* Returns name of the next clause.
14820 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
14821 the token is not consumed. Otherwise appropriate pragma_omp_clause is
14822 returned and the token is consumed. */
14824 static pragma_omp_clause
14825 c_parser_omp_clause_name (c_parser
*parser
)
14827 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
14829 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
14830 result
= PRAGMA_OACC_CLAUSE_AUTO
;
14831 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
14832 result
= PRAGMA_OMP_CLAUSE_IF
;
14833 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
14834 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
14835 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
14836 result
= PRAGMA_OMP_CLAUSE_FOR
;
14837 else if (c_parser_next_token_is (parser
, CPP_NAME
))
14839 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14844 if (!strcmp ("affinity", p
))
14845 result
= PRAGMA_OMP_CLAUSE_AFFINITY
;
14846 else if (!strcmp ("aligned", p
))
14847 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
14848 else if (!strcmp ("allocate", p
))
14849 result
= PRAGMA_OMP_CLAUSE_ALLOCATE
;
14850 else if (!strcmp ("async", p
))
14851 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
14852 else if (!strcmp ("attach", p
))
14853 result
= PRAGMA_OACC_CLAUSE_ATTACH
;
14856 if (!strcmp ("bind", p
))
14857 result
= PRAGMA_OMP_CLAUSE_BIND
;
14860 if (!strcmp ("collapse", p
))
14861 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
14862 else if (!strcmp ("copy", p
))
14863 result
= PRAGMA_OACC_CLAUSE_COPY
;
14864 else if (!strcmp ("copyin", p
))
14865 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
14866 else if (!strcmp ("copyout", p
))
14867 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
14868 else if (!strcmp ("copyprivate", p
))
14869 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
14870 else if (!strcmp ("create", p
))
14871 result
= PRAGMA_OACC_CLAUSE_CREATE
;
14874 if (!strcmp ("defaultmap", p
))
14875 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
14876 else if (!strcmp ("delete", p
))
14877 result
= PRAGMA_OACC_CLAUSE_DELETE
;
14878 else if (!strcmp ("depend", p
))
14879 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
14880 else if (!strcmp ("detach", p
))
14881 result
= PRAGMA_OACC_CLAUSE_DETACH
;
14882 else if (!strcmp ("device", p
))
14883 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
14884 else if (!strcmp ("deviceptr", p
))
14885 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
14886 else if (!strcmp ("device_resident", p
))
14887 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
14888 else if (!strcmp ("device_type", p
))
14889 result
= PRAGMA_OMP_CLAUSE_DEVICE_TYPE
;
14890 else if (!strcmp ("dist_schedule", p
))
14891 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
14892 else if (!strcmp ("doacross", p
))
14893 result
= PRAGMA_OMP_CLAUSE_DOACROSS
;
14896 if (!strcmp ("enter", p
))
14897 result
= PRAGMA_OMP_CLAUSE_ENTER
;
14900 if (!strcmp ("filter", p
))
14901 result
= PRAGMA_OMP_CLAUSE_FILTER
;
14902 else if (!strcmp ("final", p
))
14903 result
= PRAGMA_OMP_CLAUSE_FINAL
;
14904 else if (!strcmp ("finalize", p
))
14905 result
= PRAGMA_OACC_CLAUSE_FINALIZE
;
14906 else if (!strcmp ("firstprivate", p
))
14907 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
14908 else if (!strcmp ("from", p
))
14909 result
= PRAGMA_OMP_CLAUSE_FROM
;
14912 if (!strcmp ("gang", p
))
14913 result
= PRAGMA_OACC_CLAUSE_GANG
;
14914 else if (!strcmp ("grainsize", p
))
14915 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
14918 if (!strcmp ("has_device_addr", p
))
14919 result
= PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
;
14920 else if (!strcmp ("hint", p
))
14921 result
= PRAGMA_OMP_CLAUSE_HINT
;
14922 else if (!strcmp ("host", p
))
14923 result
= PRAGMA_OACC_CLAUSE_HOST
;
14926 if (!strcmp ("if_present", p
))
14927 result
= PRAGMA_OACC_CLAUSE_IF_PRESENT
;
14928 else if (!strcmp ("in_reduction", p
))
14929 result
= PRAGMA_OMP_CLAUSE_IN_REDUCTION
;
14930 else if (!strcmp ("inbranch", p
))
14931 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
14932 else if (!strcmp ("independent", p
))
14933 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
14934 else if (!strcmp ("indirect", p
))
14935 result
= PRAGMA_OMP_CLAUSE_INDIRECT
;
14936 else if (!strcmp ("is_device_ptr", p
))
14937 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
14940 if (!strcmp ("lastprivate", p
))
14941 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
14942 else if (!strcmp ("linear", p
))
14943 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
14944 else if (!strcmp ("link", p
))
14945 result
= PRAGMA_OMP_CLAUSE_LINK
;
14948 if (!strcmp ("map", p
))
14949 result
= PRAGMA_OMP_CLAUSE_MAP
;
14950 else if (!strcmp ("mergeable", p
))
14951 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
14954 if (!strcmp ("no_create", p
))
14955 result
= PRAGMA_OACC_CLAUSE_NO_CREATE
;
14956 else if (!strcmp ("nogroup", p
))
14957 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
14958 else if (!strcmp ("nohost", p
))
14959 result
= PRAGMA_OACC_CLAUSE_NOHOST
;
14960 else if (!strcmp ("nontemporal", p
))
14961 result
= PRAGMA_OMP_CLAUSE_NONTEMPORAL
;
14962 else if (!strcmp ("notinbranch", p
))
14963 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
14964 else if (!strcmp ("nowait", p
))
14965 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
14966 else if (!strcmp ("num_gangs", p
))
14967 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
14968 else if (!strcmp ("num_tasks", p
))
14969 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
14970 else if (!strcmp ("num_teams", p
))
14971 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
14972 else if (!strcmp ("num_threads", p
))
14973 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
14974 else if (!strcmp ("num_workers", p
))
14975 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
14978 if (!strcmp ("ordered", p
))
14979 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
14980 else if (!strcmp ("order", p
))
14981 result
= PRAGMA_OMP_CLAUSE_ORDER
;
14984 if (!strcmp ("parallel", p
))
14985 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
14986 else if (!strcmp ("present", p
))
14987 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
14988 /* As of OpenACC 2.5, these are now aliases of the non-present_or
14990 else if (!strcmp ("present_or_copy", p
)
14991 || !strcmp ("pcopy", p
))
14992 result
= PRAGMA_OACC_CLAUSE_COPY
;
14993 else if (!strcmp ("present_or_copyin", p
)
14994 || !strcmp ("pcopyin", p
))
14995 result
= PRAGMA_OACC_CLAUSE_COPYIN
;
14996 else if (!strcmp ("present_or_copyout", p
)
14997 || !strcmp ("pcopyout", p
))
14998 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
14999 else if (!strcmp ("present_or_create", p
)
15000 || !strcmp ("pcreate", p
))
15001 result
= PRAGMA_OACC_CLAUSE_CREATE
;
15002 else if (!strcmp ("priority", p
))
15003 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
15004 else if (!strcmp ("private", p
))
15005 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
15006 else if (!strcmp ("proc_bind", p
))
15007 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
15010 if (!strcmp ("reduction", p
))
15011 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
15014 if (!strcmp ("safelen", p
))
15015 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
15016 else if (!strcmp ("schedule", p
))
15017 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
15018 else if (!strcmp ("sections", p
))
15019 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
15020 else if (!strcmp ("self", p
))
15021 result
= PRAGMA_OACC_CLAUSE_SELF
;
15022 else if (!strcmp ("seq", p
))
15023 result
= PRAGMA_OACC_CLAUSE_SEQ
;
15024 else if (!strcmp ("shared", p
))
15025 result
= PRAGMA_OMP_CLAUSE_SHARED
;
15026 else if (!strcmp ("simd", p
))
15027 result
= PRAGMA_OMP_CLAUSE_SIMD
;
15028 else if (!strcmp ("simdlen", p
))
15029 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
15032 if (!strcmp ("task_reduction", p
))
15033 result
= PRAGMA_OMP_CLAUSE_TASK_REDUCTION
;
15034 else if (!strcmp ("taskgroup", p
))
15035 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
15036 else if (!strcmp ("thread_limit", p
))
15037 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
15038 else if (!strcmp ("threads", p
))
15039 result
= PRAGMA_OMP_CLAUSE_THREADS
;
15040 else if (!strcmp ("tile", p
))
15041 result
= PRAGMA_OACC_CLAUSE_TILE
;
15042 else if (!strcmp ("to", p
))
15043 result
= PRAGMA_OMP_CLAUSE_TO
;
15046 if (!strcmp ("uniform", p
))
15047 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
15048 else if (!strcmp ("untied", p
))
15049 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
15050 else if (!strcmp ("use_device", p
))
15051 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
15052 else if (!strcmp ("use_device_addr", p
))
15053 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
;
15054 else if (!strcmp ("use_device_ptr", p
))
15055 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
15058 if (!strcmp ("vector", p
))
15059 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
15060 else if (!strcmp ("vector_length", p
))
15061 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
15064 if (!strcmp ("wait", p
))
15065 result
= PRAGMA_OACC_CLAUSE_WAIT
;
15066 else if (!strcmp ("worker", p
))
15067 result
= PRAGMA_OACC_CLAUSE_WORKER
;
15072 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
15073 c_parser_consume_token (parser
);
15078 /* Validate that a clause of the given type does not already exist. */
15081 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
15084 if (tree c
= omp_find_clause (clauses
, code
))
15085 error_at (OMP_CLAUSE_LOCATION (c
), "too many %qs clauses", name
);
15089 Parse wait clause or wait directive parameters. */
15092 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
15094 vec
<tree
, va_gc
> *args
;
15097 matching_parens parens
;
15098 if (!parens
.require_open (parser
))
15101 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
15102 args_tree
= build_tree_list_vec (args
);
15104 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
15106 tree targ
= TREE_VALUE (t
);
15108 if (targ
!= error_mark_node
)
15110 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
15112 c_parser_error (parser
, "expression must be integral");
15113 targ
= error_mark_node
;
15117 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
15119 OMP_CLAUSE_DECL (c
) = targ
;
15120 OMP_CLAUSE_CHAIN (c
) = list
;
15126 release_tree_vector (args
);
15127 parens
.require_close (parser
);
15131 /* OpenACC 2.0, OpenMP 2.5:
15134 variable-list , identifier
15136 If KIND is nonzero, create the appropriate node and install the
15137 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
15138 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
15140 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
15141 return the list created.
15143 The optional ALLOW_DEREF argument is true if list items can use the deref
15148 tree low_bound
, length
;
15151 omp_dim (tree lb
, tree len
, location_t lo
, bool nc
)
15152 : low_bound (lb
), length (len
), loc (lo
), no_colon (nc
) {}
15156 c_parser_omp_variable_list (c_parser
*parser
,
15157 location_t clause_loc
,
15158 enum omp_clause_code kind
, tree list
,
15159 bool map_lvalue
= false)
15161 auto_vec
<omp_dim
> dims
;
15162 bool array_section_p
;
15163 auto_vec
<c_token
> tokens
;
15164 unsigned int tokens_avail
= 0;
15165 c_token
*saved_tokens
= NULL
;
15170 tree t
= NULL_TREE
;
15172 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
15174 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
15175 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
15177 struct c_expr expr
;
15178 if (kind
== OMP_CLAUSE_DEPEND
15179 && c_parser_next_token_is_keyword (parser
,
15180 RID_OMP_ALL_MEMORY
)
15181 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
15182 || (c_parser_peek_2nd_token (parser
)->type
15183 == CPP_CLOSE_PAREN
)))
15185 expr
.value
= ridpointers
[RID_OMP_ALL_MEMORY
];
15186 c_parser_consume_token (parser
);
15189 expr
= c_parser_expr_no_commas (parser
, NULL
);
15190 if (expr
.value
!= error_mark_node
)
15192 tree u
= build_omp_clause (clause_loc
, kind
);
15193 OMP_CLAUSE_DECL (u
) = expr
.value
;
15194 OMP_CLAUSE_CHAIN (u
) = list
;
15198 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
15201 c_parser_consume_token (parser
);
15206 tokens
.truncate (0);
15207 unsigned int nesting_depth
= 0;
15210 c_token
*token
= c_parser_peek_token (parser
);
15211 switch (token
->type
)
15214 case CPP_PRAGMA_EOL
:
15216 case CPP_OPEN_BRACE
:
15217 case CPP_OPEN_PAREN
:
15218 case CPP_OPEN_SQUARE
:
15221 case CPP_CLOSE_BRACE
:
15222 case CPP_CLOSE_PAREN
:
15223 case CPP_CLOSE_SQUARE
:
15224 if (nesting_depth
-- == 0)
15228 if (nesting_depth
== 0)
15233 tokens
.safe_push (*token
);
15234 c_parser_consume_token (parser
);
15240 /* Make sure nothing tries to read past the end of the tokens. */
15242 memset (&eof_token
, 0, sizeof (eof_token
));
15243 eof_token
.type
= CPP_EOF
;
15244 tokens
.safe_push (eof_token
);
15245 tokens
.safe_push (eof_token
);
15247 saved_tokens
= parser
->tokens
;
15248 tokens_avail
= parser
->tokens_avail
;
15249 parser
->tokens
= tokens
.address ();
15250 parser
->tokens_avail
= tokens
.length ();
15252 else if (map_lvalue
15253 && (kind
== OMP_CLAUSE_MAP
15254 || kind
== OMP_CLAUSE_TO
15255 || kind
== OMP_CLAUSE_FROM
))
15257 location_t loc
= c_parser_peek_token (parser
)->location
;
15258 bool save_c_omp_array_section_p
= c_omp_array_section_p
;
15259 c_omp_array_section_p
= true;
15260 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15261 if (expr
.value
!= error_mark_node
)
15262 mark_exp_read (expr
.value
);
15263 c_omp_array_section_p
= save_c_omp_array_section_p
;
15264 tree decl
= expr
.value
;
15266 /* This code rewrites a parsed expression containing various tree
15267 codes used to represent array accesses into a more uniform nest of
15268 OMP_ARRAY_SECTION nodes before it is processed by
15269 c-typeck.cc:handle_omp_array_sections_1. It might be more
15270 efficient to move this logic to that function instead, analysing
15271 the parsed expression directly rather than this preprocessed
15272 form. (See also equivalent code in cp/parser.cc,
15273 cp/semantics.cc). */
15275 if (TREE_CODE (decl
) == OMP_ARRAY_SECTION
)
15277 while (TREE_CODE (decl
) == OMP_ARRAY_SECTION
)
15279 tree low_bound
= TREE_OPERAND (decl
, 1);
15280 tree length
= TREE_OPERAND (decl
, 2);
15281 dims
.safe_push (omp_dim (low_bound
, length
, loc
, false));
15282 decl
= TREE_OPERAND (decl
, 0);
15285 while (TREE_CODE (decl
) == ARRAY_REF
15286 || TREE_CODE (decl
) == INDIRECT_REF
15287 || TREE_CODE (decl
) == COMPOUND_EXPR
)
15289 if (TREE_CODE (decl
) == COMPOUND_EXPR
)
15291 decl
= TREE_OPERAND (decl
, 1);
15294 else if (TREE_CODE (decl
) == INDIRECT_REF
)
15296 dims
.safe_push (omp_dim (integer_zero_node
,
15297 integer_one_node
, loc
, true));
15298 decl
= TREE_OPERAND (decl
, 0);
15300 else /* ARRAY_REF. */
15302 tree index
= TREE_OPERAND (decl
, 1);
15303 dims
.safe_push (omp_dim (index
, integer_one_node
, loc
,
15305 decl
= TREE_OPERAND (decl
, 0);
15309 for (int i
= dims
.length () - 1; i
>= 0; i
--)
15310 decl
= build_omp_array_section (loc
, decl
, dims
[i
].low_bound
,
15313 else if (TREE_CODE (decl
) == INDIRECT_REF
)
15315 /* Turn indirection of a pointer "*foo" into "foo[0:1]". */
15316 decl
= TREE_OPERAND (decl
, 0);
15319 decl
= build_omp_array_section (loc
, decl
, integer_zero_node
,
15322 else if (TREE_CODE (decl
) == ARRAY_REF
)
15324 tree idx
= TREE_OPERAND (decl
, 1);
15326 decl
= TREE_OPERAND (decl
, 0);
15329 decl
= build_omp_array_section (loc
, decl
, idx
, integer_one_node
);
15331 else if (TREE_CODE (decl
) == NON_LVALUE_EXPR
15332 || CONVERT_EXPR_P (decl
))
15333 decl
= TREE_OPERAND (decl
, 0);
15335 tree u
= build_omp_clause (clause_loc
, kind
);
15336 OMP_CLAUSE_DECL (u
) = decl
;
15337 OMP_CLAUSE_CHAIN (u
) = list
;
15343 if (c_parser_next_token_is (parser
, CPP_NAME
)
15344 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
15346 t
= lookup_name (c_parser_peek_token (parser
)->value
);
15348 if (t
== NULL_TREE
)
15350 undeclared_variable (c_parser_peek_token (parser
)->location
,
15351 c_parser_peek_token (parser
)->value
);
15352 t
= error_mark_node
;
15355 c_parser_consume_token (parser
);
15357 else if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
15358 && (c_parser_peek_token (parser
)->keyword
== RID_FUNCTION_NAME
15359 || (c_parser_peek_token (parser
)->keyword
15360 == RID_PRETTY_FUNCTION_NAME
)
15361 || (c_parser_peek_token (parser
)->keyword
15362 == RID_C99_FUNCTION_NAME
)))
15363 t
= c_parser_predefined_identifier (parser
).value
;
15367 c_parser_error (parser
, "expected identifier");
15371 if (t
== error_mark_node
)
15373 else if (kind
!= 0)
15377 case OMP_CLAUSE__CACHE_
:
15378 /* The OpenACC cache directive explicitly only allows "array
15379 elements or subarrays". */
15380 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
15382 c_parser_error (parser
, "expected %<[%>");
15383 t
= error_mark_node
;
15387 case OMP_CLAUSE_MAP
:
15388 case OMP_CLAUSE_FROM
:
15389 case OMP_CLAUSE_TO
:
15390 start_component_ref
:
15391 while (c_parser_next_token_is (parser
, CPP_DOT
)
15392 || c_parser_next_token_is (parser
, CPP_DEREF
))
15394 location_t op_loc
= c_parser_peek_token (parser
)->location
;
15395 location_t arrow_loc
= UNKNOWN_LOCATION
;
15396 if (c_parser_next_token_is (parser
, CPP_DEREF
))
15400 t_expr
.original_code
= ERROR_MARK
;
15401 t_expr
.original_type
= NULL
;
15402 set_c_expr_source_range (&t_expr
, op_loc
, op_loc
);
15403 t_expr
.m_decimal
= 0;
15404 t_expr
= convert_lvalue_to_rvalue (op_loc
, t_expr
,
15406 t
= build_indirect_ref (op_loc
, t_expr
.value
, RO_ARROW
);
15407 arrow_loc
= t_expr
.get_location ();
15409 c_parser_consume_token (parser
);
15410 if (!c_parser_next_token_is (parser
, CPP_NAME
))
15412 c_parser_error (parser
, "expected identifier");
15413 t
= error_mark_node
;
15417 c_token
*comp_tok
= c_parser_peek_token (parser
);
15418 tree ident
= comp_tok
->value
;
15419 location_t comp_loc
= comp_tok
->location
;
15420 c_parser_consume_token (parser
);
15421 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
,
15425 case OMP_CLAUSE_AFFINITY
:
15426 case OMP_CLAUSE_DEPEND
:
15427 case OMP_CLAUSE_REDUCTION
:
15428 case OMP_CLAUSE_IN_REDUCTION
:
15429 case OMP_CLAUSE_TASK_REDUCTION
:
15430 case OMP_CLAUSE_HAS_DEVICE_ADDR
:
15431 array_section_p
= false;
15433 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
15435 location_t loc
= UNKNOWN_LOCATION
;
15436 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
15437 bool no_colon
= false;
15439 c_parser_consume_token (parser
);
15440 if (!c_parser_next_token_is (parser
, CPP_COLON
))
15442 location_t expr_loc
15443 = c_parser_peek_token (parser
)->location
;
15444 c_expr expr
= c_parser_expression (parser
);
15445 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
15447 low_bound
= expr
.value
;
15450 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
15452 length
= integer_one_node
;
15457 /* Look for `:'. */
15458 if (!c_parser_require (parser
, CPP_COLON
,
15461 t
= error_mark_node
;
15464 array_section_p
= true;
15465 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
15467 location_t expr_loc
15468 = c_parser_peek_token (parser
)->location
;
15469 c_expr expr
= c_parser_expression (parser
);
15470 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
15472 length
= expr
.value
;
15475 /* Look for the closing `]'. */
15476 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
15479 t
= error_mark_node
;
15483 dims
.safe_push (omp_dim (low_bound
, length
, loc
, no_colon
));
15486 if (t
!= error_mark_node
)
15488 if ((kind
== OMP_CLAUSE_MAP
15489 || kind
== OMP_CLAUSE_FROM
15490 || kind
== OMP_CLAUSE_TO
)
15491 && !array_section_p
15492 && (c_parser_next_token_is (parser
, CPP_DOT
)
15493 || c_parser_next_token_is (parser
, CPP_DEREF
)))
15495 for (unsigned i
= 0; i
< dims
.length (); i
++)
15497 gcc_assert (dims
[i
].length
== integer_one_node
);
15498 t
= build_array_ref (dims
[i
].loc
,
15499 t
, dims
[i
].low_bound
);
15501 goto start_component_ref
;
15504 for (unsigned i
= 0; i
< dims
.length (); i
++)
15505 t
= build_omp_array_section (clause_loc
, t
,
15510 if ((kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
15511 && t
!= error_mark_node
15512 && parser
->tokens_avail
!= 2)
15514 if (array_section_p
)
15516 error_at (c_parser_peek_token (parser
)->location
,
15517 "expected %<)%> or %<,%>");
15518 t
= error_mark_node
;
15522 parser
->tokens
= tokens
.address ();
15523 parser
->tokens_avail
= tokens
.length ();
15525 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
15526 if (t
!= error_mark_node
&& parser
->tokens_avail
!= 2)
15528 error_at (c_parser_peek_token (parser
)->location
,
15529 "expected %<)%> or %<,%>");
15530 t
= error_mark_node
;
15539 if (t
!= error_mark_node
)
15541 tree u
= build_omp_clause (clause_loc
, kind
);
15542 OMP_CLAUSE_DECL (u
) = t
;
15543 OMP_CLAUSE_CHAIN (u
) = list
;
15548 list
= tree_cons (t
, NULL_TREE
, list
);
15550 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
15552 parser
->tokens
= saved_tokens
;
15553 parser
->tokens_avail
= tokens_avail
;
15557 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
15560 c_parser_consume_token (parser
);
15567 /* Similarly, but expect leading and trailing parenthesis. This is a very
15568 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
15569 argument is true if list items can use the deref (->) operator. */
15572 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
15573 tree list
, bool map_lvalue
= false)
15575 /* The clauses location. */
15576 location_t loc
= c_parser_peek_token (parser
)->location
;
15578 if (parser
->in_omp_decl_attribute
)
15582 tree u
= build_omp_clause (loc
, kind
);
15583 OMP_CLAUSE_DECL (u
) = parser
->in_omp_decl_attribute
;
15584 OMP_CLAUSE_CHAIN (u
) = list
;
15588 return tree_cons (parser
->in_omp_decl_attribute
, NULL_TREE
, list
);
15591 matching_parens parens
;
15592 if (parens
.require_open (parser
))
15594 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
, map_lvalue
);
15595 parens
.skip_until_found_close (parser
);
15601 copy ( variable-list )
15602 copyin ( variable-list )
15603 copyout ( variable-list )
15604 create ( variable-list )
15605 delete ( variable-list )
15606 present ( variable-list )
15609 no_create ( variable-list )
15610 attach ( variable-list )
15611 detach ( variable-list ) */
15614 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
15617 enum gomp_map_kind kind
;
15620 case PRAGMA_OACC_CLAUSE_ATTACH
:
15621 kind
= GOMP_MAP_ATTACH
;
15623 case PRAGMA_OACC_CLAUSE_COPY
:
15624 kind
= GOMP_MAP_TOFROM
;
15626 case PRAGMA_OACC_CLAUSE_COPYIN
:
15627 kind
= GOMP_MAP_TO
;
15629 case PRAGMA_OACC_CLAUSE_COPYOUT
:
15630 kind
= GOMP_MAP_FROM
;
15632 case PRAGMA_OACC_CLAUSE_CREATE
:
15633 kind
= GOMP_MAP_ALLOC
;
15635 case PRAGMA_OACC_CLAUSE_DELETE
:
15636 kind
= GOMP_MAP_RELEASE
;
15638 case PRAGMA_OACC_CLAUSE_DETACH
:
15639 kind
= GOMP_MAP_DETACH
;
15641 case PRAGMA_OACC_CLAUSE_DEVICE
:
15642 kind
= GOMP_MAP_FORCE_TO
;
15644 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
15645 kind
= GOMP_MAP_DEVICE_RESIDENT
;
15647 case PRAGMA_OACC_CLAUSE_LINK
:
15648 kind
= GOMP_MAP_LINK
;
15650 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
15651 kind
= GOMP_MAP_IF_PRESENT
;
15653 case PRAGMA_OACC_CLAUSE_PRESENT
:
15654 kind
= GOMP_MAP_FORCE_PRESENT
;
15656 case PRAGMA_OACC_CLAUSE_SELF
:
15657 /* "The 'host' clause is a synonym for the 'self' clause." */
15658 case PRAGMA_OACC_CLAUSE_HOST
:
15659 kind
= GOMP_MAP_FORCE_FROM
;
15662 gcc_unreachable ();
15665 nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_MAP
, list
, false);
15667 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15668 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
15674 deviceptr ( variable-list ) */
15677 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
15679 location_t loc
= c_parser_peek_token (parser
)->location
;
15682 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
15683 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
15684 variable-list must only allow for pointer variables. */
15685 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
15686 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
15688 tree v
= TREE_PURPOSE (t
);
15690 /* FIXME diagnostics: Ideally we should keep individual
15691 locations for all the variables in the var list to make the
15692 following errors more precise. Perhaps
15693 c_parser_omp_var_list_parens() should construct a list of
15694 locations to go along with the var list. */
15696 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
15697 error_at (loc
, "%qD is not a variable", v
);
15698 else if (TREE_TYPE (v
) == error_mark_node
)
15700 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
15701 error_at (loc
, "%qD is not a pointer variable", v
);
15703 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
15704 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
15705 OMP_CLAUSE_DECL (u
) = v
;
15706 OMP_CLAUSE_CHAIN (u
) = list
;
15713 /* OpenACC 2.0, OpenMP 3.0:
15714 collapse ( constant-expression ) */
15717 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
15719 tree c
, num
= error_mark_node
;
15723 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
15724 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
15726 loc
= c_parser_peek_token (parser
)->location
;
15727 matching_parens parens
;
15728 if (parens
.require_open (parser
))
15730 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
15731 parens
.skip_until_found_close (parser
);
15733 if (num
== error_mark_node
)
15735 mark_exp_read (num
);
15736 num
= c_fully_fold (num
, false, NULL
);
15737 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
15738 || !tree_fits_shwi_p (num
)
15739 || (n
= tree_to_shwi (num
)) <= 0
15743 "collapse argument needs positive constant integer expression");
15746 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
15747 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
15748 OMP_CLAUSE_CHAIN (c
) = list
;
15753 copyin ( variable-list ) */
15756 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
15758 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
15762 copyprivate ( variable-list ) */
15765 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
15767 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
15771 default ( none | shared )
15774 default ( private | firstprivate )
15777 default ( none | present ) */
15780 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
15782 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
15783 location_t loc
= c_parser_peek_token (parser
)->location
;
15786 matching_parens parens
;
15787 if (!parens
.require_open (parser
))
15789 if (c_parser_next_token_is (parser
, CPP_NAME
))
15791 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15796 if (strcmp ("none", p
) != 0)
15798 kind
= OMP_CLAUSE_DEFAULT_NONE
;
15804 if (strcmp ("present", p
) != 0)
15806 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
15810 if (strcmp ("private", p
) != 0)
15812 kind
= OMP_CLAUSE_DEFAULT_PRIVATE
;
15817 if (strcmp ("firstprivate", p
) != 0 || is_oacc
)
15819 kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
15823 if (strcmp ("shared", p
) != 0 || is_oacc
)
15825 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
15832 c_parser_consume_token (parser
);
15838 c_parser_error (parser
, "expected %<none%> or %<present%>");
15840 c_parser_error (parser
, "expected %<none%>, %<shared%>, "
15841 "%<private%> or %<firstprivate%>");
15843 parens
.skip_until_found_close (parser
);
15845 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
15848 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
15849 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
15850 OMP_CLAUSE_CHAIN (c
) = list
;
15851 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
15857 firstprivate ( variable-list ) */
15860 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
15862 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
15866 final ( expression ) */
15869 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
15871 location_t loc
= c_parser_peek_token (parser
)->location
;
15872 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
15874 matching_parens parens
;
15876 if (!parens
.require_open (parser
))
15877 t
= error_mark_node
;
15880 location_t eloc
= c_parser_peek_token (parser
)->location
;
15881 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15882 t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
15883 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
15884 t
= c_fully_fold (t
, false, NULL
);
15885 parens
.skip_until_found_close (parser
);
15888 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
15890 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
15891 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
15892 OMP_CLAUSE_CHAIN (c
) = list
;
15896 c_parser_error (parser
, "expected %<(%>");
15902 indirect [( expression )]
15906 c_parser_omp_clause_indirect (c_parser
*parser
, tree list
)
15908 location_t location
= c_parser_peek_token (parser
)->location
;
15911 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
15913 matching_parens parens
;
15914 if (!parens
.require_open (parser
))
15917 location_t loc
= c_parser_peek_token (parser
)->location
;
15918 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15919 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
15920 t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
);
15921 t
= c_fully_fold (t
, false, NULL
);
15922 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
15923 || TREE_CODE (t
) != INTEGER_CST
)
15925 c_parser_error (parser
, "expected constant logical expression");
15928 parens
.skip_until_found_close (parser
);
15931 t
= integer_one_node
;
15933 check_no_duplicate_clause (list
, OMP_CLAUSE_INDIRECT
, "indirect");
15935 tree c
= build_omp_clause (location
, OMP_CLAUSE_INDIRECT
);
15936 OMP_CLAUSE_INDIRECT_EXPR (c
) = t
;
15937 OMP_CLAUSE_CHAIN (c
) = list
;
15942 /* OpenACC, OpenMP 2.5:
15946 if ( directive-name-modifier : expression )
15948 directive-name-modifier:
15949 parallel | task | taskloop | target data | target | target update
15950 | target enter data | target exit data
15953 directive-name-modifier:
15954 ... | simd | cancel */
15957 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
15959 location_t location
= c_parser_peek_token (parser
)->location
;
15960 enum tree_code if_modifier
= ERROR_MARK
;
15962 matching_parens parens
;
15963 if (!parens
.require_open (parser
))
15966 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
15968 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15970 if (strcmp (p
, "cancel") == 0)
15971 if_modifier
= VOID_CST
;
15972 else if (strcmp (p
, "parallel") == 0)
15973 if_modifier
= OMP_PARALLEL
;
15974 else if (strcmp (p
, "simd") == 0)
15975 if_modifier
= OMP_SIMD
;
15976 else if (strcmp (p
, "task") == 0)
15977 if_modifier
= OMP_TASK
;
15978 else if (strcmp (p
, "taskloop") == 0)
15979 if_modifier
= OMP_TASKLOOP
;
15980 else if (strcmp (p
, "target") == 0)
15982 if_modifier
= OMP_TARGET
;
15983 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
15985 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
15986 if (strcmp ("data", p
) == 0)
15987 if_modifier
= OMP_TARGET_DATA
;
15988 else if (strcmp ("update", p
) == 0)
15989 if_modifier
= OMP_TARGET_UPDATE
;
15990 else if (strcmp ("enter", p
) == 0)
15991 if_modifier
= OMP_TARGET_ENTER_DATA
;
15992 else if (strcmp ("exit", p
) == 0)
15993 if_modifier
= OMP_TARGET_EXIT_DATA
;
15994 if (if_modifier
!= OMP_TARGET
)
15997 c_parser_consume_token (parser
);
16001 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
16002 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
16004 if_modifier
= ERROR_MARK
;
16006 if (if_modifier
== OMP_TARGET_ENTER_DATA
16007 || if_modifier
== OMP_TARGET_EXIT_DATA
)
16009 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
16011 p
= IDENTIFIER_POINTER
16012 (c_parser_peek_2nd_token (parser
)->value
);
16013 if (strcmp ("data", p
) == 0)
16017 c_parser_consume_token (parser
);
16021 = c_parser_peek_2nd_token (parser
)->location
;
16022 error_at (loc
, "expected %<data%>");
16023 if_modifier
= ERROR_MARK
;
16028 if (if_modifier
!= ERROR_MARK
)
16030 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16032 c_parser_consume_token (parser
);
16033 c_parser_consume_token (parser
);
16039 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
16040 error_at (loc
, "expected %<:%>");
16042 if_modifier
= ERROR_MARK
;
16047 location_t loc
= c_parser_peek_token (parser
)->location
;
16048 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16049 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
16050 tree t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
), c
;
16051 t
= c_fully_fold (t
, false, NULL
);
16052 parens
.skip_until_found_close (parser
);
16054 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
16055 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
16057 if (if_modifier
!= ERROR_MARK
16058 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
16060 const char *p
= NULL
;
16061 switch (if_modifier
)
16063 case VOID_CST
: p
= "cancel"; break;
16064 case OMP_PARALLEL
: p
= "parallel"; break;
16065 case OMP_SIMD
: p
= "simd"; break;
16066 case OMP_TASK
: p
= "task"; break;
16067 case OMP_TASKLOOP
: p
= "taskloop"; break;
16068 case OMP_TARGET_DATA
: p
= "target data"; break;
16069 case OMP_TARGET
: p
= "target"; break;
16070 case OMP_TARGET_UPDATE
: p
= "target update"; break;
16071 case OMP_TARGET_ENTER_DATA
: p
= "target enter data"; break;
16072 case OMP_TARGET_EXIT_DATA
: p
= "target exit data"; break;
16073 default: gcc_unreachable ();
16075 error_at (location
, "too many %<if%> clauses with %qs modifier",
16079 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
16082 error_at (location
, "too many %<if%> clauses");
16084 error_at (location
, "too many %<if%> clauses without modifier");
16087 else if (if_modifier
== ERROR_MARK
16088 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
16090 error_at (location
, "if any %<if%> clause has modifier, then all "
16091 "%<if%> clauses have to use modifier");
16096 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
16097 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
16098 OMP_CLAUSE_IF_EXPR (c
) = t
;
16099 OMP_CLAUSE_CHAIN (c
) = list
;
16104 lastprivate ( variable-list )
16107 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
16110 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
16112 /* The clauses location. */
16113 location_t loc
= c_parser_peek_token (parser
)->location
;
16115 if (c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
16117 bool conditional
= false;
16118 if (c_parser_next_token_is (parser
, CPP_NAME
)
16119 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16122 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16123 if (strcmp (p
, "conditional") == 0)
16125 conditional
= true;
16126 c_parser_consume_token (parser
);
16127 c_parser_consume_token (parser
);
16130 tree nlist
= c_parser_omp_variable_list (parser
, loc
,
16131 OMP_CLAUSE_LASTPRIVATE
, list
);
16132 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
16134 for (tree c
= nlist
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16135 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 1;
16145 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
16149 /* FIXME: Should we allow duplicates? */
16150 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
16152 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
16153 OMP_CLAUSE_MERGEABLE
);
16154 OMP_CLAUSE_CHAIN (c
) = list
;
16163 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
16166 location_t loc
= c_parser_peek_token (parser
)->location
;
16168 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
16170 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
16171 OMP_CLAUSE_CHAIN (c
) = list
;
16176 num_threads ( expression ) */
16179 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
16181 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
16182 matching_parens parens
;
16183 if (parens
.require_open (parser
))
16185 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16186 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16187 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16188 tree c
, t
= expr
.value
;
16189 t
= c_fully_fold (t
, false, NULL
);
16191 parens
.skip_until_found_close (parser
);
16193 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16195 c_parser_error (parser
, "expected integer expression");
16199 /* Attempt to statically determine when the number isn't positive. */
16200 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
16201 build_int_cst (TREE_TYPE (t
), 0));
16202 protected_set_expr_location (c
, expr_loc
);
16203 if (c
== boolean_true_node
)
16205 warning_at (expr_loc
, OPT_Wopenmp
,
16206 "%<num_threads%> value must be positive");
16207 t
= integer_one_node
;
16210 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
16212 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
16213 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
16214 OMP_CLAUSE_CHAIN (c
) = list
;
16222 num_tasks ( expression )
16225 num_tasks ( strict : expression ) */
16228 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
16230 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
16231 matching_parens parens
;
16232 if (parens
.require_open (parser
))
16234 bool strict
= false;
16235 if (c_parser_next_token_is (parser
, CPP_NAME
)
16236 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
16237 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
16241 c_parser_consume_token (parser
);
16242 c_parser_consume_token (parser
);
16245 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16246 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16247 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16248 tree c
, t
= expr
.value
;
16249 t
= c_fully_fold (t
, false, NULL
);
16251 parens
.skip_until_found_close (parser
);
16253 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16255 c_parser_error (parser
, "expected integer expression");
16259 /* Attempt to statically determine when the number isn't positive. */
16260 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
16261 build_int_cst (TREE_TYPE (t
), 0));
16262 if (CAN_HAVE_LOCATION_P (c
))
16263 SET_EXPR_LOCATION (c
, expr_loc
);
16264 if (c
== boolean_true_node
)
16266 warning_at (expr_loc
, OPT_Wopenmp
,
16267 "%<num_tasks%> value must be positive");
16268 t
= integer_one_node
;
16271 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
16273 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
16274 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
16275 OMP_CLAUSE_NUM_TASKS_STRICT (c
) = strict
;
16276 OMP_CLAUSE_CHAIN (c
) = list
;
16284 grainsize ( expression )
16287 grainsize ( strict : expression ) */
16290 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
16292 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
16293 matching_parens parens
;
16294 if (parens
.require_open (parser
))
16296 bool strict
= false;
16297 if (c_parser_next_token_is (parser
, CPP_NAME
)
16298 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
16299 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
16303 c_parser_consume_token (parser
);
16304 c_parser_consume_token (parser
);
16307 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16308 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16309 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16310 tree c
, t
= expr
.value
;
16311 t
= c_fully_fold (t
, false, NULL
);
16313 parens
.skip_until_found_close (parser
);
16315 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16317 c_parser_error (parser
, "expected integer expression");
16321 /* Attempt to statically determine when the number isn't positive. */
16322 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
16323 build_int_cst (TREE_TYPE (t
), 0));
16324 if (CAN_HAVE_LOCATION_P (c
))
16325 SET_EXPR_LOCATION (c
, expr_loc
);
16326 if (c
== boolean_true_node
)
16328 warning_at (expr_loc
, OPT_Wopenmp
,
16329 "%<grainsize%> value must be positive");
16330 t
= integer_one_node
;
16333 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
16335 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
16336 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
16337 OMP_CLAUSE_GRAINSIZE_STRICT (c
) = strict
;
16338 OMP_CLAUSE_CHAIN (c
) = list
;
16346 priority ( expression ) */
16349 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
16351 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
16352 matching_parens parens
;
16353 if (parens
.require_open (parser
))
16355 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16356 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16357 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16358 tree c
, t
= expr
.value
;
16359 t
= c_fully_fold (t
, false, NULL
);
16361 parens
.skip_until_found_close (parser
);
16363 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16365 c_parser_error (parser
, "expected integer expression");
16369 /* Attempt to statically determine when the number isn't
16371 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
16372 build_int_cst (TREE_TYPE (t
), 0));
16373 if (CAN_HAVE_LOCATION_P (c
))
16374 SET_EXPR_LOCATION (c
, expr_loc
);
16375 if (c
== boolean_true_node
)
16377 warning_at (expr_loc
, OPT_Wopenmp
,
16378 "%<priority%> value must be non-negative");
16379 t
= integer_one_node
;
16382 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
16384 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
16385 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
16386 OMP_CLAUSE_CHAIN (c
) = list
;
16394 hint ( expression ) */
16397 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
16399 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
16400 matching_parens parens
;
16401 if (parens
.require_open (parser
))
16403 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16404 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16405 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16406 tree c
, t
= expr
.value
;
16407 t
= c_fully_fold (t
, false, NULL
);
16408 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
16409 || TREE_CODE (t
) != INTEGER_CST
16410 || tree_int_cst_sgn (t
) == -1)
16412 c_parser_error (parser
, "expected constant integer expression "
16413 "with valid sync-hint value");
16416 parens
.skip_until_found_close (parser
);
16417 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
16419 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
16420 OMP_CLAUSE_HINT_EXPR (c
) = t
;
16421 OMP_CLAUSE_CHAIN (c
) = list
;
16429 filter ( integer-expression ) */
16432 c_parser_omp_clause_filter (c_parser
*parser
, tree list
)
16434 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
16435 matching_parens parens
;
16436 if (parens
.require_open (parser
))
16438 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16439 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16440 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16441 tree c
, t
= expr
.value
;
16442 t
= c_fully_fold (t
, false, NULL
);
16443 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16445 c_parser_error (parser
, "expected integer expression");
16448 parens
.skip_until_found_close (parser
);
16449 check_no_duplicate_clause (list
, OMP_CLAUSE_FILTER
, "filter");
16451 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_FILTER
);
16452 OMP_CLAUSE_FILTER_EXPR (c
) = t
;
16453 OMP_CLAUSE_CHAIN (c
) = list
;
16461 defaultmap ( tofrom : scalar )
16464 defaultmap ( implicit-behavior [ : variable-category ] ) */
16467 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
16469 location_t loc
= c_parser_peek_token (parser
)->location
;
16472 enum omp_clause_defaultmap_kind behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
16473 enum omp_clause_defaultmap_kind category
16474 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
16476 matching_parens parens
;
16477 if (!parens
.require_open (parser
))
16479 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
16481 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
16484 c_parser_error (parser
, "expected %<alloc%>, %<to%>, %<from%>, "
16485 "%<tofrom%>, %<firstprivate%>, %<none%> "
16490 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16495 if (strcmp ("alloc", p
) == 0)
16496 behavior
= OMP_CLAUSE_DEFAULTMAP_ALLOC
;
16498 goto invalid_behavior
;
16502 if (strcmp ("default", p
) == 0)
16503 behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
16505 goto invalid_behavior
;
16509 if (strcmp ("firstprivate", p
) == 0)
16510 behavior
= OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
16511 else if (strcmp ("from", p
) == 0)
16512 behavior
= OMP_CLAUSE_DEFAULTMAP_FROM
;
16514 goto invalid_behavior
;
16518 if (strcmp ("none", p
) == 0)
16519 behavior
= OMP_CLAUSE_DEFAULTMAP_NONE
;
16521 goto invalid_behavior
;
16525 if (strcmp ("present", p
) == 0)
16526 behavior
= OMP_CLAUSE_DEFAULTMAP_PRESENT
;
16528 goto invalid_behavior
;
16532 if (strcmp ("tofrom", p
) == 0)
16533 behavior
= OMP_CLAUSE_DEFAULTMAP_TOFROM
;
16534 else if (strcmp ("to", p
) == 0)
16535 behavior
= OMP_CLAUSE_DEFAULTMAP_TO
;
16537 goto invalid_behavior
;
16541 goto invalid_behavior
;
16543 c_parser_consume_token (parser
);
16545 if (!c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
16547 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16549 if (!c_parser_next_token_is (parser
, CPP_NAME
))
16552 c_parser_error (parser
, "expected %<scalar%>, %<aggregate%>, "
16553 "%<pointer%> or %<all%>");
16556 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16560 if (strcmp ("aggregate", p
) == 0)
16561 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
;
16562 else if (strcmp ("all", p
) == 0)
16563 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
;
16565 goto invalid_category
;
16569 if (strcmp ("pointer", p
) == 0)
16570 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
;
16572 goto invalid_category
;
16576 if (strcmp ("scalar", p
) == 0)
16577 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
;
16579 goto invalid_category
;
16583 goto invalid_category
;
16586 c_parser_consume_token (parser
);
16588 parens
.skip_until_found_close (parser
);
16590 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
16591 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEFAULTMAP
16592 && (category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16593 || category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16594 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
) == category
16595 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
16596 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
16597 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
16598 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
)))
16600 enum omp_clause_defaultmap_kind cat
= category
;
16601 location_t loc
= OMP_CLAUSE_LOCATION (c
);
16602 if (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
16603 || (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
16604 && (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
16605 != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)))
16606 cat
= OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
);
16610 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
16613 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
:
16616 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
16619 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
16622 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
16626 gcc_unreachable ();
16629 error_at (loc
, "too many %<defaultmap%> clauses with %qs category",
16632 error_at (loc
, "too many %<defaultmap%> clauses with unspecified "
16637 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
16638 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c
, behavior
, category
);
16639 OMP_CLAUSE_CHAIN (c
) = list
;
16643 parens
.skip_until_found_close (parser
);
16648 use_device ( variable-list )
16651 use_device_ptr ( variable-list ) */
16654 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
16656 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
16661 use_device_addr ( variable-list ) */
16664 c_parser_omp_clause_use_device_addr (c_parser
*parser
, tree list
)
16666 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_ADDR
,
16671 has_device_addr ( variable-list ) */
16674 c_parser_omp_clause_has_device_addr (c_parser
*parser
, tree list
)
16676 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_HAS_DEVICE_ADDR
,
16681 is_device_ptr ( variable-list ) */
16684 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
16686 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
16690 num_gangs ( expression )
16691 num_workers ( expression )
16692 vector_length ( expression ) */
16695 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
16698 location_t loc
= c_parser_peek_token (parser
)->location
;
16700 matching_parens parens
;
16701 if (!parens
.require_open (parser
))
16704 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16705 c_expr expr
= c_parser_expression (parser
);
16706 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16707 tree c
, t
= expr
.value
;
16708 t
= c_fully_fold (t
, false, NULL
);
16710 parens
.skip_until_found_close (parser
);
16712 if (t
== error_mark_node
)
16714 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16716 error_at (expr_loc
, "%qs expression must be integral",
16717 omp_clause_code_name
[code
]);
16721 /* Attempt to statically determine when the number isn't positive. */
16722 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
16723 build_int_cst (TREE_TYPE (t
), 0));
16724 protected_set_expr_location (c
, expr_loc
);
16725 if (c
== boolean_true_node
)
16727 warning_at (expr_loc
, 0,
16728 "%qs value must be positive",
16729 omp_clause_code_name
[code
]);
16730 t
= integer_one_node
;
16733 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
16735 c
= build_omp_clause (loc
, code
);
16736 OMP_CLAUSE_OPERAND (c
, 0) = t
;
16737 OMP_CLAUSE_CHAIN (c
) = list
;
16743 gang [( gang-arg-list )]
16744 worker [( [num:] int-expr )]
16745 vector [( [length:] int-expr )]
16747 where gang-arg is one of:
16752 and size-expr may be:
16759 c_parser_oacc_shape_clause (c_parser
*parser
, location_t loc
,
16760 omp_clause_code kind
,
16761 const char *str
, tree list
)
16763 const char *id
= "num";
16764 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
16766 if (kind
== OMP_CLAUSE_VECTOR
)
16769 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
16771 c_parser_consume_token (parser
);
16775 c_token
*next
= c_parser_peek_token (parser
);
16778 /* Gang static argument. */
16779 if (kind
== OMP_CLAUSE_GANG
16780 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
16782 c_parser_consume_token (parser
);
16784 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16785 goto cleanup_error
;
16788 if (ops
[idx
] != NULL_TREE
)
16790 c_parser_error (parser
, "too many %<static%> arguments");
16791 goto cleanup_error
;
16794 /* Check for the '*' argument. */
16795 if (c_parser_next_token_is (parser
, CPP_MULT
)
16796 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
16797 || c_parser_peek_2nd_token (parser
)->type
16798 == CPP_CLOSE_PAREN
))
16800 c_parser_consume_token (parser
);
16801 ops
[idx
] = integer_minus_one_node
;
16803 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16805 c_parser_consume_token (parser
);
16812 /* Worker num: argument and vector length: arguments. */
16813 else if (c_parser_next_token_is (parser
, CPP_NAME
)
16814 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
16815 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16817 c_parser_consume_token (parser
); /* id */
16818 c_parser_consume_token (parser
); /* ':' */
16821 /* Now collect the actual argument. */
16822 if (ops
[idx
] != NULL_TREE
)
16824 c_parser_error (parser
, "unexpected argument");
16825 goto cleanup_error
;
16828 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16829 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
16830 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
16831 tree expr
= cexpr
.value
;
16832 if (expr
== error_mark_node
)
16833 goto cleanup_error
;
16835 expr
= c_fully_fold (expr
, false, NULL
);
16837 /* Attempt to statically determine when the number isn't a
16838 positive integer. */
16840 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
16842 c_parser_error (parser
, "expected integer expression");
16846 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
16847 build_int_cst (TREE_TYPE (expr
), 0));
16848 if (c
== boolean_true_node
)
16850 warning_at (loc
, 0,
16851 "%qs value must be positive", str
);
16852 expr
= integer_one_node
;
16857 if (kind
== OMP_CLAUSE_GANG
16858 && c_parser_next_token_is (parser
, CPP_COMMA
))
16860 c_parser_consume_token (parser
);
16867 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
16868 goto cleanup_error
;
16871 check_no_duplicate_clause (list
, kind
, str
);
16873 c
= build_omp_clause (loc
, kind
);
16876 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
16878 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
16879 OMP_CLAUSE_CHAIN (c
) = list
;
16884 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
16896 c_parser_oacc_simple_clause (location_t loc
, enum omp_clause_code code
,
16899 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
16901 tree c
= build_omp_clause (loc
, code
);
16902 OMP_CLAUSE_CHAIN (c
) = list
;
16908 async [( int-expr )] */
16911 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
16914 location_t loc
= c_parser_peek_token (parser
)->location
;
16916 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
16918 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
16920 c_parser_consume_token (parser
);
16922 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
16923 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16924 c_parser_error (parser
, "expected integer expression");
16925 else if (t
== error_mark_node
16926 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
16930 t
= c_fully_fold (t
, false, NULL
);
16932 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
16934 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
16935 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
16936 OMP_CLAUSE_CHAIN (c
) = list
;
16943 tile ( size-expr-list ) */
16946 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
16948 tree c
, expr
= error_mark_node
;
16950 tree tile
= NULL_TREE
;
16952 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
16953 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
16955 loc
= c_parser_peek_token (parser
)->location
;
16956 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
16961 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
16964 if (c_parser_next_token_is (parser
, CPP_MULT
)
16965 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
16966 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
16968 c_parser_consume_token (parser
);
16969 expr
= integer_zero_node
;
16973 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16974 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
16975 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
16976 expr
= cexpr
.value
;
16978 if (expr
== error_mark_node
)
16980 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
16985 expr
= c_fully_fold (expr
, false, NULL
);
16987 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
16988 || !tree_fits_shwi_p (expr
)
16989 || tree_to_shwi (expr
) <= 0)
16991 error_at (expr_loc
, "%<tile%> argument needs positive"
16992 " integral constant");
16993 expr
= integer_zero_node
;
16997 tile
= tree_cons (NULL_TREE
, expr
, tile
);
16999 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
17001 /* Consume the trailing ')'. */
17002 c_parser_consume_token (parser
);
17004 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
17005 tile
= nreverse (tile
);
17006 OMP_CLAUSE_TILE_LIST (c
) = tile
;
17007 OMP_CLAUSE_CHAIN (c
) = list
;
17012 wait [( int-expr-list )] */
17015 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
17017 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17019 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
17020 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
17023 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
17025 OMP_CLAUSE_DECL (c
) = build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
17026 OMP_CLAUSE_CHAIN (c
) = list
;
17034 self [( expression )] */
17037 c_parser_oacc_compute_clause_self (c_parser
*parser
, tree list
)
17040 location_t location
= c_parser_peek_token (parser
)->location
;
17041 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
17043 matching_parens parens
;
17044 parens
.consume_open (parser
);
17046 location_t loc
= c_parser_peek_token (parser
)->location
;
17047 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17048 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
17049 t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
);
17050 t
= c_fully_fold (t
, false, NULL
);
17051 parens
.skip_until_found_close (parser
);
17054 t
= truthvalue_true_node
;
17056 for (tree c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
17057 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SELF
)
17059 error_at (location
, "too many %<self%> clauses");
17063 tree c
= build_omp_clause (location
, OMP_CLAUSE_SELF
);
17064 OMP_CLAUSE_SELF_EXPR (c
) = t
;
17065 OMP_CLAUSE_CHAIN (c
) = list
;
17070 order ( concurrent )
17073 order ( order-modifier : concurrent )
17080 c_parser_omp_clause_order (c_parser
*parser
, tree list
)
17082 location_t loc
= c_parser_peek_token (parser
)->location
;
17085 bool unconstrained
= false;
17086 bool reproducible
= false;
17088 matching_parens parens
;
17089 if (!parens
.require_open (parser
))
17091 if (c_parser_next_token_is (parser
, CPP_NAME
)
17092 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
17094 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17095 if (strcmp (p
, "unconstrained") == 0)
17096 unconstrained
= true;
17097 else if (strcmp (p
, "reproducible") == 0)
17098 reproducible
= true;
17101 c_parser_error (parser
, "expected %<reproducible%> or "
17102 "%<unconstrained%>");
17105 c_parser_consume_token (parser
);
17106 c_parser_consume_token (parser
);
17108 if (!c_parser_next_token_is (parser
, CPP_NAME
))
17110 c_parser_error (parser
, "expected %<concurrent%>");
17113 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17114 if (strcmp (p
, "concurrent") != 0)
17116 c_parser_error (parser
, "expected %<concurrent%>");
17119 c_parser_consume_token (parser
);
17120 parens
.skip_until_found_close (parser
);
17121 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDER
, "order");
17122 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDER
);
17123 OMP_CLAUSE_ORDER_UNCONSTRAINED (c
) = unconstrained
;
17124 OMP_CLAUSE_ORDER_REPRODUCIBLE (c
) = reproducible
;
17125 OMP_CLAUSE_CHAIN (c
) = list
;
17129 parens
.skip_until_found_close (parser
);
17135 bind ( teams | parallel | thread ) */
17138 c_parser_omp_clause_bind (c_parser
*parser
, tree list
)
17140 location_t loc
= c_parser_peek_token (parser
)->location
;
17143 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
17145 matching_parens parens
;
17146 if (!parens
.require_open (parser
))
17148 if (!c_parser_next_token_is (parser
, CPP_NAME
))
17151 c_parser_error (parser
,
17152 "expected %<teams%>, %<parallel%> or %<thread%>");
17153 parens
.skip_until_found_close (parser
);
17156 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17157 if (strcmp (p
, "teams") == 0)
17158 kind
= OMP_CLAUSE_BIND_TEAMS
;
17159 else if (strcmp (p
, "parallel") == 0)
17160 kind
= OMP_CLAUSE_BIND_PARALLEL
;
17161 else if (strcmp (p
, "thread") != 0)
17163 c_parser_consume_token (parser
);
17164 parens
.skip_until_found_close (parser
);
17165 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
17166 c
= build_omp_clause (loc
, OMP_CLAUSE_BIND
);
17167 OMP_CLAUSE_BIND_KIND (c
) = kind
;
17168 OMP_CLAUSE_CHAIN (c
) = list
;
17177 ordered ( constant-expression ) */
17180 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
17182 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
17184 tree c
, num
= NULL_TREE
;
17186 location_t loc
= c_parser_peek_token (parser
)->location
;
17187 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17189 matching_parens parens
;
17190 parens
.consume_open (parser
);
17191 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
17192 parens
.skip_until_found_close (parser
);
17194 if (num
== error_mark_node
)
17198 mark_exp_read (num
);
17199 num
= c_fully_fold (num
, false, NULL
);
17200 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
17201 || !tree_fits_shwi_p (num
)
17202 || (n
= tree_to_shwi (num
)) <= 0
17205 error_at (loc
, "ordered argument needs positive "
17206 "constant integer expression");
17210 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
17211 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
17212 OMP_CLAUSE_CHAIN (c
) = list
;
17217 private ( variable-list ) */
17220 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
17222 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
17226 reduction ( reduction-operator : variable-list )
17228 reduction-operator:
17229 One of: + * - & ^ | && ||
17233 reduction-operator:
17234 One of: + * - & ^ | && || max min
17238 reduction-operator:
17239 One of: + * - & ^ | && ||
17243 reduction ( reduction-modifier, reduction-operator : variable-list )
17244 in_reduction ( reduction-operator : variable-list )
17245 task_reduction ( reduction-operator : variable-list ) */
17248 c_parser_omp_clause_reduction (c_parser
*parser
, enum omp_clause_code kind
,
17249 bool is_omp
, tree list
)
17251 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17252 matching_parens parens
;
17253 if (parens
.require_open (parser
))
17256 bool inscan
= false;
17257 enum tree_code code
= ERROR_MARK
;
17258 tree reduc_id
= NULL_TREE
;
17260 if (kind
== OMP_CLAUSE_REDUCTION
&& is_omp
)
17262 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
17263 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
17265 c_parser_consume_token (parser
);
17266 c_parser_consume_token (parser
);
17268 else if (c_parser_next_token_is (parser
, CPP_NAME
)
17269 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
17272 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17273 if (strcmp (p
, "task") == 0)
17275 else if (strcmp (p
, "inscan") == 0)
17277 if (task
|| inscan
)
17279 c_parser_consume_token (parser
);
17280 c_parser_consume_token (parser
);
17285 switch (c_parser_peek_token (parser
)->type
)
17297 code
= BIT_AND_EXPR
;
17300 code
= BIT_XOR_EXPR
;
17303 code
= BIT_IOR_EXPR
;
17306 code
= TRUTH_ANDIF_EXPR
;
17309 code
= TRUTH_ORIF_EXPR
;
17314 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17315 if (strcmp (p
, "min") == 0)
17320 if (strcmp (p
, "max") == 0)
17325 reduc_id
= c_parser_peek_token (parser
)->value
;
17329 c_parser_error (parser
,
17330 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
17331 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
17332 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
17335 c_parser_consume_token (parser
);
17336 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
17337 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
17341 nl
= c_parser_omp_variable_list (parser
, clause_loc
, kind
, list
);
17342 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
17344 tree d
= OMP_CLAUSE_DECL (c
), type
;
17345 if (TREE_CODE (d
) != OMP_ARRAY_SECTION
)
17346 type
= TREE_TYPE (d
);
17352 TREE_CODE (t
) == OMP_ARRAY_SECTION
;
17353 t
= TREE_OPERAND (t
, 0))
17355 type
= TREE_TYPE (t
);
17358 if (TREE_CODE (type
) != POINTER_TYPE
17359 && TREE_CODE (type
) != ARRAY_TYPE
)
17361 type
= TREE_TYPE (type
);
17365 while (TREE_CODE (type
) == ARRAY_TYPE
)
17366 type
= TREE_TYPE (type
);
17367 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
17369 OMP_CLAUSE_REDUCTION_TASK (c
) = 1;
17371 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 1;
17372 if (code
== ERROR_MARK
17373 || !(INTEGRAL_TYPE_P (type
)
17374 || SCALAR_FLOAT_TYPE_P (type
)
17375 || TREE_CODE (type
) == COMPLEX_TYPE
))
17376 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
17377 = c_omp_reduction_lookup (reduc_id
,
17378 TYPE_MAIN_VARIANT (type
));
17383 parens
.skip_until_found_close (parser
);
17389 schedule ( schedule-kind )
17390 schedule ( schedule-kind , expression )
17393 static | dynamic | guided | runtime | auto
17396 schedule ( schedule-modifier : schedule-kind )
17397 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
17405 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
17408 location_t loc
= c_parser_peek_token (parser
)->location
;
17409 int modifiers
= 0, nmodifiers
= 0;
17411 matching_parens parens
;
17412 if (!parens
.require_open (parser
))
17415 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
17417 location_t comma
= UNKNOWN_LOCATION
;
17418 while (c_parser_next_token_is (parser
, CPP_NAME
))
17420 tree kind
= c_parser_peek_token (parser
)->value
;
17421 const char *p
= IDENTIFIER_POINTER (kind
);
17422 if (strcmp ("simd", p
) == 0)
17423 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
17424 else if (strcmp ("monotonic", p
) == 0)
17425 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
17426 else if (strcmp ("nonmonotonic", p
) == 0)
17427 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
17430 comma
= UNKNOWN_LOCATION
;
17431 c_parser_consume_token (parser
);
17432 if (nmodifiers
++ == 0
17433 && c_parser_next_token_is (parser
, CPP_COMMA
))
17435 comma
= c_parser_peek_token (parser
)->location
;
17436 c_parser_consume_token (parser
);
17440 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
17444 if (comma
!= UNKNOWN_LOCATION
)
17445 error_at (comma
, "expected %<:%>");
17447 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
17448 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
17449 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
17450 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
17452 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
17457 if (c_parser_next_token_is (parser
, CPP_NAME
))
17459 tree kind
= c_parser_peek_token (parser
)->value
;
17460 const char *p
= IDENTIFIER_POINTER (kind
);
17465 if (strcmp ("dynamic", p
) != 0)
17467 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
17471 if (strcmp ("guided", p
) != 0)
17473 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
17477 if (strcmp ("runtime", p
) != 0)
17479 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
17486 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
17487 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
17488 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
17489 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
17493 c_parser_consume_token (parser
);
17494 if (c_parser_next_token_is (parser
, CPP_COMMA
))
17497 c_parser_consume_token (parser
);
17499 here
= c_parser_peek_token (parser
)->location
;
17500 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17501 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
17503 t
= c_fully_fold (t
, false, NULL
);
17505 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
17506 error_at (here
, "schedule %<runtime%> does not take "
17507 "a %<chunk_size%> parameter");
17508 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
17510 "schedule %<auto%> does not take "
17511 "a %<chunk_size%> parameter");
17512 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
17513 || TREE_CODE (TREE_TYPE (t
)) == BITINT_TYPE
)
17515 /* Attempt to statically determine when the number isn't
17517 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
17518 build_int_cst (TREE_TYPE (t
), 0));
17519 protected_set_expr_location (s
, loc
);
17520 if (s
== boolean_true_node
)
17522 warning_at (loc
, OPT_Wopenmp
,
17523 "chunk size value must be positive");
17524 t
= integer_one_node
;
17526 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
17529 c_parser_error (parser
, "expected integer expression");
17531 parens
.skip_until_found_close (parser
);
17534 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
17535 "expected %<,%> or %<)%>");
17537 OMP_CLAUSE_SCHEDULE_KIND (c
)
17538 = (enum omp_clause_schedule_kind
)
17539 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
17541 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
17542 OMP_CLAUSE_CHAIN (c
) = list
;
17546 c_parser_error (parser
, "invalid schedule kind");
17547 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
17552 shared ( variable-list ) */
17555 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
17557 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
17564 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
17568 /* FIXME: Should we allow duplicates? */
17569 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
17571 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
17572 OMP_CLAUSE_UNTIED
);
17573 OMP_CLAUSE_CHAIN (c
) = list
;
17583 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
17584 enum omp_clause_code code
, tree list
)
17586 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
17588 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
17589 OMP_CLAUSE_CHAIN (c
) = list
;
17601 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
17602 enum omp_clause_code code
, tree list
)
17604 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
17605 OMP_CLAUSE_CHAIN (c
) = list
;
17614 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
17616 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
17617 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
17618 OMP_CLAUSE_NOGROUP
);
17619 OMP_CLAUSE_CHAIN (c
) = list
;
17628 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
17629 enum omp_clause_code code
, tree list
)
17631 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
17632 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
17633 OMP_CLAUSE_CHAIN (c
) = list
;
17638 num_teams ( expression )
17641 num_teams ( expression : expression ) */
17644 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
17646 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
17647 matching_parens parens
;
17648 if (parens
.require_open (parser
))
17650 location_t upper_loc
= c_parser_peek_token (parser
)->location
;
17651 location_t lower_loc
= UNKNOWN_LOCATION
;
17652 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17653 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
17654 tree c
, upper
= expr
.value
, lower
= NULL_TREE
;
17655 upper
= c_fully_fold (upper
, false, NULL
);
17657 if (c_parser_next_token_is (parser
, CPP_COLON
))
17659 c_parser_consume_token (parser
);
17660 lower_loc
= upper_loc
;
17662 upper_loc
= c_parser_peek_token (parser
)->location
;
17663 expr
= c_parser_expr_no_commas (parser
, NULL
);
17664 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
17665 upper
= expr
.value
;
17666 upper
= c_fully_fold (upper
, false, NULL
);
17669 parens
.skip_until_found_close (parser
);
17671 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper
))
17672 || (lower
&& !INTEGRAL_TYPE_P (TREE_TYPE (lower
))))
17674 c_parser_error (parser
, "expected integer expression");
17678 /* Attempt to statically determine when the number isn't positive. */
17679 c
= fold_build2_loc (upper_loc
, LE_EXPR
, boolean_type_node
, upper
,
17680 build_int_cst (TREE_TYPE (upper
), 0));
17681 protected_set_expr_location (c
, upper_loc
);
17682 if (c
== boolean_true_node
)
17684 warning_at (upper_loc
, OPT_Wopenmp
,
17685 "%<num_teams%> value must be positive");
17686 upper
= integer_one_node
;
17690 c
= fold_build2_loc (lower_loc
, LE_EXPR
, boolean_type_node
, lower
,
17691 build_int_cst (TREE_TYPE (lower
), 0));
17692 protected_set_expr_location (c
, lower_loc
);
17693 if (c
== boolean_true_node
)
17695 warning_at (lower_loc
, OPT_Wopenmp
,
17696 "%<num_teams%> value must be positive");
17699 else if (TREE_CODE (lower
) == INTEGER_CST
17700 && TREE_CODE (upper
) == INTEGER_CST
17701 && tree_int_cst_lt (upper
, lower
))
17703 warning_at (lower_loc
, OPT_Wopenmp
,
17704 "%<num_teams%> lower bound %qE bigger than upper "
17705 "bound %qE", lower
, upper
);
17710 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
17712 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
17713 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c
) = upper
;
17714 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
) = lower
;
17715 OMP_CLAUSE_CHAIN (c
) = list
;
17723 thread_limit ( expression ) */
17726 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
17728 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
17729 matching_parens parens
;
17730 if (parens
.require_open (parser
))
17732 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17733 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17734 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17735 tree c
, t
= expr
.value
;
17736 t
= c_fully_fold (t
, false, NULL
);
17738 parens
.skip_until_found_close (parser
);
17740 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
17742 c_parser_error (parser
, "expected integer expression");
17746 /* Attempt to statically determine when the number isn't positive. */
17747 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
17748 build_int_cst (TREE_TYPE (t
), 0));
17749 protected_set_expr_location (c
, expr_loc
);
17750 if (c
== boolean_true_node
)
17752 warning_at (expr_loc
, OPT_Wopenmp
,
17753 "%<thread_limit%> value must be positive");
17754 t
= integer_one_node
;
17757 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
17760 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
17761 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
17762 OMP_CLAUSE_CHAIN (c
) = list
;
17770 aligned ( variable-list )
17771 aligned ( variable-list : constant-expression ) */
17774 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
17776 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17779 matching_parens parens
;
17780 if (!parens
.require_open (parser
))
17783 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
17784 OMP_CLAUSE_ALIGNED
, list
);
17786 if (c_parser_next_token_is (parser
, CPP_COLON
))
17788 c_parser_consume_token (parser
);
17789 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17790 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17791 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17792 tree alignment
= expr
.value
;
17793 alignment
= c_fully_fold (alignment
, false, NULL
);
17794 if (TREE_CODE (alignment
) != INTEGER_CST
17795 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
17796 || tree_int_cst_sgn (alignment
) != 1)
17798 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
17799 "be positive constant integer expression");
17800 alignment
= NULL_TREE
;
17803 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
17804 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
17807 parens
.skip_until_found_close (parser
);
17812 allocate ( variable-list )
17813 allocate ( expression : variable-list )
17816 allocate ( allocator-modifier : variable-list )
17817 allocate ( allocator-modifier , allocator-modifier : variable-list )
17819 allocator-modifier:
17820 allocator ( expression )
17821 align ( expression ) */
17824 c_parser_omp_clause_allocate (c_parser
*parser
, tree list
)
17826 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17828 tree allocator
= NULL_TREE
;
17829 tree align
= NULL_TREE
;
17831 matching_parens parens
;
17832 if (!parens
.require_open (parser
))
17835 if ((c_parser_next_token_is_not (parser
, CPP_NAME
)
17836 && c_parser_next_token_is_not (parser
, CPP_KEYWORD
))
17837 || (c_parser_peek_2nd_token (parser
)->type
!= CPP_COMMA
17838 && c_parser_peek_2nd_token (parser
)->type
!= CPP_CLOSE_PAREN
))
17840 bool has_modifiers
= false;
17841 tree orig_type
= NULL_TREE
;
17842 if (c_parser_next_token_is (parser
, CPP_NAME
)
17843 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
17845 unsigned int n
= 3;
17847 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17848 if ((strcmp (p
, "allocator") == 0 || strcmp (p
, "align") == 0)
17849 && c_parser_check_balanced_raw_token_sequence (parser
, &n
)
17850 && (c_parser_peek_nth_token_raw (parser
, n
)->type
17851 == CPP_CLOSE_PAREN
))
17853 if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
17855 has_modifiers
= true;
17856 else if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
17858 && (c_parser_peek_nth_token_raw (parser
, n
+ 2)->type
17860 && (c_parser_peek_nth_token_raw (parser
, n
+ 3)->type
17861 == CPP_OPEN_PAREN
))
17863 c_token
*tok
= c_parser_peek_nth_token_raw (parser
, n
+ 2);
17864 const char *q
= IDENTIFIER_POINTER (tok
->value
);
17866 if ((strcmp (q
, "allocator") == 0
17867 || strcmp (q
, "align") == 0)
17868 && c_parser_check_balanced_raw_token_sequence (parser
,
17870 && (c_parser_peek_nth_token_raw (parser
, n
)->type
17871 == CPP_CLOSE_PAREN
)
17872 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
17874 has_modifiers
= true;
17879 c_parser_consume_token (parser
);
17880 matching_parens parens2
;;
17881 parens2
.require_open (parser
);
17882 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17883 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17884 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17885 if (expr
.value
== error_mark_node
)
17887 else if (strcmp (p
, "allocator") == 0)
17889 allocator
= expr
.value
;
17890 allocator
= c_fully_fold (allocator
, false, NULL
);
17891 orig_type
= expr
.original_type
17892 ? expr
.original_type
: TREE_TYPE (allocator
);
17893 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
17897 align
= expr
.value
;
17898 align
= c_fully_fold (align
, false, NULL
);
17900 parens2
.skip_until_found_close (parser
);
17901 if (c_parser_next_token_is (parser
, CPP_COMMA
))
17903 c_parser_consume_token (parser
);
17904 c_token
*tok
= c_parser_peek_token (parser
);
17905 const char *q
= "";
17906 if (c_parser_next_token_is (parser
, CPP_NAME
))
17907 q
= IDENTIFIER_POINTER (tok
->value
);
17908 if (strcmp (q
, "allocator") != 0 && strcmp (q
, "align") != 0)
17910 c_parser_error (parser
, "expected %<allocator%> or "
17912 parens
.skip_until_found_close (parser
);
17915 else if (strcmp (p
, q
) == 0)
17917 error_at (tok
->location
, "duplicate %qs modifier", p
);
17918 parens
.skip_until_found_close (parser
);
17921 c_parser_consume_token (parser
);
17922 if (!parens2
.require_open (parser
))
17924 parens
.skip_until_found_close (parser
);
17927 expr_loc
= c_parser_peek_token (parser
)->location
;
17928 expr
= c_parser_expr_no_commas (parser
, NULL
);
17929 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
17931 if (strcmp (q
, "allocator") == 0)
17933 allocator
= expr
.value
;
17934 allocator
= c_fully_fold (allocator
, false, NULL
);
17935 orig_type
= expr
.original_type
17936 ? expr
.original_type
: TREE_TYPE (allocator
);
17937 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
17941 align
= expr
.value
;
17942 align
= c_fully_fold (align
, false, NULL
);
17944 parens2
.skip_until_found_close (parser
);
17948 if (!has_modifiers
)
17950 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17951 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17952 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17953 allocator
= expr
.value
;
17954 allocator
= c_fully_fold (allocator
, false, NULL
);
17955 orig_type
= expr
.original_type
17956 ? expr
.original_type
: TREE_TYPE (allocator
);
17957 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
17960 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
17961 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
17962 || (TYPE_NAME (orig_type
)
17963 != get_identifier ("omp_allocator_handle_t"))))
17965 error_at (clause_loc
, "%<allocate%> clause allocator expression "
17966 "has type %qT rather than "
17967 "%<omp_allocator_handle_t%>",
17968 TREE_TYPE (allocator
));
17969 allocator
= NULL_TREE
;
17972 && (!INTEGRAL_TYPE_P (TREE_TYPE (align
))
17973 || !tree_fits_uhwi_p (align
)
17974 || !integer_pow2p (align
)))
17976 error_at (clause_loc
, "%<allocate%> clause %<align%> modifier "
17977 "argument needs to be positive constant "
17978 "power of two integer expression");
17981 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
17983 parens
.skip_until_found_close (parser
);
17988 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
17989 OMP_CLAUSE_ALLOCATE
, list
);
17991 if (allocator
|| align
)
17992 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
17994 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
17995 OMP_CLAUSE_ALLOCATE_ALIGN (c
) = align
;
17998 parens
.skip_until_found_close (parser
);
18003 linear ( variable-list )
18004 linear ( variable-list : expression )
18007 linear ( modifier ( variable-list ) )
18008 linear ( modifier ( variable-list ) : expression )
18014 linear ( variable-list : modifiers-list )
18018 step ( expression ) */
18021 c_parser_omp_clause_linear (c_parser
*parser
, tree list
)
18023 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18025 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
18026 bool old_linear_modifier
= false;
18028 matching_parens parens
;
18029 if (!parens
.require_open (parser
))
18032 if (c_parser_next_token_is (parser
, CPP_NAME
))
18034 c_token
*tok
= c_parser_peek_token (parser
);
18035 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18036 if (strcmp ("val", p
) == 0)
18037 kind
= OMP_CLAUSE_LINEAR_VAL
;
18038 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
18039 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
18040 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
18042 old_linear_modifier
= true;
18043 c_parser_consume_token (parser
);
18044 c_parser_consume_token (parser
);
18048 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
18049 OMP_CLAUSE_LINEAR
, list
);
18051 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
18052 parens
.skip_until_found_close (parser
);
18054 if (c_parser_next_token_is (parser
, CPP_COLON
))
18056 c_parser_consume_token (parser
);
18057 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18058 bool has_modifiers
= false;
18059 if (kind
== OMP_CLAUSE_LINEAR_DEFAULT
18060 && c_parser_next_token_is (parser
, CPP_NAME
))
18062 c_token
*tok
= c_parser_peek_token (parser
);
18063 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18064 unsigned int pos
= 0;
18065 if (strcmp ("val", p
) == 0)
18067 else if (strcmp ("step", p
) == 0
18068 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
18071 if (c_parser_check_balanced_raw_token_sequence (parser
, &pos
)
18072 && (c_parser_peek_nth_token_raw (parser
, pos
)->type
18073 == CPP_CLOSE_PAREN
))
18080 tok
= c_parser_peek_nth_token_raw (parser
, pos
);
18081 if (tok
->type
== CPP_COMMA
|| tok
->type
== CPP_CLOSE_PAREN
)
18082 has_modifiers
= true;
18088 while (c_parser_next_token_is (parser
, CPP_NAME
))
18090 c_token
*tok
= c_parser_peek_token (parser
);
18091 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18092 if (strcmp ("val", p
) == 0)
18094 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
18095 error_at (tok
->location
, "multiple linear modifiers");
18096 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
18097 c_parser_consume_token (parser
);
18099 else if (strcmp ("step", p
) == 0)
18101 c_parser_consume_token (parser
);
18102 matching_parens parens2
;
18103 if (parens2
.require_open (parser
))
18106 error_at (tok
->location
,
18107 "multiple %<step%> modifiers");
18108 expr_loc
= c_parser_peek_token (parser
)->location
;
18109 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18110 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
18112 step
= c_fully_fold (expr
.value
, false, NULL
);
18113 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
18115 error_at (clause_loc
, "%<linear%> clause step "
18116 "expression must be integral");
18117 step
= integer_one_node
;
18119 parens2
.skip_until_found_close (parser
);
18126 if (c_parser_next_token_is (parser
, CPP_COMMA
))
18128 c_parser_consume_token (parser
);
18134 step
= integer_one_node
;
18138 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18139 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18140 step
= c_fully_fold (expr
.value
, false, NULL
);
18141 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
18143 error_at (clause_loc
, "%<linear%> clause step expression must "
18145 step
= integer_one_node
;
18151 step
= integer_one_node
;
18153 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18155 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
18156 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
18157 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c
) = old_linear_modifier
;
18160 parens
.skip_until_found_close (parser
);
18165 nontemporal ( variable-list ) */
18168 c_parser_omp_clause_nontemporal (c_parser
*parser
, tree list
)
18170 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_NONTEMPORAL
, list
);
18174 safelen ( constant-expression ) */
18177 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
18179 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18182 matching_parens parens
;
18183 if (!parens
.require_open (parser
))
18186 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18187 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18188 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18190 t
= c_fully_fold (t
, false, NULL
);
18191 if (TREE_CODE (t
) != INTEGER_CST
18192 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
18193 || tree_int_cst_sgn (t
) != 1)
18195 error_at (clause_loc
, "%<safelen%> clause expression must "
18196 "be positive constant integer expression");
18200 parens
.skip_until_found_close (parser
);
18201 if (t
== NULL_TREE
|| t
== error_mark_node
)
18204 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
18206 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
18207 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
18208 OMP_CLAUSE_CHAIN (c
) = list
;
18213 simdlen ( constant-expression ) */
18216 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
18218 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18221 matching_parens parens
;
18222 if (!parens
.require_open (parser
))
18225 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18226 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18227 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18229 t
= c_fully_fold (t
, false, NULL
);
18230 if (TREE_CODE (t
) != INTEGER_CST
18231 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
18232 || tree_int_cst_sgn (t
) != 1)
18234 error_at (clause_loc
, "%<simdlen%> clause expression must "
18235 "be positive constant integer expression");
18239 parens
.skip_until_found_close (parser
);
18240 if (t
== NULL_TREE
|| t
== error_mark_node
)
18243 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
18245 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
18246 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
18247 OMP_CLAUSE_CHAIN (c
) = list
;
18253 identifier [+/- integer]
18254 vec , identifier [+/- integer]
18258 c_parser_omp_clause_doacross_sink (c_parser
*parser
, location_t clause_loc
,
18259 tree list
, bool depend_p
)
18262 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
18263 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
18265 c_parser_error (parser
, "expected identifier");
18271 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18272 if (strcmp (p
, "omp_cur_iteration") == 0
18273 && c_parser_peek_2nd_token (parser
)->type
== CPP_MINUS
18274 && c_parser_peek_nth_token (parser
, 3)->type
== CPP_NUMBER
18275 && c_parser_peek_nth_token (parser
, 4)->type
== CPP_CLOSE_PAREN
)
18277 tree val
= c_parser_peek_nth_token (parser
, 3)->value
;
18278 if (integer_onep (val
))
18280 c_parser_consume_token (parser
);
18281 c_parser_consume_token (parser
);
18282 c_parser_consume_token (parser
);
18283 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
18284 OMP_CLAUSE_DOACROSS_KIND (u
) = OMP_CLAUSE_DOACROSS_SINK
;
18285 OMP_CLAUSE_CHAIN (u
) = list
;
18293 while (c_parser_next_token_is (parser
, CPP_NAME
)
18294 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
18296 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
18297 tree addend
= NULL
;
18299 if (t
== NULL_TREE
)
18301 undeclared_variable (c_parser_peek_token (parser
)->location
,
18302 c_parser_peek_token (parser
)->value
);
18303 t
= error_mark_node
;
18306 c_parser_consume_token (parser
);
18309 if (c_parser_next_token_is (parser
, CPP_MINUS
))
18311 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
18313 addend
= integer_zero_node
;
18315 goto add_to_vector
;
18317 c_parser_consume_token (parser
);
18319 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
18321 c_parser_error (parser
, "expected integer");
18325 addend
= c_parser_peek_token (parser
)->value
;
18326 if (TREE_CODE (addend
) != INTEGER_CST
)
18328 c_parser_error (parser
, "expected integer");
18331 c_parser_consume_token (parser
);
18334 if (t
!= error_mark_node
)
18336 vec
= tree_cons (addend
, t
, vec
);
18338 OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec
) = 1;
18341 if (c_parser_next_token_is_not (parser
, CPP_COMMA
)
18342 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
18343 || c_parser_peek_2nd_token (parser
)->id_kind
!= C_ID_ID
)
18346 c_parser_consume_token (parser
);
18349 if (vec
== NULL_TREE
)
18352 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
18353 OMP_CLAUSE_DOACROSS_KIND (u
) = OMP_CLAUSE_DOACROSS_SINK
;
18354 OMP_CLAUSE_DOACROSS_DEPEND (u
) = depend_p
;
18355 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
18356 OMP_CLAUSE_CHAIN (u
) = list
;
18361 iterators ( iterators-definition )
18363 iterators-definition:
18365 iterator-specifier , iterators-definition
18367 iterator-specifier:
18368 identifier = range-specification
18369 iterator-type identifier = range-specification
18371 range-specification:
18373 begin : end : step */
18376 c_parser_omp_iterators (c_parser
*parser
)
18378 tree ret
= NULL_TREE
, *last
= &ret
;
18379 c_parser_consume_token (parser
);
18383 matching_parens parens
;
18384 if (!parens
.require_open (parser
))
18385 return error_mark_node
;
18389 tree iter_type
= NULL_TREE
, type_expr
= NULL_TREE
;
18390 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
18392 struct c_type_name
*type
= c_parser_type_name (parser
);
18394 iter_type
= groktypename (type
, &type_expr
, NULL
);
18396 if (iter_type
== NULL_TREE
)
18397 iter_type
= integer_type_node
;
18399 location_t loc
= c_parser_peek_token (parser
)->location
;
18400 if (!c_parser_next_token_is (parser
, CPP_NAME
))
18402 c_parser_error (parser
, "expected identifier");
18406 tree id
= c_parser_peek_token (parser
)->value
;
18407 c_parser_consume_token (parser
);
18409 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18412 location_t eloc
= c_parser_peek_token (parser
)->location
;
18413 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18414 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
18415 tree begin
= expr
.value
;
18417 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18420 eloc
= c_parser_peek_token (parser
)->location
;
18421 expr
= c_parser_expr_no_commas (parser
, NULL
);
18422 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
18423 tree end
= expr
.value
;
18425 tree step
= integer_one_node
;
18426 if (c_parser_next_token_is (parser
, CPP_COLON
))
18428 c_parser_consume_token (parser
);
18429 eloc
= c_parser_peek_token (parser
)->location
;
18430 expr
= c_parser_expr_no_commas (parser
, NULL
);
18431 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
18435 tree iter_var
= build_decl (loc
, VAR_DECL
, id
, iter_type
);
18436 DECL_ARTIFICIAL (iter_var
) = 1;
18437 DECL_CONTEXT (iter_var
) = current_function_decl
;
18438 pushdecl (iter_var
);
18440 *last
= make_tree_vec (6);
18441 TREE_VEC_ELT (*last
, 0) = iter_var
;
18442 TREE_VEC_ELT (*last
, 1) = begin
;
18443 TREE_VEC_ELT (*last
, 2) = end
;
18444 TREE_VEC_ELT (*last
, 3) = step
;
18445 last
= &TREE_CHAIN (*last
);
18447 if (c_parser_next_token_is (parser
, CPP_COMMA
))
18449 c_parser_consume_token (parser
);
18456 parens
.skip_until_found_close (parser
);
18457 return ret
? ret
: error_mark_node
;
18461 affinity ( [aff-modifier :] variable-list )
18463 iterator ( iterators-definition ) */
18466 c_parser_omp_clause_affinity (c_parser
*parser
, tree list
)
18468 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18469 tree nl
, iterators
= NULL_TREE
;
18471 matching_parens parens
;
18472 if (!parens
.require_open (parser
))
18475 if (c_parser_next_token_is (parser
, CPP_NAME
))
18477 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18478 bool parse_iter
= ((strcmp ("iterator", p
) == 0)
18479 && (c_parser_peek_2nd_token (parser
)->type
18480 == CPP_OPEN_PAREN
));
18484 parse_iter
= (c_parser_check_balanced_raw_token_sequence (parser
, &n
)
18485 && (c_parser_peek_nth_token_raw (parser
, n
)->type
18486 == CPP_CLOSE_PAREN
)
18487 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
18492 iterators
= c_parser_omp_iterators (parser
);
18493 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18497 parens
.skip_until_found_close (parser
);
18502 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_AFFINITY
,
18506 tree block
= pop_scope ();
18507 if (iterators
!= error_mark_node
)
18509 TREE_VEC_ELT (iterators
, 5) = block
;
18510 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18511 OMP_CLAUSE_DECL (c
) = build_tree_list (iterators
,
18512 OMP_CLAUSE_DECL (c
));
18516 parens
.skip_until_found_close (parser
);
18522 depend ( depend-kind: variable-list )
18530 depend ( sink : vec )
18533 depend ( depend-modifier , depend-kind: variable-list )
18536 in | out | inout | mutexinoutset | depobj | inoutset
18539 iterator ( iterators-definition ) */
18542 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
18544 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18545 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_LAST
;
18546 enum omp_clause_doacross_kind dkind
= OMP_CLAUSE_DOACROSS_LAST
;
18547 tree nl
, c
, iterators
= NULL_TREE
;
18549 matching_parens parens
;
18550 if (!parens
.require_open (parser
))
18555 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
18558 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18559 if (strcmp ("iterator", p
) == 0 && iterators
== NULL_TREE
)
18561 iterators
= c_parser_omp_iterators (parser
);
18562 c_parser_require (parser
, CPP_COMMA
, "expected %<,%>");
18565 if (strcmp ("in", p
) == 0)
18566 kind
= OMP_CLAUSE_DEPEND_IN
;
18567 else if (strcmp ("inout", p
) == 0)
18568 kind
= OMP_CLAUSE_DEPEND_INOUT
;
18569 else if (strcmp ("inoutset", p
) == 0)
18570 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
18571 else if (strcmp ("mutexinoutset", p
) == 0)
18572 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
18573 else if (strcmp ("out", p
) == 0)
18574 kind
= OMP_CLAUSE_DEPEND_OUT
;
18575 else if (strcmp ("depobj", p
) == 0)
18576 kind
= OMP_CLAUSE_DEPEND_DEPOBJ
;
18577 else if (strcmp ("sink", p
) == 0)
18578 dkind
= OMP_CLAUSE_DOACROSS_SINK
;
18579 else if (strcmp ("source", p
) == 0)
18580 dkind
= OMP_CLAUSE_DOACROSS_SOURCE
;
18587 c_parser_consume_token (parser
);
18590 && (dkind
== OMP_CLAUSE_DOACROSS_SOURCE
18591 || dkind
== OMP_CLAUSE_DOACROSS_SINK
))
18594 error_at (clause_loc
, "%<iterator%> modifier incompatible with %qs",
18595 dkind
== OMP_CLAUSE_DOACROSS_SOURCE
? "source" : "sink");
18596 iterators
= NULL_TREE
;
18599 if (dkind
== OMP_CLAUSE_DOACROSS_SOURCE
)
18601 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
18602 OMP_CLAUSE_DOACROSS_KIND (c
) = dkind
;
18603 OMP_CLAUSE_DOACROSS_DEPEND (c
) = 1;
18604 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
18605 OMP_CLAUSE_CHAIN (c
) = list
;
18606 parens
.skip_until_found_close (parser
);
18610 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18613 if (dkind
== OMP_CLAUSE_DOACROSS_SINK
)
18614 nl
= c_parser_omp_clause_doacross_sink (parser
, clause_loc
, list
, true);
18617 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
18618 OMP_CLAUSE_DEPEND
, list
);
18622 tree block
= pop_scope ();
18623 if (iterators
== error_mark_node
)
18624 iterators
= NULL_TREE
;
18626 TREE_VEC_ELT (iterators
, 5) = block
;
18629 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18631 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
18633 OMP_CLAUSE_DECL (c
)
18634 = build_tree_list (iterators
, OMP_CLAUSE_DECL (c
));
18638 parens
.skip_until_found_close (parser
);
18642 c_parser_error (parser
, "invalid depend kind");
18644 parens
.skip_until_found_close (parser
);
18651 doacross ( source : )
18652 doacross ( source : omp_cur_iteration )
18654 doacross ( sink : vec )
18655 doacross ( sink : omp_cur_iteration - logical_iteration ) */
18658 c_parser_omp_clause_doacross (c_parser
*parser
, tree list
)
18660 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18661 enum omp_clause_doacross_kind kind
= OMP_CLAUSE_DOACROSS_LAST
;
18665 matching_parens parens
;
18666 if (!parens
.require_open (parser
))
18669 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
18672 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18673 if (strcmp ("sink", p
) == 0)
18674 kind
= OMP_CLAUSE_DOACROSS_SINK
;
18675 else if (strcmp ("source", p
) == 0)
18676 kind
= OMP_CLAUSE_DOACROSS_SOURCE
;
18680 c_parser_consume_token (parser
);
18682 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
18685 if (kind
== OMP_CLAUSE_DOACROSS_SOURCE
)
18687 if (c_parser_next_token_is (parser
, CPP_NAME
)
18688 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
18689 "omp_cur_iteration") == 0)
18690 c_parser_consume_token (parser
);
18691 nl
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
18692 OMP_CLAUSE_DOACROSS_KIND (nl
) = OMP_CLAUSE_DOACROSS_SOURCE
;
18693 OMP_CLAUSE_DECL (nl
) = NULL_TREE
;
18694 OMP_CLAUSE_CHAIN (nl
) = list
;
18697 nl
= c_parser_omp_clause_doacross_sink (parser
, clause_loc
, list
, false);
18699 parens
.skip_until_found_close (parser
);
18703 c_parser_error (parser
, "invalid doacross kind");
18705 parens
.skip_until_found_close (parser
);
18710 map ( map-kind: variable-list )
18711 map ( variable-list )
18714 alloc | to | from | tofrom
18718 alloc | to | from | tofrom | release | delete
18720 map ( always [,] map-kind: variable-list )
18723 map ( [map-type-modifier[,] ...] map-kind: variable-list )
18729 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
18731 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18732 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
18735 matching_parens parens
;
18736 if (!parens
.require_open (parser
))
18740 int map_kind_pos
= 0;
18741 while (c_parser_peek_nth_token_raw (parser
, pos
)->type
== CPP_NAME
)
18743 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COLON
)
18745 map_kind_pos
= pos
;
18749 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COMMA
)
18754 int always_modifier
= 0;
18755 int close_modifier
= 0;
18756 int present_modifier
= 0;
18757 for (int pos
= 1; pos
< map_kind_pos
; ++pos
)
18759 c_token
*tok
= c_parser_peek_token (parser
);
18761 if (tok
->type
== CPP_COMMA
)
18763 c_parser_consume_token (parser
);
18767 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18768 if (strcmp ("always", p
) == 0)
18770 if (always_modifier
)
18772 c_parser_error (parser
, "too many %<always%> modifiers");
18773 parens
.skip_until_found_close (parser
);
18778 else if (strcmp ("close", p
) == 0)
18780 if (close_modifier
)
18782 c_parser_error (parser
, "too many %<close%> modifiers");
18783 parens
.skip_until_found_close (parser
);
18788 else if (strcmp ("present", p
) == 0)
18790 if (present_modifier
)
18792 c_parser_error (parser
, "too many %<present%> modifiers");
18793 parens
.skip_until_found_close (parser
);
18796 present_modifier
++;
18800 c_parser_error (parser
, "%<map%> clause with map-type modifier other "
18801 "than %<always%>, %<close%> or %<present%>");
18802 parens
.skip_until_found_close (parser
);
18806 c_parser_consume_token (parser
);
18809 if (c_parser_next_token_is (parser
, CPP_NAME
)
18810 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
18812 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18813 int always_present_modifier
= always_modifier
&& present_modifier
;
18815 if (strcmp ("alloc", p
) == 0)
18816 kind
= present_modifier
? GOMP_MAP_PRESENT_ALLOC
: GOMP_MAP_ALLOC
;
18817 else if (strcmp ("to", p
) == 0)
18818 kind
= (always_present_modifier
? GOMP_MAP_ALWAYS_PRESENT_TO
18819 : present_modifier
? GOMP_MAP_PRESENT_TO
18820 : always_modifier
? GOMP_MAP_ALWAYS_TO
18822 else if (strcmp ("from", p
) == 0)
18823 kind
= (always_present_modifier
? GOMP_MAP_ALWAYS_PRESENT_FROM
18824 : present_modifier
? GOMP_MAP_PRESENT_FROM
18825 : always_modifier
? GOMP_MAP_ALWAYS_FROM
18827 else if (strcmp ("tofrom", p
) == 0)
18828 kind
= (always_present_modifier
? GOMP_MAP_ALWAYS_PRESENT_TOFROM
18829 : present_modifier
? GOMP_MAP_PRESENT_TOFROM
18830 : always_modifier
? GOMP_MAP_ALWAYS_TOFROM
18831 : GOMP_MAP_TOFROM
);
18832 else if (strcmp ("release", p
) == 0)
18833 kind
= GOMP_MAP_RELEASE
;
18834 else if (strcmp ("delete", p
) == 0)
18835 kind
= GOMP_MAP_DELETE
;
18838 c_parser_error (parser
, "invalid map kind");
18839 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
18843 c_parser_consume_token (parser
);
18844 c_parser_consume_token (parser
);
18847 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
,
18850 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
18851 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
18853 parens
.skip_until_found_close (parser
);
18858 device ( expression )
18861 device ( [device-modifier :] integer-expression )
18864 ancestor | device_num */
18867 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
18869 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
18870 location_t expr_loc
;
18873 bool ancestor
= false;
18875 matching_parens parens
;
18876 if (!parens
.require_open (parser
))
18879 if (c_parser_next_token_is (parser
, CPP_NAME
)
18880 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
18882 c_token
*tok
= c_parser_peek_token (parser
);
18883 const char *p
= IDENTIFIER_POINTER (tok
->value
);
18884 if (strcmp ("ancestor", p
) == 0)
18886 /* A requires directive with the reverse_offload clause must be
18888 if ((omp_requires_mask
& OMP_REQUIRES_REVERSE_OFFLOAD
) == 0)
18890 error_at (tok
->location
, "%<ancestor%> device modifier not "
18891 "preceded by %<requires%> directive "
18892 "with %<reverse_offload%> clause");
18893 parens
.skip_until_found_close (parser
);
18898 else if (strcmp ("device_num", p
) == 0)
18902 error_at (tok
->location
, "expected %<ancestor%> or %<device_num%>");
18903 parens
.skip_until_found_close (parser
);
18906 c_parser_consume_token (parser
);
18907 c_parser_consume_token (parser
);
18910 expr_loc
= c_parser_peek_token (parser
)->location
;
18911 expr
= c_parser_expr_no_commas (parser
, NULL
);
18912 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18914 t
= c_fully_fold (t
, false, NULL
);
18916 parens
.skip_until_found_close (parser
);
18918 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
18920 c_parser_error (parser
, "expected integer expression");
18923 if (ancestor
&& TREE_CODE (t
) == INTEGER_CST
&& !integer_onep (t
))
18925 error_at (expr_loc
, "the %<device%> clause expression must evaluate to "
18930 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
18932 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
18934 OMP_CLAUSE_DEVICE_ID (c
) = t
;
18935 OMP_CLAUSE_CHAIN (c
) = list
;
18936 OMP_CLAUSE_DEVICE_ANCESTOR (c
) = ancestor
;
18943 dist_schedule ( static )
18944 dist_schedule ( static , expression ) */
18947 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
18949 tree c
, t
= NULL_TREE
;
18950 location_t loc
= c_parser_peek_token (parser
)->location
;
18952 matching_parens parens
;
18953 if (!parens
.require_open (parser
))
18956 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
18958 c_parser_error (parser
, "invalid dist_schedule kind");
18959 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
18964 c_parser_consume_token (parser
);
18965 if (c_parser_next_token_is (parser
, CPP_COMMA
))
18967 c_parser_consume_token (parser
);
18969 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18970 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18971 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18973 t
= c_fully_fold (t
, false, NULL
);
18974 parens
.skip_until_found_close (parser
);
18977 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
18978 "expected %<,%> or %<)%>");
18980 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
18981 "dist_schedule"); */
18982 if (omp_find_clause (list
, OMP_CLAUSE_DIST_SCHEDULE
))
18983 warning_at (loc
, OPT_Wopenmp
, "too many %qs clauses", "dist_schedule");
18984 if (t
== error_mark_node
)
18987 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
18988 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
18989 OMP_CLAUSE_CHAIN (c
) = list
;
18994 proc_bind ( proc-bind-kind )
18997 primary | master | close | spread
18998 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
19001 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
19003 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
19004 enum omp_clause_proc_bind_kind kind
;
19007 matching_parens parens
;
19008 if (!parens
.require_open (parser
))
19011 if (c_parser_next_token_is (parser
, CPP_NAME
))
19013 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19014 if (strcmp ("primary", p
) == 0)
19015 kind
= OMP_CLAUSE_PROC_BIND_PRIMARY
;
19016 else if (strcmp ("master", p
) == 0)
19017 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
19018 else if (strcmp ("close", p
) == 0)
19019 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
19020 else if (strcmp ("spread", p
) == 0)
19021 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
19028 check_no_duplicate_clause (list
, OMP_CLAUSE_PROC_BIND
, "proc_bind");
19029 c_parser_consume_token (parser
);
19030 parens
.skip_until_found_close (parser
);
19031 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
19032 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
19033 OMP_CLAUSE_CHAIN (c
) = list
;
19037 c_parser_error (parser
, "invalid proc_bind kind");
19038 parens
.skip_until_found_close (parser
);
19043 device_type ( host | nohost | any ) */
19046 c_parser_omp_clause_device_type (c_parser
*parser
, tree list
)
19048 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
19049 enum omp_clause_device_type_kind kind
;
19052 matching_parens parens
;
19053 if (!parens
.require_open (parser
))
19056 if (c_parser_next_token_is (parser
, CPP_NAME
))
19058 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19059 if (strcmp ("host", p
) == 0)
19060 kind
= OMP_CLAUSE_DEVICE_TYPE_HOST
;
19061 else if (strcmp ("nohost", p
) == 0)
19062 kind
= OMP_CLAUSE_DEVICE_TYPE_NOHOST
;
19063 else if (strcmp ("any", p
) == 0)
19064 kind
= OMP_CLAUSE_DEVICE_TYPE_ANY
;
19071 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE_TYPE
,
19073 c_parser_consume_token (parser
);
19074 parens
.skip_until_found_close (parser
);
19075 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE_TYPE
);
19076 OMP_CLAUSE_DEVICE_TYPE_KIND (c
) = kind
;
19077 OMP_CLAUSE_CHAIN (c
) = list
;
19081 c_parser_error (parser
, "expected %<host%>, %<nohost%> or %<any%>");
19082 parens
.skip_until_found_close (parser
);
19087 from ( variable-list )
19088 to ( variable-list )
19091 from ( [present :] variable-list )
19092 to ( [present :] variable-list ) */
19095 c_parser_omp_clause_from_to (c_parser
*parser
, enum omp_clause_code kind
,
19098 location_t loc
= c_parser_peek_token (parser
)->location
;
19099 matching_parens parens
;
19100 if (!parens
.require_open (parser
))
19103 bool present
= false;
19104 c_token
*token
= c_parser_peek_token (parser
);
19106 if (token
->type
== CPP_NAME
19107 && strcmp (IDENTIFIER_POINTER (token
->value
), "present") == 0
19108 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
19111 c_parser_consume_token (parser
);
19112 c_parser_consume_token (parser
);
19115 tree nl
= c_parser_omp_variable_list (parser
, loc
, kind
, list
);
19116 parens
.skip_until_found_close (parser
);
19119 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
19120 OMP_CLAUSE_MOTION_PRESENT (c
) = 1;
19126 uniform ( variable-list ) */
19129 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
19131 /* The clauses location. */
19132 location_t loc
= c_parser_peek_token (parser
)->location
;
19134 matching_parens parens
;
19135 if (parens
.require_open (parser
))
19137 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
19139 parens
.skip_until_found_close (parser
);
19145 detach ( event-handle ) */
19148 c_parser_omp_clause_detach (c_parser
*parser
, tree list
)
19150 matching_parens parens
;
19151 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
19153 if (!parens
.require_open (parser
))
19156 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
19157 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
19159 c_parser_error (parser
, "expected identifier");
19160 parens
.skip_until_found_close (parser
);
19164 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
19165 if (t
== NULL_TREE
)
19167 undeclared_variable (c_parser_peek_token (parser
)->location
,
19168 c_parser_peek_token (parser
)->value
);
19169 parens
.skip_until_found_close (parser
);
19172 c_parser_consume_token (parser
);
19174 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (t
));
19175 if (!INTEGRAL_TYPE_P (type
)
19176 || TREE_CODE (type
) != ENUMERAL_TYPE
19177 || TYPE_NAME (type
) != get_identifier ("omp_event_handle_t"))
19179 error_at (clause_loc
, "%<detach%> clause event handle "
19180 "has type %qT rather than "
19181 "%<omp_event_handle_t%>",
19183 parens
.skip_until_found_close (parser
);
19187 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DETACH
);
19188 OMP_CLAUSE_DECL (u
) = t
;
19189 OMP_CLAUSE_CHAIN (u
) = list
;
19190 parens
.skip_until_found_close (parser
);
19194 /* Parse all OpenACC clauses. The set clauses allowed by the directive
19195 is a bitmask in MASK. Return the list of clauses found. */
19198 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
19199 const char *where
, bool finish_p
= true,
19200 bool target_p
= false)
19202 tree clauses
= NULL
;
19205 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19208 pragma_omp_clause c_kind
;
19209 const char *c_name
;
19210 tree prev
= clauses
;
19212 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
19213 c_parser_consume_token (parser
);
19215 here
= c_parser_peek_token (parser
)->location
;
19216 c_kind
= c_parser_omp_clause_name (parser
);
19220 case PRAGMA_OACC_CLAUSE_ASYNC
:
19221 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
19224 case PRAGMA_OACC_CLAUSE_AUTO
:
19225 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_AUTO
,
19229 case PRAGMA_OACC_CLAUSE_ATTACH
:
19230 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19233 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
19234 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
19235 c_name
= "collapse";
19237 case PRAGMA_OACC_CLAUSE_COPY
:
19238 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19241 case PRAGMA_OACC_CLAUSE_COPYIN
:
19242 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19245 case PRAGMA_OACC_CLAUSE_COPYOUT
:
19246 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19247 c_name
= "copyout";
19249 case PRAGMA_OACC_CLAUSE_CREATE
:
19250 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19253 case PRAGMA_OACC_CLAUSE_DELETE
:
19254 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19257 case PRAGMA_OMP_CLAUSE_DEFAULT
:
19258 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
19259 c_name
= "default";
19261 case PRAGMA_OACC_CLAUSE_DETACH
:
19262 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19265 case PRAGMA_OACC_CLAUSE_DEVICE
:
19266 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19269 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
19270 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
19271 c_name
= "deviceptr";
19273 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
19274 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19275 c_name
= "device_resident";
19277 case PRAGMA_OACC_CLAUSE_FINALIZE
:
19278 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_FINALIZE
,
19280 c_name
= "finalize";
19282 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
19283 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
19284 c_name
= "firstprivate";
19286 case PRAGMA_OACC_CLAUSE_GANG
:
19288 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_GANG
,
19291 case PRAGMA_OACC_CLAUSE_HOST
:
19292 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19295 case PRAGMA_OACC_CLAUSE_IF
:
19296 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
19299 case PRAGMA_OACC_CLAUSE_IF_PRESENT
:
19300 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_IF_PRESENT
,
19302 c_name
= "if_present";
19304 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
19305 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_INDEPENDENT
,
19307 c_name
= "independent";
19309 case PRAGMA_OACC_CLAUSE_LINK
:
19310 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19313 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
19314 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19315 c_name
= "no_create";
19317 case PRAGMA_OACC_CLAUSE_NOHOST
:
19318 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_NOHOST
,
19322 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
19323 clauses
= c_parser_oacc_single_int_clause (parser
,
19324 OMP_CLAUSE_NUM_GANGS
,
19326 c_name
= "num_gangs";
19328 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
19329 clauses
= c_parser_oacc_single_int_clause (parser
,
19330 OMP_CLAUSE_NUM_WORKERS
,
19332 c_name
= "num_workers";
19334 case PRAGMA_OACC_CLAUSE_PRESENT
:
19335 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19336 c_name
= "present";
19338 case PRAGMA_OACC_CLAUSE_PRIVATE
:
19339 clauses
= c_parser_omp_clause_private (parser
, clauses
);
19340 c_name
= "private";
19342 case PRAGMA_OACC_CLAUSE_REDUCTION
:
19344 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
19346 c_name
= "reduction";
19348 case PRAGMA_OACC_CLAUSE_SELF
:
19349 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OACC_CLAUSE_HOST
)) == 0)
19350 /* OpenACC compute construct */
19351 clauses
= c_parser_oacc_compute_clause_self (parser
, clauses
);
19353 /* OpenACC 'update' directive */
19354 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
19357 case PRAGMA_OACC_CLAUSE_SEQ
:
19358 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_SEQ
,
19362 case PRAGMA_OACC_CLAUSE_TILE
:
19363 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
19366 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
19367 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
19368 c_name
= "use_device";
19370 case PRAGMA_OACC_CLAUSE_VECTOR
:
19372 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_VECTOR
,
19375 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
19376 clauses
= c_parser_oacc_single_int_clause (parser
,
19377 OMP_CLAUSE_VECTOR_LENGTH
,
19379 c_name
= "vector_length";
19381 case PRAGMA_OACC_CLAUSE_WAIT
:
19382 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
19385 case PRAGMA_OACC_CLAUSE_WORKER
:
19387 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_WORKER
,
19391 c_parser_error (parser
, "expected an OpenACC clause");
19397 if (((mask
>> c_kind
) & 1) == 0)
19399 /* Remove the invalid clause(s) from the list to avoid
19400 confusing the rest of the compiler. */
19402 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
19407 c_parser_skip_to_pragma_eol (parser
);
19410 return c_finish_omp_clauses (clauses
, target_p
? C_ORT_ACC_TARGET
19416 /* Parse all OpenMP clauses. The set clauses allowed by the directive
19417 is a bitmask in MASK. Return the list of clauses found.
19418 FINISH_P set if c_finish_omp_clauses should be called.
19419 NESTED non-zero if clauses should be terminated by closing paren instead
19420 of end of pragma. If it is 2, additionally commas are required in between
19424 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
19425 const char *where
, bool finish_p
= true,
19428 tree clauses
= NULL
;
19431 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19434 pragma_omp_clause c_kind
;
19435 const char *c_name
;
19436 tree prev
= clauses
;
19438 if (nested
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
19441 if (!first
|| nested
!= 2)
19443 if (c_parser_next_token_is (parser
, CPP_COMMA
))
19444 c_parser_consume_token (parser
);
19445 else if (nested
== 2)
19446 error_at (c_parser_peek_token (parser
)->location
,
19447 "clauses in %<simd%> trait should be separated "
19451 here
= c_parser_peek_token (parser
)->location
;
19452 c_kind
= c_parser_omp_clause_name (parser
);
19456 case PRAGMA_OMP_CLAUSE_BIND
:
19457 clauses
= c_parser_omp_clause_bind (parser
, clauses
);
19460 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
19461 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
19462 c_name
= "collapse";
19464 case PRAGMA_OMP_CLAUSE_COPYIN
:
19465 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
19468 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
19469 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
19470 c_name
= "copyprivate";
19472 case PRAGMA_OMP_CLAUSE_DEFAULT
:
19473 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
19474 c_name
= "default";
19476 case PRAGMA_OMP_CLAUSE_DETACH
:
19477 clauses
= c_parser_omp_clause_detach (parser
, clauses
);
19480 case PRAGMA_OMP_CLAUSE_FILTER
:
19481 clauses
= c_parser_omp_clause_filter (parser
, clauses
);
19484 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
19485 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
19486 c_name
= "firstprivate";
19488 case PRAGMA_OMP_CLAUSE_FINAL
:
19489 clauses
= c_parser_omp_clause_final (parser
, clauses
);
19492 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
19493 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
19494 c_name
= "grainsize";
19496 case PRAGMA_OMP_CLAUSE_HINT
:
19497 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
19500 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
19501 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
19502 c_name
= "defaultmap";
19504 case PRAGMA_OMP_CLAUSE_IF
:
19505 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
19508 case PRAGMA_OMP_CLAUSE_IN_REDUCTION
:
19510 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_IN_REDUCTION
,
19512 c_name
= "in_reduction";
19514 case PRAGMA_OMP_CLAUSE_INDIRECT
:
19515 clauses
= c_parser_omp_clause_indirect (parser
, clauses
);
19516 c_name
= "indirect";
19518 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
19519 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
19520 c_name
= "lastprivate";
19522 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
19523 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
19524 c_name
= "mergeable";
19526 case PRAGMA_OMP_CLAUSE_NOWAIT
:
19527 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
19530 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
19531 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
19532 c_name
= "num_tasks";
19534 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
19535 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
19536 c_name
= "num_threads";
19538 case PRAGMA_OMP_CLAUSE_ORDER
:
19539 clauses
= c_parser_omp_clause_order (parser
, clauses
);
19542 case PRAGMA_OMP_CLAUSE_ORDERED
:
19543 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
19544 c_name
= "ordered";
19546 case PRAGMA_OMP_CLAUSE_PRIORITY
:
19547 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
19548 c_name
= "priority";
19550 case PRAGMA_OMP_CLAUSE_PRIVATE
:
19551 clauses
= c_parser_omp_clause_private (parser
, clauses
);
19552 c_name
= "private";
19554 case PRAGMA_OMP_CLAUSE_REDUCTION
:
19556 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
19558 c_name
= "reduction";
19560 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
19561 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
19562 c_name
= "schedule";
19564 case PRAGMA_OMP_CLAUSE_SHARED
:
19565 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
19568 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION
:
19570 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_TASK_REDUCTION
,
19572 c_name
= "task_reduction";
19574 case PRAGMA_OMP_CLAUSE_UNTIED
:
19575 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
19578 case PRAGMA_OMP_CLAUSE_INBRANCH
:
19579 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
19581 c_name
= "inbranch";
19583 case PRAGMA_OMP_CLAUSE_NONTEMPORAL
:
19584 clauses
= c_parser_omp_clause_nontemporal (parser
, clauses
);
19585 c_name
= "nontemporal";
19587 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
19588 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
19590 c_name
= "notinbranch";
19592 case PRAGMA_OMP_CLAUSE_PARALLEL
:
19594 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
19596 c_name
= "parallel";
19600 error_at (here
, "%qs must be the first clause of %qs",
19605 case PRAGMA_OMP_CLAUSE_FOR
:
19607 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
19611 goto clause_not_first
;
19613 case PRAGMA_OMP_CLAUSE_SECTIONS
:
19615 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
19617 c_name
= "sections";
19619 goto clause_not_first
;
19621 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
19623 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
19625 c_name
= "taskgroup";
19627 goto clause_not_first
;
19629 case PRAGMA_OMP_CLAUSE_LINK
:
19631 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
19634 case PRAGMA_OMP_CLAUSE_TO
:
19635 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
19637 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
19639 for (tree c
= nl
; c
!= clauses
; c
= OMP_CLAUSE_CHAIN (c
))
19640 OMP_CLAUSE_ENTER_TO (c
) = 1;
19644 clauses
= c_parser_omp_clause_from_to (parser
, OMP_CLAUSE_TO
,
19648 case PRAGMA_OMP_CLAUSE_FROM
:
19649 clauses
= c_parser_omp_clause_from_to (parser
, OMP_CLAUSE_FROM
,
19653 case PRAGMA_OMP_CLAUSE_UNIFORM
:
19654 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
19655 c_name
= "uniform";
19657 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
19658 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
19659 c_name
= "num_teams";
19661 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
19662 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
19663 c_name
= "thread_limit";
19665 case PRAGMA_OMP_CLAUSE_ALIGNED
:
19666 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
19667 c_name
= "aligned";
19669 case PRAGMA_OMP_CLAUSE_ALLOCATE
:
19670 clauses
= c_parser_omp_clause_allocate (parser
, clauses
);
19671 c_name
= "allocate";
19673 case PRAGMA_OMP_CLAUSE_LINEAR
:
19674 clauses
= c_parser_omp_clause_linear (parser
, clauses
);
19677 case PRAGMA_OMP_CLAUSE_AFFINITY
:
19678 clauses
= c_parser_omp_clause_affinity (parser
, clauses
);
19679 c_name
= "affinity";
19681 case PRAGMA_OMP_CLAUSE_DEPEND
:
19682 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
19685 case PRAGMA_OMP_CLAUSE_DOACROSS
:
19686 clauses
= c_parser_omp_clause_doacross (parser
, clauses
);
19687 c_name
= "doacross";
19689 case PRAGMA_OMP_CLAUSE_MAP
:
19690 clauses
= c_parser_omp_clause_map (parser
, clauses
);
19693 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
19694 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
19695 c_name
= "use_device_ptr";
19697 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
:
19698 clauses
= c_parser_omp_clause_use_device_addr (parser
, clauses
);
19699 c_name
= "use_device_addr";
19701 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
:
19702 clauses
= c_parser_omp_clause_has_device_addr (parser
, clauses
);
19703 c_name
= "has_device_addr";
19705 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
19706 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
19707 c_name
= "is_device_ptr";
19709 case PRAGMA_OMP_CLAUSE_DEVICE
:
19710 clauses
= c_parser_omp_clause_device (parser
, clauses
);
19713 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
19714 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
19715 c_name
= "dist_schedule";
19717 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
19718 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
19719 c_name
= "proc_bind";
19721 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE
:
19722 clauses
= c_parser_omp_clause_device_type (parser
, clauses
);
19723 c_name
= "device_type";
19725 case PRAGMA_OMP_CLAUSE_SAFELEN
:
19726 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
19727 c_name
= "safelen";
19729 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
19730 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
19731 c_name
= "simdlen";
19733 case PRAGMA_OMP_CLAUSE_NOGROUP
:
19734 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
19735 c_name
= "nogroup";
19737 case PRAGMA_OMP_CLAUSE_THREADS
:
19739 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
19741 c_name
= "threads";
19743 case PRAGMA_OMP_CLAUSE_SIMD
:
19745 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
19749 case PRAGMA_OMP_CLAUSE_ENTER
:
19751 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
19756 c_parser_error (parser
, "expected an OpenMP clause");
19762 if (((mask
>> c_kind
) & 1) == 0)
19764 /* Remove the invalid clause(s) from the list to avoid
19765 confusing the rest of the compiler. */
19767 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
19773 c_parser_skip_to_pragma_eol (parser
);
19777 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
19778 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
19779 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
19785 /* OpenACC 2.0, OpenMP 2.5:
19789 In practice, we're also interested in adding the statement to an
19790 outer node. So it is convenient if we work around the fact that
19791 c_parser_statement calls add_stmt. */
19794 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
19796 tree stmt
= push_stmt_list ();
19797 parser
->omp_attrs_forbidden_p
= true;
19798 c_parser_statement (parser
, if_p
);
19799 return pop_stmt_list (stmt
);
19803 # pragma acc cache (variable-list) new-line
19805 LOC is the location of the #pragma token.
19809 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
19811 tree stmt
, clauses
;
19813 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE__CACHE_
, NULL
);
19814 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
19816 c_parser_skip_to_pragma_eol (parser
);
19818 stmt
= make_node (OACC_CACHE
);
19819 TREE_TYPE (stmt
) = void_type_node
;
19820 OACC_CACHE_CLAUSES (stmt
) = clauses
;
19821 SET_EXPR_LOCATION (stmt
, loc
);
19828 # pragma acc data oacc-data-clause[optseq] new-line
19831 LOC is the location of the #pragma token.
19834 #define OACC_DATA_CLAUSE_MASK \
19835 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
19836 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19837 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19838 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19839 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19840 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
19841 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19842 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
19843 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
19844 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
19847 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
19849 tree stmt
, clauses
, block
;
19851 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
19852 "#pragma acc data");
19854 block
= c_begin_omp_parallel ();
19855 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
19857 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
19863 # pragma acc declare oacc-data-clause[optseq] new-line
19866 #define OACC_DECLARE_CLAUSE_MASK \
19867 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
19868 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
19869 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
19870 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
19871 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
19872 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
19873 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
19874 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
19877 c_parser_oacc_declare (c_parser
*parser
)
19879 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
19880 tree clauses
, stmt
, t
, decl
;
19882 bool error
= false;
19884 c_parser_consume_pragma (parser
);
19886 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
19887 "#pragma acc declare");
19890 error_at (pragma_loc
,
19891 "no valid clauses specified in %<#pragma acc declare%>");
19895 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
19897 location_t loc
= OMP_CLAUSE_LOCATION (t
);
19898 decl
= OMP_CLAUSE_DECL (t
);
19899 if (!DECL_P (decl
))
19901 error_at (loc
, "array section in %<#pragma acc declare%>");
19906 switch (OMP_CLAUSE_MAP_KIND (t
))
19908 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
19909 case GOMP_MAP_ALLOC
:
19911 case GOMP_MAP_FORCE_DEVICEPTR
:
19912 case GOMP_MAP_DEVICE_RESIDENT
:
19915 case GOMP_MAP_LINK
:
19916 if (!global_bindings_p ()
19917 && (TREE_STATIC (decl
)
19918 || !DECL_EXTERNAL (decl
)))
19921 "%qD must be a global variable in "
19922 "%<#pragma acc declare link%>",
19930 if (global_bindings_p ())
19932 error_at (loc
, "invalid OpenACC clause at file scope");
19936 if (DECL_EXTERNAL (decl
))
19939 "invalid use of %<extern%> variable %qD "
19940 "in %<#pragma acc declare%>", decl
);
19944 else if (TREE_PUBLIC (decl
))
19947 "invalid use of %<global%> variable %qD "
19948 "in %<#pragma acc declare%>", decl
);
19955 if (!c_check_in_current_scope (decl
))
19958 "%qD must be a variable declared in the same scope as "
19959 "%<#pragma acc declare%>", decl
);
19964 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
19965 || lookup_attribute ("omp declare target link",
19966 DECL_ATTRIBUTES (decl
)))
19968 error_at (loc
, "variable %qD used more than once with "
19969 "%<#pragma acc declare%>", decl
);
19978 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
19979 id
= get_identifier ("omp declare target link");
19981 id
= get_identifier ("omp declare target");
19983 DECL_ATTRIBUTES (decl
)
19984 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
19986 if (global_bindings_p ())
19988 symtab_node
*node
= symtab_node::get (decl
);
19991 node
->offloadable
= 1;
19992 if (ENABLE_OFFLOADING
)
19994 g
->have_offload
= true;
19995 if (is_a
<varpool_node
*> (node
))
19996 vec_safe_push (offload_vars
, decl
);
20003 if (error
|| global_bindings_p ())
20006 stmt
= make_node (OACC_DECLARE
);
20007 TREE_TYPE (stmt
) = void_type_node
;
20008 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
20009 SET_EXPR_LOCATION (stmt
, pragma_loc
);
20017 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
20021 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
20024 LOC is the location of the #pragma token.
20027 #define OACC_ENTER_DATA_CLAUSE_MASK \
20028 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20029 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20030 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20031 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20032 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20033 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20035 #define OACC_EXIT_DATA_CLAUSE_MASK \
20036 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20037 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20038 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20039 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
20040 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
20041 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
20042 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20045 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
20047 location_t loc
= c_parser_peek_token (parser
)->location
;
20048 tree clauses
, stmt
;
20049 const char *p
= "";
20051 c_parser_consume_pragma (parser
);
20053 if (c_parser_next_token_is (parser
, CPP_NAME
))
20055 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20056 c_parser_consume_token (parser
);
20059 if (strcmp (p
, "data") != 0)
20061 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
20062 enter
? "enter" : "exit");
20063 parser
->error
= true;
20064 c_parser_skip_to_pragma_eol (parser
);
20069 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
20070 "#pragma acc enter data");
20072 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
20073 "#pragma acc exit data");
20075 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
20077 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
20078 enter
? "enter" : "exit");
20082 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
20083 TREE_TYPE (stmt
) = void_type_node
;
20084 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
20085 SET_EXPR_LOCATION (stmt
, loc
);
20091 # pragma acc host_data oacc-data-clause[optseq] new-line
20095 #define OACC_HOST_DATA_CLAUSE_MASK \
20096 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
20097 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20098 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
20101 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
20103 tree stmt
, clauses
, block
;
20105 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
20106 "#pragma acc host_data", false);
20107 if (!omp_find_clause (clauses
, OMP_CLAUSE_USE_DEVICE_PTR
))
20109 error_at (loc
, "%<host_data%> construct requires %<use_device%> clause");
20110 return error_mark_node
;
20112 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
20113 block
= c_begin_omp_parallel ();
20114 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
20115 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
20122 # pragma acc loop oacc-loop-clause[optseq] new-line
20125 LOC is the location of the #pragma token.
20128 #define OACC_LOOP_CLAUSE_MASK \
20129 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
20130 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20131 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20132 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
20133 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
20134 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
20135 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
20136 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
20137 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
20138 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
20140 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
20141 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
20143 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
20145 strcat (p_name
, " loop");
20146 mask
|= OACC_LOOP_CLAUSE_MASK
;
20148 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
20149 /*finish_p=*/cclauses
== NULL
,
20150 /*target=*/is_parallel
);
20153 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
20155 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC_TARGET
);
20157 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
20160 tree block
= c_begin_compound_stmt (true);
20161 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
20163 block
= c_end_compound_stmt (loc
, block
, true);
20170 # pragma acc kernels oacc-kernels-clause[optseq] new-line
20175 # pragma acc parallel oacc-parallel-clause[optseq] new-line
20180 # pragma acc serial oacc-serial-clause[optseq] new-line
20183 LOC is the location of the #pragma token.
20186 #define OACC_KERNELS_CLAUSE_MASK \
20187 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20188 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20189 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20190 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20191 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20192 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20193 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20194 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20195 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20196 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20197 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
20198 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
20199 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20200 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20201 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
20202 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20204 #define OACC_PARALLEL_CLAUSE_MASK \
20205 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20206 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20207 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20208 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20209 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20210 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20211 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20212 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20213 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20214 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20215 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20216 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
20217 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
20218 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
20219 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20220 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20221 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20222 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
20223 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20225 #define OACC_SERIAL_CLAUSE_MASK \
20226 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20227 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
20228 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
20229 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
20230 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
20231 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
20232 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
20233 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
20234 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20235 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
20236 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
20237 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
20238 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
20239 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
20240 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20241 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20244 c_parser_oacc_compute (location_t loc
, c_parser
*parser
,
20245 enum pragma_kind p_kind
, char *p_name
, bool *if_p
)
20247 omp_clause_mask mask
;
20248 enum tree_code code
;
20251 case PRAGMA_OACC_KERNELS
:
20252 strcat (p_name
, " kernels");
20253 mask
= OACC_KERNELS_CLAUSE_MASK
;
20254 code
= OACC_KERNELS
;
20256 case PRAGMA_OACC_PARALLEL
:
20257 strcat (p_name
, " parallel");
20258 mask
= OACC_PARALLEL_CLAUSE_MASK
;
20259 code
= OACC_PARALLEL
;
20261 case PRAGMA_OACC_SERIAL
:
20262 strcat (p_name
, " serial");
20263 mask
= OACC_SERIAL_CLAUSE_MASK
;
20264 code
= OACC_SERIAL
;
20267 gcc_unreachable ();
20270 if (c_parser_next_token_is (parser
, CPP_NAME
))
20272 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20273 if (strcmp (p
, "loop") == 0)
20275 c_parser_consume_token (parser
);
20276 tree block
= c_begin_omp_parallel ();
20278 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
20279 return c_finish_omp_construct (loc
, code
, block
, clauses
);
20283 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
20287 tree block
= c_begin_omp_parallel ();
20288 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
20290 return c_finish_omp_construct (loc
, code
, block
, clauses
);
20294 # pragma acc routine oacc-routine-clause[optseq] new-line
20295 function-definition
20297 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
20300 #define OACC_ROUTINE_CLAUSE_MASK \
20301 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
20302 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
20303 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
20304 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
20305 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
20307 /* Parse an OpenACC routine directive. For named directives, we apply
20308 immediately to the named function. For unnamed ones we then parse
20309 a declaration or definition, which must be for a function. */
20312 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
20314 gcc_checking_assert (context
== pragma_external
);
20316 oacc_routine_data data
;
20317 data
.error_seen
= false;
20318 data
.fndecl_seen
= false;
20319 data
.loc
= c_parser_peek_token (parser
)->location
;
20321 c_parser_consume_pragma (parser
);
20323 /* Look for optional '( name )'. */
20324 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
20326 c_parser_consume_token (parser
); /* '(' */
20328 tree decl
= NULL_TREE
;
20329 c_token
*name_token
= c_parser_peek_token (parser
);
20330 location_t name_loc
= name_token
->location
;
20331 if (name_token
->type
== CPP_NAME
20332 && (name_token
->id_kind
== C_ID_ID
20333 || name_token
->id_kind
== C_ID_TYPENAME
))
20335 decl
= lookup_name (name_token
->value
);
20337 error_at (name_loc
,
20338 "%qE has not been declared", name_token
->value
);
20339 c_parser_consume_token (parser
);
20342 c_parser_error (parser
, "expected function name");
20345 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
20347 c_parser_skip_to_pragma_eol (parser
, false);
20352 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
20353 "#pragma acc routine");
20354 /* The clauses are in reverse order; fix that to make later diagnostic
20355 emission easier. */
20356 data
.clauses
= nreverse (data
.clauses
);
20358 if (TREE_CODE (decl
) != FUNCTION_DECL
)
20360 error_at (name_loc
, "%qD does not refer to a function", decl
);
20364 c_finish_oacc_routine (&data
, decl
, false);
20366 else /* No optional '( name )'. */
20369 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
20370 "#pragma acc routine");
20371 /* The clauses are in reverse order; fix that to make later diagnostic
20372 emission easier. */
20373 data
.clauses
= nreverse (data
.clauses
);
20375 /* Emit a helpful diagnostic if there's another pragma following this
20376 one. Also don't allow a static assertion declaration, as in the
20377 following we'll just parse a *single* "declaration or function
20378 definition", and the static assertion counts an one. */
20379 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
20380 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
20382 error_at (data
.loc
,
20383 "%<#pragma acc routine%> not immediately followed by"
20384 " function declaration or definition");
20385 /* ..., and then just keep going. */
20389 /* We only have to consider the pragma_external case here. */
20390 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20391 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
20393 int ext
= disable_extension_diagnostics ();
20395 c_parser_consume_token (parser
);
20396 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
20397 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
20398 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
20399 NULL
, NULL
, false, NULL
, &data
);
20400 restore_extension_diagnostics (ext
);
20403 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
20404 NULL
, NULL
, false, NULL
, &data
);
20408 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
20409 IS_DEFN is true if we're applying it to the definition. */
20412 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
20415 /* Keep going if we're in error reporting mode. */
20416 if (data
->error_seen
20417 || fndecl
== error_mark_node
)
20420 if (data
->fndecl_seen
)
20422 error_at (data
->loc
,
20423 "%<#pragma acc routine%> not immediately followed by"
20424 " a single function declaration or definition");
20425 data
->error_seen
= true;
20428 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
20430 error_at (data
->loc
,
20431 "%<#pragma acc routine%> not immediately followed by"
20432 " function declaration or definition");
20433 data
->error_seen
= true;
20438 = oacc_verify_routine_clauses (fndecl
, &data
->clauses
, data
->loc
,
20439 "#pragma acc routine");
20440 if (compatible
< 0)
20442 data
->error_seen
= true;
20445 if (compatible
> 0)
20450 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
20452 error_at (data
->loc
,
20454 ? G_("%<#pragma acc routine%> must be applied before use")
20455 : G_("%<#pragma acc routine%> must be applied before"
20457 data
->error_seen
= true;
20461 /* Set the routine's level of parallelism. */
20462 tree dims
= oacc_build_routine_dims (data
->clauses
);
20463 oacc_replace_fn_attrib (fndecl
, dims
);
20465 /* Add an "omp declare target" attribute. */
20466 DECL_ATTRIBUTES (fndecl
)
20467 = tree_cons (get_identifier ("omp declare target"),
20468 data
->clauses
, DECL_ATTRIBUTES (fndecl
));
20471 /* Remember that we've used this "#pragma acc routine". */
20472 data
->fndecl_seen
= true;
20476 # pragma acc update oacc-update-clause[optseq] new-line
20479 #define OACC_UPDATE_CLAUSE_MASK \
20480 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
20481 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
20482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
20483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
20484 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
20485 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
20486 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
20489 c_parser_oacc_update (c_parser
*parser
)
20491 location_t loc
= c_parser_peek_token (parser
)->location
;
20493 c_parser_consume_pragma (parser
);
20495 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
20496 "#pragma acc update");
20497 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
20500 "%<#pragma acc update%> must contain at least one "
20501 "%<device%> or %<host%> or %<self%> clause");
20508 tree stmt
= make_node (OACC_UPDATE
);
20509 TREE_TYPE (stmt
) = void_type_node
;
20510 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
20511 SET_EXPR_LOCATION (stmt
, loc
);
20516 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
20518 LOC is the location of the #pragma token.
20521 #define OACC_WAIT_CLAUSE_MASK \
20522 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
20525 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
20527 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
20529 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
20530 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
20532 strcpy (p_name
, " wait");
20533 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
20534 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
20540 struct c_omp_loc_tree
20546 /* Check whether the expression used in the allocator clause is declared or
20547 modified between the variable declaration and its allocate directive. */
20549 c_check_omp_allocate_allocator_r (tree
*tp
, int *, void *data
)
20551 tree var
= ((struct c_omp_loc_tree
*) data
)->var
;
20552 location_t loc
= ((struct c_omp_loc_tree
*) data
)->loc
;
20553 if (TREE_CODE (*tp
) == VAR_DECL
&& c_check_in_current_scope (*tp
))
20555 if (linemap_location_before_p (line_table
, DECL_SOURCE_LOCATION (var
),
20556 DECL_SOURCE_LOCATION (*tp
)))
20558 error_at (loc
, "variable %qD used in the %<allocator%> clause must "
20559 "be declared before %qD", *tp
, var
);
20560 inform (DECL_SOURCE_LOCATION (*tp
), "declared here");
20561 inform (DECL_SOURCE_LOCATION (var
),
20562 "to be allocated variable declared here");
20567 gcc_assert (cur_stmt_list
20568 && TREE_CODE (cur_stmt_list
) == STATEMENT_LIST
);
20570 tree_stmt_iterator l
= tsi_last (cur_stmt_list
);
20571 while (!tsi_end_p (l
))
20573 if (linemap_location_before_p (line_table
, EXPR_LOCATION (*l
),
20574 DECL_SOURCE_LOCATION (var
)))
20576 if (TREE_CODE (*l
) == MODIFY_EXPR
20577 && TREE_OPERAND (*l
, 0) == *tp
)
20580 "variable %qD used in the %<allocator%> clause "
20581 "must not be modified between declaration of %qD "
20582 "and its %<allocate%> directive", *tp
, var
);
20583 inform (EXPR_LOCATION (*l
), "modified here");
20584 inform (DECL_SOURCE_LOCATION (var
),
20585 "to be allocated variable declared here");
20596 # pragma omp allocate (list) clauses
20599 allocator (omp_allocator_handle_t expression)
20601 OpenMP 5.1 additional clause:
20602 align (constant-expression)] */
20605 c_parser_omp_allocate (c_parser
*parser
)
20607 tree alignment
= NULL_TREE
;
20608 tree allocator
= NULL_TREE
;
20609 c_parser_consume_pragma (parser
);
20610 location_t loc
= c_parser_peek_token (parser
)->location
;
20611 location_t allocator_loc
= UNKNOWN_LOCATION
;
20612 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ALLOCATE
, NULL_TREE
);
20615 if (c_parser_next_token_is (parser
, CPP_COMMA
)
20616 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
20617 c_parser_consume_token (parser
);
20618 if (!c_parser_next_token_is (parser
, CPP_NAME
))
20620 matching_parens parens
;
20621 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20622 c_parser_consume_token (parser
);
20623 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
20624 if (strcmp ("align", p
) != 0 && strcmp ("allocator", p
) != 0)
20626 error_at (c_parser_peek_token (parser
)->location
,
20627 "expected %<allocator%> or %<align%>");
20630 if (!parens
.require_open (parser
))
20633 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
20634 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
20635 expr_loc
= c_parser_peek_token (parser
)->location
;
20636 if (expr
.value
== error_mark_node
)
20638 else if (p
[2] == 'i' && alignment
)
20640 error_at (expr_loc
, "too many %qs clauses", "align");
20643 else if (p
[2] == 'i')
20645 alignment
= c_fully_fold (expr
.value
, false, NULL
);
20646 if (TREE_CODE (alignment
) != INTEGER_CST
20647 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
20648 || tree_int_cst_sgn (alignment
) != 1
20649 || !integer_pow2p (alignment
))
20651 error_at (expr_loc
, "%<align%> clause argument needs to be "
20652 "positive constant power of two integer "
20654 alignment
= NULL_TREE
;
20657 else if (allocator
)
20659 error_at (expr_loc
, "too many %qs clauses", "allocator");
20664 allocator
= c_fully_fold (expr
.value
, false, NULL
);
20665 allocator_loc
= expr_loc
;
20667 = expr
.original_type
? expr
.original_type
: TREE_TYPE (allocator
);
20668 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
20669 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
20670 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
20671 || TYPE_NAME (orig_type
)
20672 != get_identifier ("omp_allocator_handle_t"))
20674 error_at (expr_loc
,
20675 "%<allocator%> clause allocator expression has type "
20676 "%qT rather than %<omp_allocator_handle_t%>",
20677 TREE_TYPE (allocator
));
20678 allocator
= NULL_TREE
;
20681 parens
.skip_until_found_close (parser
);
20683 c_parser_skip_to_pragma_eol (parser
);
20685 c_mark_decl_jump_unsafe_in_current_scope ();
20686 for (tree c
= nl
; c
!= NULL_TREE
; c
= OMP_CLAUSE_CHAIN (c
))
20688 tree var
= OMP_CLAUSE_DECL (c
);
20689 if (TREE_CODE (var
) == PARM_DECL
)
20691 error_at (OMP_CLAUSE_LOCATION (nl
),
20692 "function parameter %qD may not appear as list item in an "
20693 "%<allocate%> directive", var
);
20696 if (!c_check_in_current_scope (var
))
20698 error_at (OMP_CLAUSE_LOCATION (nl
),
20699 "%<allocate%> directive must be in the same scope as %qD",
20701 inform (DECL_SOURCE_LOCATION (var
), "declared here");
20704 if (lookup_attribute ("omp allocate", DECL_ATTRIBUTES (var
)))
20706 error_at (OMP_CLAUSE_LOCATION (nl
),
20707 "%qD already appeared as list item in an "
20708 "%<allocate%> directive", var
);
20711 if (TREE_STATIC (var
))
20713 if (allocator
== NULL_TREE
&& allocator_loc
== UNKNOWN_LOCATION
)
20714 error_at (loc
, "%<allocator%> clause required for "
20715 "static variable %qD", var
);
20717 && (wi::to_widest (allocator
) < 1
20718 || wi::to_widest (allocator
) > 8))
20719 /* 8 = largest predefined memory allocator. */
20720 error_at (allocator_loc
,
20721 "%<allocator%> clause requires a predefined allocator as "
20722 "%qD is static", var
);
20724 sorry_at (OMP_CLAUSE_LOCATION (nl
),
20725 "%<#pragma omp allocate%> for static variables like "
20726 "%qD not yet supported", var
);
20731 struct c_omp_loc_tree data
20732 = {EXPR_LOC_OR_LOC (allocator
, OMP_CLAUSE_LOCATION (nl
)), var
};
20733 walk_tree (&allocator
, c_check_omp_allocate_allocator_r
, &data
, NULL
);
20735 DECL_ATTRIBUTES (var
) = tree_cons (get_identifier ("omp allocate"),
20736 build_tree_list (allocator
, alignment
),
20737 DECL_ATTRIBUTES (var
));
20742 # pragma omp atomic new-line
20746 x binop= expr | x++ | ++x | x-- | --x
20748 +, *, -, /, &, ^, |, <<, >>
20750 where x is an lvalue expression with scalar type.
20753 # pragma omp atomic new-line
20756 # pragma omp atomic read new-line
20759 # pragma omp atomic write new-line
20762 # pragma omp atomic update new-line
20765 # pragma omp atomic capture new-line
20768 # pragma omp atomic capture new-line
20776 expression-stmt | x = x binop expr
20778 v = expression-stmt
20780 { v = x; update-stmt; } | { update-stmt; v = x; }
20784 expression-stmt | x = x binop expr | x = expr binop x
20788 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
20791 # pragma omp atomic compare new-line
20792 conditional-update-atomic
20794 # pragma omp atomic compare capture new-line
20795 conditional-update-capture-atomic
20797 conditional-update-atomic:
20798 cond-expr-stmt | cond-update-stmt
20800 x = expr ordop x ? expr : x;
20801 x = x ordop expr ? expr : x;
20802 x = x == e ? d : x;
20804 if (expr ordop x) { x = expr; }
20805 if (x ordop expr) { x = expr; }
20806 if (x == e) { x = d; }
20809 conditional-update-capture-atomic:
20811 { v = x; cond-expr-stmt }
20812 { cond-expr-stmt v = x; }
20813 { v = x; cond-update-stmt }
20814 { cond-update-stmt v = x; }
20815 if (x == e) { x = d; } else { v = x; }
20816 { r = x == e; if (r) { x = d; } }
20817 { r = x == e; if (r) { x = d; } else { v = x; } }
20819 where x, r and v are lvalue expressions with scalar type,
20820 expr, e and d are expressions with scalar type and e might be
20823 LOC is the location of the #pragma token. */
20826 c_parser_omp_atomic (location_t loc
, c_parser
*parser
, bool openacc
)
20828 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
, r
= NULL_TREE
;
20829 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
20830 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
20831 enum tree_code code
= ERROR_MARK
, opcode
= NOP_EXPR
;
20832 enum omp_memory_order memory_order
= OMP_MEMORY_ORDER_UNSPECIFIED
;
20833 struct c_expr expr
;
20835 bool structured_block
= false;
20836 bool swapped
= false;
20838 tree clauses
= NULL_TREE
;
20839 bool capture
= false;
20840 bool compare
= false;
20842 enum omp_memory_order fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
20843 bool no_semicolon
= false;
20844 bool extra_scope
= false;
20846 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
20848 if (c_parser_next_token_is (parser
, CPP_COMMA
)
20849 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
20850 c_parser_consume_token (parser
);
20852 if (c_parser_next_token_is (parser
, CPP_NAME
))
20855 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20856 location_t cloc
= c_parser_peek_token (parser
)->location
;
20857 enum tree_code new_code
= ERROR_MARK
;
20858 enum omp_memory_order new_memory_order
20859 = OMP_MEMORY_ORDER_UNSPECIFIED
;
20860 bool new_capture
= false;
20861 bool new_compare
= false;
20862 bool new_weak
= false;
20863 enum omp_memory_order new_fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
20865 if (!strcmp (p
, "read"))
20866 new_code
= OMP_ATOMIC_READ
;
20867 else if (!strcmp (p
, "write"))
20868 new_code
= NOP_EXPR
;
20869 else if (!strcmp (p
, "update"))
20870 new_code
= OMP_ATOMIC
;
20871 else if (openacc
&& !strcmp (p
, "capture"))
20872 new_code
= OMP_ATOMIC_CAPTURE_NEW
;
20876 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
20877 "or %<capture%> clause");
20879 else if (!strcmp (p
, "capture"))
20880 new_capture
= true;
20881 else if (!strcmp (p
, "compare"))
20882 new_compare
= true;
20883 else if (!strcmp (p
, "weak"))
20885 else if (!strcmp (p
, "fail"))
20887 matching_parens parens
;
20889 c_parser_consume_token (parser
);
20890 if (!parens
.require_open (parser
))
20893 if (c_parser_next_token_is (parser
, CPP_NAME
))
20896 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20898 if (!strcmp (q
, "seq_cst"))
20899 new_fail
= OMP_MEMORY_ORDER_SEQ_CST
;
20900 else if (!strcmp (q
, "acquire"))
20901 new_fail
= OMP_MEMORY_ORDER_ACQUIRE
;
20902 else if (!strcmp (q
, "relaxed"))
20903 new_fail
= OMP_MEMORY_ORDER_RELAXED
;
20906 if (new_fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
20908 c_parser_consume_token (parser
);
20909 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
20910 error_at (cloc
, "too many %qs clauses", "fail");
20915 c_parser_error (parser
, "expected %<seq_cst%>, %<acquire%> "
20917 parens
.skip_until_found_close (parser
);
20920 else if (!strcmp (p
, "seq_cst"))
20921 new_memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
20922 else if (!strcmp (p
, "acq_rel"))
20923 new_memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
20924 else if (!strcmp (p
, "release"))
20925 new_memory_order
= OMP_MEMORY_ORDER_RELEASE
;
20926 else if (!strcmp (p
, "acquire"))
20927 new_memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
20928 else if (!strcmp (p
, "relaxed"))
20929 new_memory_order
= OMP_MEMORY_ORDER_RELAXED
;
20930 else if (!strcmp (p
, "hint"))
20932 c_parser_consume_token (parser
);
20933 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
20939 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
20940 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
20941 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
20942 "%<relaxed%> or %<hint%> clause");
20946 if (new_code
!= ERROR_MARK
)
20948 /* OpenACC permits 'update capture'. */
20950 && code
== OMP_ATOMIC
20951 && new_code
== OMP_ATOMIC_CAPTURE_NEW
)
20953 else if (code
!= ERROR_MARK
)
20954 error_at (cloc
, "too many atomic clauses");
20958 else if (new_memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
20960 if (memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
20961 error_at (cloc
, "too many memory order clauses");
20963 memory_order
= new_memory_order
;
20965 else if (new_capture
)
20968 error_at (cloc
, "too many %qs clauses", "capture");
20972 else if (new_compare
)
20975 error_at (cloc
, "too many %qs clauses", "compare");
20982 error_at (cloc
, "too many %qs clauses", "weak");
20986 c_parser_consume_token (parser
);
20992 c_parser_skip_to_pragma_eol (parser
);
20994 if (code
== ERROR_MARK
)
20998 if (code
!= OMP_ATOMIC
)
20999 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
21000 "clauses", "capture");
21002 code
= OMP_ATOMIC_CAPTURE_NEW
;
21004 if (compare
&& code
!= OMP_ATOMIC
&& code
!= OMP_ATOMIC_CAPTURE_NEW
)
21006 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
21007 "clauses", "compare");
21010 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
&& !compare
)
21012 error_at (loc
, "%qs clause requires %qs clause", "fail", "compare");
21013 fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
21015 if (weak
&& !compare
)
21017 error_at (loc
, "%qs clause requires %qs clause", "weak", "compare");
21021 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
21022 else if (memory_order
== OMP_MEMORY_ORDER_UNSPECIFIED
)
21025 = (enum omp_requires
) (omp_requires_mask
21026 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
);
21027 switch ((enum omp_memory_order
)
21028 (omp_requires_mask
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
))
21030 case OMP_MEMORY_ORDER_UNSPECIFIED
:
21031 case OMP_MEMORY_ORDER_RELAXED
:
21032 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
21034 case OMP_MEMORY_ORDER_SEQ_CST
:
21035 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21037 case OMP_MEMORY_ORDER_ACQUIRE
:
21038 if (code
== NOP_EXPR
) /* atomic write */
21040 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
21041 "%<acquire%> clause implicitly provided by a "
21042 "%<requires%> directive");
21043 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21046 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
21048 case OMP_MEMORY_ORDER_RELEASE
:
21049 if (code
== OMP_ATOMIC_READ
)
21051 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
21052 "%<release%> clause implicitly provided by a "
21053 "%<requires%> directive");
21054 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21057 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
21059 case OMP_MEMORY_ORDER_ACQ_REL
:
21062 case OMP_ATOMIC_READ
:
21063 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
21065 case NOP_EXPR
: /* atomic write */
21066 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
21069 memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
21074 gcc_unreachable ();
21080 case OMP_ATOMIC_READ
:
21081 if (memory_order
== OMP_MEMORY_ORDER_RELEASE
)
21083 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
21084 "%<release%> clause");
21085 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21087 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
21088 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
21090 case NOP_EXPR
: /* atomic write */
21091 if (memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
21093 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
21094 "%<acquire%> clause");
21095 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
21097 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
21098 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
21103 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
21105 = (enum omp_memory_order
) (memory_order
21106 | (fail
<< OMP_FAIL_MEMORY_ORDER_SHIFT
));
21110 case OMP_ATOMIC_READ
:
21111 case NOP_EXPR
: /* atomic write */
21112 v
= c_parser_cast_expression (parser
, NULL
).value
;
21113 non_lvalue_p
= !lvalue_p (v
);
21114 v
= c_fully_fold (v
, false, NULL
, true);
21115 if (v
== error_mark_node
)
21118 v
= non_lvalue (v
);
21119 loc
= c_parser_peek_token (parser
)->location
;
21120 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21122 if (code
== NOP_EXPR
)
21124 lhs
= c_parser_expression (parser
).value
;
21125 lhs
= c_fully_fold (lhs
, false, NULL
);
21126 if (lhs
== error_mark_node
)
21131 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
21132 non_lvalue_p
= !lvalue_p (lhs
);
21133 lhs
= c_fully_fold (lhs
, false, NULL
, true);
21134 if (lhs
== error_mark_node
)
21137 lhs
= non_lvalue (lhs
);
21139 if (code
== NOP_EXPR
)
21141 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
21149 case OMP_ATOMIC_CAPTURE_NEW
:
21150 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
21152 c_parser_consume_token (parser
);
21153 structured_block
= true;
21156 && c_parser_next_token_is_keyword (parser
, RID_IF
))
21160 v
= c_parser_cast_expression (parser
, NULL
).value
;
21161 non_lvalue_p
= !lvalue_p (v
);
21162 v
= c_fully_fold (v
, false, NULL
, true);
21163 if (v
== error_mark_node
)
21166 v
= non_lvalue (v
);
21167 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21169 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
21171 eloc
= c_parser_peek_token (parser
)->location
;
21172 error_at (eloc
, "expected expression");
21181 /* For structured_block case we don't know yet whether
21182 old or new x should be captured. */
21184 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
21186 c_parser_consume_token (parser
);
21188 matching_parens parens
;
21189 if (!parens
.require_open (parser
))
21191 eloc
= c_parser_peek_token (parser
)->location
;
21195 cmp_expr
= c_parser_cast_expression (parser
, NULL
);
21196 cmp_expr
= default_function_array_conversion (eloc
, cmp_expr
);
21199 cmp_expr
= c_parser_binary_expression (parser
, NULL
, void_list_node
);
21200 parens
.skip_until_found_close (parser
);
21201 if (cmp_expr
.value
== error_mark_node
)
21205 if (!c_tree_equal (cmp_expr
.value
, unfolded_lhs
))
21207 cmp_expr
.value
= rhs1
;
21209 gcc_assert (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
);
21211 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
21213 else if (!structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
21215 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
21216 "expected %<==%> comparison in %<if%> condition");
21219 else if (TREE_CODE (cmp_expr
.value
) != GT_EXPR
21220 && TREE_CODE (cmp_expr
.value
) != LT_EXPR
)
21222 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
21223 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
21227 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
21230 extra_scope
= true;
21231 eloc
= c_parser_peek_token (parser
)->location
;
21232 expr
= c_parser_cast_expression (parser
, NULL
);
21234 expr
= default_function_array_conversion (eloc
, expr
);
21235 unfolded_lhs
= expr
.value
;
21236 lhs
= c_fully_fold (lhs
, false, NULL
, true);
21238 if (lhs
== error_mark_node
)
21240 if (!lvalue_p (unfolded_lhs
))
21241 lhs
= non_lvalue (lhs
);
21242 if (!c_parser_next_token_is (parser
, CPP_EQ
))
21244 c_parser_error (parser
, "expected %<=%>");
21247 c_parser_consume_token (parser
);
21248 eloc
= c_parser_peek_token (parser
)->location
;
21249 expr
= c_parser_expr_no_commas (parser
, NULL
);
21252 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
21255 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
21258 extra_scope
= false;
21259 no_semicolon
= true;
21261 if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), unfolded_lhs
))
21263 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
21265 opcode
= COND_EXPR
;
21266 rhs
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
21267 false, NULL
, true);
21268 rhs1
= c_fully_fold (rhs1
, false, NULL
, true);
21270 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), rhs1
))
21272 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
21273 ? MIN_EXPR
: MAX_EXPR
);
21274 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
21275 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 0),
21276 false, NULL
, true);
21281 else if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
21283 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), unfolded_lhs
)
21284 && c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), rhs1
))
21286 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
21287 ? MAX_EXPR
: MIN_EXPR
);
21288 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
21289 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
21290 false, NULL
, true);
21295 c_parser_error (parser
,
21296 "invalid form of %<#pragma omp atomic compare%>");
21300 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
21302 if (code
!= OMP_ATOMIC_CAPTURE_NEW
21303 || (structured_block
&& r
== NULL_TREE
)
21304 || TREE_CODE (cmp_expr
.value
) != EQ_EXPR
)
21306 eloc
= c_parser_peek_token (parser
)->location
;
21307 error_at (eloc
, "unexpected %<else%>");
21311 c_parser_consume_token (parser
);
21313 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
21316 extra_scope
= true;
21317 v
= c_parser_cast_expression (parser
, NULL
).value
;
21318 non_lvalue_p
= !lvalue_p (v
);
21319 v
= c_fully_fold (v
, false, NULL
, true);
21320 if (v
== error_mark_node
)
21323 v
= non_lvalue (v
);
21324 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21327 expr
= c_parser_expr_no_commas (parser
, NULL
);
21329 if (!c_tree_equal (expr
.value
, unfolded_lhs
))
21332 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
21335 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
21338 extra_scope
= false;
21339 code
= OMP_ATOMIC_CAPTURE_OLD
;
21340 if (r
== NULL_TREE
)
21341 /* Signal to c_finish_omp_atomic that in
21342 if (x == e) { x = d; } else { v = x; }
21343 case the store to v should be conditional. */
21344 r
= void_list_node
;
21346 else if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
21348 c_parser_require_keyword (parser
, RID_ELSE
, "expected %<else%>");
21351 else if (code
== OMP_ATOMIC_CAPTURE_NEW
21357 eloc
= c_parser_peek_token (parser
)->location
;
21358 expr
= c_parser_cast_expression (parser
, NULL
);
21360 expr
= default_function_array_conversion (eloc
, expr
);
21361 unfolded_lhs
= expr
.value
;
21362 lhs
= c_fully_fold (lhs
, false, NULL
, true);
21364 switch (TREE_CODE (lhs
))
21367 error_at (eloc
, "invalid form of %<pragma omp atomic compare%>");
21371 c_parser_skip_to_end_of_block_or_statement (parser
);
21372 if (extra_scope
&& c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
21373 c_parser_consume_token (parser
);
21374 if (structured_block
)
21376 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
21377 c_parser_consume_token (parser
);
21378 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
21380 c_parser_skip_to_end_of_block_or_statement (parser
);
21381 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
21382 c_parser_consume_token (parser
);
21387 case POSTINCREMENT_EXPR
:
21388 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
21389 code
= OMP_ATOMIC_CAPTURE_OLD
;
21391 case PREINCREMENT_EXPR
:
21392 lhs
= TREE_OPERAND (lhs
, 0);
21393 unfolded_lhs
= NULL_TREE
;
21394 opcode
= PLUS_EXPR
;
21395 rhs
= integer_one_node
;
21397 goto invalid_compare
;
21400 case POSTDECREMENT_EXPR
:
21401 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
21402 code
= OMP_ATOMIC_CAPTURE_OLD
;
21404 case PREDECREMENT_EXPR
:
21405 lhs
= TREE_OPERAND (lhs
, 0);
21406 unfolded_lhs
= NULL_TREE
;
21407 opcode
= MINUS_EXPR
;
21408 rhs
= integer_one_node
;
21410 goto invalid_compare
;
21413 case COMPOUND_EXPR
:
21414 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
21415 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
21416 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
21417 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
21418 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
21419 (TREE_OPERAND (lhs
, 1), 0), 0))))
21420 /* Undo effects of boolean_increment for post {in,de}crement. */
21421 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
21424 if (TREE_CODE (lhs
) == MODIFY_EXPR
21425 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs
, 0))))
21427 /* Undo effects of boolean_increment. */
21428 if (integer_onep (TREE_OPERAND (lhs
, 1)))
21430 /* This is pre or post increment. */
21431 rhs
= TREE_OPERAND (lhs
, 1);
21432 lhs
= TREE_OPERAND (lhs
, 0);
21433 unfolded_lhs
= NULL_TREE
;
21435 if (code
== OMP_ATOMIC_CAPTURE_NEW
21436 && !structured_block
21437 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
21438 code
= OMP_ATOMIC_CAPTURE_OLD
;
21440 goto invalid_compare
;
21443 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
21444 && TREE_OPERAND (lhs
, 0)
21445 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
21447 /* This is pre or post decrement. */
21448 rhs
= TREE_OPERAND (lhs
, 1);
21449 lhs
= TREE_OPERAND (lhs
, 0);
21450 unfolded_lhs
= NULL_TREE
;
21452 if (code
== OMP_ATOMIC_CAPTURE_NEW
21453 && !structured_block
21454 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
21455 code
= OMP_ATOMIC_CAPTURE_OLD
;
21457 goto invalid_compare
;
21463 if (!lvalue_p (unfolded_lhs
))
21464 lhs
= non_lvalue (lhs
);
21465 if (compare
&& !c_parser_next_token_is (parser
, CPP_EQ
))
21467 c_parser_error (parser
, "expected %<=%>");
21470 switch (c_parser_peek_token (parser
)->type
)
21473 opcode
= MULT_EXPR
;
21476 opcode
= TRUNC_DIV_EXPR
;
21479 opcode
= PLUS_EXPR
;
21482 opcode
= MINUS_EXPR
;
21484 case CPP_LSHIFT_EQ
:
21485 opcode
= LSHIFT_EXPR
;
21487 case CPP_RSHIFT_EQ
:
21488 opcode
= RSHIFT_EXPR
;
21491 opcode
= BIT_AND_EXPR
;
21494 opcode
= BIT_IOR_EXPR
;
21497 opcode
= BIT_XOR_EXPR
;
21500 c_parser_consume_token (parser
);
21501 eloc
= c_parser_peek_token (parser
)->location
;
21502 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
21504 switch (TREE_CODE (rhs1
))
21507 case TRUNC_DIV_EXPR
:
21518 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
21520 opcode
= TREE_CODE (rhs1
);
21521 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21523 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
21527 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
21529 opcode
= TREE_CODE (rhs1
);
21530 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
21532 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21534 swapped
= !commutative_tree_code (opcode
);
21541 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) != GT_EXPR
21542 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != LT_EXPR
21543 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != EQ_EXPR
)
21545 if (!TREE_OPERAND (rhs1
, 1))
21547 if (!c_tree_equal (TREE_OPERAND (rhs1
, 2), unfolded_lhs
))
21549 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
21552 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
21554 opcode
= COND_EXPR
;
21555 rhs
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
21557 false, NULL
, true);
21558 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false,
21562 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
21563 TREE_OPERAND (rhs1
, 1)))
21565 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
21566 ? MIN_EXPR
: MAX_EXPR
);
21567 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21569 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
21571 false, NULL
, true);
21575 else if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
21577 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
21580 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
21581 TREE_OPERAND (rhs1
, 1)))
21583 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
21584 ? MAX_EXPR
: MIN_EXPR
);
21585 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
21587 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
21589 false, NULL
, true);
21596 || code
!= OMP_ATOMIC_CAPTURE_NEW
21597 || !structured_block
21601 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
21602 && c_parser_peek_2nd_token (parser
)->keyword
== RID_IF
)
21606 c_parser_consume_token (parser
);
21615 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
21617 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
21619 code
= OMP_ATOMIC_CAPTURE_OLD
;
21622 expr
= default_function_array_read_conversion (eloc
, expr
);
21623 unfolded_lhs1
= expr
.value
;
21624 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
21626 c_parser_consume_token (parser
);
21629 if (structured_block
&& !compare
)
21632 expr
= default_function_array_read_conversion (eloc
, expr
);
21633 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
21638 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
21641 c_parser_error (parser
,
21642 "invalid operator for %<#pragma omp atomic%>");
21646 /* Arrange to pass the location of the assignment operator to
21647 c_finish_omp_atomic. */
21648 loc
= c_parser_peek_token (parser
)->location
;
21649 c_parser_consume_token (parser
);
21650 eloc
= c_parser_peek_token (parser
)->location
;
21651 expr
= c_parser_expression (parser
);
21652 expr
= default_function_array_read_conversion (eloc
, expr
);
21654 rhs
= c_fully_fold (rhs
, false, NULL
, true);
21658 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
&& r
== NULL_TREE
)
21661 && !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
21663 no_semicolon
= false;
21664 v
= c_parser_cast_expression (parser
, NULL
).value
;
21665 non_lvalue_p
= !lvalue_p (v
);
21666 v
= c_fully_fold (v
, false, NULL
, true);
21667 if (v
== error_mark_node
)
21670 v
= non_lvalue (v
);
21671 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21673 eloc
= c_parser_peek_token (parser
)->location
;
21674 expr
= c_parser_cast_expression (parser
, NULL
);
21676 expr
= default_function_array_read_conversion (eloc
, expr
);
21677 unfolded_lhs1
= expr
.value
;
21678 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
21679 if (lhs1
== error_mark_node
)
21681 if (!lvalue_p (unfolded_lhs1
))
21682 lhs1
= non_lvalue (lhs1
);
21684 if (structured_block
)
21687 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
21688 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
21691 if (weak
&& opcode
!= COND_EXPR
)
21693 error_at (loc
, "%<weak%> clause requires atomic equality comparison");
21696 if (unfolded_lhs
&& unfolded_lhs1
21697 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
21699 error ("%<#pragma omp atomic capture%> uses two different "
21700 "expressions for memory");
21701 stmt
= error_mark_node
;
21704 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
, r
,
21705 swapped
, memory_order
, weak
);
21706 if (stmt
!= error_mark_node
)
21709 if (!structured_block
&& !no_semicolon
)
21710 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
21715 # pragma omp barrier new-line
21719 c_parser_omp_barrier (c_parser
*parser
)
21721 location_t loc
= c_parser_peek_token (parser
)->location
;
21722 c_parser_consume_pragma (parser
);
21723 c_parser_skip_to_pragma_eol (parser
);
21725 c_finish_omp_barrier (loc
);
21729 # pragma omp critical [(name)] new-line
21733 # pragma omp critical [(name) [hint(expression)]] new-line
21735 LOC is the location of the #pragma itself. */
21737 #define OMP_CRITICAL_CLAUSE_MASK \
21738 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
21741 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
21743 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
21745 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
21747 c_parser_consume_token (parser
);
21748 if (c_parser_next_token_is (parser
, CPP_NAME
))
21750 name
= c_parser_peek_token (parser
)->value
;
21751 c_parser_consume_token (parser
);
21752 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
21755 c_parser_error (parser
, "expected identifier");
21757 if (c_parser_next_token_is (parser
, CPP_COMMA
)
21758 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
21759 c_parser_consume_token (parser
);
21761 clauses
= c_parser_omp_all_clauses (parser
, OMP_CRITICAL_CLAUSE_MASK
,
21762 "#pragma omp critical");
21763 stmt
= c_parser_omp_structured_block (parser
, if_p
);
21764 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
21768 # pragma omp depobj ( depobj ) depobj-clause new-line
21771 depend (dependence-type : locator)
21773 update (dependence-type)
21775 OpenMP 5.2 additionally:
21785 c_parser_omp_depobj (c_parser
*parser
)
21787 location_t loc
= c_parser_peek_token (parser
)->location
;
21788 c_parser_consume_pragma (parser
);
21789 matching_parens parens
;
21790 if (!parens
.require_open (parser
))
21792 c_parser_skip_to_pragma_eol (parser
);
21796 tree depobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
21797 if (depobj
!= error_mark_node
)
21799 if (!lvalue_p (depobj
))
21801 error_at (EXPR_LOC_OR_LOC (depobj
, loc
),
21802 "%<depobj%> expression is not lvalue expression");
21803 depobj
= error_mark_node
;
21807 tree addr
= build_unary_op (EXPR_LOC_OR_LOC (depobj
, loc
), ADDR_EXPR
,
21809 if (addr
== error_mark_node
)
21810 depobj
= error_mark_node
;
21812 depobj
= build_indirect_ref (EXPR_LOC_OR_LOC (depobj
, loc
),
21813 addr
, RO_UNARY_STAR
);
21817 parens
.skip_until_found_close (parser
);
21818 tree clause
= NULL_TREE
;
21819 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_INVALID
;
21820 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21821 c_parser_consume_token (parser
);
21822 location_t c_loc
= c_parser_peek_token (parser
)->location
;
21823 if (c_parser_next_token_is (parser
, CPP_NAME
))
21825 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21827 c_parser_consume_token (parser
);
21828 if (!strcmp ("depend", p
))
21830 clause
= c_parser_omp_clause_depend (parser
, NULL_TREE
);
21831 clause
= c_finish_omp_clauses (clause
, C_ORT_OMP
);
21833 clause
= error_mark_node
;
21835 else if (!strcmp ("destroy", p
))
21837 matching_parens c_parens
;
21838 kind
= OMP_CLAUSE_DEPEND_LAST
;
21839 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
21840 && c_parens
.require_open (parser
))
21842 tree destobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
21843 if (!lvalue_p (destobj
))
21844 error_at (EXPR_LOC_OR_LOC (destobj
, c_loc
),
21845 "%<destroy%> expression is not lvalue expression");
21846 else if (depobj
!= error_mark_node
21847 && !operand_equal_p (destobj
, depobj
,
21848 OEP_MATCH_SIDE_EFFECTS
21849 | OEP_LEXICOGRAPHIC
))
21850 warning_at (EXPR_LOC_OR_LOC (destobj
, c_loc
), OPT_Wopenmp
,
21851 "the %<destroy%> expression %qE should be the same "
21852 "as the %<depobj%> argument %qE", destobj
, depobj
);
21853 c_parens
.skip_until_found_close (parser
);
21856 else if (!strcmp ("update", p
))
21858 matching_parens c_parens
;
21859 if (c_parens
.require_open (parser
))
21861 location_t c2_loc
= c_parser_peek_token (parser
)->location
;
21862 if (c_parser_next_token_is (parser
, CPP_NAME
))
21865 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21867 c_parser_consume_token (parser
);
21868 if (!strcmp ("in", p2
))
21869 kind
= OMP_CLAUSE_DEPEND_IN
;
21870 else if (!strcmp ("out", p2
))
21871 kind
= OMP_CLAUSE_DEPEND_OUT
;
21872 else if (!strcmp ("inout", p2
))
21873 kind
= OMP_CLAUSE_DEPEND_INOUT
;
21874 else if (!strcmp ("mutexinoutset", p2
))
21875 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
21876 else if (!strcmp ("inoutset", p2
))
21877 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
21879 if (kind
== OMP_CLAUSE_DEPEND_INVALID
)
21881 clause
= error_mark_node
;
21882 error_at (c2_loc
, "expected %<in%>, %<out%>, %<inout%>, "
21883 "%<mutexinoutset%> or %<inoutset%>");
21885 c_parens
.skip_until_found_close (parser
);
21888 clause
= error_mark_node
;
21891 if (!clause
&& kind
== OMP_CLAUSE_DEPEND_INVALID
)
21893 clause
= error_mark_node
;
21894 error_at (c_loc
, "expected %<depend%>, %<destroy%> or %<update%> clause");
21896 c_parser_skip_to_pragma_eol (parser
);
21898 c_finish_omp_depobj (loc
, depobj
, kind
, clause
);
21903 # pragma omp flush flush-vars[opt] new-line
21909 # pragma omp flush memory-order-clause new-line */
21912 c_parser_omp_flush (c_parser
*parser
)
21914 location_t loc
= c_parser_peek_token (parser
)->location
;
21915 c_parser_consume_pragma (parser
);
21916 enum memmodel mo
= MEMMODEL_LAST
;
21917 if (c_parser_next_token_is (parser
, CPP_COMMA
)
21918 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
21919 c_parser_consume_token (parser
);
21920 if (c_parser_next_token_is (parser
, CPP_NAME
))
21923 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21925 if (!strcmp (p
, "seq_cst"))
21926 mo
= MEMMODEL_SEQ_CST
;
21927 else if (!strcmp (p
, "acq_rel"))
21928 mo
= MEMMODEL_ACQ_REL
;
21929 else if (!strcmp (p
, "release"))
21930 mo
= MEMMODEL_RELEASE
;
21931 else if (!strcmp (p
, "acquire"))
21932 mo
= MEMMODEL_ACQUIRE
;
21934 error_at (c_parser_peek_token (parser
)->location
,
21935 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
21937 c_parser_consume_token (parser
);
21939 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
21941 if (mo
!= MEMMODEL_LAST
)
21942 error_at (c_parser_peek_token (parser
)->location
,
21943 "%<flush%> list specified together with memory order "
21945 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
21947 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21948 c_parser_error (parser
, "expected %<(%> or end of line");
21949 c_parser_skip_to_pragma_eol (parser
);
21951 c_finish_omp_flush (loc
, mo
);
21954 /* Return true if next tokens contain a standard attribute that contains
21955 omp::directive (DIRECTIVE). */
21958 c_parser_omp_section_scan (c_parser
*parser
, const char *directive
,
21961 if (!c_parser_nth_token_starts_std_attributes (parser
, 1))
21963 unsigned int n
= 3;
21964 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
21966 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
21967 if (token
->type
!= CPP_CLOSE_SQUARE
)
21969 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
21970 if (token
->type
!= CPP_CLOSE_SQUARE
)
21974 if (c_parser_peek_nth_token_raw (parser
, 3)->type
== CPP_NAME
21975 && c_parser_peek_nth_token_raw (parser
, 4)->type
== CPP_OPEN_PAREN
21976 && c_parser_peek_nth_token_raw (parser
, 5)->type
== CPP_NAME
)
21978 tree first
= c_parser_peek_nth_token_raw (parser
, 3)->value
;
21979 tree second
= c_parser_peek_nth_token_raw (parser
, 5)->value
;
21980 if (strcmp (IDENTIFIER_POINTER (first
), "directive")
21981 && strcmp (IDENTIFIER_POINTER (first
), "__directive__"))
21983 if (strcmp (IDENTIFIER_POINTER (second
), directive
))
21988 location_t first_loc
= c_parser_peek_token (parser
)->location
;
21989 location_t last_loc
= c_parser_peek_nth_token_raw (parser
, n
+ 1)->location
;
21990 location_t middle_loc
= UNKNOWN_LOCATION
;
21991 tree std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
21994 for (tree attr
= std_attrs
; attr
; attr
= TREE_CHAIN (attr
))
21995 if (is_attribute_namespace_p ("omp", attr
)
21996 && is_attribute_p ("directive", get_attribute_name (attr
)))
21998 for (tree a
= TREE_VALUE (attr
); a
; a
= TREE_CHAIN (a
))
22000 tree d
= TREE_VALUE (a
);
22001 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
22002 c_token
*first
= C_TOKEN_VEC_TOKENS (d
)->address ();
22004 if (first
->type
== CPP_NAME
22005 && strcmp (IDENTIFIER_POINTER (first
->value
),
22009 if (middle_loc
== UNKNOWN_LOCATION
)
22010 middle_loc
= first
->location
;
22016 if (cnt
!= 1 || TREE_CHAIN (std_attrs
))
22018 error_at (make_location (first_loc
, last_loc
, middle_loc
),
22019 "%<[[omp::directive(%s)]]%> must be the only specified "
22020 "attribute on a statement", directive
);
22023 c_parser_handle_statement_omp_attributes (parser
, std_attrs
, NULL
);
22027 /* Parse an OpenMP structured block sequence. KIND is the corresponding
22028 separating directive. */
22031 c_parser_omp_structured_block_sequence (c_parser
*parser
,
22032 enum pragma_kind kind
)
22034 tree stmt
= push_stmt_list ();
22035 c_parser_statement (parser
, NULL
);
22038 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
22040 if (c_parser_next_token_is (parser
, CPP_EOF
))
22043 if (kind
!= PRAGMA_NONE
22044 && c_parser_peek_token (parser
)->pragma_kind
== kind
)
22047 if (kind
!= PRAGMA_NONE
22048 && c_parser_omp_section_scan (parser
,
22049 kind
== PRAGMA_OMP_SCAN
22050 ? "scan" : "section", false))
22053 c_parser_statement (parser
, NULL
);
22056 return pop_stmt_list (stmt
);
22062 { structured-block scan-directive structured-block } */
22065 c_parser_omp_scan_loop_body (c_parser
*parser
, bool open_brace_parsed
)
22069 tree clauses
= NULL_TREE
;
22070 bool found_scan
= false;
22072 loc
= c_parser_peek_token (parser
)->location
;
22073 if (!open_brace_parsed
22074 && !c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
22076 /* Avoid skipping until the end of the block. */
22077 parser
->error
= false;
22081 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SCAN
)
22082 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_OMP_SCAN
);
22085 warning_at (c_parser_peek_token (parser
)->location
, OPT_Wopenmp
,
22086 "%<#pragma omp scan%> with zero preceding executable "
22088 substmt
= build_empty_stmt (loc
);
22090 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, NULL_TREE
);
22091 SET_EXPR_LOCATION (substmt
, loc
);
22092 add_stmt (substmt
);
22094 loc
= c_parser_peek_token (parser
)->location
;
22095 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SCAN
)
22097 enum omp_clause_code clause
= OMP_CLAUSE_ERROR
;
22100 c_parser_consume_pragma (parser
);
22102 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22103 c_parser_consume_token (parser
);
22105 if (c_parser_next_token_is (parser
, CPP_NAME
))
22108 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22109 if (strcmp (p
, "inclusive") == 0)
22110 clause
= OMP_CLAUSE_INCLUSIVE
;
22111 else if (strcmp (p
, "exclusive") == 0)
22112 clause
= OMP_CLAUSE_EXCLUSIVE
;
22114 if (clause
!= OMP_CLAUSE_ERROR
)
22116 c_parser_consume_token (parser
);
22117 clauses
= c_parser_omp_var_list_parens (parser
, clause
, NULL_TREE
);
22120 c_parser_error (parser
, "expected %<inclusive%> or "
22121 "%<exclusive%> clause");
22122 c_parser_skip_to_pragma_eol (parser
);
22125 error ("expected %<#pragma omp scan%>");
22127 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
22128 if (!c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
22129 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_NONE
);
22133 warning_at (loc
, OPT_Wopenmp
,
22134 "%<#pragma omp scan%> with zero succeeding executable "
22136 substmt
= build_empty_stmt (loc
);
22138 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, clauses
);
22139 SET_EXPR_LOCATION (substmt
, loc
);
22140 add_stmt (substmt
);
22142 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
22147 /* This function parses a single level of a loop nest, invoking itself
22148 recursively if necessary.
22150 loop-nest :: for (...) loop-body
22151 loop-body :: loop-nest
22152 | { [intervening-code] loop-body [intervening-code] }
22154 intervening-code :: structured-block-sequence
22155 final-loop-body :: structured-block
22157 For a collapsed loop nest, only a single OMP_FOR is built, pulling out
22158 all the iterator information from the inner loops into the
22159 parser->omp_for_parse_state structure.
22161 The iterator decl, init, cond, and incr are stored in vectors.
22163 Initialization code for iterator variables is collected into
22164 parser->omp_for_parse_state->pre_body and ends up inserted directly
22165 into the OMP_FOR structure. */
22168 c_parser_omp_loop_nest (c_parser
*parser
, bool *if_p
)
22170 tree decl
, cond
, incr
, init
;
22171 tree body
= NULL_TREE
;
22172 matching_parens parens
;
22174 unsigned char save_in_statement
;
22177 struct omp_for_parse_data
*omp_for_parse_state
22178 = parser
->omp_for_parse_state
;
22179 gcc_assert (omp_for_parse_state
);
22180 int depth
= omp_for_parse_state
->depth
;
22182 /* We have already matched the FOR token but not consumed it yet. */
22183 loc
= c_parser_peek_token (parser
)->location
;
22184 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
22185 c_parser_consume_token (parser
);
22187 /* Forbid break/continue in the loop initializer, condition, and
22188 increment expressions. */
22189 save_in_statement
= in_statement
;
22190 in_statement
= IN_OMP_BLOCK
;
22192 /* We are not in intervening code now. */
22193 omp_for_parse_state
->in_intervening_code
= false;
22195 if (!parens
.require_open (parser
))
22197 omp_for_parse_state
->fail
= true;
22201 /* An implicit scope block surrounds each level of FOR loop, for
22202 declarations of iteration variables at this loop depth. */
22203 loop_scope
= c_begin_compound_stmt (true);
22205 /* Parse the initialization declaration or expression. */
22206 if (c_parser_next_tokens_start_declaration (parser
))
22208 /* This is a declaration, which must be added to the pre_body code. */
22209 tree this_pre_body
= push_stmt_list ();
22210 c_in_omp_for
= true;
22211 c_parser_declaration_or_fndef (parser
, true, true, true, true, true);
22212 c_in_omp_for
= false;
22213 this_pre_body
= pop_stmt_list (this_pre_body
);
22214 append_to_statement_list_force (this_pre_body
,
22215 &(omp_for_parse_state
->pre_body
));
22216 decl
= check_for_loop_decls (omp_for_parse_state
->for_loc
, flag_isoc99
);
22219 if (DECL_INITIAL (decl
) == error_mark_node
)
22220 decl
= error_mark_node
;
22223 else if (c_parser_next_token_is (parser
, CPP_NAME
)
22224 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
22226 struct c_expr decl_exp
;
22227 struct c_expr init_exp
;
22228 location_t init_loc
;
22230 decl_exp
= c_parser_postfix_expression (parser
);
22231 decl
= decl_exp
.value
;
22233 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
22235 init_loc
= c_parser_peek_token (parser
)->location
;
22236 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
22237 init_exp
= default_function_array_read_conversion (init_loc
,
22239 c_in_omp_for
= true;
22240 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
22241 NOP_EXPR
, init_loc
, init_exp
.value
,
22242 init_exp
.original_type
);
22243 c_in_omp_for
= false;
22244 init
= c_process_expr_stmt (init_loc
, init
);
22246 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
22251 c_parser_error (parser
,
22252 "expected iteration declaration or initialization");
22253 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
22255 omp_for_parse_state
->fail
= true;
22259 /* Parse the loop condition. */
22261 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
22263 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
22264 c_in_omp_for
= true;
22265 struct c_expr cond_expr
22266 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
22267 c_in_omp_for
= false;
22269 cond
= cond_expr
.value
;
22270 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
22271 switch (cond_expr
.original_code
)
22279 if (omp_for_parse_state
->code
!= OACC_LOOP
)
22283 /* Can't be cond = error_mark_node, because we want to preserve
22284 the location until c_finish_omp_for. */
22285 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
22288 protected_set_expr_location (cond
, cond_loc
);
22290 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
22292 /* Parse the increment expression. */
22294 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
22296 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
22298 incr
= c_process_expr_stmt (incr_loc
,
22299 c_parser_expression (parser
).value
);
22301 parens
.skip_until_found_close (parser
);
22303 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
22304 omp_for_parse_state
->fail
= true;
22307 TREE_VEC_ELT (omp_for_parse_state
->declv
, depth
) = decl
;
22308 TREE_VEC_ELT (omp_for_parse_state
->initv
, depth
) = init
;
22309 TREE_VEC_ELT (omp_for_parse_state
->condv
, depth
) = cond
;
22310 TREE_VEC_ELT (omp_for_parse_state
->incrv
, depth
) = incr
;
22314 moreloops
= depth
< omp_for_parse_state
->count
- 1;
22315 omp_for_parse_state
->want_nested_loop
= moreloops
;
22316 if (moreloops
&& c_parser_next_token_is_keyword (parser
, RID_FOR
))
22318 omp_for_parse_state
->depth
++;
22319 body
= c_parser_omp_loop_nest (parser
, if_p
);
22320 omp_for_parse_state
->depth
--;
22322 else if (moreloops
&& c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
22324 /* This is the open brace in the loop-body grammar production. Rather
22325 than trying to special-case braces, just parse it as a compound
22326 statement and handle the nested loop-body case there. Note that
22327 when we see a further open brace inside the compound statement
22328 loop-body, we don't know whether it is the start of intervening
22329 code that is a compound statement, or a level of braces
22330 surrounding a nested loop-body. Use the WANT_NESTED_LOOP state
22331 bit to ensure we have only one nested loop at each level. */
22332 omp_for_parse_state
->in_intervening_code
= true;
22333 body
= c_parser_compound_statement (parser
, NULL
);
22334 omp_for_parse_state
->in_intervening_code
= false;
22335 if (omp_for_parse_state
->want_nested_loop
)
22337 /* We have already parsed the whole loop body and not found a
22339 error_at (omp_for_parse_state
->for_loc
,
22340 "not enough nested loops");
22341 omp_for_parse_state
->fail
= true;
22347 /* This is the final-loop-body case in the grammar: we have
22348 something that is not a FOR and not an open brace. */
22351 /* If we were expecting a nested loop, give an error and mark
22352 that parsing has failed, and try to recover by parsing the
22353 body as regular code without further collapsing. */
22354 error_at (omp_for_parse_state
->for_loc
,
22355 "not enough nested loops");
22356 omp_for_parse_state
->fail
= true;
22358 in_statement
= IN_OMP_FOR
;
22359 parser
->omp_for_parse_state
= NULL
;
22360 body
= push_stmt_list ();
22361 if (omp_for_parse_state
->inscan
)
22362 c_parser_omp_scan_loop_body (parser
, false);
22364 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
22365 body
= pop_stmt_list (body
);
22366 parser
->omp_for_parse_state
= omp_for_parse_state
;
22368 in_statement
= save_in_statement
;
22369 omp_for_parse_state
->want_nested_loop
= false;
22370 omp_for_parse_state
->in_intervening_code
= true;
22372 /* Pop and return the implicit scope surrounding this level of loop.
22373 If the iteration variable at this depth was bound in the for loop,
22374 pull out and save the binding. Later in c_parser_omp_for_loop,
22375 these bindings will be moved to the scope surrounding the entire
22376 OMP_FOR. That keeps the gimplifier happy later on, and meanwhile
22377 we have already resolved all references to the iteration variable
22378 in its true scope. */
22380 body
= c_end_compound_stmt (loc
, loop_scope
, true);
22381 if (decl
&& TREE_CODE (body
) == BIND_EXPR
)
22383 tree t
= BIND_EXPR_VARS (body
);
22384 tree prev
= NULL_TREE
, next
= NULL_TREE
;
22387 next
= DECL_CHAIN (t
);
22391 DECL_CHAIN (prev
) = next
;
22394 BIND_EXPR_VARS (body
) = next
;
22395 BLOCK_VARS (BIND_EXPR_BLOCK (body
)) = next
;
22397 DECL_CHAIN (t
) = omp_for_parse_state
->bindings
;
22398 omp_for_parse_state
->bindings
= t
;
22407 if (BIND_EXPR_VARS (body
) == NULL_TREE
)
22408 body
= BIND_EXPR_BODY (body
);
22414 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
22415 The real trick here is to determine the loop control variable early
22416 so that we can push a new decl if necessary to make it private.
22417 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
22421 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
22422 tree clauses
, tree
*cclauses
, bool *if_p
)
22424 tree body
, stmt
, cl
;
22425 tree ret
= NULL_TREE
;
22426 tree ordered_cl
= NULL_TREE
;
22427 int i
, collapse
= 1, ordered
= 0, count
;
22428 bool tiling
= false;
22429 bool inscan
= false;
22430 struct omp_for_parse_data data
;
22431 struct omp_for_parse_data
*save_data
= parser
->omp_for_parse_state
;
22433 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
22434 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
22435 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
22436 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
22439 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
22441 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
22442 && OMP_CLAUSE_ORDERED_EXPR (cl
))
22445 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
22447 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_REDUCTION
22448 && OMP_CLAUSE_REDUCTION_INSCAN (cl
)
22449 && (code
== OMP_SIMD
|| code
== OMP_FOR
))
22452 if (ordered
&& ordered
< collapse
)
22454 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
22455 "%<ordered%> clause parameter is less than %<collapse%>");
22456 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
22457 = build_int_cst (NULL_TREE
, collapse
);
22458 ordered
= collapse
;
22461 gcc_assert (tiling
|| (collapse
>= 1 && ordered
>= 0));
22462 count
= ordered
? ordered
: collapse
;
22464 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
))
22466 c_parser_error (parser
, "for statement expected");
22470 /* Initialize parse state for recursive descent. */
22471 data
.declv
= make_tree_vec (count
);
22472 data
.initv
= make_tree_vec (count
);
22473 data
.condv
= make_tree_vec (count
);
22474 data
.incrv
= make_tree_vec (count
);
22475 data
.pre_body
= NULL_TREE
;;
22476 data
.bindings
= NULL_TREE
;
22477 data
.for_loc
= c_parser_peek_token (parser
)->location
;
22478 data
.count
= count
;
22480 data
.want_nested_loop
= true;
22481 data
.ordered
= ordered
> 0;
22482 data
.in_intervening_code
= false;
22483 data
.perfect_nesting_fail
= false;
22485 data
.inscan
= inscan
;
22486 data
.saw_intervening_code
= false;
22488 parser
->omp_for_parse_state
= &data
;
22490 body
= c_parser_omp_loop_nest (parser
, if_p
);
22492 /* Add saved bindings for iteration variables that were declared in
22493 the nested for loop to the scope surrounding the entire loop. */
22494 for (tree t
= data
.bindings
; t
; )
22496 tree n
= TREE_CHAIN (t
);
22497 TREE_CHAIN (t
) = NULL_TREE
;
22502 /* Only bother calling c_finish_omp_for if we haven't already generated
22503 an error from the initialization parsing. */
22506 c_in_omp_for
= true;
22507 stmt
= c_finish_omp_for (loc
, code
, data
.declv
, NULL
, data
.initv
,
22508 data
.condv
, data
.incrv
,
22509 body
, data
.pre_body
, true);
22510 c_in_omp_for
= false;
22512 /* Check for iterators appearing in lb, b or incr expressions. */
22513 if (stmt
&& !c_omp_check_loop_iv (stmt
, data
.declv
, NULL
))
22516 /* Check for errors involving lb/ub/incr expressions referencing
22517 variables declared in intervening code. */
22518 if (data
.saw_intervening_code
22519 && !c_omp_check_loop_binding_exprs (stmt
, NULL
))
22526 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (stmt
)); i
++)
22528 tree init
= TREE_VEC_ELT (OMP_FOR_INIT (stmt
), i
);
22529 gcc_assert (TREE_CODE (init
) == MODIFY_EXPR
);
22530 tree decl
= TREE_OPERAND (init
, 0);
22531 tree cond
= TREE_VEC_ELT (OMP_FOR_COND (stmt
), i
);
22532 gcc_assert (COMPARISON_CLASS_P (cond
));
22533 gcc_assert (TREE_OPERAND (cond
, 0) == decl
);
22535 tree op0
= TREE_OPERAND (init
, 1);
22536 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
22537 || TREE_CODE (op0
) != TREE_VEC
)
22538 TREE_OPERAND (init
, 1) = c_fully_fold (op0
, false, NULL
);
22541 TREE_VEC_ELT (op0
, 1)
22542 = c_fully_fold (TREE_VEC_ELT (op0
, 1), false, NULL
);
22543 TREE_VEC_ELT (op0
, 2)
22544 = c_fully_fold (TREE_VEC_ELT (op0
, 2), false, NULL
);
22547 tree op1
= TREE_OPERAND (cond
, 1);
22548 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
22549 || TREE_CODE (op1
) != TREE_VEC
)
22550 TREE_OPERAND (cond
, 1) = c_fully_fold (op1
, false, NULL
);
22553 TREE_VEC_ELT (op1
, 1)
22554 = c_fully_fold (TREE_VEC_ELT (op1
, 1), false, NULL
);
22555 TREE_VEC_ELT (op1
, 2)
22556 = c_fully_fold (TREE_VEC_ELT (op1
, 2), false, NULL
);
22560 if (cclauses
!= NULL
22561 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
22564 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
22565 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
22566 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
22567 c
= &OMP_CLAUSE_CHAIN (*c
);
22570 for (i
= 0; i
< count
; i
++)
22571 if (TREE_VEC_ELT (data
.declv
, i
) == OMP_CLAUSE_DECL (*c
))
22574 c
= &OMP_CLAUSE_CHAIN (*c
);
22575 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
22578 "iteration variable %qD should not be firstprivate",
22579 OMP_CLAUSE_DECL (*c
));
22580 *c
= OMP_CLAUSE_CHAIN (*c
);
22584 /* Move lastprivate (decl) clause to
22585 OMP_FOR_CLAUSES. */
22587 *c
= OMP_CLAUSE_CHAIN (*c
);
22588 if (code
== OMP_SIMD
)
22590 OMP_CLAUSE_CHAIN (l
)
22591 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
22592 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
22596 OMP_CLAUSE_CHAIN (l
) = clauses
;
22602 OMP_FOR_CLAUSES (stmt
) = clauses
;
22607 parser
->omp_for_parse_state
= save_data
;
22611 /* Helper function for OpenMP parsing, split clauses and call
22612 finish_omp_clauses on each of the set of clauses afterwards. */
22615 omp_split_clauses (location_t loc
, enum tree_code code
,
22616 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
22619 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
22620 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
22622 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
],
22623 i
== C_OMP_CLAUSE_SPLIT_TARGET
22624 ? C_ORT_OMP_TARGET
: C_ORT_OMP
);
22628 #pragma omp loop loop-clause[optseq] new-line
22631 LOC is the location of the #pragma token.
22634 #define OMP_LOOP_CLAUSE_MASK \
22635 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22636 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
22640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22643 c_parser_omp_loop (location_t loc
, c_parser
*parser
,
22644 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22647 tree block
, clauses
, ret
;
22649 strcat (p_name
, " loop");
22650 mask
|= OMP_LOOP_CLAUSE_MASK
;
22652 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22655 omp_split_clauses (loc
, OMP_LOOP
, mask
, clauses
, cclauses
);
22656 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_LOOP
];
22659 block
= c_begin_compound_stmt (true);
22660 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_LOOP
, clauses
, cclauses
, if_p
);
22661 block
= c_end_compound_stmt (loc
, block
, true);
22668 #pragma omp simd simd-clause[optseq] new-line
22671 LOC is the location of the #pragma token.
22674 #define OMP_SIMD_CLAUSE_MASK \
22675 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
22676 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
22677 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
22678 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
22679 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22680 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22681 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22682 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22683 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22684 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
22685 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22688 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
22689 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22692 tree block
, clauses
, ret
;
22694 strcat (p_name
, " simd");
22695 mask
|= OMP_SIMD_CLAUSE_MASK
;
22697 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22700 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
22701 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
22704 block
= c_begin_compound_stmt (true);
22705 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
22706 block
= c_end_compound_stmt (loc
, block
, true);
22713 #pragma omp for for-clause[optseq] new-line
22717 #pragma omp for simd for-simd-clause[optseq] new-line
22720 LOC is the location of the #pragma token.
22723 #define OMP_FOR_CLAUSE_MASK \
22724 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22726 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22727 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
22728 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22729 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
22730 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
22731 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22732 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
22733 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
22737 c_parser_omp_for (location_t loc
, c_parser
*parser
,
22738 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22741 tree block
, clauses
, ret
;
22743 strcat (p_name
, " for");
22744 mask
|= OMP_FOR_CLAUSE_MASK
;
22745 /* parallel for{, simd} disallows nowait clause, but for
22746 target {teams distribute ,}parallel for{, simd} it should be accepted. */
22747 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
22748 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
22749 /* Composite distribute parallel for{, simd} disallows ordered clause. */
22750 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
22751 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
22753 if (c_parser_next_token_is (parser
, CPP_NAME
))
22755 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22757 if (strcmp (p
, "simd") == 0)
22759 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22760 if (cclauses
== NULL
)
22761 cclauses
= cclauses_buf
;
22763 c_parser_consume_token (parser
);
22764 if (!flag_openmp
) /* flag_openmp_simd */
22765 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
22767 block
= c_begin_compound_stmt (true);
22768 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
22769 block
= c_end_compound_stmt (loc
, block
, true);
22770 if (ret
== NULL_TREE
)
22772 ret
= make_node (OMP_FOR
);
22773 TREE_TYPE (ret
) = void_type_node
;
22774 OMP_FOR_BODY (ret
) = block
;
22775 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
22776 SET_EXPR_LOCATION (ret
, loc
);
22781 if (!flag_openmp
) /* flag_openmp_simd */
22783 c_parser_skip_to_pragma_eol (parser
, false);
22787 /* Composite distribute parallel for disallows linear clause. */
22788 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
22789 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
22791 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22794 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
22795 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
22798 block
= c_begin_compound_stmt (true);
22799 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
22800 block
= c_end_compound_stmt (loc
, block
, true);
22806 static tree
c_parser_omp_taskloop (location_t
, c_parser
*, char *,
22807 omp_clause_mask
, tree
*, bool *);
22810 # pragma omp master new-line
22813 LOC is the location of the #pragma token.
22817 c_parser_omp_master (location_t loc
, c_parser
*parser
,
22818 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22821 tree block
, clauses
, ret
;
22823 strcat (p_name
, " master");
22825 if (c_parser_next_token_is (parser
, CPP_NAME
))
22827 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22829 if (strcmp (p
, "taskloop") == 0)
22831 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22832 if (cclauses
== NULL
)
22833 cclauses
= cclauses_buf
;
22835 c_parser_consume_token (parser
);
22836 if (!flag_openmp
) /* flag_openmp_simd */
22837 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
22839 block
= c_begin_compound_stmt (true);
22840 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
22842 block
= c_end_compound_stmt (loc
, block
, true);
22843 if (ret
== NULL_TREE
)
22845 ret
= c_finish_omp_master (loc
, block
);
22846 OMP_MASTER_COMBINED (ret
) = 1;
22850 if (!flag_openmp
) /* flag_openmp_simd */
22852 c_parser_skip_to_pragma_eol (parser
, false);
22858 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, false);
22859 omp_split_clauses (loc
, OMP_MASTER
, mask
, clauses
, cclauses
);
22862 c_parser_skip_to_pragma_eol (parser
);
22864 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
22869 # pragma omp masked masked-clauses new-line
22872 LOC is the location of the #pragma token.
22875 #define OMP_MASKED_CLAUSE_MASK \
22876 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
22879 c_parser_omp_masked (location_t loc
, c_parser
*parser
,
22880 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22883 tree block
, clauses
, ret
;
22885 strcat (p_name
, " masked");
22886 mask
|= OMP_MASKED_CLAUSE_MASK
;
22888 if (c_parser_next_token_is (parser
, CPP_NAME
))
22890 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22892 if (strcmp (p
, "taskloop") == 0)
22894 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22895 if (cclauses
== NULL
)
22896 cclauses
= cclauses_buf
;
22898 c_parser_consume_token (parser
);
22899 if (!flag_openmp
) /* flag_openmp_simd */
22900 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
22902 block
= c_begin_compound_stmt (true);
22903 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
22905 block
= c_end_compound_stmt (loc
, block
, true);
22906 if (ret
== NULL_TREE
)
22908 ret
= c_finish_omp_masked (loc
, block
,
22909 cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
]);
22910 OMP_MASKED_COMBINED (ret
) = 1;
22914 if (!flag_openmp
) /* flag_openmp_simd */
22916 c_parser_skip_to_pragma_eol (parser
, false);
22920 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22923 omp_split_clauses (loc
, OMP_MASKED
, mask
, clauses
, cclauses
);
22924 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
];
22927 return c_finish_omp_masked (loc
, c_parser_omp_structured_block (parser
,
22933 # pragma omp ordered new-line
22937 # pragma omp ordered ordered-clauses new-line
22940 # pragma omp ordered depend-clauses new-line
22943 # pragma omp ordered doacross-clauses new-line */
22945 #define OMP_ORDERED_CLAUSE_MASK \
22946 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
22947 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
22949 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
22950 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
22951 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
22954 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
22957 location_t loc
= c_parser_peek_token (parser
)->location
;
22958 c_parser_consume_pragma (parser
);
22960 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
22962 c_parser_error (parser
, "expected declaration specifiers");
22963 c_parser_skip_to_pragma_eol (parser
, false);
22968 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22971 if (c_parser_peek_nth_token (parser
, n
)->type
== CPP_NAME
)
22974 = IDENTIFIER_POINTER (c_parser_peek_nth_token (parser
, n
)->value
);
22976 if (!strcmp ("depend", p
) || !strcmp ("doacross", p
))
22978 if (!flag_openmp
) /* flag_openmp_simd */
22980 c_parser_skip_to_pragma_eol (parser
, false);
22983 if (context
== pragma_stmt
)
22986 "%<#pragma omp ordered%> with %qs clause may "
22987 "only be used in compound statements", p
);
22988 c_parser_skip_to_pragma_eol (parser
, false);
22993 = c_parser_omp_all_clauses (parser
,
22994 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
22995 "#pragma omp ordered");
22996 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
23001 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
23002 "#pragma omp ordered");
23004 if (!flag_openmp
/* flag_openmp_simd */
23005 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
23008 c_finish_omp_ordered (loc
, clauses
,
23009 c_parser_omp_structured_block (parser
, if_p
));
23016 { section-sequence }
23019 section-directive[opt] structured-block
23020 section-sequence section-directive structured-block
23022 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
23024 SECTIONS_LOC is the location of the #pragma omp sections. */
23027 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
23029 tree stmt
, substmt
;
23030 bool error_suppress
= false;
23033 loc
= c_parser_peek_token (parser
)->location
;
23034 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
23036 /* Avoid skipping until the end of the block. */
23037 parser
->error
= false;
23041 stmt
= push_stmt_list ();
23043 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
23044 && !c_parser_omp_section_scan (parser
, "section", true))
23046 substmt
= c_parser_omp_structured_block_sequence (parser
,
23047 PRAGMA_OMP_SECTION
);
23048 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
23049 SET_EXPR_LOCATION (substmt
, loc
);
23050 add_stmt (substmt
);
23055 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
23057 if (c_parser_next_token_is (parser
, CPP_EOF
))
23060 loc
= c_parser_peek_token (parser
)->location
;
23061 c_parser_omp_section_scan (parser
, "section", false);
23062 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
23064 c_parser_consume_pragma (parser
);
23065 c_parser_skip_to_pragma_eol (parser
);
23066 error_suppress
= false;
23068 else if (!error_suppress
)
23070 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
23071 error_suppress
= true;
23074 substmt
= c_parser_omp_structured_block_sequence (parser
,
23075 PRAGMA_OMP_SECTION
);
23076 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
23077 SET_EXPR_LOCATION (substmt
, loc
);
23078 add_stmt (substmt
);
23080 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
23081 "expected %<#pragma omp section%> or %<}%>");
23083 substmt
= pop_stmt_list (stmt
);
23085 stmt
= make_node (OMP_SECTIONS
);
23086 SET_EXPR_LOCATION (stmt
, sections_loc
);
23087 TREE_TYPE (stmt
) = void_type_node
;
23088 OMP_SECTIONS_BODY (stmt
) = substmt
;
23090 return add_stmt (stmt
);
23094 # pragma omp sections sections-clause[optseq] newline
23097 LOC is the location of the #pragma token.
23100 #define OMP_SECTIONS_CLAUSE_MASK \
23101 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23102 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23103 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23104 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23105 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23106 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23109 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
23110 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
23112 tree block
, clauses
, ret
;
23114 strcat (p_name
, " sections");
23115 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
23117 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
23119 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23122 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
23123 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
23126 block
= c_begin_compound_stmt (true);
23127 ret
= c_parser_omp_sections_scope (loc
, parser
);
23129 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
23130 block
= c_end_compound_stmt (loc
, block
, true);
23137 # pragma omp parallel parallel-clause[optseq] new-line
23139 # pragma omp parallel for parallel-for-clause[optseq] new-line
23141 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
23145 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
23148 LOC is the location of the #pragma token.
23151 #define OMP_PARALLEL_CLAUSE_MASK \
23152 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23154 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23155 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23156 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23157 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
23158 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23159 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
23160 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23161 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
23164 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
23165 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23168 tree stmt
, clauses
, block
;
23170 strcat (p_name
, " parallel");
23171 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
23172 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
23173 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
23174 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
23175 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
23177 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
23179 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23180 if (cclauses
== NULL
)
23181 cclauses
= cclauses_buf
;
23183 c_parser_consume_token (parser
);
23184 if (!flag_openmp
) /* flag_openmp_simd */
23185 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
23186 block
= c_begin_omp_parallel ();
23187 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
23189 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23191 if (ret
== NULL_TREE
)
23193 OMP_PARALLEL_COMBINED (stmt
) = 1;
23196 /* When combined with distribute, parallel has to be followed by for.
23197 #pragma omp target parallel is allowed though. */
23199 && (mask
& (OMP_CLAUSE_MASK_1
23200 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
23202 error_at (loc
, "expected %<for%> after %qs", p_name
);
23203 c_parser_skip_to_pragma_eol (parser
);
23206 else if (c_parser_next_token_is (parser
, CPP_NAME
))
23208 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23209 if (cclauses
== NULL
&& strcmp (p
, "masked") == 0)
23211 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23212 cclauses
= cclauses_buf
;
23214 c_parser_consume_token (parser
);
23215 if (!flag_openmp
) /* flag_openmp_simd */
23216 return c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
23218 block
= c_begin_omp_parallel ();
23219 tree ret
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
23221 stmt
= c_finish_omp_parallel (loc
,
23222 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23226 /* masked does have just filter clause, but during gimplification
23227 isn't represented by a gimplification omp context, so for
23228 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
23230 #pragma omp parallel masked
23231 #pragma omp taskloop simd lastprivate (x)
23232 isn't confused with
23233 #pragma omp parallel masked taskloop simd lastprivate (x) */
23234 if (OMP_MASKED_COMBINED (ret
))
23235 OMP_PARALLEL_COMBINED (stmt
) = 1;
23238 else if (cclauses
== NULL
&& strcmp (p
, "master") == 0)
23240 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23241 cclauses
= cclauses_buf
;
23243 c_parser_consume_token (parser
);
23244 if (!flag_openmp
) /* flag_openmp_simd */
23245 return c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
23247 block
= c_begin_omp_parallel ();
23248 tree ret
= c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
23250 stmt
= c_finish_omp_parallel (loc
,
23251 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23255 /* master doesn't have any clauses and during gimplification
23256 isn't represented by a gimplification omp context, so for
23257 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
23259 #pragma omp parallel master
23260 #pragma omp taskloop simd lastprivate (x)
23261 isn't confused with
23262 #pragma omp parallel master taskloop simd lastprivate (x) */
23263 if (OMP_MASTER_COMBINED (ret
))
23264 OMP_PARALLEL_COMBINED (stmt
) = 1;
23267 else if (strcmp (p
, "loop") == 0)
23269 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23270 if (cclauses
== NULL
)
23271 cclauses
= cclauses_buf
;
23273 c_parser_consume_token (parser
);
23274 if (!flag_openmp
) /* flag_openmp_simd */
23275 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
23277 block
= c_begin_omp_parallel ();
23278 tree ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
23281 = c_finish_omp_parallel (loc
,
23282 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23284 if (ret
== NULL_TREE
)
23286 OMP_PARALLEL_COMBINED (stmt
) = 1;
23289 else if (!flag_openmp
) /* flag_openmp_simd */
23291 c_parser_skip_to_pragma_eol (parser
, false);
23294 else if (cclauses
== NULL
&& strcmp (p
, "sections") == 0)
23296 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23297 cclauses
= cclauses_buf
;
23299 c_parser_consume_token (parser
);
23300 block
= c_begin_omp_parallel ();
23301 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
23302 stmt
= c_finish_omp_parallel (loc
,
23303 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
23305 OMP_PARALLEL_COMBINED (stmt
) = 1;
23309 else if (!flag_openmp
) /* flag_openmp_simd */
23311 c_parser_skip_to_pragma_eol (parser
, false);
23315 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23318 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
23319 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
23322 block
= c_begin_omp_parallel ();
23323 parser
->omp_attrs_forbidden_p
= true;
23324 c_parser_statement (parser
, if_p
);
23325 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
23331 # pragma omp single single-clause[optseq] new-line
23334 LOC is the location of the #pragma.
23337 #define OMP_SINGLE_CLAUSE_MASK \
23338 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23339 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23340 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
23341 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23342 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23345 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
23347 tree stmt
= make_node (OMP_SINGLE
);
23348 SET_EXPR_LOCATION (stmt
, loc
);
23349 TREE_TYPE (stmt
) = void_type_node
;
23351 OMP_SINGLE_CLAUSES (stmt
)
23352 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
23353 "#pragma omp single");
23354 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
23356 return add_stmt (stmt
);
23360 # pragma omp scope scope-clause[optseq] new-line
23363 LOC is the location of the #pragma.
23366 #define OMP_SCOPE_CLAUSE_MASK \
23367 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23368 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23369 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23370 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23371 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23374 c_parser_omp_scope (location_t loc
, c_parser
*parser
, bool *if_p
)
23376 tree stmt
= make_node (OMP_SCOPE
);
23377 SET_EXPR_LOCATION (stmt
, loc
);
23378 TREE_TYPE (stmt
) = void_type_node
;
23380 OMP_SCOPE_CLAUSES (stmt
)
23381 = c_parser_omp_all_clauses (parser
, OMP_SCOPE_CLAUSE_MASK
,
23382 "#pragma omp scope");
23383 OMP_SCOPE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
23385 return add_stmt (stmt
);
23389 # pragma omp task task-clause[optseq] new-line
23391 LOC is the location of the #pragma.
23394 #define OMP_TASK_CLAUSE_MASK \
23395 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23396 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
23397 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23398 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23399 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23400 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23401 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
23402 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
23403 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23404 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
23405 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23406 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
23407 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
23408 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
23411 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
23413 tree clauses
, block
;
23415 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
23416 "#pragma omp task");
23418 block
= c_begin_omp_task ();
23419 parser
->omp_attrs_forbidden_p
= true;
23420 c_parser_statement (parser
, if_p
);
23421 return c_finish_omp_task (loc
, clauses
, block
);
23425 # pragma omp taskwait new-line
23428 # pragma omp taskwait taskwait-clause[optseq] new-line
23431 #define OMP_TASKWAIT_CLAUSE_MASK \
23432 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23433 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23436 c_parser_omp_taskwait (c_parser
*parser
)
23438 location_t loc
= c_parser_peek_token (parser
)->location
;
23439 c_parser_consume_pragma (parser
);
23442 = c_parser_omp_all_clauses (parser
, OMP_TASKWAIT_CLAUSE_MASK
,
23443 "#pragma omp taskwait");
23447 tree stmt
= make_node (OMP_TASK
);
23448 TREE_TYPE (stmt
) = void_node
;
23449 OMP_TASK_CLAUSES (stmt
) = clauses
;
23450 OMP_TASK_BODY (stmt
) = NULL_TREE
;
23451 SET_EXPR_LOCATION (stmt
, loc
);
23455 c_finish_omp_taskwait (loc
);
23459 # pragma omp taskyield new-line
23463 c_parser_omp_taskyield (c_parser
*parser
)
23465 location_t loc
= c_parser_peek_token (parser
)->location
;
23466 c_parser_consume_pragma (parser
);
23467 c_parser_skip_to_pragma_eol (parser
);
23469 c_finish_omp_taskyield (loc
);
23473 # pragma omp taskgroup new-line
23476 # pragma omp taskgroup taskgroup-clause[optseq] new-line
23479 #define OMP_TASKGROUP_CLAUSE_MASK \
23480 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23481 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
23484 c_parser_omp_taskgroup (location_t loc
, c_parser
*parser
, bool *if_p
)
23486 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_TASKGROUP_CLAUSE_MASK
,
23487 "#pragma omp taskgroup");
23489 tree body
= c_parser_omp_structured_block (parser
, if_p
);
23490 return c_finish_omp_taskgroup (loc
, body
, clauses
);
23494 # pragma omp cancel cancel-clause[optseq] new-line
23496 LOC is the location of the #pragma.
23499 #define OMP_CANCEL_CLAUSE_MASK \
23500 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23501 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23502 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23503 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
23504 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
23507 c_parser_omp_cancel (c_parser
*parser
)
23509 location_t loc
= c_parser_peek_token (parser
)->location
;
23511 c_parser_consume_pragma (parser
);
23512 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
23513 "#pragma omp cancel");
23515 c_finish_omp_cancel (loc
, clauses
);
23519 # pragma omp cancellation point cancelpt-clause[optseq] new-line
23521 LOC is the location of the #pragma.
23524 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
23525 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
23526 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
23527 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
23528 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
23531 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
23533 location_t loc
= c_parser_peek_token (parser
)->location
;
23535 bool point_seen
= false;
23537 c_parser_consume_pragma (parser
);
23538 if (c_parser_next_token_is (parser
, CPP_NAME
))
23540 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23541 if (strcmp (p
, "point") == 0)
23543 c_parser_consume_token (parser
);
23549 c_parser_error (parser
, "expected %<point%>");
23550 c_parser_skip_to_pragma_eol (parser
);
23554 if (context
!= pragma_compound
)
23556 if (context
== pragma_stmt
)
23558 "%<#pragma %s%> may only be used in compound statements",
23559 "omp cancellation point");
23561 c_parser_error (parser
, "expected declaration specifiers");
23562 c_parser_skip_to_pragma_eol (parser
, false);
23567 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
23568 "#pragma omp cancellation point");
23570 c_finish_omp_cancellation_point (loc
, clauses
);
23575 #pragma omp distribute distribute-clause[optseq] new-line
23578 #define OMP_DISTRIBUTE_CLAUSE_MASK \
23579 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23580 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23581 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23582 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
23583 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23584 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23585 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
23588 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
23589 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23592 tree clauses
, block
, ret
;
23594 strcat (p_name
, " distribute");
23595 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
23597 if (c_parser_next_token_is (parser
, CPP_NAME
))
23599 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23601 bool parallel
= false;
23603 if (strcmp (p
, "simd") == 0)
23606 parallel
= strcmp (p
, "parallel") == 0;
23607 if (parallel
|| simd
)
23609 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23610 if (cclauses
== NULL
)
23611 cclauses
= cclauses_buf
;
23612 c_parser_consume_token (parser
);
23613 if (!flag_openmp
) /* flag_openmp_simd */
23616 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
23619 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
23622 block
= c_begin_compound_stmt (true);
23624 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
23627 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
23629 block
= c_end_compound_stmt (loc
, block
, true);
23632 ret
= make_node (OMP_DISTRIBUTE
);
23633 TREE_TYPE (ret
) = void_type_node
;
23634 OMP_FOR_BODY (ret
) = block
;
23635 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
23636 SET_EXPR_LOCATION (ret
, loc
);
23641 if (!flag_openmp
) /* flag_openmp_simd */
23643 c_parser_skip_to_pragma_eol (parser
, false);
23647 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23650 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
23651 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
23654 block
= c_begin_compound_stmt (true);
23655 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
23657 block
= c_end_compound_stmt (loc
, block
, true);
23664 # pragma omp teams teams-clause[optseq] new-line
23665 structured-block */
23667 #define OMP_TEAMS_CLAUSE_MASK \
23668 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23669 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23670 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23671 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23672 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
23673 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
23674 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23675 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
23678 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
23679 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23682 tree clauses
, block
, ret
;
23684 strcat (p_name
, " teams");
23685 mask
|= OMP_TEAMS_CLAUSE_MASK
;
23687 if (c_parser_next_token_is (parser
, CPP_NAME
))
23689 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23690 if (strcmp (p
, "distribute") == 0)
23692 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23693 if (cclauses
== NULL
)
23694 cclauses
= cclauses_buf
;
23696 c_parser_consume_token (parser
);
23697 if (!flag_openmp
) /* flag_openmp_simd */
23698 return c_parser_omp_distribute (loc
, parser
, p_name
, mask
,
23700 block
= c_begin_omp_parallel ();
23701 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
23703 block
= c_end_compound_stmt (loc
, block
, true);
23706 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
23707 ret
= make_node (OMP_TEAMS
);
23708 TREE_TYPE (ret
) = void_type_node
;
23709 OMP_TEAMS_CLAUSES (ret
) = clauses
;
23710 OMP_TEAMS_BODY (ret
) = block
;
23711 OMP_TEAMS_COMBINED (ret
) = 1;
23712 SET_EXPR_LOCATION (ret
, loc
);
23713 return add_stmt (ret
);
23715 else if (strcmp (p
, "loop") == 0)
23717 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23718 if (cclauses
== NULL
)
23719 cclauses
= cclauses_buf
;
23721 c_parser_consume_token (parser
);
23722 if (!flag_openmp
) /* flag_openmp_simd */
23723 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
23725 block
= c_begin_omp_parallel ();
23726 ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
23727 block
= c_end_compound_stmt (loc
, block
, true);
23730 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
23731 ret
= make_node (OMP_TEAMS
);
23732 TREE_TYPE (ret
) = void_type_node
;
23733 OMP_TEAMS_CLAUSES (ret
) = clauses
;
23734 OMP_TEAMS_BODY (ret
) = block
;
23735 OMP_TEAMS_COMBINED (ret
) = 1;
23736 SET_EXPR_LOCATION (ret
, loc
);
23737 return add_stmt (ret
);
23740 if (!flag_openmp
) /* flag_openmp_simd */
23742 c_parser_skip_to_pragma_eol (parser
, false);
23746 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23749 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
23750 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
23753 tree stmt
= make_node (OMP_TEAMS
);
23754 TREE_TYPE (stmt
) = void_type_node
;
23755 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
23756 block
= c_begin_omp_parallel ();
23757 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
23758 OMP_TEAMS_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
23759 SET_EXPR_LOCATION (stmt
, loc
);
23761 return add_stmt (stmt
);
23765 # pragma omp target data target-data-clause[optseq] new-line
23766 structured-block */
23768 #define OMP_TARGET_DATA_CLAUSE_MASK \
23769 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23770 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
23771 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23772 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
23773 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
23776 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
23780 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
23783 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
23784 "#pragma omp target data");
23785 c_omp_adjust_map_clauses (clauses
, false);
23787 for (tree
*pc
= &clauses
; *pc
;)
23789 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
23790 switch (OMP_CLAUSE_MAP_KIND (*pc
))
23793 case GOMP_MAP_ALWAYS_TO
:
23794 case GOMP_MAP_PRESENT_TO
:
23795 case GOMP_MAP_ALWAYS_PRESENT_TO
:
23796 case GOMP_MAP_FROM
:
23797 case GOMP_MAP_ALWAYS_FROM
:
23798 case GOMP_MAP_PRESENT_FROM
:
23799 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
23800 case GOMP_MAP_TOFROM
:
23801 case GOMP_MAP_ALWAYS_TOFROM
:
23802 case GOMP_MAP_PRESENT_TOFROM
:
23803 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
23804 case GOMP_MAP_ALLOC
:
23805 case GOMP_MAP_PRESENT_ALLOC
:
23808 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
23809 case GOMP_MAP_ALWAYS_POINTER
:
23810 case GOMP_MAP_ATTACH_DETACH
:
23811 case GOMP_MAP_ATTACH
:
23815 error_at (OMP_CLAUSE_LOCATION (*pc
),
23816 "%<#pragma omp target data%> with map-type other "
23817 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
23818 "on %<map%> clause");
23819 *pc
= OMP_CLAUSE_CHAIN (*pc
);
23822 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
23823 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
23825 pc
= &OMP_CLAUSE_CHAIN (*pc
);
23832 "%<#pragma omp target data%> must contain at least "
23833 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
23838 tree stmt
= make_node (OMP_TARGET_DATA
);
23839 TREE_TYPE (stmt
) = void_type_node
;
23840 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
23841 keep_next_level ();
23842 tree block
= c_begin_compound_stmt (true);
23843 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
23844 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
23846 SET_EXPR_LOCATION (stmt
, loc
);
23847 return add_stmt (stmt
);
23851 # pragma omp target update target-update-clause[optseq] new-line */
23853 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
23854 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
23855 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
23856 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23857 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23858 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23859 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23862 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
23863 enum pragma_context context
)
23865 if (context
== pragma_stmt
)
23867 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
23868 "omp target update");
23869 c_parser_skip_to_pragma_eol (parser
, false);
23874 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
23875 "#pragma omp target update");
23876 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
23877 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
23880 "%<#pragma omp target update%> must contain at least one "
23881 "%<from%> or %<to%> clauses");
23887 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
23889 tree stmt
= make_node (OMP_TARGET_UPDATE
);
23890 TREE_TYPE (stmt
) = void_type_node
;
23891 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
23892 SET_EXPR_LOCATION (stmt
, loc
);
23898 # pragma omp target enter data target-data-clause[optseq] new-line */
23900 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
23901 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
23902 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
23903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23904 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
23905 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
23908 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
23909 enum pragma_context context
)
23911 bool data_seen
= false;
23912 if (c_parser_next_token_is (parser
, CPP_NAME
))
23914 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23915 if (strcmp (p
, "data") == 0)
23917 c_parser_consume_token (parser
);
23923 c_parser_error (parser
, "expected %<data%>");
23924 c_parser_skip_to_pragma_eol (parser
);
23928 if (context
== pragma_stmt
)
23930 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
23931 "omp target enter data");
23932 c_parser_skip_to_pragma_eol (parser
, false);
23938 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
23941 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
23942 "#pragma omp target enter data");
23943 c_omp_adjust_map_clauses (clauses
, false);
23945 for (tree
*pc
= &clauses
; *pc
;)
23947 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
23948 switch (OMP_CLAUSE_MAP_KIND (*pc
))
23951 case GOMP_MAP_ALWAYS_TO
:
23952 case GOMP_MAP_PRESENT_TO
:
23953 case GOMP_MAP_ALWAYS_PRESENT_TO
:
23954 case GOMP_MAP_ALLOC
:
23955 case GOMP_MAP_PRESENT_ALLOC
:
23958 case GOMP_MAP_TOFROM
:
23959 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_TO
);
23962 case GOMP_MAP_ALWAYS_TOFROM
:
23963 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_TO
);
23966 case GOMP_MAP_PRESENT_TOFROM
:
23967 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_PRESENT_TO
);
23970 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
23971 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_PRESENT_TO
);
23974 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
23975 case GOMP_MAP_ALWAYS_POINTER
:
23976 case GOMP_MAP_ATTACH_DETACH
:
23977 case GOMP_MAP_ATTACH
:
23981 error_at (OMP_CLAUSE_LOCATION (*pc
),
23982 "%<#pragma omp target enter data%> with map-type other "
23983 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
23984 *pc
= OMP_CLAUSE_CHAIN (*pc
);
23987 pc
= &OMP_CLAUSE_CHAIN (*pc
);
23994 "%<#pragma omp target enter data%> must contain at least "
23995 "one %<map%> clause");
23999 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
24000 TREE_TYPE (stmt
) = void_type_node
;
24001 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
24002 SET_EXPR_LOCATION (stmt
, loc
);
24008 # pragma omp target exit data target-data-clause[optseq] new-line */
24010 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
24011 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24012 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24013 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24014 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24015 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
24018 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
24019 enum pragma_context context
)
24021 bool data_seen
= false;
24022 if (c_parser_next_token_is (parser
, CPP_NAME
))
24024 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24025 if (strcmp (p
, "data") == 0)
24027 c_parser_consume_token (parser
);
24033 c_parser_error (parser
, "expected %<data%>");
24034 c_parser_skip_to_pragma_eol (parser
);
24038 if (context
== pragma_stmt
)
24040 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
24041 "omp target exit data");
24042 c_parser_skip_to_pragma_eol (parser
, false);
24048 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
24051 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
24052 "#pragma omp target exit data", false);
24053 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP_EXIT_DATA
);
24054 c_omp_adjust_map_clauses (clauses
, false);
24056 for (tree
*pc
= &clauses
; *pc
;)
24058 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
24059 switch (OMP_CLAUSE_MAP_KIND (*pc
))
24061 case GOMP_MAP_FROM
:
24062 case GOMP_MAP_ALWAYS_FROM
:
24063 case GOMP_MAP_PRESENT_FROM
:
24064 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
24065 case GOMP_MAP_RELEASE
:
24066 case GOMP_MAP_DELETE
:
24069 case GOMP_MAP_TOFROM
:
24070 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_FROM
);
24073 case GOMP_MAP_ALWAYS_TOFROM
:
24074 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_FROM
);
24077 case GOMP_MAP_PRESENT_TOFROM
:
24078 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_PRESENT_FROM
);
24081 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
24082 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_PRESENT_FROM
);
24085 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
24086 case GOMP_MAP_ALWAYS_POINTER
:
24087 case GOMP_MAP_ATTACH_DETACH
:
24088 case GOMP_MAP_DETACH
:
24092 error_at (OMP_CLAUSE_LOCATION (*pc
),
24093 "%<#pragma omp target exit data%> with map-type other "
24094 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
24095 "on %<map%> clause");
24096 *pc
= OMP_CLAUSE_CHAIN (*pc
);
24099 pc
= &OMP_CLAUSE_CHAIN (*pc
);
24106 "%<#pragma omp target exit data%> must contain at least one "
24111 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
24112 TREE_TYPE (stmt
) = void_type_node
;
24113 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
24114 SET_EXPR_LOCATION (stmt
, loc
);
24120 # pragma omp target target-clause[optseq] new-line
24121 structured-block */
24123 #define OMP_TARGET_CLAUSE_MASK \
24124 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
24125 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
24126 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
24127 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
24128 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
24129 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
24130 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
24131 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
24132 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
24133 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
24134 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
24135 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
24136 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
24139 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
24141 location_t loc
= c_parser_peek_token (parser
)->location
;
24142 c_parser_consume_pragma (parser
);
24143 tree
*pc
= NULL
, stmt
, block
;
24145 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
24147 c_parser_error (parser
, "expected declaration specifiers");
24148 c_parser_skip_to_pragma_eol (parser
);
24154 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
24156 if (c_parser_next_token_is (parser
, CPP_NAME
))
24158 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24159 enum tree_code ccode
= ERROR_MARK
;
24161 if (strcmp (p
, "teams") == 0)
24163 else if (strcmp (p
, "parallel") == 0)
24164 ccode
= OMP_PARALLEL
;
24165 else if (strcmp (p
, "simd") == 0)
24167 if (ccode
!= ERROR_MARK
)
24169 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
24170 char p_name
[sizeof ("#pragma omp target teams distribute "
24171 "parallel for simd")];
24173 c_parser_consume_token (parser
);
24174 strcpy (p_name
, "#pragma omp target");
24175 if (!flag_openmp
) /* flag_openmp_simd */
24181 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
24182 OMP_TARGET_CLAUSE_MASK
,
24186 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
24187 OMP_TARGET_CLAUSE_MASK
,
24191 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
24192 OMP_TARGET_CLAUSE_MASK
,
24196 gcc_unreachable ();
24198 return stmt
!= NULL_TREE
;
24200 keep_next_level ();
24201 tree block
= c_begin_compound_stmt (true), ret
;
24205 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
24206 OMP_TARGET_CLAUSE_MASK
, cclauses
,
24210 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
24211 OMP_TARGET_CLAUSE_MASK
, cclauses
,
24215 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
24216 OMP_TARGET_CLAUSE_MASK
, cclauses
,
24220 gcc_unreachable ();
24222 block
= c_end_compound_stmt (loc
, block
, true);
24223 if (ret
== NULL_TREE
)
24225 if (ccode
== OMP_TEAMS
)
24226 /* For combined target teams, ensure the num_teams and
24227 thread_limit clause expressions are evaluated on the host,
24228 before entering the target construct. */
24229 for (tree c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
24230 c
; c
= OMP_CLAUSE_CHAIN (c
))
24231 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
24232 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
24234 i
<= (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
); ++i
)
24235 if (OMP_CLAUSE_OPERAND (c
, i
)
24236 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, i
)) != INTEGER_CST
)
24238 tree expr
= OMP_CLAUSE_OPERAND (c
, i
);
24239 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
24240 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
24241 expr
, NULL_TREE
, NULL_TREE
);
24243 OMP_CLAUSE_OPERAND (c
, i
) = expr
;
24244 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
24245 OMP_CLAUSE_FIRSTPRIVATE
);
24246 OMP_CLAUSE_DECL (tc
) = tmp
;
24247 OMP_CLAUSE_CHAIN (tc
)
24248 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
24249 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
24251 tree stmt
= make_node (OMP_TARGET
);
24252 TREE_TYPE (stmt
) = void_type_node
;
24253 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
24254 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
24255 OMP_TARGET_BODY (stmt
) = block
;
24256 OMP_TARGET_COMBINED (stmt
) = 1;
24257 SET_EXPR_LOCATION (stmt
, loc
);
24259 pc
= &OMP_TARGET_CLAUSES (stmt
);
24260 goto check_clauses
;
24262 else if (!flag_openmp
) /* flag_openmp_simd */
24264 c_parser_skip_to_pragma_eol (parser
, false);
24267 else if (strcmp (p
, "data") == 0)
24269 c_parser_consume_token (parser
);
24270 c_parser_omp_target_data (loc
, parser
, if_p
);
24273 else if (strcmp (p
, "enter") == 0)
24275 c_parser_consume_token (parser
);
24276 return c_parser_omp_target_enter_data (loc
, parser
, context
);
24278 else if (strcmp (p
, "exit") == 0)
24280 c_parser_consume_token (parser
);
24281 return c_parser_omp_target_exit_data (loc
, parser
, context
);
24283 else if (strcmp (p
, "update") == 0)
24285 c_parser_consume_token (parser
);
24286 return c_parser_omp_target_update (loc
, parser
, context
);
24289 if (!flag_openmp
) /* flag_openmp_simd */
24291 c_parser_skip_to_pragma_eol (parser
, false);
24295 stmt
= make_node (OMP_TARGET
);
24296 TREE_TYPE (stmt
) = void_type_node
;
24298 OMP_TARGET_CLAUSES (stmt
)
24299 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
24300 "#pragma omp target", false);
24301 for (tree c
= OMP_TARGET_CLAUSES (stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
24302 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
)
24304 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
24305 OMP_CLAUSE_DECL (nc
) = OMP_CLAUSE_DECL (c
);
24306 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_ALWAYS_TOFROM
);
24307 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
24308 OMP_CLAUSE_CHAIN (c
) = nc
;
24310 OMP_TARGET_CLAUSES (stmt
)
24311 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt
), C_ORT_OMP_TARGET
);
24312 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
24314 pc
= &OMP_TARGET_CLAUSES (stmt
);
24315 keep_next_level ();
24316 block
= c_begin_compound_stmt (true);
24317 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
24318 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
24320 SET_EXPR_LOCATION (stmt
, loc
);
24326 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
24327 switch (OMP_CLAUSE_MAP_KIND (*pc
))
24330 case GOMP_MAP_ALWAYS_TO
:
24331 case GOMP_MAP_PRESENT_TO
:
24332 case GOMP_MAP_ALWAYS_PRESENT_TO
:
24333 case GOMP_MAP_FROM
:
24334 case GOMP_MAP_ALWAYS_FROM
:
24335 case GOMP_MAP_PRESENT_FROM
:
24336 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
24337 case GOMP_MAP_TOFROM
:
24338 case GOMP_MAP_ALWAYS_TOFROM
:
24339 case GOMP_MAP_PRESENT_TOFROM
:
24340 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
24341 case GOMP_MAP_ALLOC
:
24342 case GOMP_MAP_PRESENT_ALLOC
:
24343 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
24344 case GOMP_MAP_ALWAYS_POINTER
:
24345 case GOMP_MAP_POINTER
:
24346 case GOMP_MAP_ATTACH_DETACH
:
24347 case GOMP_MAP_ATTACH
:
24350 error_at (OMP_CLAUSE_LOCATION (*pc
),
24351 "%<#pragma omp target%> with map-type other "
24352 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
24353 "on %<map%> clause");
24354 *pc
= OMP_CLAUSE_CHAIN (*pc
);
24357 pc
= &OMP_CLAUSE_CHAIN (*pc
);
24359 cfun
->has_omp_target
= true;
24364 # pragma omp declare simd declare-simd-clauses[optseq] new-line
24367 # pragma omp declare variant (identifier) match(context-selector) new-line
24370 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
24371 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
24372 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
24373 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
24374 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
24375 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
24376 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
24379 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
24381 c_token
*token
= c_parser_peek_token (parser
);
24382 gcc_assert (token
->type
== CPP_NAME
);
24383 tree kind
= token
->value
;
24384 gcc_assert (strcmp (IDENTIFIER_POINTER (kind
), "simd") == 0
24385 || strcmp (IDENTIFIER_POINTER (kind
), "variant") == 0);
24387 auto_vec
<c_token
> clauses
;
24388 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
24390 c_token
*token
= c_parser_peek_token (parser
);
24391 if (token
->type
== CPP_EOF
)
24393 c_parser_skip_to_pragma_eol (parser
);
24396 clauses
.safe_push (*token
);
24397 c_parser_consume_token (parser
);
24399 clauses
.safe_push (*c_parser_peek_token (parser
));
24400 c_parser_skip_to_pragma_eol (parser
);
24402 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
24404 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_DECLARE
24405 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
24406 || c_parser_peek_2nd_token (parser
)->value
!= kind
)
24408 error ("%<#pragma omp declare %s%> must be followed by "
24409 "function declaration or definition or another "
24410 "%<#pragma omp declare %s%>",
24411 IDENTIFIER_POINTER (kind
), IDENTIFIER_POINTER (kind
));
24414 c_parser_consume_pragma (parser
);
24415 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
24417 c_token
*token
= c_parser_peek_token (parser
);
24418 if (token
->type
== CPP_EOF
)
24420 c_parser_skip_to_pragma_eol (parser
);
24423 clauses
.safe_push (*token
);
24424 c_parser_consume_token (parser
);
24426 clauses
.safe_push (*c_parser_peek_token (parser
));
24427 c_parser_skip_to_pragma_eol (parser
);
24430 /* Make sure nothing tries to read past the end of the tokens. */
24432 memset (&eof_token
, 0, sizeof (eof_token
));
24433 eof_token
.type
= CPP_EOF
;
24434 clauses
.safe_push (eof_token
);
24435 clauses
.safe_push (eof_token
);
24439 case pragma_external
:
24440 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24441 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
24443 int ext
= disable_extension_diagnostics ();
24445 c_parser_consume_token (parser
);
24446 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24447 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
24448 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
24450 restore_extension_diagnostics (ext
);
24453 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
24456 case pragma_struct
:
24459 error ("%<#pragma omp declare %s%> must be followed by "
24460 "function declaration or definition",
24461 IDENTIFIER_POINTER (kind
));
24463 case pragma_compound
:
24464 bool have_std_attrs
;
24466 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
24467 if (have_std_attrs
)
24468 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
24470 std_attrs
= NULL_TREE
;
24471 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24472 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
24474 int ext
= disable_extension_diagnostics ();
24476 c_parser_consume_token (parser
);
24477 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24478 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
24479 if (c_parser_next_tokens_start_declaration (parser
)
24480 || c_parser_nth_token_starts_std_attributes (parser
, 1))
24482 c_parser_declaration_or_fndef (parser
, true, true, true, true,
24483 true, NULL
, &clauses
,
24484 have_std_attrs
, std_attrs
);
24485 restore_extension_diagnostics (ext
);
24488 restore_extension_diagnostics (ext
);
24490 else if (c_parser_next_tokens_start_declaration (parser
))
24492 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
24493 NULL
, &clauses
, have_std_attrs
,
24497 error ("%<#pragma omp declare %s%> must be followed by "
24498 "function declaration or definition",
24499 IDENTIFIER_POINTER (kind
));
24502 gcc_unreachable ();
24509 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
24512 score(score-expression)
24514 Note that this function returns a list of trait selectors for the
24515 trait-selector-set SET. */
24518 c_parser_omp_context_selector (c_parser
*parser
, enum omp_tss_code set
,
24521 tree ret
= NULL_TREE
;
24525 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24526 || c_parser_next_token_is (parser
, CPP_NAME
))
24527 selector
= c_parser_peek_token (parser
)->value
;
24530 c_parser_error (parser
, "expected trait selector name");
24531 return error_mark_node
;
24533 enum omp_ts_code sel
24534 = omp_lookup_ts_code (set
, IDENTIFIER_POINTER (selector
));
24536 if (sel
== OMP_TRAIT_INVALID
)
24538 /* Per the spec, "Implementations can ignore specified selectors
24539 that are not those described in this section"; however, we
24540 must record such selectors because they cause match failures. */
24541 warning_at (c_parser_peek_token (parser
)->location
, OPT_Wopenmp
,
24542 "unknown selector %qs for context selector set %qs",
24543 IDENTIFIER_POINTER (selector
), omp_tss_map
[set
]);
24544 c_parser_consume_token (parser
);
24545 ret
= make_trait_selector (sel
, NULL_TREE
, NULL_TREE
, ret
);
24546 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
24547 c_parser_balanced_token_sequence (parser
);
24548 if (c_parser_next_token_is (parser
, CPP_COMMA
))
24550 c_parser_consume_token (parser
);
24557 c_parser_consume_token (parser
);
24559 tree properties
= NULL_TREE
;
24560 tree scoreval
= NULL_TREE
;
24561 enum omp_tp_type property_kind
= omp_ts_map
[sel
].tp_type
;
24562 bool allow_score
= omp_ts_map
[sel
].allow_score
;
24565 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
24567 if (property_kind
== OMP_TRAIT_PROPERTY_NONE
)
24569 error_at (c_parser_peek_token (parser
)->location
,
24570 "selector %qs does not accept any properties",
24571 IDENTIFIER_POINTER (selector
));
24572 return error_mark_node
;
24575 matching_parens parens
;
24576 parens
.require_open (parser
);
24578 c_token
*token
= c_parser_peek_token (parser
);
24579 if (c_parser_next_token_is (parser
, CPP_NAME
)
24580 && strcmp (IDENTIFIER_POINTER (token
->value
), "score") == 0
24581 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
24583 c_parser_consume_token (parser
);
24585 matching_parens parens2
;
24586 parens2
.require_open (parser
);
24587 tree score
= c_parser_expr_no_commas (parser
, NULL
).value
;
24588 parens2
.skip_until_found_close (parser
);
24589 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
24591 error_at (token
->location
,
24592 "%<score%> cannot be specified in traits "
24593 "in the %qs trait-selector-set",
24595 else if (score
!= error_mark_node
)
24597 mark_exp_read (score
);
24598 score
= c_fully_fold (score
, false, NULL
);
24599 if (!INTEGRAL_TYPE_P (TREE_TYPE (score
))
24600 || TREE_CODE (score
) != INTEGER_CST
)
24601 error_at (token
->location
, "%<score%> argument must "
24602 "be constant integer expression");
24603 else if (tree_int_cst_sgn (score
) < 0)
24604 error_at (token
->location
, "%<score%> argument must "
24605 "be non-negative");
24609 token
= c_parser_peek_token (parser
);
24612 switch (property_kind
)
24614 case OMP_TRAIT_PROPERTY_ID
:
24615 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24616 || c_parser_next_token_is (parser
, CPP_NAME
))
24618 tree prop
= c_parser_peek_token (parser
)->value
;
24619 c_parser_consume_token (parser
);
24620 properties
= make_trait_property (prop
, NULL_TREE
,
24625 c_parser_error (parser
, "expected identifier");
24626 return error_mark_node
;
24629 case OMP_TRAIT_PROPERTY_NAME_LIST
:
24632 tree prop
= OMP_TP_NAMELIST_NODE
;
24633 tree value
= NULL_TREE
;
24634 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
24635 || c_parser_next_token_is (parser
, CPP_NAME
))
24637 value
= c_parser_peek_token (parser
)->value
;
24638 c_parser_consume_token (parser
);
24640 else if (c_parser_next_token_is (parser
, CPP_STRING
))
24641 value
= c_parser_string_literal (parser
, false,
24645 c_parser_error (parser
, "expected identifier or "
24647 return error_mark_node
;
24650 properties
= make_trait_property (prop
, value
, properties
);
24652 if (c_parser_next_token_is (parser
, CPP_COMMA
))
24653 c_parser_consume_token (parser
);
24659 case OMP_TRAIT_PROPERTY_EXPR
:
24660 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
24661 if (t
!= error_mark_node
)
24664 t
= c_fully_fold (t
, false, NULL
);
24665 /* FIXME: this is bogus, both device_num and
24666 condition selectors allow arbitrary expressions. */
24667 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
24668 || !tree_fits_shwi_p (t
))
24669 error_at (token
->location
, "property must be "
24670 "constant integer expression");
24672 properties
= make_trait_property (NULL_TREE
, t
,
24676 return error_mark_node
;
24678 case OMP_TRAIT_PROPERTY_CLAUSE_LIST
:
24679 if (sel
== OMP_TRAIT_CONSTRUCT_SIMD
)
24681 if (parms
== NULL_TREE
)
24683 error_at (token
->location
, "properties for %<simd%> "
24684 "selector may not be specified in "
24685 "%<metadirective%>");
24686 return error_mark_node
;
24689 c
= c_parser_omp_all_clauses (parser
,
24690 OMP_DECLARE_SIMD_CLAUSE_MASK
,
24692 c
= c_omp_declare_simd_clauses_to_numbers (parms
24694 ? NULL_TREE
: parms
,
24698 else if (sel
== OMP_TRAIT_IMPLEMENTATION_REQUIRES
)
24700 /* FIXME: The "requires" selector was added in OpenMP 5.1.
24701 Currently only the now-deprecated syntax
24702 from OpenMP 5.0 is supported. */
24703 sorry_at (token
->location
,
24704 "%<requires%> selector is not supported yet");
24705 return error_mark_node
;
24708 gcc_unreachable ();
24711 gcc_unreachable ();
24714 parens
.skip_until_found_close (parser
);
24715 properties
= nreverse (properties
);
24717 else if (property_kind
!= OMP_TRAIT_PROPERTY_NONE
24718 && property_kind
!= OMP_TRAIT_PROPERTY_CLAUSE_LIST
24719 && property_kind
!= OMP_TRAIT_PROPERTY_EXTENSION
)
24721 c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>");
24722 return error_mark_node
;
24725 ret
= make_trait_selector (sel
, scoreval
, properties
, ret
);
24727 if (c_parser_next_token_is (parser
, CPP_COMMA
))
24728 c_parser_consume_token (parser
);
24734 return nreverse (ret
);
24739 trait-set-selector[,trait-set-selector[,...]]
24741 trait-set-selector:
24742 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
24744 trait-set-selector-name:
24751 c_parser_omp_context_selector_specification (c_parser
*parser
, tree parms
)
24753 tree ret
= NULL_TREE
;
24756 const char *setp
= "";
24757 if (c_parser_next_token_is (parser
, CPP_NAME
))
24758 setp
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24759 enum omp_tss_code set
= omp_lookup_tss_code (setp
);
24761 if (set
== OMP_TRAIT_SET_INVALID
)
24763 c_parser_error (parser
, "expected context selector set name");
24764 return error_mark_node
;
24767 c_parser_consume_token (parser
);
24769 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
24770 return error_mark_node
;
24772 matching_braces braces
;
24773 if (!braces
.require_open (parser
))
24774 return error_mark_node
;
24776 tree selectors
= c_parser_omp_context_selector (parser
, set
, parms
);
24777 if (selectors
== error_mark_node
)
24778 ret
= error_mark_node
;
24779 else if (ret
!= error_mark_node
)
24780 ret
= make_trait_set_selector (set
, selectors
, ret
);
24782 braces
.skip_until_found_close (parser
);
24784 if (c_parser_next_token_is (parser
, CPP_COMMA
))
24785 c_parser_consume_token (parser
);
24791 if (ret
== error_mark_node
)
24793 return nreverse (ret
);
24796 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
24797 that into "omp declare variant base" attribute. */
24800 c_finish_omp_declare_variant (c_parser
*parser
, tree fndecl
, tree parms
)
24802 matching_parens parens
;
24803 if (!parens
.require_open (parser
))
24806 c_parser_skip_to_pragma_eol (parser
, false);
24810 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
24811 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
24813 c_parser_error (parser
, "expected identifier");
24817 c_token
*token
= c_parser_peek_token (parser
);
24818 tree variant
= lookup_name (token
->value
);
24820 if (variant
== NULL_TREE
)
24822 undeclared_variable (token
->location
, token
->value
);
24823 variant
= error_mark_node
;
24826 c_parser_consume_token (parser
);
24828 parens
.require_close (parser
);
24830 if (c_parser_next_token_is (parser
, CPP_COMMA
)
24831 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
24832 c_parser_consume_token (parser
);
24834 const char *clause
= "";
24835 location_t match_loc
= c_parser_peek_token (parser
)->location
;
24836 if (c_parser_next_token_is (parser
, CPP_NAME
))
24837 clause
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24838 if (strcmp (clause
, "match"))
24840 c_parser_error (parser
, "expected %<match%>");
24844 c_parser_consume_token (parser
);
24846 if (!parens
.require_open (parser
))
24849 if (parms
== NULL_TREE
)
24850 parms
= error_mark_node
;
24852 tree ctx
= c_parser_omp_context_selector_specification (parser
, parms
);
24853 if (ctx
== error_mark_node
)
24855 ctx
= omp_check_context_selector (match_loc
, ctx
);
24856 if (ctx
!= error_mark_node
&& variant
!= error_mark_node
)
24858 if (TREE_CODE (variant
) != FUNCTION_DECL
)
24860 error_at (token
->location
, "variant %qD is not a function", variant
);
24861 variant
= error_mark_node
;
24863 else if (!omp_get_context_selector (ctx
, OMP_TRAIT_SET_CONSTRUCT
,
24864 OMP_TRAIT_CONSTRUCT_SIMD
)
24865 && !comptypes (TREE_TYPE (fndecl
), TREE_TYPE (variant
)))
24867 error_at (token
->location
, "variant %qD and base %qD have "
24868 "incompatible types", variant
, fndecl
);
24869 variant
= error_mark_node
;
24871 else if (fndecl_built_in_p (variant
)
24872 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
24873 "__builtin_", strlen ("__builtin_")) == 0
24874 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
24875 "__sync_", strlen ("__sync_")) == 0
24876 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
24877 "__atomic_", strlen ("__atomic_")) == 0))
24879 error_at (token
->location
, "variant %qD is a built-in", variant
);
24880 variant
= error_mark_node
;
24882 if (variant
!= error_mark_node
)
24884 C_DECL_USED (variant
) = 1;
24886 = omp_get_context_selector_list (ctx
, OMP_TRAIT_SET_CONSTRUCT
);
24887 omp_mark_declare_variant (match_loc
, variant
, construct
);
24888 if (omp_context_selector_matches (ctx
))
24891 = tree_cons (get_identifier ("omp declare variant base"),
24892 build_tree_list (variant
, ctx
),
24893 DECL_ATTRIBUTES (fndecl
));
24894 DECL_ATTRIBUTES (fndecl
) = attr
;
24899 parens
.require_close (parser
);
24900 c_parser_skip_to_pragma_eol (parser
);
24903 /* Finalize #pragma omp declare simd or #pragma omp declare variant
24904 clauses after FNDECL has been parsed, and put that into "omp declare simd"
24905 or "omp declare variant base" attribute. */
24908 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
24909 vec
<c_token
> *pclauses
)
24911 vec
<c_token
> &clauses
= *pclauses
;
24913 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
24914 indicates error has been reported and CPP_PRAGMA that
24915 c_finish_omp_declare_simd has already processed the tokens. */
24916 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
24918 const char *kind
= "simd";
24919 if (clauses
.exists ()
24920 && (clauses
[0].type
== CPP_NAME
|| clauses
[0].type
== CPP_PRAGMA
))
24921 kind
= IDENTIFIER_POINTER (clauses
[0].value
);
24922 gcc_assert (strcmp (kind
, "simd") == 0 || strcmp (kind
, "variant") == 0);
24923 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
24925 error ("%<#pragma omp declare %s%> not immediately followed by "
24926 "a function declaration or definition", kind
);
24927 clauses
[0].type
= CPP_EOF
;
24930 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
24932 error_at (DECL_SOURCE_LOCATION (fndecl
),
24933 "%<#pragma omp declare %s%> not immediately followed by "
24934 "a single function declaration or definition", kind
);
24935 clauses
[0].type
= CPP_EOF
;
24939 if (parms
== NULL_TREE
)
24940 parms
= DECL_ARGUMENTS (fndecl
);
24942 unsigned int tokens_avail
= parser
->tokens_avail
;
24943 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
24945 parser
->tokens
= clauses
.address ();
24946 parser
->tokens_avail
= clauses
.length ();
24948 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
24949 while (parser
->tokens_avail
> 3)
24951 c_token
*token
= c_parser_peek_token (parser
);
24952 gcc_assert (token
->type
== CPP_NAME
);
24953 kind
= IDENTIFIER_POINTER (token
->value
);
24954 c_parser_consume_token (parser
);
24955 parser
->in_pragma
= true;
24957 if (strcmp (kind
, "simd") == 0)
24960 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
24961 "#pragma omp declare simd");
24962 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
24963 if (c
!= NULL_TREE
)
24964 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
24965 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
24966 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
24967 DECL_ATTRIBUTES (fndecl
) = c
;
24971 gcc_assert (strcmp (kind
, "variant") == 0);
24972 c_finish_omp_declare_variant (parser
, fndecl
, parms
);
24976 parser
->tokens
= &parser
->tokens_buf
[0];
24977 parser
->tokens_avail
= tokens_avail
;
24978 if (clauses
.exists ())
24979 clauses
[0].type
= CPP_PRAGMA
;
24982 /* D should be C_TOKEN_VEC from omp::decl attribute. If it contains
24983 a threadprivate, groupprivate, allocate or declare target directive,
24984 return true and parse it for DECL. */
24987 c_maybe_parse_omp_decl (tree decl
, tree d
)
24989 gcc_assert (TREE_CODE (d
) == C_TOKEN_VEC
);
24990 vec
<c_token
, va_gc
> *toks
= C_TOKEN_VEC_TOKENS (d
);
24991 c_token
*first
= toks
->address ();
24992 c_token
*last
= first
+ toks
->length ();
24993 const char *directive
[3] = {};
24994 for (int j
= 0; j
< 3; j
++)
24996 tree id
= NULL_TREE
;
24997 if (first
+ j
== last
)
24999 if (first
[j
].type
== CPP_NAME
)
25000 id
= first
[j
].value
;
25001 else if (first
[j
].type
== CPP_KEYWORD
)
25002 id
= ridpointers
[(int) first
[j
].keyword
];
25005 directive
[j
] = IDENTIFIER_POINTER (id
);
25007 const c_omp_directive
*dir
= NULL
;
25009 dir
= c_omp_categorize_directive (directive
[0], directive
[1],
25013 error_at (first
->location
,
25014 "unknown OpenMP directive name in "
25015 "%qs attribute argument", "omp::decl");
25018 if (dir
->id
!= PRAGMA_OMP_THREADPRIVATE
25019 /* && dir->id != PRAGMA_OMP_GROUPPRIVATE */
25020 && dir
->id
!= PRAGMA_OMP_ALLOCATE
25021 && (dir
->id
!= PRAGMA_OMP_DECLARE
25022 || strcmp (directive
[1], "target") != 0))
25025 if (!flag_openmp
&& !dir
->simd
)
25028 c_parser
*parser
= the_parser
;
25029 unsigned int tokens_avail
= parser
->tokens_avail
;
25030 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
25032 vec_safe_reserve (toks
, last
- first
+ 2, true);
25034 tok
.type
= CPP_PRAGMA
;
25035 tok
.keyword
= RID_MAX
;
25036 tok
.pragma_kind
= pragma_kind (dir
->id
);
25037 tok
.location
= first
->location
;
25038 toks
->quick_push (tok
);
25039 while (++first
< last
)
25040 toks
->quick_push (*first
);
25042 tok
.type
= CPP_PRAGMA_EOL
;
25043 tok
.keyword
= RID_MAX
;
25044 tok
.location
= last
[-1].location
;
25045 toks
->quick_push (tok
);
25047 tok
.type
= CPP_EOF
;
25048 tok
.keyword
= RID_MAX
;
25049 tok
.location
= last
[-1].location
;
25050 tok
.flags
= tokens_avail
;
25051 toks
->quick_push (tok
);
25052 parser
->in_omp_decl_attribute
= decl
;
25053 parser
->tokens
= toks
->address ();
25054 parser
->tokens_avail
= toks
->length ();
25055 parser
->in_omp_attribute_pragma
= toks
;
25056 c_parser_pragma (parser
, pragma_external
, NULL
);
25057 parser
->in_omp_decl_attribute
= NULL_TREE
;
25062 # pragma omp declare target new-line
25063 declarations and definitions
25064 # pragma omp end declare target new-line
25067 # pragma omp declare target ( extended-list ) new-line
25069 # pragma omp declare target declare-target-clauses[seq] new-line */
25071 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
25072 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
25073 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
25074 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
25075 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
25076 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
25079 c_parser_omp_declare_target (c_parser
*parser
)
25081 tree clauses
= NULL_TREE
;
25082 int device_type
= 0;
25083 bool indirect
= false;
25084 bool only_device_type_or_indirect
= true;
25085 if (c_parser_next_token_is (parser
, CPP_NAME
)
25086 || (c_parser_next_token_is (parser
, CPP_COMMA
)
25087 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
))
25088 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
25089 "#pragma omp declare target");
25090 else if (parser
->in_omp_decl_attribute
25091 || c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
25093 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
25095 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
25096 c_parser_skip_to_pragma_eol (parser
);
25100 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25101 c_parser_skip_to_pragma_eol (parser
);
25102 c_omp_declare_target_attr attr
= { attr_syntax
, -1, 0 };
25103 vec_safe_push (current_omp_declare_target_attribute
, attr
);
25106 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
25108 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
25109 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
25110 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_INDIRECT
)
25111 indirect
|= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c
));
25113 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
25115 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
25116 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_INDIRECT
)
25118 tree t
= OMP_CLAUSE_DECL (c
), id
;
25119 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
25120 tree at2
= lookup_attribute ("omp declare target link",
25121 DECL_ATTRIBUTES (t
));
25122 only_device_type_or_indirect
= false;
25123 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
25125 id
= get_identifier ("omp declare target link");
25126 std::swap (at1
, at2
);
25129 id
= get_identifier ("omp declare target");
25132 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_ENTER
)
25133 error_at (OMP_CLAUSE_LOCATION (c
),
25134 "%qD specified both in declare target %<link%> and %qs"
25135 " clauses", t
, OMP_CLAUSE_ENTER_TO (c
) ? "to" : "enter");
25137 error_at (OMP_CLAUSE_LOCATION (c
),
25138 "%qD specified both in declare target %<link%> and "
25139 "%<to%> or %<enter%> clauses", t
);
25144 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
25145 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
25148 symtab_node
*node
= symtab_node::get (t
);
25151 node
->offloadable
= 1;
25152 if (ENABLE_OFFLOADING
)
25154 g
->have_offload
= true;
25155 if (is_a
<varpool_node
*> (node
))
25156 vec_safe_push (offload_vars
, t
);
25160 if (TREE_CODE (t
) != FUNCTION_DECL
)
25162 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_HOST
) != 0)
25164 tree at3
= lookup_attribute ("omp declare target host",
25165 DECL_ATTRIBUTES (t
));
25166 if (at3
== NULL_TREE
)
25168 id
= get_identifier ("omp declare target host");
25169 DECL_ATTRIBUTES (t
)
25170 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
25173 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_NOHOST
) != 0)
25175 tree at3
= lookup_attribute ("omp declare target nohost",
25176 DECL_ATTRIBUTES (t
));
25177 if (at3
== NULL_TREE
)
25179 id
= get_identifier ("omp declare target nohost");
25180 DECL_ATTRIBUTES (t
)
25181 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
25186 tree at4
= lookup_attribute ("omp declare target indirect",
25187 DECL_ATTRIBUTES (t
));
25188 if (at4
== NULL_TREE
)
25190 id
= get_identifier ("omp declare target indirect");
25191 DECL_ATTRIBUTES (t
)
25192 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
25196 if ((device_type
|| indirect
) && only_device_type_or_indirect
)
25197 error_at (OMP_CLAUSE_LOCATION (clauses
),
25198 "directive with only %<device_type%> or %<indirect%> clauses");
25199 if (indirect
&& device_type
&& device_type
!= OMP_CLAUSE_DEVICE_TYPE_ANY
)
25200 error_at (OMP_CLAUSE_LOCATION (clauses
),
25201 "%<device_type%> clause must specify 'any' when used with "
25202 "an %<indirect%> clause");
25206 #pragma omp begin assumes clauses[optseq] new-line
25208 #pragma omp begin declare target clauses[optseq] new-line */
25210 #define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \
25211 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
25212 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
25215 c_parser_omp_begin (c_parser
*parser
)
25217 const char *p
= "";
25218 c_parser_consume_pragma (parser
);
25219 if (c_parser_next_token_is (parser
, CPP_NAME
))
25220 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25221 if (strcmp (p
, "declare") == 0)
25223 c_parser_consume_token (parser
);
25225 if (c_parser_next_token_is (parser
, CPP_NAME
))
25226 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25227 if (strcmp (p
, "target") == 0)
25229 c_parser_consume_token (parser
);
25230 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25232 = c_parser_omp_all_clauses (parser
,
25233 OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK
,
25234 "#pragma omp begin declare target");
25235 int device_type
= 0;
25237 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
25239 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
25240 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
25241 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_INDIRECT
)
25242 indirect
|= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c
));
25244 c_omp_declare_target_attr attr
= { attr_syntax
, device_type
,
25246 vec_safe_push (current_omp_declare_target_attribute
, attr
);
25250 c_parser_error (parser
, "expected %<target%>");
25251 c_parser_skip_to_pragma_eol (parser
);
25254 else if (strcmp (p
, "assumes") == 0)
25256 c_parser_consume_token (parser
);
25257 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25258 c_parser_omp_assumption_clauses (parser
, false);
25259 struct c_omp_begin_assumes_data a
= { attr_syntax
};
25260 vec_safe_push (current_omp_begin_assumes
, a
);
25264 c_parser_error (parser
, "expected %<declare target%> or %<assumes%>");
25265 c_parser_skip_to_pragma_eol (parser
);
25270 #pragma omp end declare target
25273 #pragma omp end assumes */
25276 c_parser_omp_end (c_parser
*parser
)
25278 location_t loc
= c_parser_peek_token (parser
)->location
;
25279 const char *p
= "";
25280 c_parser_consume_pragma (parser
);
25281 if (c_parser_next_token_is (parser
, CPP_NAME
))
25282 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25283 if (strcmp (p
, "declare") == 0)
25285 c_parser_consume_token (parser
);
25286 if (c_parser_next_token_is (parser
, CPP_NAME
)
25287 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
25289 c_parser_consume_token (parser
);
25292 c_parser_error (parser
, "expected %<target%>");
25293 c_parser_skip_to_pragma_eol (parser
);
25296 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25297 c_parser_skip_to_pragma_eol (parser
);
25298 if (!vec_safe_length (current_omp_declare_target_attribute
))
25299 error_at (loc
, "%<#pragma omp end declare target%> without "
25300 "corresponding %<#pragma omp declare target%> or "
25301 "%<#pragma omp begin declare target%>");
25304 c_omp_declare_target_attr
25305 a
= current_omp_declare_target_attribute
->pop ();
25306 if (a
.attr_syntax
!= attr_syntax
)
25310 "%qs in attribute syntax terminated "
25311 "with %qs in pragma syntax",
25312 a
.device_type
>= 0 ? "begin declare target"
25313 : "declare target",
25314 "end declare target");
25317 "%qs in pragma syntax terminated "
25318 "with %qs in attribute syntax",
25319 a
.device_type
>= 0 ? "begin declare target"
25320 : "declare target",
25321 "end declare target");
25325 else if (strcmp (p
, "assumes") == 0)
25327 c_parser_consume_token (parser
);
25328 bool attr_syntax
= parser
->in_omp_attribute_pragma
!= NULL
;
25329 c_parser_skip_to_pragma_eol (parser
);
25330 if (!vec_safe_length (current_omp_begin_assumes
))
25331 error_at (loc
, "%qs without corresponding %qs",
25332 "#pragma omp end assumes", "#pragma omp begin assumes");
25335 c_omp_begin_assumes_data
25336 a
= current_omp_begin_assumes
->pop ();
25337 if (a
.attr_syntax
!= attr_syntax
)
25341 "%qs in attribute syntax terminated "
25342 "with %qs in pragma syntax",
25343 "begin assumes", "end assumes");
25346 "%qs in pragma syntax terminated "
25347 "with %qs in attribute syntax",
25348 "begin assumes", "end assumes");
25354 c_parser_error (parser
, "expected %<declare%> or %<assumes%>");
25355 c_parser_skip_to_pragma_eol (parser
);
25360 #pragma omp declare reduction (reduction-id : typename-list : expression) \
25361 initializer-clause[opt] new-line
25363 initializer-clause:
25364 initializer (omp_priv = initializer)
25365 initializer (function-name (argument-list)) */
25368 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
25370 unsigned int tokens_avail
= 0, i
;
25371 c_token
*saved_tokens
= NULL
;
25372 vec
<tree
> types
= vNULL
;
25373 vec
<c_token
> clauses
= vNULL
;
25374 enum tree_code reduc_code
= ERROR_MARK
;
25375 tree reduc_id
= NULL_TREE
;
25377 location_t rloc
= c_parser_peek_token (parser
)->location
;
25379 if (context
== pragma_struct
|| context
== pragma_param
)
25381 error ("%<#pragma omp declare reduction%> not at file or block scope");
25385 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
25388 switch (c_parser_peek_token (parser
)->type
)
25391 reduc_code
= PLUS_EXPR
;
25394 reduc_code
= MULT_EXPR
;
25397 reduc_code
= MINUS_EXPR
;
25400 reduc_code
= BIT_AND_EXPR
;
25403 reduc_code
= BIT_XOR_EXPR
;
25406 reduc_code
= BIT_IOR_EXPR
;
25409 reduc_code
= TRUTH_ANDIF_EXPR
;
25412 reduc_code
= TRUTH_ORIF_EXPR
;
25416 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25417 if (strcmp (p
, "min") == 0)
25419 reduc_code
= MIN_EXPR
;
25422 if (strcmp (p
, "max") == 0)
25424 reduc_code
= MAX_EXPR
;
25427 reduc_id
= c_parser_peek_token (parser
)->value
;
25430 c_parser_error (parser
,
25431 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
25432 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
25436 tree orig_reduc_id
, reduc_decl
;
25437 orig_reduc_id
= reduc_id
;
25438 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
25439 reduc_decl
= c_omp_reduction_decl (reduc_id
);
25440 c_parser_consume_token (parser
);
25442 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
25447 location_t loc
= c_parser_peek_token (parser
)->location
;
25448 struct c_type_name
*ctype
= c_parser_type_name (parser
);
25451 type
= groktypename (ctype
, NULL
, NULL
);
25452 if (type
== error_mark_node
)
25454 else if ((INTEGRAL_TYPE_P (type
)
25455 || SCALAR_FLOAT_TYPE_P (type
)
25456 || TREE_CODE (type
) == COMPLEX_TYPE
)
25457 && orig_reduc_id
== NULL_TREE
)
25458 error_at (loc
, "predeclared arithmetic type in "
25459 "%<#pragma omp declare reduction%>");
25460 else if (TREE_CODE (type
) == FUNCTION_TYPE
25461 || TREE_CODE (type
) == ARRAY_TYPE
)
25462 error_at (loc
, "function or array type in "
25463 "%<#pragma omp declare reduction%>");
25464 else if (TYPE_ATOMIC (type
))
25465 error_at (loc
, "%<_Atomic%> qualified type in "
25466 "%<#pragma omp declare reduction%>");
25467 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
25468 error_at (loc
, "const, volatile or restrict qualified type in "
25469 "%<#pragma omp declare reduction%>");
25473 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
25474 if (comptypes (TREE_PURPOSE (t
), type
))
25476 error_at (loc
, "redeclaration of %qs "
25477 "%<#pragma omp declare reduction%> for "
25479 IDENTIFIER_POINTER (reduc_id
)
25480 + sizeof ("omp declare reduction ") - 1,
25483 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
25485 error_at (ploc
, "previous %<#pragma omp declare "
25489 if (t
== NULL_TREE
)
25490 types
.safe_push (type
);
25492 if (c_parser_next_token_is (parser
, CPP_COMMA
))
25493 c_parser_consume_token (parser
);
25501 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
25502 || types
.is_empty ())
25505 clauses
.release ();
25509 c_token
*token
= c_parser_peek_token (parser
);
25510 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
25512 c_parser_consume_token (parser
);
25514 c_parser_skip_to_pragma_eol (parser
);
25518 if (types
.length () > 1)
25520 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
25522 c_token
*token
= c_parser_peek_token (parser
);
25523 if (token
->type
== CPP_EOF
)
25525 clauses
.safe_push (*token
);
25526 c_parser_consume_token (parser
);
25528 clauses
.safe_push (*c_parser_peek_token (parser
));
25529 c_parser_skip_to_pragma_eol (parser
);
25531 /* Make sure nothing tries to read past the end of the tokens. */
25533 memset (&eof_token
, 0, sizeof (eof_token
));
25534 eof_token
.type
= CPP_EOF
;
25535 clauses
.safe_push (eof_token
);
25536 clauses
.safe_push (eof_token
);
25539 int errs
= errorcount
;
25540 FOR_EACH_VEC_ELT (types
, i
, type
)
25542 saved_tokens
= parser
->tokens
;
25543 tokens_avail
= parser
->tokens_avail
;
25544 if (!clauses
.is_empty ())
25546 parser
->tokens
= clauses
.address ();
25547 parser
->tokens_avail
= clauses
.length ();
25548 parser
->in_pragma
= true;
25551 bool nested
= current_function_decl
!= NULL_TREE
;
25553 c_push_function_context ();
25554 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
25555 reduc_id
, default_function_type
);
25556 current_function_decl
= fndecl
;
25557 allocate_struct_function (fndecl
, true);
25559 tree stmt
= push_stmt_list ();
25560 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
25561 warn about these. */
25562 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
25563 get_identifier ("omp_out"), type
);
25564 DECL_ARTIFICIAL (omp_out
) = 1;
25565 DECL_CONTEXT (omp_out
) = fndecl
;
25566 pushdecl (omp_out
);
25567 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
25568 get_identifier ("omp_in"), type
);
25569 DECL_ARTIFICIAL (omp_in
) = 1;
25570 DECL_CONTEXT (omp_in
) = fndecl
;
25572 struct c_expr combiner
= c_parser_expression (parser
);
25573 struct c_expr initializer
;
25574 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
25576 initializer
.set_error ();
25577 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
25579 else if (c_parser_next_token_is (parser
, CPP_COMMA
)
25580 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
25581 c_parser_consume_token (parser
);
25583 && (c_parser_next_token_is (parser
, CPP_NAME
)
25584 && strcmp (IDENTIFIER_POINTER
25585 (c_parser_peek_token (parser
)->value
),
25586 "initializer") == 0))
25588 c_parser_consume_token (parser
);
25591 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
25592 get_identifier ("omp_priv"), type
);
25593 DECL_ARTIFICIAL (omp_priv
) = 1;
25594 DECL_INITIAL (omp_priv
) = error_mark_node
;
25595 DECL_CONTEXT (omp_priv
) = fndecl
;
25596 pushdecl (omp_priv
);
25597 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
25598 get_identifier ("omp_orig"), type
);
25599 DECL_ARTIFICIAL (omp_orig
) = 1;
25600 DECL_CONTEXT (omp_orig
) = fndecl
;
25601 pushdecl (omp_orig
);
25602 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
25604 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
25606 c_parser_error (parser
, "expected %<omp_priv%> or "
25610 else if (strcmp (IDENTIFIER_POINTER
25611 (c_parser_peek_token (parser
)->value
),
25614 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
25615 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
25617 c_parser_error (parser
, "expected function-name %<(%>");
25621 initializer
= c_parser_postfix_expression (parser
);
25622 if (initializer
.value
25623 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
25626 tree c
= initializer
.value
;
25627 for (j
= 0; j
< call_expr_nargs (c
); j
++)
25629 tree a
= CALL_EXPR_ARG (c
, j
);
25631 if (TREE_CODE (a
) == ADDR_EXPR
25632 && TREE_OPERAND (a
, 0) == omp_priv
)
25635 if (j
== call_expr_nargs (c
))
25636 error ("one of the initializer call arguments should be "
25642 c_parser_consume_token (parser
);
25643 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
25647 tree st
= push_stmt_list ();
25648 location_t loc
= c_parser_peek_token (parser
)->location
;
25649 rich_location
richloc (line_table
, loc
);
25650 start_init (omp_priv
, NULL_TREE
, false, false, &richloc
);
25651 struct c_expr init
= c_parser_initializer (parser
, omp_priv
);
25653 finish_decl (omp_priv
, loc
, init
.value
,
25654 init
.original_type
, NULL_TREE
);
25655 pop_stmt_list (st
);
25659 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
25665 c_parser_skip_to_pragma_eol (parser
);
25667 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
25668 DECL_INITIAL (reduc_decl
));
25669 DECL_INITIAL (reduc_decl
) = t
;
25670 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
25671 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
25672 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
25673 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
25674 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
25675 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
25678 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
25679 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
25680 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
25681 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
25682 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
25683 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
25684 walk_tree (&DECL_INITIAL (omp_priv
),
25685 c_check_omp_declare_reduction_r
,
25686 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
25690 pop_stmt_list (stmt
);
25692 if (cfun
->language
!= NULL
)
25694 ggc_free (cfun
->language
);
25695 cfun
->language
= NULL
;
25698 current_function_decl
= NULL_TREE
;
25700 c_pop_function_context ();
25702 if (!clauses
.is_empty ())
25704 parser
->tokens
= saved_tokens
;
25705 parser
->tokens_avail
= tokens_avail
;
25709 if (errs
!= errorcount
)
25713 clauses
.release ();
25719 #pragma omp declare simd declare-simd-clauses[optseq] new-line
25720 #pragma omp declare reduction (reduction-id : typename-list : expression) \
25721 initializer-clause[opt] new-line
25722 #pragma omp declare target new-line
25725 #pragma omp declare variant (identifier) match (context-selector) */
25728 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
25730 c_parser_consume_pragma (parser
);
25731 if (c_parser_next_token_is (parser
, CPP_NAME
))
25733 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25734 if (strcmp (p
, "simd") == 0)
25736 /* c_parser_consume_token (parser); done in
25737 c_parser_omp_declare_simd. */
25738 c_parser_omp_declare_simd (parser
, context
);
25741 if (strcmp (p
, "reduction") == 0)
25743 c_parser_consume_token (parser
);
25744 c_parser_omp_declare_reduction (parser
, context
);
25747 if (!flag_openmp
) /* flag_openmp_simd */
25749 c_parser_skip_to_pragma_eol (parser
, false);
25752 if (strcmp (p
, "target") == 0)
25754 c_parser_consume_token (parser
);
25755 c_parser_omp_declare_target (parser
);
25758 if (strcmp (p
, "variant") == 0)
25760 /* c_parser_consume_token (parser); done in
25761 c_parser_omp_declare_simd. */
25762 c_parser_omp_declare_simd (parser
, context
);
25767 c_parser_error (parser
, "expected %<simd%>, %<reduction%>, "
25768 "%<target%> or %<variant%>");
25769 c_parser_skip_to_pragma_eol (parser
);
25774 #pragma omp requires clauses[optseq] new-line */
25777 c_parser_omp_requires (c_parser
*parser
)
25779 enum omp_requires new_req
= (enum omp_requires
) 0;
25781 c_parser_consume_pragma (parser
);
25783 location_t loc
= c_parser_peek_token (parser
)->location
;
25784 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
25786 if (c_parser_next_token_is (parser
, CPP_COMMA
)
25787 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
25788 c_parser_consume_token (parser
);
25790 if (c_parser_next_token_is (parser
, CPP_NAME
))
25793 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
25794 location_t cloc
= c_parser_peek_token (parser
)->location
;
25795 enum omp_requires this_req
= (enum omp_requires
) 0;
25797 if (!strcmp (p
, "unified_address"))
25798 this_req
= OMP_REQUIRES_UNIFIED_ADDRESS
;
25799 else if (!strcmp (p
, "unified_shared_memory"))
25800 this_req
= OMP_REQUIRES_UNIFIED_SHARED_MEMORY
;
25801 else if (!strcmp (p
, "dynamic_allocators"))
25802 this_req
= OMP_REQUIRES_DYNAMIC_ALLOCATORS
;
25803 else if (!strcmp (p
, "reverse_offload"))
25804 this_req
= OMP_REQUIRES_REVERSE_OFFLOAD
;
25805 else if (!strcmp (p
, "atomic_default_mem_order"))
25807 c_parser_consume_token (parser
);
25809 matching_parens parens
;
25810 if (parens
.require_open (parser
))
25812 if (c_parser_next_token_is (parser
, CPP_NAME
))
25814 tree v
= c_parser_peek_token (parser
)->value
;
25815 p
= IDENTIFIER_POINTER (v
);
25817 if (!strcmp (p
, "seq_cst"))
25819 = (enum omp_requires
) OMP_MEMORY_ORDER_SEQ_CST
;
25820 else if (!strcmp (p
, "relaxed"))
25822 = (enum omp_requires
) OMP_MEMORY_ORDER_RELAXED
;
25823 else if (!strcmp (p
, "release"))
25825 = (enum omp_requires
) OMP_MEMORY_ORDER_RELEASE
;
25826 else if (!strcmp (p
, "acq_rel"))
25828 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQ_REL
;
25829 else if (!strcmp (p
, "acquire"))
25831 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQUIRE
;
25835 error_at (c_parser_peek_token (parser
)->location
,
25836 "expected %<acq_rel%>, %<acquire%>, "
25837 "%<relaxed%>, %<release%> or %<seq_cst%>");
25838 switch (c_parser_peek_token (parser
)->type
)
25841 case CPP_PRAGMA_EOL
:
25842 case CPP_CLOSE_PAREN
:
25845 if (c_parser_peek_2nd_token (parser
)->type
25846 == CPP_CLOSE_PAREN
)
25847 c_parser_consume_token (parser
);
25852 c_parser_consume_token (parser
);
25854 parens
.skip_until_found_close (parser
);
25857 c_parser_skip_to_pragma_eol (parser
, false);
25865 error_at (cloc
, "expected %<unified_address%>, "
25866 "%<unified_shared_memory%>, "
25867 "%<dynamic_allocators%>, "
25868 "%<reverse_offload%> "
25869 "or %<atomic_default_mem_order%> clause");
25870 c_parser_skip_to_pragma_eol (parser
, false);
25874 c_parser_consume_token (parser
);
25877 if ((this_req
& ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
25879 if ((this_req
& new_req
) != 0)
25880 error_at (cloc
, "too many %qs clauses", p
);
25881 if (this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
25882 && (omp_requires_mask
& OMP_REQUIRES_TARGET_USED
) != 0)
25883 error_at (cloc
, "%qs clause used lexically after first "
25884 "target construct or offloading API", p
);
25886 else if ((new_req
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
25888 error_at (cloc
, "too many %qs clauses",
25889 "atomic_default_mem_order");
25890 this_req
= (enum omp_requires
) 0;
25892 else if ((omp_requires_mask
25893 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
25895 error_at (cloc
, "more than one %<atomic_default_mem_order%>"
25896 " clause in a single compilation unit");
25898 = (enum omp_requires
)
25900 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
);
25902 else if ((omp_requires_mask
25903 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
) != 0)
25904 error_at (cloc
, "%<atomic_default_mem_order%> clause used "
25905 "lexically after first %<atomic%> construct "
25906 "without memory order clause");
25907 new_req
= (enum omp_requires
) (new_req
| this_req
);
25909 = (enum omp_requires
) (omp_requires_mask
| this_req
);
25915 c_parser_skip_to_pragma_eol (parser
);
25918 error_at (loc
, "%<pragma omp requires%> requires at least one clause");
25921 /* Helper function for c_parser_omp_taskloop.
25922 Disallow zero sized or potentially zero sized task reductions. */
25925 c_finish_taskloop_clauses (tree clauses
)
25927 tree
*pc
= &clauses
;
25928 for (tree c
= clauses
; c
; c
= *pc
)
25930 bool remove
= false;
25931 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
25933 tree type
= strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
25934 if (integer_zerop (TYPE_SIZE_UNIT (type
)))
25936 error_at (OMP_CLAUSE_LOCATION (c
),
25937 "zero sized type %qT in %<reduction%> clause", type
);
25940 else if (TREE_CODE (TYPE_SIZE_UNIT (type
)) != INTEGER_CST
)
25942 error_at (OMP_CLAUSE_LOCATION (c
),
25943 "variable sized type %qT in %<reduction%> clause",
25949 *pc
= OMP_CLAUSE_CHAIN (c
);
25951 pc
= &OMP_CLAUSE_CHAIN (c
);
25957 #pragma omp taskloop taskloop-clause[optseq] new-line
25960 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
25963 #define OMP_TASKLOOP_CLAUSE_MASK \
25964 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
25965 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
25966 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
25967 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
25968 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
25969 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
25970 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
25971 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
25972 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
25973 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
25974 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
25975 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
25976 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
25977 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
25978 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
25979 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
25980 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
25983 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
25984 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
25987 tree clauses
, block
, ret
;
25989 strcat (p_name
, " taskloop");
25990 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
25991 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
25993 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
)) != 0)
25994 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_IN_REDUCTION
);
25996 if (c_parser_next_token_is (parser
, CPP_NAME
))
25998 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
26000 if (strcmp (p
, "simd") == 0)
26002 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
26003 if (cclauses
== NULL
)
26004 cclauses
= cclauses_buf
;
26005 c_parser_consume_token (parser
);
26006 if (!flag_openmp
) /* flag_openmp_simd */
26007 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
26009 block
= c_begin_compound_stmt (true);
26010 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
26011 block
= c_end_compound_stmt (loc
, block
, true);
26014 ret
= make_node (OMP_TASKLOOP
);
26015 TREE_TYPE (ret
) = void_type_node
;
26016 OMP_FOR_BODY (ret
) = block
;
26017 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
26018 OMP_FOR_CLAUSES (ret
)
26019 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret
));
26020 SET_EXPR_LOCATION (ret
, loc
);
26025 if (!flag_openmp
) /* flag_openmp_simd */
26027 c_parser_skip_to_pragma_eol (parser
, false);
26031 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
26034 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
26035 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
26038 clauses
= c_finish_taskloop_clauses (clauses
);
26039 block
= c_begin_compound_stmt (true);
26040 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
26041 block
= c_end_compound_stmt (loc
, block
, true);
26048 #pragma omp nothing new-line */
26051 c_parser_omp_nothing (c_parser
*parser
)
26053 c_parser_consume_pragma (parser
);
26054 c_parser_skip_to_pragma_eol (parser
);
26058 #pragma omp error clauses[optseq] new-line */
26061 c_parser_omp_error (c_parser
*parser
, enum pragma_context context
)
26063 int at_compilation
= -1;
26064 int severity_fatal
= -1;
26065 tree message
= NULL_TREE
;
26067 location_t loc
= c_parser_peek_token (parser
)->location
;
26069 c_parser_consume_pragma (parser
);
26071 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
26073 if (c_parser_next_token_is (parser
, CPP_COMMA
)
26074 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
26075 c_parser_consume_token (parser
);
26077 if (!c_parser_next_token_is (parser
, CPP_NAME
))
26081 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
26082 location_t cloc
= c_parser_peek_token (parser
)->location
;
26083 static const char *args
[] = {
26084 "execution", "compilation", "warning", "fatal"
26087 int idx
= 0, n
= -1;
26088 tree m
= NULL_TREE
;
26090 if (!strcmp (p
, "at"))
26091 v
= &at_compilation
;
26092 else if (!strcmp (p
, "severity"))
26094 v
= &severity_fatal
;
26097 else if (strcmp (p
, "message"))
26100 "expected %<at%>, %<severity%> or %<message%> clause");
26101 c_parser_skip_to_pragma_eol (parser
, false);
26105 c_parser_consume_token (parser
);
26107 matching_parens parens
;
26108 if (parens
.require_open (parser
))
26112 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
26113 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
26114 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
26115 m
= convert (const_string_type_node
, expr
.value
);
26116 m
= c_fully_fold (m
, false, NULL
);
26120 if (c_parser_next_token_is (parser
, CPP_NAME
))
26122 tree val
= c_parser_peek_token (parser
)->value
;
26123 const char *q
= IDENTIFIER_POINTER (val
);
26125 if (!strcmp (q
, args
[idx
]))
26127 else if (!strcmp (q
, args
[idx
+ 1]))
26132 error_at (c_parser_peek_token (parser
)->location
,
26133 "expected %qs or %qs", args
[idx
], args
[idx
+ 1]);
26135 switch (c_parser_peek_token (parser
)->type
)
26138 case CPP_PRAGMA_EOL
:
26139 case CPP_CLOSE_PAREN
:
26142 if (c_parser_peek_2nd_token (parser
)->type
26143 == CPP_CLOSE_PAREN
)
26144 c_parser_consume_token (parser
);
26149 c_parser_consume_token (parser
);
26152 parens
.skip_until_found_close (parser
);
26158 error_at (cloc
, "too many %qs clauses", p
);
26168 error_at (cloc
, "too many %qs clauses", p
);
26178 c_parser_skip_to_pragma_eol (parser
);
26182 if (at_compilation
== -1)
26183 at_compilation
= 1;
26184 if (severity_fatal
== -1)
26185 severity_fatal
= 1;
26186 if (!at_compilation
)
26188 if (context
!= pragma_compound
)
26190 error_at (loc
, "%<#pragma omp error%> with %<at(execution)%> clause "
26191 "may only be used in compound statements");
26195 = builtin_decl_explicit (severity_fatal
? BUILT_IN_GOMP_ERROR
26196 : BUILT_IN_GOMP_WARNING
);
26198 message
= build_zero_cst (const_string_type_node
);
26199 tree stmt
= build_call_expr_loc (loc
, fndecl
, 2, message
,
26200 build_all_ones_cst (size_type_node
));
26204 const char *msg
= NULL
;
26207 msg
= c_getstr (message
);
26209 msg
= _("<message unknown at compile time>");
26212 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
26213 "%<pragma omp error%> encountered: %s", msg
);
26215 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
26216 "%<pragma omp error%> encountered");
26220 /* Assumption clauses:
26222 absent (directive-name-list)
26223 contains (directive-name-list)
26230 c_parser_omp_assumption_clauses (c_parser
*parser
, bool is_assume
)
26232 bool no_openmp
= false;
26233 bool no_openmp_routines
= false;
26234 bool no_parallelism
= false;
26235 bitmap_head absent_head
, contains_head
;
26237 bitmap_obstack_initialize (NULL
);
26238 bitmap_initialize (&absent_head
, &bitmap_default_obstack
);
26239 bitmap_initialize (&contains_head
, &bitmap_default_obstack
);
26241 if (c_parser_next_token_is (parser
, CPP_PRAGMA_EOL
))
26242 error_at (c_parser_peek_token (parser
)->location
,
26243 "expected at least one assumption clause");
26245 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
26247 if (c_parser_next_token_is (parser
, CPP_COMMA
)
26248 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
26249 c_parser_consume_token (parser
);
26251 if (!c_parser_next_token_is (parser
, CPP_NAME
))
26255 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
26256 location_t cloc
= c_parser_peek_token (parser
)->location
;
26258 if (!strcmp (p
, "no_openmp"))
26260 c_parser_consume_token (parser
);
26262 error_at (cloc
, "too many %qs clauses", "no_openmp");
26265 else if (!strcmp (p
, "no_openmp_routines"))
26267 c_parser_consume_token (parser
);
26268 if (no_openmp_routines
)
26269 error_at (cloc
, "too many %qs clauses", "no_openmp_routines");
26270 no_openmp_routines
= true;
26272 else if (!strcmp (p
, "no_parallelism"))
26274 c_parser_consume_token (parser
);
26275 if (no_parallelism
)
26276 error_at (cloc
, "too many %qs clauses", "no_parallelism");
26277 no_parallelism
= true;
26279 else if (!strcmp (p
, "holds"))
26281 c_parser_consume_token (parser
);
26282 matching_parens parens
;
26283 if (parens
.require_open (parser
))
26285 location_t eloc
= c_parser_peek_token (parser
)->location
;
26286 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
26287 tree t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
26288 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
26289 t
= c_fully_fold (t
, false, NULL
);
26290 if (is_assume
&& t
!= error_mark_node
)
26292 tree fn
= build_call_expr_internal_loc (eloc
, IFN_ASSUME
,
26297 parens
.skip_until_found_close (parser
);
26300 else if (!strcmp (p
, "absent") || !strcmp (p
, "contains"))
26302 c_parser_consume_token (parser
);
26303 matching_parens parens
;
26304 if (parens
.require_open (parser
))
26308 const char *directive
[3] = {};
26310 location_t dloc
= c_parser_peek_token (parser
)->location
;
26311 for (i
= 0; i
< 3; i
++)
26314 if (c_parser_peek_nth_token (parser
, i
+ 1)->type
26316 id
= c_parser_peek_nth_token (parser
, i
+ 1)->value
;
26317 else if (c_parser_peek_nth_token (parser
, i
+ 1)->keyword
26321 = c_parser_peek_nth_token (parser
, i
+ 1)->keyword
;
26322 id
= ridpointers
[rid
];
26326 directive
[i
] = IDENTIFIER_POINTER (id
);
26329 error_at (dloc
, "expected directive name");
26332 const struct c_omp_directive
*dir
26333 = c_omp_categorize_directive (directive
[0],
26337 || dir
->kind
== C_OMP_DIR_DECLARATIVE
26338 || dir
->kind
== C_OMP_DIR_INFORMATIONAL
26339 || dir
->id
== PRAGMA_OMP_END
26340 || (!dir
->second
&& directive
[1])
26341 || (!dir
->third
&& directive
[2]))
26342 error_at (dloc
, "unknown OpenMP directive name in "
26343 "%qs clause argument", p
);
26346 int id
= dir
- c_omp_directives
;
26347 if (bitmap_bit_p (p
[0] == 'a' ? &contains_head
26348 : &absent_head
, id
))
26349 error_at (dloc
, "%<%s%s%s%s%s%> directive "
26350 "mentioned in both %<absent%> and "
26351 "%<contains%> clauses",
26353 directive
[1] ? " " : "",
26354 directive
[1] ? directive
[1] : "",
26355 directive
[2] ? " " : "",
26356 directive
[2] ? directive
[2] : "");
26357 else if (!bitmap_set_bit (p
[0] == 'a'
26359 : &contains_head
, id
))
26360 error_at (dloc
, "%<%s%s%s%s%s%> directive "
26361 "mentioned multiple times in %qs "
26364 directive
[1] ? " " : "",
26365 directive
[1] ? directive
[1] : "",
26366 directive
[2] ? " " : "",
26367 directive
[2] ? directive
[2] : "", p
);
26370 c_parser_consume_token (parser
);
26372 if (c_parser_next_token_is (parser
, CPP_COMMA
))
26373 c_parser_consume_token (parser
);
26378 parens
.skip_until_found_close (parser
);
26381 else if (startswith (p
, "ext_"))
26383 warning_at (cloc
, OPT_Wopenmp
, "unknown assumption clause %qs", p
);
26384 c_parser_consume_token (parser
);
26385 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
26387 matching_parens parens
;
26388 parens
.consume_open (parser
);
26389 c_parser_balanced_token_sequence (parser
);
26390 parens
.require_close (parser
);
26395 c_parser_consume_token (parser
);
26396 error_at (cloc
, "expected assumption clause");
26400 c_parser_skip_to_pragma_eol (parser
);
26404 #pragma omp assume clauses[optseq] new-line */
26407 c_parser_omp_assume (c_parser
*parser
, bool *if_p
)
26409 c_parser_omp_assumption_clauses (parser
, true);
26410 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
26414 #pragma omp assumes clauses[optseq] new-line */
26417 c_parser_omp_assumes (c_parser
*parser
)
26419 c_parser_consume_pragma (parser
);
26420 c_parser_omp_assumption_clauses (parser
, false);
26423 /* Main entry point to parsing most OpenMP pragmas. */
26426 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
26428 enum pragma_kind p_kind
;
26431 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
26432 omp_clause_mask
mask (0);
26434 loc
= c_parser_peek_token (parser
)->location
;
26435 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
26436 c_parser_consume_pragma (parser
);
26440 case PRAGMA_OACC_ATOMIC
:
26441 c_parser_omp_atomic (loc
, parser
, true);
26443 case PRAGMA_OACC_CACHE
:
26444 strcpy (p_name
, "#pragma acc");
26445 stmt
= c_parser_oacc_cache (loc
, parser
);
26447 case PRAGMA_OACC_DATA
:
26448 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
26450 case PRAGMA_OACC_HOST_DATA
:
26451 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
26453 case PRAGMA_OACC_KERNELS
:
26454 case PRAGMA_OACC_PARALLEL
:
26455 case PRAGMA_OACC_SERIAL
:
26456 strcpy (p_name
, "#pragma acc");
26457 stmt
= c_parser_oacc_compute (loc
, parser
, p_kind
, p_name
, if_p
);
26459 case PRAGMA_OACC_LOOP
:
26460 strcpy (p_name
, "#pragma acc");
26461 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26463 case PRAGMA_OACC_WAIT
:
26464 strcpy (p_name
, "#pragma wait");
26465 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
26467 case PRAGMA_OMP_ATOMIC
:
26468 c_parser_omp_atomic (loc
, parser
, false);
26470 case PRAGMA_OMP_CRITICAL
:
26471 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
26473 case PRAGMA_OMP_DISTRIBUTE
:
26474 strcpy (p_name
, "#pragma omp");
26475 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26477 case PRAGMA_OMP_FOR
:
26478 strcpy (p_name
, "#pragma omp");
26479 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26481 case PRAGMA_OMP_LOOP
:
26482 strcpy (p_name
, "#pragma omp");
26483 stmt
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26485 case PRAGMA_OMP_MASKED
:
26486 strcpy (p_name
, "#pragma omp");
26487 stmt
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26489 case PRAGMA_OMP_MASTER
:
26490 strcpy (p_name
, "#pragma omp");
26491 stmt
= c_parser_omp_master (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26493 case PRAGMA_OMP_PARALLEL
:
26494 strcpy (p_name
, "#pragma omp");
26495 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26497 case PRAGMA_OMP_SCOPE
:
26498 stmt
= c_parser_omp_scope (loc
, parser
, if_p
);
26500 case PRAGMA_OMP_SECTIONS
:
26501 strcpy (p_name
, "#pragma omp");
26502 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
26504 case PRAGMA_OMP_SIMD
:
26505 strcpy (p_name
, "#pragma omp");
26506 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26508 case PRAGMA_OMP_SINGLE
:
26509 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
26511 case PRAGMA_OMP_TASK
:
26512 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
26514 case PRAGMA_OMP_TASKGROUP
:
26515 stmt
= c_parser_omp_taskgroup (loc
, parser
, if_p
);
26517 case PRAGMA_OMP_TASKLOOP
:
26518 strcpy (p_name
, "#pragma omp");
26519 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26521 case PRAGMA_OMP_TEAMS
:
26522 strcpy (p_name
, "#pragma omp");
26523 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
26525 case PRAGMA_OMP_ASSUME
:
26526 c_parser_omp_assume (parser
, if_p
);
26529 gcc_unreachable ();
26532 if (stmt
&& stmt
!= error_mark_node
)
26533 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
26538 # pragma omp threadprivate (variable-list) */
26541 c_parser_omp_threadprivate (c_parser
*parser
)
26546 c_parser_consume_pragma (parser
);
26547 loc
= c_parser_peek_token (parser
)->location
;
26548 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
26550 /* Mark every variable in VARS to be assigned thread local storage. */
26551 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
26553 tree v
= TREE_PURPOSE (t
);
26555 /* FIXME diagnostics: Ideally we should keep individual
26556 locations for all the variables in the var list to make the
26557 following errors more precise. Perhaps
26558 c_parser_omp_var_list_parens() should construct a list of
26559 locations to go along with the var list. */
26561 /* If V had already been marked threadprivate, it doesn't matter
26562 whether it had been used prior to this point. */
26564 error_at (loc
, "%qD is not a variable", v
);
26565 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
26566 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
26567 else if (! is_global_var (v
))
26568 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
26569 else if (TREE_TYPE (v
) == error_mark_node
)
26571 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
26572 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
26575 if (! DECL_THREAD_LOCAL_P (v
))
26577 set_decl_tls_model (v
, decl_default_tls_model (v
));
26578 /* If rtl has been already set for this var, call
26579 make_decl_rtl once again, so that encode_section_info
26580 has a chance to look at the new decl flags. */
26581 if (DECL_RTL_SET_P (v
))
26584 C_DECL_THREADPRIVATE_P (v
) = 1;
26588 c_parser_skip_to_pragma_eol (parser
);
26591 /* Parse a transaction attribute (GCC Extension).
26593 transaction-attribute:
26595 attribute-specifier
26599 c_parser_transaction_attributes (c_parser
*parser
)
26601 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
26602 return c_parser_gnu_attributes (parser
);
26604 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
26606 return c_parser_std_attribute_specifier (parser
, true);
26609 /* Parse a __transaction_atomic or __transaction_relaxed statement
26612 transaction-statement:
26613 __transaction_atomic transaction-attribute[opt] compound-statement
26614 __transaction_relaxed compound-statement
26616 Note that the only valid attribute is: "outer".
26620 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
26622 unsigned int old_in
= parser
->in_transaction
;
26623 unsigned int this_in
= 1, new_in
;
26624 location_t loc
= c_parser_peek_token (parser
)->location
;
26627 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
26628 || keyword
== RID_TRANSACTION_RELAXED
)
26629 && c_parser_next_token_is_keyword (parser
, keyword
));
26630 c_parser_consume_token (parser
);
26632 if (keyword
== RID_TRANSACTION_RELAXED
)
26633 this_in
|= TM_STMT_ATTR_RELAXED
;
26636 attrs
= c_parser_transaction_attributes (parser
);
26638 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
26641 /* Keep track if we're in the lexical scope of an outer transaction. */
26642 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
26644 parser
->in_transaction
= new_in
;
26645 stmt
= c_parser_compound_statement (parser
);
26646 parser
->in_transaction
= old_in
;
26649 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
26651 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
26652 "%<__transaction_atomic%> without transactional memory support enabled"
26653 : "%<__transaction_relaxed %> "
26654 "without transactional memory support enabled"));
26659 /* Parse a __transaction_atomic or __transaction_relaxed expression
26662 transaction-expression:
26663 __transaction_atomic ( expression )
26664 __transaction_relaxed ( expression )
26667 static struct c_expr
26668 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
26671 unsigned int old_in
= parser
->in_transaction
;
26672 unsigned int this_in
= 1;
26673 location_t loc
= c_parser_peek_token (parser
)->location
;
26676 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
26677 || keyword
== RID_TRANSACTION_RELAXED
)
26678 && c_parser_next_token_is_keyword (parser
, keyword
));
26679 c_parser_consume_token (parser
);
26681 if (keyword
== RID_TRANSACTION_RELAXED
)
26682 this_in
|= TM_STMT_ATTR_RELAXED
;
26685 attrs
= c_parser_transaction_attributes (parser
);
26687 this_in
|= parse_tm_stmt_attr (attrs
, 0);
26690 parser
->in_transaction
= this_in
;
26691 matching_parens parens
;
26692 if (parens
.require_open (parser
))
26694 tree expr
= c_parser_expression (parser
).value
;
26695 ret
.original_type
= TREE_TYPE (expr
);
26696 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
26697 if (this_in
& TM_STMT_ATTR_RELAXED
)
26698 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
26699 SET_EXPR_LOCATION (ret
.value
, loc
);
26700 ret
.original_code
= TRANSACTION_EXPR
;
26702 if (!parens
.require_close (parser
))
26704 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
26712 ret
.original_code
= ERROR_MARK
;
26713 ret
.original_type
= NULL
;
26715 parser
->in_transaction
= old_in
;
26718 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
26719 "%<__transaction_atomic%> without transactional memory support enabled"
26720 : "%<__transaction_relaxed %> "
26721 "without transactional memory support enabled"));
26723 set_c_expr_source_range (&ret
, loc
, loc
);
26728 /* Parse a __transaction_cancel statement (GCC Extension).
26730 transaction-cancel-statement:
26731 __transaction_cancel transaction-attribute[opt] ;
26733 Note that the only valid attribute is "outer".
26737 c_parser_transaction_cancel (c_parser
*parser
)
26739 location_t loc
= c_parser_peek_token (parser
)->location
;
26741 bool is_outer
= false;
26743 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
26744 c_parser_consume_token (parser
);
26746 attrs
= c_parser_transaction_attributes (parser
);
26748 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
26752 error_at (loc
, "%<__transaction_cancel%> without "
26753 "transactional memory support enabled");
26756 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
26758 error_at (loc
, "%<__transaction_cancel%> within a "
26759 "%<__transaction_relaxed%>");
26764 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
26765 && !is_tm_may_cancel_outer (current_function_decl
))
26767 error_at (loc
, "outer %<__transaction_cancel%> not "
26768 "within outer %<__transaction_atomic%> or "
26769 "a %<transaction_may_cancel_outer%> function");
26773 else if (parser
->in_transaction
== 0)
26775 error_at (loc
, "%<__transaction_cancel%> not within "
26776 "%<__transaction_atomic%>");
26780 return add_stmt (build_tm_abort_call (loc
, is_outer
));
26783 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
26786 /* Parse a single source file. */
26789 c_parse_file (void)
26791 /* Use local storage to begin. If the first token is a pragma, parse it.
26792 If it is #pragma GCC pch_preprocess, then this will load a PCH file
26793 which will cause garbage collection. */
26796 memset (&tparser
, 0, sizeof tparser
);
26797 tparser
.translate_strings_p
= true;
26798 tparser
.tokens
= &tparser
.tokens_buf
[0];
26799 the_parser
= &tparser
;
26801 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
26802 c_parser_pragma_pch_preprocess (&tparser
);
26804 c_common_no_more_pch ();
26806 the_parser
= ggc_alloc
<c_parser
> ();
26807 *the_parser
= tparser
;
26808 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
26809 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
26811 /* Initialize EH, if we've been told to do so. */
26812 if (flag_exceptions
)
26813 using_eh_for_cleanups ();
26815 c_parser_translation_unit (the_parser
);
26820 c_init_preprocess (void)
26822 /* Create a parser for use by pragma_lex during preprocessing. */
26823 the_parser
= ggc_alloc
<c_parser
> ();
26824 memset (the_parser
, 0, sizeof (c_parser
));
26825 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
26828 /* Parse the body of a function declaration marked with "__RTL".
26830 The RTL parser works on the level of characters read from a
26831 FILE *, whereas c_parser works at the level of tokens.
26832 Square this circle by consuming all of the tokens up to and
26833 including the closing brace, recording the start/end of the RTL
26834 fragment, and reopening the file and re-reading the relevant
26835 lines within the RTL parser.
26837 This requires the opening and closing braces of the C function
26838 to be on separate lines from the RTL they wrap.
26840 Take ownership of START_WITH_PASS, if non-NULL. */
26843 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
26845 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
26847 free (start_with_pass
);
26848 return c_parser_peek_token (parser
)->location
;
26851 location_t start_loc
= c_parser_peek_token (parser
)->location
;
26853 /* Consume all tokens, up to the closing brace, handling
26854 matching pairs of braces in the rtl dump. */
26855 int num_open_braces
= 1;
26858 switch (c_parser_peek_token (parser
)->type
)
26860 case CPP_OPEN_BRACE
:
26863 case CPP_CLOSE_BRACE
:
26864 if (--num_open_braces
== 0)
26865 goto found_closing_brace
;
26868 error_at (start_loc
, "no closing brace");
26869 free (start_with_pass
);
26870 return c_parser_peek_token (parser
)->location
;
26874 c_parser_consume_token (parser
);
26877 found_closing_brace
:
26878 /* At the closing brace; record its location. */
26879 location_t end_loc
= c_parser_peek_token (parser
)->location
;
26881 /* Consume the closing brace. */
26882 c_parser_consume_token (parser
);
26884 /* Invoke the RTL parser. */
26885 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
26887 free (start_with_pass
);
26891 /* Run the backend on the cfun created above, transferring ownership of
26892 START_WITH_PASS. */
26893 run_rtl_passes (start_with_pass
);
26897 #include "gt-c-c-parser.h"