1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2023 Free Software Foundation, Inc.
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 Make sure all relevant comments, and all relevant code from all
26 actions, brought over from old parser. Verify exact correspondence
29 Add testcases covering every input symbol in every state in old and
32 Include full syntax for GNU C, including erroneous cases accepted
33 with error messages, in syntax productions in comments.
35 Make more diagnostics in the front end generally take an explicit
36 location rather than implicitly using input_location. */
39 #define INCLUDE_MEMORY
41 #include "coretypes.h"
46 #include "stringpool.h"
49 #include "stor-layout.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
54 #include "c-family/c-objc.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
63 #include "gcc-rich-location.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
71 #include "tree-pretty-print.h"
73 #include "c-family/known-headers.h"
75 #include "analyzer/analyzer-language.h"
78 /* We need to walk over decls with incomplete struct/union/enum types
79 after parsing the whole translation unit.
80 In finish_decl(), if the decl is static, has incomplete
81 struct/union/enum type, it is appended to incomplete_record_decls.
82 In c_parser_translation_unit(), we iterate over incomplete_record_decls
83 and report error if any of the decls are still incomplete. */
85 vec
<tree
> incomplete_record_decls
;
88 set_c_expr_source_range (c_expr
*expr
,
89 location_t start
, location_t finish
)
91 expr
->src_range
.m_start
= start
;
92 expr
->src_range
.m_finish
= finish
;
94 set_source_range (expr
->value
, start
, finish
);
98 set_c_expr_source_range (c_expr
*expr
,
99 source_range src_range
)
101 expr
->src_range
= src_range
;
103 set_source_range (expr
->value
, src_range
);
107 /* Initialization routine for this file. */
112 /* The only initialization required is of the reserved word
118 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
119 the c_token structure. */
120 gcc_assert (RID_MAX
<= 255);
129 mask
|= D_ASM
| D_EXT
;
135 if (!c_dialect_objc ())
136 mask
|= D_OBJC
| D_CXX_OBJC
;
138 ridpointers
= ggc_cleared_vec_alloc
<tree
> ((int) RID_MAX
);
139 for (i
= 0; i
< num_c_common_reswords
; i
++)
141 /* If a keyword is disabled, do not enter it into the table
142 and so create a canonical spelling that isn't a keyword. */
143 if (c_common_reswords
[i
].disable
& mask
)
146 && (c_common_reswords
[i
].disable
& D_CXXWARN
))
148 id
= get_identifier (c_common_reswords
[i
].word
);
149 C_SET_RID_CODE (id
, RID_CXX_COMPAT_WARN
);
150 C_IS_RESERVED_WORD (id
) = 1;
155 id
= get_identifier (c_common_reswords
[i
].word
);
156 C_SET_RID_CODE (id
, c_common_reswords
[i
].rid
);
157 C_IS_RESERVED_WORD (id
) = 1;
158 ridpointers
[(int) c_common_reswords
[i
].rid
] = id
;
161 for (i
= 0; i
< NUM_INT_N_ENTS
; i
++)
163 /* We always create the symbols but they aren't always supported. */
165 sprintf (name
, "__int%d", int_n_data
[i
].bitsize
);
166 id
= get_identifier (name
);
167 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
168 C_IS_RESERVED_WORD (id
) = 1;
170 sprintf (name
, "__int%d__", int_n_data
[i
].bitsize
);
171 id
= get_identifier (name
);
172 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
173 C_IS_RESERVED_WORD (id
) = 1;
178 id
= get_identifier ("omp_all_memory");
179 C_SET_RID_CODE (id
, RID_OMP_ALL_MEMORY
);
180 C_IS_RESERVED_WORD (id
) = 1;
181 ridpointers
[RID_OMP_ALL_MEMORY
] = id
;
185 /* A parser structure recording information about the state and
186 context of parsing. Includes lexer information with up to two
187 tokens of look-ahead; more are not needed for C. */
188 struct GTY(()) c_parser
{
189 /* The look-ahead tokens. */
190 c_token
* GTY((skip
)) tokens
;
191 /* Buffer for look-ahead tokens. */
192 c_token tokens_buf
[4];
193 /* How many look-ahead tokens are available (0 - 4, or
194 more if parsing from pre-lexed tokens). */
195 unsigned int tokens_avail
;
196 /* Raw look-ahead tokens, used only for checking in Objective-C
197 whether '[[' starts attributes. */
198 vec
<c_token
, va_gc
> *raw_tokens
;
199 /* The number of raw look-ahead tokens that have since been fully
201 unsigned int raw_tokens_used
;
202 /* True if a syntax error is being recovered from; false otherwise.
203 c_parser_error sets this flag. It should clear this flag when
204 enough tokens have been consumed to recover from the error. */
205 BOOL_BITFIELD error
: 1;
206 /* True if we're processing a pragma, and shouldn't automatically
207 consume CPP_PRAGMA_EOL. */
208 BOOL_BITFIELD in_pragma
: 1;
209 /* True if we're parsing the outermost block of an if statement. */
210 BOOL_BITFIELD in_if_block
: 1;
211 /* True if we want to lex a translated, joined string (for an
212 initial #pragma pch_preprocess). Otherwise the parser is
213 responsible for concatenating strings and translating to the
214 execution character set as needed. */
215 BOOL_BITFIELD lex_joined_string
: 1;
216 /* True if, when the parser is concatenating string literals, it
217 should translate them to the execution character set (false
218 inside attributes). */
219 BOOL_BITFIELD translate_strings_p
: 1;
221 /* Objective-C specific parser/lexer information. */
223 /* True if we are in a context where the Objective-C "PQ" keywords
224 are considered keywords. */
225 BOOL_BITFIELD objc_pq_context
: 1;
226 /* True if we are parsing a (potential) Objective-C foreach
227 statement. This is set to true after we parsed 'for (' and while
228 we wait for 'in' or ';' to decide if it's a standard C for loop or an
229 Objective-C foreach loop. */
230 BOOL_BITFIELD objc_could_be_foreach_context
: 1;
231 /* The following flag is needed to contextualize Objective-C lexical
232 analysis. In some cases (e.g., 'int NSObject;'), it is
233 undesirable to bind an identifier to an Objective-C class, even
234 if a class with that name exists. */
235 BOOL_BITFIELD objc_need_raw_identifier
: 1;
236 /* Nonzero if we're processing a __transaction statement. The value
237 is 1 | TM_STMT_ATTR_*. */
238 unsigned int in_transaction
: 4;
239 /* True if we are in a context where the Objective-C "Property attribute"
240 keywords are valid. */
241 BOOL_BITFIELD objc_property_attr_context
: 1;
243 /* Whether we have just seen/constructed a string-literal. Set when
244 returning a string-literal from c_parser_string_literal. Reset
245 in consume_token. Useful when we get a parse error and see an
246 unknown token, which could have been a string-literal constant
248 BOOL_BITFIELD seen_string_literal
: 1;
250 /* Location of the last consumed token. */
251 location_t last_token_location
;
254 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
257 c_parser_tokens_buf (c_parser
*parser
, unsigned n
)
259 return &parser
->tokens_buf
[n
];
262 /* Return the error state of PARSER. */
265 c_parser_error (c_parser
*parser
)
267 return parser
->error
;
270 /* Set the error state of PARSER to ERR. */
273 c_parser_set_error (c_parser
*parser
, bool err
)
279 /* The actual parser and external interface. ??? Does this need to be
280 garbage-collected? */
282 static GTY (()) c_parser
*the_parser
;
284 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
285 context-sensitive postprocessing of the token is not done. */
288 c_lex_one_token (c_parser
*parser
, c_token
*token
, bool raw
= false)
290 timevar_push (TV_LEX
);
292 if (raw
|| vec_safe_length (parser
->raw_tokens
) == 0)
294 token
->type
= c_lex_with_flags (&token
->value
, &token
->location
,
296 (parser
->lex_joined_string
297 ? 0 : C_LEX_STRING_NO_JOIN
));
298 token
->id_kind
= C_ID_NONE
;
299 token
->keyword
= RID_MAX
;
300 token
->pragma_kind
= PRAGMA_NONE
;
304 /* Use a token previously lexed as a raw look-ahead token, and
305 complete the processing on it. */
306 *token
= (*parser
->raw_tokens
)[parser
->raw_tokens_used
];
307 ++parser
->raw_tokens_used
;
308 if (parser
->raw_tokens_used
== vec_safe_length (parser
->raw_tokens
))
310 vec_free (parser
->raw_tokens
);
311 parser
->raw_tokens_used
= 0;
324 bool objc_force_identifier
= parser
->objc_need_raw_identifier
;
325 if (c_dialect_objc ())
326 parser
->objc_need_raw_identifier
= false;
328 if (C_IS_RESERVED_WORD (token
->value
))
330 enum rid rid_code
= C_RID_CODE (token
->value
);
332 if (rid_code
== RID_CXX_COMPAT_WARN
)
334 warning_at (token
->location
,
336 "identifier %qE conflicts with C++ keyword",
339 else if (rid_code
>= RID_FIRST_ADDR_SPACE
340 && rid_code
<= RID_LAST_ADDR_SPACE
)
343 as
= (addr_space_t
) (rid_code
- RID_FIRST_ADDR_SPACE
);
344 targetm
.addr_space
.diagnose_usage (as
, token
->location
);
345 token
->id_kind
= C_ID_ADDRSPACE
;
346 token
->keyword
= rid_code
;
349 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code
))
351 /* We found an Objective-C "pq" keyword (in, out,
352 inout, bycopy, byref, oneway). They need special
353 care because the interpretation depends on the
355 if (parser
->objc_pq_context
)
357 token
->type
= CPP_KEYWORD
;
358 token
->keyword
= rid_code
;
361 else if (parser
->objc_could_be_foreach_context
362 && rid_code
== RID_IN
)
364 /* We are in Objective-C, inside a (potential)
365 foreach context (which means after having
366 parsed 'for (', but before having parsed ';'),
367 and we found 'in'. We consider it the keyword
368 which terminates the declaration at the
369 beginning of a foreach-statement. Note that
370 this means you can't use 'in' for anything else
371 in that context; in particular, in Objective-C
372 you can't use 'in' as the name of the running
373 variable in a C for loop. We could potentially
374 try to add code here to disambiguate, but it
375 seems a reasonable limitation. */
376 token
->type
= CPP_KEYWORD
;
377 token
->keyword
= rid_code
;
380 /* Else, "pq" keywords outside of the "pq" context are
381 not keywords, and we fall through to the code for
384 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code
))
386 /* We found an Objective-C "property attribute"
387 keyword (getter, setter, readonly, etc). These are
388 only valid in the property context. */
389 if (parser
->objc_property_attr_context
)
391 token
->type
= CPP_KEYWORD
;
392 token
->keyword
= rid_code
;
395 /* Else they are not special keywords.
398 else if (c_dialect_objc ()
399 && (OBJC_IS_AT_KEYWORD (rid_code
)
400 || OBJC_IS_CXX_KEYWORD (rid_code
)))
402 /* We found one of the Objective-C "@" keywords (defs,
403 selector, synchronized, etc) or one of the
404 Objective-C "cxx" keywords (class, private,
405 protected, public, try, catch, throw) without a
406 preceding '@' sign. Do nothing and fall through to
407 the code for normal tokens (in C++ we would still
408 consider the CXX ones keywords, but not in C). */
413 token
->type
= CPP_KEYWORD
;
414 token
->keyword
= rid_code
;
419 decl
= lookup_name (token
->value
);
422 if (TREE_CODE (decl
) == TYPE_DECL
)
424 token
->id_kind
= C_ID_TYPENAME
;
428 else if (c_dialect_objc ())
430 tree objc_interface_decl
= objc_is_class_name (token
->value
);
431 /* Objective-C class names are in the same namespace as
432 variables and typedefs, and hence are shadowed by local
434 if (objc_interface_decl
435 && (!objc_force_identifier
|| global_bindings_p ()))
437 token
->value
= objc_interface_decl
;
438 token
->id_kind
= C_ID_CLASSNAME
;
442 token
->id_kind
= C_ID_ID
;
446 /* This only happens in Objective-C; it must be a keyword. */
447 token
->type
= CPP_KEYWORD
;
448 switch (C_RID_CODE (token
->value
))
450 /* Replace 'class' with '@class', 'private' with '@private',
451 etc. This prevents confusion with the C++ keyword
452 'class', and makes the tokens consistent with other
453 Objective-C 'AT' keywords. For example '@class' is
454 reported as RID_AT_CLASS which is consistent with
455 '@synchronized', which is reported as
458 case RID_CLASS
: token
->keyword
= RID_AT_CLASS
; break;
459 case RID_PRIVATE
: token
->keyword
= RID_AT_PRIVATE
; break;
460 case RID_PROTECTED
: token
->keyword
= RID_AT_PROTECTED
; break;
461 case RID_PUBLIC
: token
->keyword
= RID_AT_PUBLIC
; break;
462 case RID_THROW
: token
->keyword
= RID_AT_THROW
; break;
463 case RID_TRY
: token
->keyword
= RID_AT_TRY
; break;
464 case RID_CATCH
: token
->keyword
= RID_AT_CATCH
; break;
465 case RID_SYNCHRONIZED
: token
->keyword
= RID_AT_SYNCHRONIZED
; break;
466 default: token
->keyword
= C_RID_CODE (token
->value
);
471 case CPP_CLOSE_PAREN
:
473 /* These tokens may affect the interpretation of any identifiers
474 following, if doing Objective-C. */
475 if (c_dialect_objc ())
476 parser
->objc_need_raw_identifier
= false;
479 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
480 token
->pragma_kind
= (enum pragma_kind
) TREE_INT_CST_LOW (token
->value
);
487 timevar_pop (TV_LEX
);
490 /* Return a pointer to the next token from PARSER, reading it in if
494 c_parser_peek_token (c_parser
*parser
)
496 if (parser
->tokens_avail
== 0)
498 c_lex_one_token (parser
, &parser
->tokens
[0]);
499 parser
->tokens_avail
= 1;
501 return &parser
->tokens
[0];
504 /* Return a pointer to the next-but-one token from PARSER, reading it
505 in if necessary. The next token is already read in. */
508 c_parser_peek_2nd_token (c_parser
*parser
)
510 if (parser
->tokens_avail
>= 2)
511 return &parser
->tokens
[1];
512 gcc_assert (parser
->tokens_avail
== 1);
513 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
514 gcc_assert (parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
515 c_lex_one_token (parser
, &parser
->tokens
[1]);
516 parser
->tokens_avail
= 2;
517 return &parser
->tokens
[1];
520 /* Return a pointer to the Nth token from PARSER, reading it
521 in if necessary. The N-1th token is already read in. */
524 c_parser_peek_nth_token (c_parser
*parser
, unsigned int n
)
526 /* N is 1-based, not zero-based. */
529 if (parser
->tokens_avail
>= n
)
530 return &parser
->tokens
[n
- 1];
531 gcc_assert (parser
->tokens_avail
== n
- 1);
532 c_lex_one_token (parser
, &parser
->tokens
[n
- 1]);
533 parser
->tokens_avail
= n
;
534 return &parser
->tokens
[n
- 1];
537 /* Return a pointer to the Nth token from PARSER, reading it in as a
538 raw look-ahead token if necessary. The N-1th token is already read
539 in. Raw look-ahead tokens remain available for when the non-raw
540 functions above are called. */
543 c_parser_peek_nth_token_raw (c_parser
*parser
, unsigned int n
)
545 /* N is 1-based, not zero-based. */
548 if (parser
->tokens_avail
>= n
)
549 return &parser
->tokens
[n
- 1];
550 unsigned int raw_len
= vec_safe_length (parser
->raw_tokens
);
551 unsigned int raw_avail
552 = parser
->tokens_avail
+ raw_len
- parser
->raw_tokens_used
;
553 gcc_assert (raw_avail
>= n
- 1);
555 return &(*parser
->raw_tokens
)[parser
->raw_tokens_used
556 + n
- 1 - parser
->tokens_avail
];
557 vec_safe_reserve (parser
->raw_tokens
, 1);
558 parser
->raw_tokens
->quick_grow (raw_len
+ 1);
559 c_lex_one_token (parser
, &(*parser
->raw_tokens
)[raw_len
], true);
560 return &(*parser
->raw_tokens
)[raw_len
];
564 c_keyword_starts_typename (enum rid keyword
)
587 case RID_TYPEOF_UNQUAL
:
600 if (keyword
>= RID_FIRST_INT_N
601 && keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
602 && int_n_enabled_p
[keyword
- RID_FIRST_INT_N
])
608 /* Return true if TOKEN can start a type name,
611 c_token_starts_typename (c_token
*token
)
616 switch (token
->id_kind
)
625 gcc_assert (c_dialect_objc ());
631 return c_keyword_starts_typename (token
->keyword
);
633 if (c_dialect_objc ())
641 /* Return true if the next token from PARSER can start a type name,
642 false otherwise. LA specifies how to do lookahead in order to
643 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
646 c_parser_next_tokens_start_typename (c_parser
*parser
, enum c_lookahead_kind la
)
648 c_token
*token
= c_parser_peek_token (parser
);
649 if (c_token_starts_typename (token
))
652 /* Try a bit harder to detect an unknown typename. */
653 if (la
!= cla_prefer_id
654 && token
->type
== CPP_NAME
655 && token
->id_kind
== C_ID_ID
657 /* Do not try too hard when we could have "object in array". */
658 && !parser
->objc_could_be_foreach_context
660 && (la
== cla_prefer_type
661 || c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
662 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
664 /* Only unknown identifiers. */
665 && !lookup_name (token
->value
))
671 /* Return true if TOKEN, after an open parenthesis, can start a
672 compound literal (either a storage class specifier allowed in that
673 context, or a type name), false otherwise. */
675 c_token_starts_compound_literal (c_token
*token
)
680 switch (token
->keyword
)
692 return c_token_starts_typename (token
);
696 /* Return true if TOKEN is a type qualifier, false otherwise. */
698 c_token_is_qualifier (c_token
*token
)
703 switch (token
->id_kind
)
711 switch (token
->keyword
)
729 /* Return true if the next token from PARSER is a type qualifier,
732 c_parser_next_token_is_qualifier (c_parser
*parser
)
734 c_token
*token
= c_parser_peek_token (parser
);
735 return c_token_is_qualifier (token
);
738 /* Return true if TOKEN can start declaration specifiers (not
739 including standard attributes), false otherwise. */
741 c_token_starts_declspecs (c_token
*token
)
746 switch (token
->id_kind
)
755 gcc_assert (c_dialect_objc ());
761 switch (token
->keyword
)
790 case RID_TYPEOF_UNQUAL
:
804 if (token
->keyword
>= RID_FIRST_INT_N
805 && token
->keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
806 && int_n_enabled_p
[token
->keyword
- RID_FIRST_INT_N
])
811 if (c_dialect_objc ())
820 /* Return true if TOKEN can start declaration specifiers (not
821 including standard attributes) or a static assertion, false
824 c_token_starts_declaration (c_token
*token
)
826 if (c_token_starts_declspecs (token
)
827 || token
->keyword
== RID_STATIC_ASSERT
)
833 /* Return true if the next token from PARSER can start declaration
834 specifiers (not including standard attributes), false
837 c_parser_next_token_starts_declspecs (c_parser
*parser
)
839 c_token
*token
= c_parser_peek_token (parser
);
841 /* In Objective-C, a classname normally starts a declspecs unless it
842 is immediately followed by a dot. In that case, it is the
843 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
844 setter/getter on the class. c_token_starts_declspecs() can't
845 differentiate between the two cases because it only checks the
846 current token, so we have a special check here. */
847 if (c_dialect_objc ()
848 && token
->type
== CPP_NAME
849 && token
->id_kind
== C_ID_CLASSNAME
850 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
853 return c_token_starts_declspecs (token
);
856 /* Return true if the next tokens from PARSER can start declaration
857 specifiers (not including standard attributes) or a static
858 assertion, false otherwise. */
860 c_parser_next_tokens_start_declaration (c_parser
*parser
)
862 c_token
*token
= c_parser_peek_token (parser
);
865 if (c_dialect_objc ()
866 && token
->type
== CPP_NAME
867 && token
->id_kind
== C_ID_CLASSNAME
868 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
871 /* Labels do not start declarations. */
872 if (token
->type
== CPP_NAME
873 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
876 if (c_token_starts_declaration (token
))
879 if (c_parser_next_tokens_start_typename (parser
, cla_nonabstract_decl
))
885 /* Consume the next token from PARSER. */
888 c_parser_consume_token (c_parser
*parser
)
890 gcc_assert (parser
->tokens_avail
>= 1);
891 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
892 gcc_assert (!parser
->in_pragma
|| parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
893 gcc_assert (parser
->error
|| parser
->tokens
[0].type
!= CPP_PRAGMA
);
894 parser
->last_token_location
= parser
->tokens
[0].location
;
895 if (parser
->tokens
!= &parser
->tokens_buf
[0])
897 else if (parser
->tokens_avail
>= 2)
899 parser
->tokens
[0] = parser
->tokens
[1];
900 if (parser
->tokens_avail
>= 3)
902 parser
->tokens
[1] = parser
->tokens
[2];
903 if (parser
->tokens_avail
>= 4)
904 parser
->tokens
[2] = parser
->tokens
[3];
907 parser
->tokens_avail
--;
908 parser
->seen_string_literal
= false;
911 /* Expect the current token to be a #pragma. Consume it and remember
912 that we've begun parsing a pragma. */
915 c_parser_consume_pragma (c_parser
*parser
)
917 gcc_assert (!parser
->in_pragma
);
918 gcc_assert (parser
->tokens_avail
>= 1);
919 gcc_assert (parser
->tokens
[0].type
== CPP_PRAGMA
);
920 if (parser
->tokens
!= &parser
->tokens_buf
[0])
922 else if (parser
->tokens_avail
>= 2)
924 parser
->tokens
[0] = parser
->tokens
[1];
925 if (parser
->tokens_avail
>= 3)
926 parser
->tokens
[1] = parser
->tokens
[2];
928 parser
->tokens_avail
--;
929 parser
->in_pragma
= true;
932 /* Update the global input_location from TOKEN. */
934 c_parser_set_source_position_from_token (c_token
*token
)
936 if (token
->type
!= CPP_EOF
)
938 input_location
= token
->location
;
942 /* Helper function for c_parser_error.
943 Having peeked a token of kind TOK1_KIND that might signify
944 a conflict marker, peek successor tokens to determine
945 if we actually do have a conflict marker.
946 Specifically, we consider a run of 7 '<', '=' or '>' characters
947 at the start of a line as a conflict marker.
948 These come through the lexer as three pairs and a single,
949 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
950 If it returns true, *OUT_LOC is written to with the location/range
954 c_parser_peek_conflict_marker (c_parser
*parser
, enum cpp_ttype tok1_kind
,
957 c_token
*token2
= c_parser_peek_2nd_token (parser
);
958 if (token2
->type
!= tok1_kind
)
960 c_token
*token3
= c_parser_peek_nth_token (parser
, 3);
961 if (token3
->type
!= tok1_kind
)
963 c_token
*token4
= c_parser_peek_nth_token (parser
, 4);
964 if (token4
->type
!= conflict_marker_get_final_tok_kind (tok1_kind
))
967 /* It must be at the start of the line. */
968 location_t start_loc
= c_parser_peek_token (parser
)->location
;
969 if (LOCATION_COLUMN (start_loc
) != 1)
972 /* We have a conflict marker. Construct a location of the form:
975 with start == caret, finishing at the end of the marker. */
976 location_t finish_loc
= get_finish (token4
->location
);
977 *out_loc
= make_location (start_loc
, start_loc
, finish_loc
);
982 /* Issue a diagnostic of the form
983 FILE:LINE: MESSAGE before TOKEN
984 where TOKEN is the next token in the input stream of PARSER.
985 MESSAGE (specified by the caller) is usually of the form "expected
988 Use RICHLOC as the location of the diagnostic.
990 Do not issue a diagnostic if still recovering from an error.
992 Return true iff an error was actually emitted.
994 ??? This is taken from the C++ parser, but building up messages in
995 this way is not i18n-friendly and some other approach should be
999 c_parser_error_richloc (c_parser
*parser
, const char *gmsgid
,
1000 rich_location
*richloc
)
1002 c_token
*token
= c_parser_peek_token (parser
);
1005 parser
->error
= true;
1009 /* If this is actually a conflict marker, report it as such. */
1010 if (token
->type
== CPP_LSHIFT
1011 || token
->type
== CPP_RSHIFT
1012 || token
->type
== CPP_EQ_EQ
)
1015 if (c_parser_peek_conflict_marker (parser
, token
->type
, &loc
))
1017 error_at (loc
, "version control conflict marker in file");
1022 /* If we were parsing a string-literal and there is an unknown name
1023 token right after, then check to see if that could also have been
1024 a literal string by checking the name against a list of known
1025 standard string literal constants defined in header files. If
1026 there is one, then add that as an hint to the error message. */
1027 auto_diagnostic_group d
;
1029 if (parser
->seen_string_literal
&& token
->type
== CPP_NAME
)
1031 tree name
= token
->value
;
1032 const char *token_name
= IDENTIFIER_POINTER (name
);
1033 const char *header_hint
1034 = get_c_stdlib_header_for_string_macro_name (token_name
);
1035 if (header_hint
!= NULL
)
1036 h
= name_hint (NULL
, new suggest_missing_header (token
->location
,
1041 c_parse_error (gmsgid
,
1042 /* Because c_parse_error does not understand
1043 CPP_KEYWORD, keywords are treated like
1045 (token
->type
== CPP_KEYWORD
? CPP_NAME
: token
->type
),
1046 /* ??? The C parser does not save the cpp flags of a
1047 token, we need to pass 0 here and we will not get
1048 the source spelling of some tokens but rather the
1049 canonical spelling. */
1050 token
->value
, /*flags=*/0, richloc
);
1054 /* As c_parser_error_richloc, but issue the message at the
1055 location of PARSER's next token, or at input_location
1056 if the next token is EOF. */
1059 c_parser_error (c_parser
*parser
, const char *gmsgid
)
1061 c_token
*token
= c_parser_peek_token (parser
);
1062 c_parser_set_source_position_from_token (token
);
1063 rich_location
richloc (line_table
, input_location
);
1064 return c_parser_error_richloc (parser
, gmsgid
, &richloc
);
1067 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1068 This class is for tracking such a matching pair of symbols.
1069 In particular, it tracks the location of the first token,
1070 so that if the second token is missing, we can highlight the
1071 location of the first token when notifying the user about the
1074 template <typename traits_t
>
1078 /* token_pair's ctor. */
1079 token_pair () : m_open_loc (UNKNOWN_LOCATION
) {}
1081 /* If the next token is the opening symbol for this pair, consume it and
1083 Otherwise, issue an error and return false.
1084 In either case, record the location of the opening token. */
1086 bool require_open (c_parser
*parser
)
1088 c_token
*token
= c_parser_peek_token (parser
);
1090 m_open_loc
= token
->location
;
1092 return c_parser_require (parser
, traits_t::open_token_type
,
1093 traits_t::open_gmsgid
);
1096 /* Consume the next token from PARSER, recording its location as
1097 that of the opening token within the pair. */
1099 void consume_open (c_parser
*parser
)
1101 c_token
*token
= c_parser_peek_token (parser
);
1102 gcc_assert (token
->type
== traits_t::open_token_type
);
1103 m_open_loc
= token
->location
;
1104 c_parser_consume_token (parser
);
1107 /* If the next token is the closing symbol for this pair, consume it
1109 Otherwise, issue an error, highlighting the location of the
1110 corresponding opening token, and return false. */
1112 bool require_close (c_parser
*parser
) const
1114 return c_parser_require (parser
, traits_t::close_token_type
,
1115 traits_t::close_gmsgid
, m_open_loc
);
1118 /* Like token_pair::require_close, except that tokens will be skipped
1119 until the desired token is found. An error message is still produced
1120 if the next token is not as expected. */
1122 void skip_until_found_close (c_parser
*parser
) const
1124 c_parser_skip_until_found (parser
, traits_t::close_token_type
,
1125 traits_t::close_gmsgid
, m_open_loc
);
1129 location_t m_open_loc
;
1132 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1134 struct matching_paren_traits
1136 static const enum cpp_ttype open_token_type
= CPP_OPEN_PAREN
;
1137 static const char * const open_gmsgid
;
1138 static const enum cpp_ttype close_token_type
= CPP_CLOSE_PAREN
;
1139 static const char * const close_gmsgid
;
1142 const char * const matching_paren_traits::open_gmsgid
= "expected %<(%>";
1143 const char * const matching_paren_traits::close_gmsgid
= "expected %<)%>";
1145 /* "matching_parens" is a token_pair<T> class for tracking matching
1146 pairs of parentheses. */
1148 typedef token_pair
<matching_paren_traits
> matching_parens
;
1150 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1152 struct matching_brace_traits
1154 static const enum cpp_ttype open_token_type
= CPP_OPEN_BRACE
;
1155 static const char * const open_gmsgid
;
1156 static const enum cpp_ttype close_token_type
= CPP_CLOSE_BRACE
;
1157 static const char * const close_gmsgid
;
1160 const char * const matching_brace_traits::open_gmsgid
= "expected %<{%>";
1161 const char * const matching_brace_traits::close_gmsgid
= "expected %<}%>";
1163 /* "matching_braces" is a token_pair<T> class for tracking matching
1166 typedef token_pair
<matching_brace_traits
> matching_braces
;
1168 /* Get a description of the matching symbol to TYPE e.g. "(" for
1172 get_matching_symbol (enum cpp_ttype type
)
1178 case CPP_CLOSE_PAREN
:
1180 case CPP_CLOSE_BRACE
:
1185 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1186 issue the error MSGID. If MSGID is NULL then a message has already
1187 been produced and no message will be produced this time. Returns
1188 true if found, false otherwise.
1190 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1191 within any error as the location of an "opening" token matching
1192 the close token TYPE (e.g. the location of the '(' when TYPE is
1195 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1196 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1197 attempt to generate a fix-it hint for the problem.
1198 Otherwise msgid describes multiple token types (e.g.
1199 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1200 generate a fix-it hint. */
1203 c_parser_require (c_parser
*parser
,
1204 enum cpp_ttype type
,
1206 location_t matching_location
,
1207 bool type_is_unique
)
1209 if (c_parser_next_token_is (parser
, type
))
1211 c_parser_consume_token (parser
);
1216 location_t next_token_loc
= c_parser_peek_token (parser
)->location
;
1217 gcc_rich_location
richloc (next_token_loc
);
1219 /* Potentially supply a fix-it hint, suggesting to add the
1220 missing token immediately after the *previous* token.
1221 This may move the primary location within richloc. */
1222 if (!parser
->error
&& type_is_unique
)
1223 maybe_suggest_missing_token_insertion (&richloc
, type
,
1224 parser
->last_token_location
);
1226 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1227 Attempt to consolidate diagnostics by printing it as a
1228 secondary range within the main diagnostic. */
1229 bool added_matching_location
= false;
1230 if (matching_location
!= UNKNOWN_LOCATION
)
1231 added_matching_location
1232 = richloc
.add_location_if_nearby (matching_location
);
1234 if (c_parser_error_richloc (parser
, msgid
, &richloc
))
1235 /* If we weren't able to consolidate matching_location, then
1236 print it as a secondary diagnostic. */
1237 if (matching_location
!= UNKNOWN_LOCATION
&& !added_matching_location
)
1238 inform (matching_location
, "to match this %qs",
1239 get_matching_symbol (type
));
1245 /* If the next token is the indicated keyword, consume it. Otherwise,
1246 issue the error MSGID. Returns true if found, false otherwise. */
1249 c_parser_require_keyword (c_parser
*parser
,
1253 if (c_parser_next_token_is_keyword (parser
, keyword
))
1255 c_parser_consume_token (parser
);
1260 c_parser_error (parser
, msgid
);
1265 /* Like c_parser_require, except that tokens will be skipped until the
1266 desired token is found. An error message is still produced if the
1267 next token is not as expected. If MSGID is NULL then a message has
1268 already been produced and no message will be produced this
1271 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1272 within any error as the location of an "opening" token matching
1273 the close token TYPE (e.g. the location of the '(' when TYPE is
1274 CPP_CLOSE_PAREN). */
1277 c_parser_skip_until_found (c_parser
*parser
,
1278 enum cpp_ttype type
,
1280 location_t matching_location
)
1282 unsigned nesting_depth
= 0;
1284 if (c_parser_require (parser
, type
, msgid
, matching_location
))
1287 /* Skip tokens until the desired token is found. */
1290 /* Peek at the next token. */
1291 c_token
*token
= c_parser_peek_token (parser
);
1292 /* If we've reached the token we want, consume it and stop. */
1293 if (token
->type
== type
&& !nesting_depth
)
1295 c_parser_consume_token (parser
);
1299 /* If we've run out of tokens, stop. */
1300 if (token
->type
== CPP_EOF
)
1302 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1304 if (token
->type
== CPP_OPEN_BRACE
1305 || token
->type
== CPP_OPEN_PAREN
1306 || token
->type
== CPP_OPEN_SQUARE
)
1308 else if (token
->type
== CPP_CLOSE_BRACE
1309 || token
->type
== CPP_CLOSE_PAREN
1310 || token
->type
== CPP_CLOSE_SQUARE
)
1312 if (nesting_depth
-- == 0)
1315 /* Consume this token. */
1316 c_parser_consume_token (parser
);
1318 parser
->error
= false;
1321 /* Skip tokens until the end of a parameter is found, but do not
1322 consume the comma, semicolon or closing delimiter. */
1325 c_parser_skip_to_end_of_parameter (c_parser
*parser
)
1327 unsigned nesting_depth
= 0;
1331 c_token
*token
= c_parser_peek_token (parser
);
1332 if ((token
->type
== CPP_COMMA
|| token
->type
== CPP_SEMICOLON
)
1335 /* If we've run out of tokens, stop. */
1336 if (token
->type
== CPP_EOF
)
1338 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1340 if (token
->type
== CPP_OPEN_BRACE
1341 || token
->type
== CPP_OPEN_PAREN
1342 || token
->type
== CPP_OPEN_SQUARE
)
1344 else if (token
->type
== CPP_CLOSE_BRACE
1345 || token
->type
== CPP_CLOSE_PAREN
1346 || token
->type
== CPP_CLOSE_SQUARE
)
1348 if (nesting_depth
-- == 0)
1351 /* Consume this token. */
1352 c_parser_consume_token (parser
);
1354 parser
->error
= false;
1357 /* Expect to be at the end of the pragma directive and consume an
1358 end of line marker. */
1361 c_parser_skip_to_pragma_eol (c_parser
*parser
, bool error_if_not_eol
= true)
1363 gcc_assert (parser
->in_pragma
);
1364 parser
->in_pragma
= false;
1366 if (error_if_not_eol
&& c_parser_peek_token (parser
)->type
!= CPP_PRAGMA_EOL
)
1367 c_parser_error (parser
, "expected end of line");
1369 cpp_ttype token_type
;
1372 c_token
*token
= c_parser_peek_token (parser
);
1373 token_type
= token
->type
;
1374 if (token_type
== CPP_EOF
)
1376 c_parser_consume_token (parser
);
1378 while (token_type
!= CPP_PRAGMA_EOL
);
1380 parser
->error
= false;
1383 /* Skip tokens until we have consumed an entire block, or until we
1384 have consumed a non-nested ';'. */
1387 c_parser_skip_to_end_of_block_or_statement (c_parser
*parser
)
1389 unsigned nesting_depth
= 0;
1390 bool save_error
= parser
->error
;
1396 /* Peek at the next token. */
1397 token
= c_parser_peek_token (parser
);
1399 switch (token
->type
)
1404 case CPP_PRAGMA_EOL
:
1405 if (parser
->in_pragma
)
1410 /* If the next token is a ';', we have reached the
1411 end of the statement. */
1414 /* Consume the ';'. */
1415 c_parser_consume_token (parser
);
1420 case CPP_CLOSE_BRACE
:
1421 /* If the next token is a non-nested '}', then we have
1422 reached the end of the current block. */
1423 if (nesting_depth
== 0 || --nesting_depth
== 0)
1425 c_parser_consume_token (parser
);
1430 case CPP_OPEN_BRACE
:
1431 /* If it the next token is a '{', then we are entering a new
1432 block. Consume the entire block. */
1437 /* If we see a pragma, consume the whole thing at once. We
1438 have some safeguards against consuming pragmas willy-nilly.
1439 Normally, we'd expect to be here with parser->error set,
1440 which disables these safeguards. But it's possible to get
1441 here for secondary error recovery, after parser->error has
1443 c_parser_consume_pragma (parser
);
1444 c_parser_skip_to_pragma_eol (parser
);
1445 parser
->error
= save_error
;
1452 c_parser_consume_token (parser
);
1456 parser
->error
= false;
1459 /* CPP's options (initialized by c-opts.cc). */
1460 extern cpp_options
*cpp_opts
;
1462 /* Save the warning flags which are controlled by __extension__. */
1465 disable_extension_diagnostics (void)
1468 | (warn_pointer_arith
<< 1)
1469 | (warn_traditional
<< 2)
1471 | (warn_long_long
<< 4)
1472 | (warn_cxx_compat
<< 5)
1473 | (warn_overlength_strings
<< 6)
1474 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1475 play tricks to properly restore it. */
1476 | ((warn_c90_c99_compat
== 1) << 7)
1477 | ((warn_c90_c99_compat
== -1) << 8)
1478 /* Similarly for warn_c99_c11_compat. */
1479 | ((warn_c99_c11_compat
== 1) << 9)
1480 | ((warn_c99_c11_compat
== -1) << 10)
1481 /* Similarly for warn_c11_c2x_compat. */
1482 | ((warn_c11_c2x_compat
== 1) << 11)
1483 | ((warn_c11_c2x_compat
== -1) << 12)
1485 cpp_opts
->cpp_pedantic
= pedantic
= 0;
1486 warn_pointer_arith
= 0;
1487 cpp_opts
->cpp_warn_traditional
= warn_traditional
= 0;
1489 cpp_opts
->cpp_warn_long_long
= warn_long_long
= 0;
1490 warn_cxx_compat
= 0;
1491 warn_overlength_strings
= 0;
1492 warn_c90_c99_compat
= 0;
1493 warn_c99_c11_compat
= 0;
1494 warn_c11_c2x_compat
= 0;
1498 /* Restore the warning flags which are controlled by __extension__.
1499 FLAGS is the return value from disable_extension_diagnostics. */
1502 restore_extension_diagnostics (int flags
)
1504 cpp_opts
->cpp_pedantic
= pedantic
= flags
& 1;
1505 warn_pointer_arith
= (flags
>> 1) & 1;
1506 cpp_opts
->cpp_warn_traditional
= warn_traditional
= (flags
>> 2) & 1;
1507 flag_iso
= (flags
>> 3) & 1;
1508 cpp_opts
->cpp_warn_long_long
= warn_long_long
= (flags
>> 4) & 1;
1509 warn_cxx_compat
= (flags
>> 5) & 1;
1510 warn_overlength_strings
= (flags
>> 6) & 1;
1511 /* See above for why is this needed. */
1512 warn_c90_c99_compat
= (flags
>> 7) & 1 ? 1 : ((flags
>> 8) & 1 ? -1 : 0);
1513 warn_c99_c11_compat
= (flags
>> 9) & 1 ? 1 : ((flags
>> 10) & 1 ? -1 : 0);
1514 warn_c11_c2x_compat
= (flags
>> 11) & 1 ? 1 : ((flags
>> 12) & 1 ? -1 : 0);
1517 /* Helper data structure for parsing #pragma acc routine. */
1518 struct oacc_routine_data
{
1519 bool error_seen
; /* Set if error has been reported. */
1520 bool fndecl_seen
; /* Set if one fn decl/definition has been seen already. */
1525 /* Used for parsing objc foreach statements. */
1526 static tree objc_foreach_break_label
, objc_foreach_continue_label
;
1528 static bool c_parser_nth_token_starts_std_attributes (c_parser
*,
1530 static tree
c_parser_std_attribute_specifier_sequence (c_parser
*);
1531 static void c_parser_external_declaration (c_parser
*);
1532 static void c_parser_asm_definition (c_parser
*);
1533 static void c_parser_declaration_or_fndef (c_parser
*, bool, bool, bool,
1534 bool, bool, tree
* = NULL
,
1535 vec
<c_token
> * = NULL
,
1536 bool have_attrs
= false,
1538 struct oacc_routine_data
* = NULL
,
1540 static void c_parser_static_assert_declaration_no_semi (c_parser
*);
1541 static void c_parser_static_assert_declaration (c_parser
*);
1542 static struct c_typespec
c_parser_enum_specifier (c_parser
*);
1543 static struct c_typespec
c_parser_struct_or_union_specifier (c_parser
*);
1544 static tree
c_parser_struct_declaration (c_parser
*);
1545 static struct c_typespec
c_parser_typeof_specifier (c_parser
*);
1546 static tree
c_parser_alignas_specifier (c_parser
*);
1547 static struct c_declarator
*c_parser_direct_declarator (c_parser
*, bool,
1549 static struct c_declarator
*c_parser_direct_declarator_inner (c_parser
*,
1551 struct c_declarator
*);
1552 static struct c_arg_info
*c_parser_parms_declarator (c_parser
*, bool, tree
,
1554 static struct c_arg_info
*c_parser_parms_list_declarator (c_parser
*, tree
,
1556 static struct c_parm
*c_parser_parameter_declaration (c_parser
*, tree
, bool);
1557 static tree
c_parser_simple_asm_expr (c_parser
*);
1558 static tree
c_parser_gnu_attributes (c_parser
*);
1559 static struct c_expr
c_parser_initializer (c_parser
*, tree
);
1560 static struct c_expr
c_parser_braced_init (c_parser
*, tree
, bool,
1561 struct obstack
*, tree
);
1562 static void c_parser_initelt (c_parser
*, struct obstack
*);
1563 static void c_parser_initval (c_parser
*, struct c_expr
*,
1565 static tree
c_parser_compound_statement (c_parser
*, location_t
* = NULL
);
1566 static location_t
c_parser_compound_statement_nostart (c_parser
*);
1567 static void c_parser_label (c_parser
*, tree
);
1568 static void c_parser_statement (c_parser
*, bool *, location_t
* = NULL
);
1569 static void c_parser_statement_after_labels (c_parser
*, bool *,
1570 vec
<tree
> * = NULL
);
1571 static tree
c_parser_c99_block_statement (c_parser
*, bool *,
1572 location_t
* = NULL
);
1573 static void c_parser_if_statement (c_parser
*, bool *, vec
<tree
> *);
1574 static void c_parser_switch_statement (c_parser
*, bool *);
1575 static void c_parser_while_statement (c_parser
*, bool, unsigned short, bool *);
1576 static void c_parser_do_statement (c_parser
*, bool, unsigned short);
1577 static void c_parser_for_statement (c_parser
*, bool, unsigned short, bool *);
1578 static tree
c_parser_asm_statement (c_parser
*);
1579 static tree
c_parser_asm_operands (c_parser
*);
1580 static tree
c_parser_asm_goto_operands (c_parser
*);
1581 static tree
c_parser_asm_clobbers (c_parser
*);
1582 static struct c_expr
c_parser_expr_no_commas (c_parser
*, struct c_expr
*,
1584 static struct c_expr
c_parser_conditional_expression (c_parser
*,
1585 struct c_expr
*, tree
);
1586 static struct c_expr
c_parser_binary_expression (c_parser
*, struct c_expr
*,
1588 static struct c_expr
c_parser_cast_expression (c_parser
*, struct c_expr
*);
1589 static struct c_expr
c_parser_unary_expression (c_parser
*);
1590 static struct c_expr
c_parser_sizeof_expression (c_parser
*);
1591 static struct c_expr
c_parser_alignof_expression (c_parser
*);
1592 static struct c_expr
c_parser_postfix_expression (c_parser
*);
1593 static struct c_expr
c_parser_postfix_expression_after_paren_type (c_parser
*,
1594 struct c_declspecs
*,
1595 struct c_type_name
*,
1597 static struct c_expr
c_parser_postfix_expression_after_primary (c_parser
*,
1600 static tree
c_parser_transaction (c_parser
*, enum rid
);
1601 static struct c_expr
c_parser_transaction_expression (c_parser
*, enum rid
);
1602 static tree
c_parser_transaction_cancel (c_parser
*);
1603 static struct c_expr
c_parser_expression (c_parser
*);
1604 static struct c_expr
c_parser_expression_conv (c_parser
*);
1605 static vec
<tree
, va_gc
> *c_parser_expr_list (c_parser
*, bool, bool,
1606 vec
<tree
, va_gc
> **, location_t
*,
1607 tree
*, vec
<location_t
> *,
1608 unsigned int * = NULL
);
1609 static struct c_expr
c_parser_has_attribute_expression (c_parser
*);
1611 static void c_parser_oacc_declare (c_parser
*);
1612 static void c_parser_oacc_enter_exit_data (c_parser
*, bool);
1613 static void c_parser_oacc_update (c_parser
*);
1614 static void c_parser_omp_construct (c_parser
*, bool *);
1615 static void c_parser_omp_threadprivate (c_parser
*);
1616 static void c_parser_omp_barrier (c_parser
*);
1617 static void c_parser_omp_depobj (c_parser
*);
1618 static void c_parser_omp_flush (c_parser
*);
1619 static tree
c_parser_omp_for_loop (location_t
, c_parser
*, enum tree_code
,
1620 tree
, tree
*, bool *);
1621 static void c_parser_omp_taskwait (c_parser
*);
1622 static void c_parser_omp_taskyield (c_parser
*);
1623 static void c_parser_omp_cancel (c_parser
*);
1624 static void c_parser_omp_nothing (c_parser
*);
1626 enum pragma_context
{ pragma_external
, pragma_struct
, pragma_param
,
1627 pragma_stmt
, pragma_compound
};
1628 static bool c_parser_pragma (c_parser
*, enum pragma_context
, bool *);
1629 static bool c_parser_omp_cancellation_point (c_parser
*, enum pragma_context
);
1630 static bool c_parser_omp_target (c_parser
*, enum pragma_context
, bool *);
1631 static void c_parser_omp_begin (c_parser
*);
1632 static void c_parser_omp_end (c_parser
*);
1633 static bool c_parser_omp_declare (c_parser
*, enum pragma_context
);
1634 static void c_parser_omp_requires (c_parser
*);
1635 static bool c_parser_omp_error (c_parser
*, enum pragma_context
);
1636 static void c_parser_omp_assumption_clauses (c_parser
*, bool);
1637 static void c_parser_omp_assumes (c_parser
*);
1638 static bool c_parser_omp_ordered (c_parser
*, enum pragma_context
, bool *);
1639 static void c_parser_oacc_routine (c_parser
*, enum pragma_context
);
1641 /* These Objective-C parser functions are only ever called when
1642 compiling Objective-C. */
1643 static void c_parser_objc_class_definition (c_parser
*, tree
);
1644 static void c_parser_objc_class_instance_variables (c_parser
*);
1645 static void c_parser_objc_class_declaration (c_parser
*);
1646 static void c_parser_objc_alias_declaration (c_parser
*);
1647 static void c_parser_objc_protocol_definition (c_parser
*, tree
);
1648 static bool c_parser_objc_method_type (c_parser
*);
1649 static void c_parser_objc_method_definition (c_parser
*);
1650 static void c_parser_objc_methodprotolist (c_parser
*);
1651 static void c_parser_objc_methodproto (c_parser
*);
1652 static tree
c_parser_objc_method_decl (c_parser
*, bool, tree
*, tree
*);
1653 static tree
c_parser_objc_type_name (c_parser
*);
1654 static tree
c_parser_objc_protocol_refs (c_parser
*);
1655 static void c_parser_objc_try_catch_finally_statement (c_parser
*);
1656 static void c_parser_objc_synchronized_statement (c_parser
*);
1657 static tree
c_parser_objc_selector (c_parser
*);
1658 static tree
c_parser_objc_selector_arg (c_parser
*);
1659 static tree
c_parser_objc_receiver (c_parser
*);
1660 static tree
c_parser_objc_message_args (c_parser
*);
1661 static tree
c_parser_objc_keywordexpr (c_parser
*);
1662 static void c_parser_objc_at_property_declaration (c_parser
*);
1663 static void c_parser_objc_at_synthesize_declaration (c_parser
*);
1664 static void c_parser_objc_at_dynamic_declaration (c_parser
*);
1665 static bool c_parser_objc_diagnose_bad_element_prefix
1666 (c_parser
*, struct c_declspecs
*);
1667 static location_t
c_parser_parse_rtl_body (c_parser
*, char *);
1673 /* Concrete implementation of ana::translation_unit for the C frontend. */
1675 class c_translation_unit
: public translation_unit
1678 /* Implementation of translation_unit::lookup_constant_by_id for use by the
1679 analyzer to look up named constants in the user's source code. */
1680 tree
lookup_constant_by_id (tree id
) const final override
1682 /* Consider decls. */
1683 if (tree decl
= lookup_name (id
))
1684 if (TREE_CODE (decl
) == CONST_DECL
)
1685 if (tree value
= DECL_INITIAL (decl
))
1686 if (TREE_CODE (value
) == INTEGER_CST
)
1689 /* Consider macros. */
1690 cpp_hashnode
*hashnode
= C_CPP_HASHNODE (id
);
1691 if (cpp_macro_p (hashnode
))
1692 if (tree value
= consider_macro (hashnode
->value
.macro
))
1699 /* Attempt to get an INTEGER_CST from MACRO.
1700 Only handle the simplest cases: where MACRO's definition is a single
1701 token containing a number, by lexing the number again.
1702 This will handle e.g.
1704 and other bases but not negative numbers, parentheses or e.g.
1706 as doing so would require a parser. */
1707 tree
consider_macro (cpp_macro
*macro
) const
1709 if (macro
->paramc
> 0)
1711 if (macro
->kind
!= cmk_macro
)
1713 if (macro
->count
!= 1)
1715 const cpp_token
&tok
= macro
->exp
.tokens
[0];
1716 if (tok
.type
!= CPP_NUMBER
)
1719 cpp_reader
*old_parse_in
= parse_in
;
1720 parse_in
= cpp_create_reader (CLK_GNUC89
, NULL
, line_table
);
1723 pp_string (&pp
, (const char *) tok
.val
.str
.text
);
1725 cpp_push_buffer (parse_in
,
1726 (const unsigned char *) pp_formatted_text (&pp
),
1727 strlen (pp_formatted_text (&pp
)),
1732 unsigned char cpp_flags
;
1733 c_lex_with_flags (&value
, &loc
, &cpp_flags
, 0);
1735 cpp_destroy (parse_in
);
1736 parse_in
= old_parse_in
;
1738 if (value
&& TREE_CODE (value
) == INTEGER_CST
)
1747 #endif /* #if ENABLE_ANALYZER */
1749 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1752 external-declarations
1754 external-declarations:
1755 external-declaration
1756 external-declarations external-declaration
1765 c_parser_translation_unit (c_parser
*parser
)
1767 if (c_parser_next_token_is (parser
, CPP_EOF
))
1769 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1770 "ISO C forbids an empty translation unit");
1774 void *obstack_position
= obstack_alloc (&parser_obstack
, 0);
1775 mark_valid_location_for_stdc_pragma (false);
1779 c_parser_external_declaration (parser
);
1780 obstack_free (&parser_obstack
, obstack_position
);
1782 while (c_parser_next_token_is_not (parser
, CPP_EOF
));
1787 FOR_EACH_VEC_ELT (incomplete_record_decls
, i
, decl
)
1788 if (DECL_SIZE (decl
) == NULL_TREE
&& TREE_TYPE (decl
) != error_mark_node
)
1789 error ("storage size of %q+D isn%'t known", decl
);
1791 if (vec_safe_length (current_omp_declare_target_attribute
))
1793 c_omp_declare_target_attr
1794 a
= current_omp_declare_target_attribute
->pop ();
1796 error ("%qs without corresponding %qs",
1797 a
.device_type
>= 0 ? "#pragma omp begin declare target"
1798 : "#pragma omp declare target",
1799 "#pragma omp end declare target");
1800 vec_safe_truncate (current_omp_declare_target_attribute
, 0);
1802 if (current_omp_begin_assumes
)
1805 error ("%qs without corresponding %qs",
1806 "#pragma omp begin assumes", "#pragma omp end assumes");
1807 current_omp_begin_assumes
= 0;
1813 ana::c_translation_unit tu
;
1814 ana::on_finish_translation_unit (tu
);
1819 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1821 external-declaration:
1827 external-declaration:
1830 __extension__ external-declaration
1834 external-declaration:
1835 objc-class-definition
1836 objc-class-declaration
1837 objc-alias-declaration
1838 objc-protocol-definition
1839 objc-method-definition
1844 c_parser_external_declaration (c_parser
*parser
)
1847 switch (c_parser_peek_token (parser
)->type
)
1850 switch (c_parser_peek_token (parser
)->keyword
)
1853 ext
= disable_extension_diagnostics ();
1854 c_parser_consume_token (parser
);
1855 c_parser_external_declaration (parser
);
1856 restore_extension_diagnostics (ext
);
1859 c_parser_asm_definition (parser
);
1861 case RID_AT_INTERFACE
:
1862 case RID_AT_IMPLEMENTATION
:
1863 gcc_assert (c_dialect_objc ());
1864 c_parser_objc_class_definition (parser
, NULL_TREE
);
1867 gcc_assert (c_dialect_objc ());
1868 c_parser_objc_class_declaration (parser
);
1871 gcc_assert (c_dialect_objc ());
1872 c_parser_objc_alias_declaration (parser
);
1874 case RID_AT_PROTOCOL
:
1875 gcc_assert (c_dialect_objc ());
1876 c_parser_objc_protocol_definition (parser
, NULL_TREE
);
1878 case RID_AT_PROPERTY
:
1879 gcc_assert (c_dialect_objc ());
1880 c_parser_objc_at_property_declaration (parser
);
1882 case RID_AT_SYNTHESIZE
:
1883 gcc_assert (c_dialect_objc ());
1884 c_parser_objc_at_synthesize_declaration (parser
);
1886 case RID_AT_DYNAMIC
:
1887 gcc_assert (c_dialect_objc ());
1888 c_parser_objc_at_dynamic_declaration (parser
);
1891 gcc_assert (c_dialect_objc ());
1892 c_parser_consume_token (parser
);
1893 objc_finish_implementation ();
1900 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1901 "ISO C does not allow extra %<;%> outside of a function");
1902 c_parser_consume_token (parser
);
1905 mark_valid_location_for_stdc_pragma (true);
1906 c_parser_pragma (parser
, pragma_external
, NULL
);
1907 mark_valid_location_for_stdc_pragma (false);
1911 if (c_dialect_objc ())
1913 c_parser_objc_method_definition (parser
);
1916 /* Else fall through, and yield a syntax error trying to parse
1917 as a declaration or function definition. */
1921 /* A declaration or a function definition (or, in Objective-C,
1922 an @interface or @protocol with prefix attributes). We can
1923 only tell which after parsing the declaration specifiers, if
1924 any, and the first declarator. */
1925 c_parser_declaration_or_fndef (parser
, true, true, true, false, true);
1930 static void c_finish_omp_declare_simd (c_parser
*, tree
, tree
, vec
<c_token
> *);
1931 static void c_finish_oacc_routine (struct oacc_routine_data
*, tree
, bool);
1933 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1936 add_debug_begin_stmt (location_t loc
)
1938 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1939 if (!MAY_HAVE_DEBUG_MARKER_STMTS
|| !building_stmt_list_p ())
1942 tree stmt
= build0 (DEBUG_BEGIN_STMT
, void_type_node
);
1943 SET_EXPR_LOCATION (stmt
, loc
);
1947 /* Helper function for c_parser_declaration_or_fndef and
1948 Handle assume attribute(s). */
1951 handle_assume_attribute (location_t here
, tree attrs
, bool nested
)
1954 for (tree attr
= lookup_attribute ("gnu", "assume", attrs
); attr
;
1955 attr
= lookup_attribute ("gnu", "assume", TREE_CHAIN (attr
)))
1957 tree args
= TREE_VALUE (attr
);
1958 int nargs
= list_length (args
);
1961 error_at (here
, "wrong number of arguments specified "
1962 "for %qE attribute",
1963 get_attribute_name (attr
));
1964 inform (here
, "expected %i, found %i", 1, nargs
);
1968 tree arg
= TREE_VALUE (args
);
1969 arg
= c_objc_common_truthvalue_conversion (here
, arg
);
1970 arg
= c_fully_fold (arg
, false, NULL
);
1971 if (arg
!= error_mark_node
)
1973 tree fn
= build_call_expr_internal_loc (here
, IFN_ASSUME
,
1981 pedwarn (here
, OPT_Wattributes
,
1982 "%<assume%> attribute at top level");
1984 return remove_attribute ("gnu", "assume", attrs
);
1987 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1988 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1989 is accepted; otherwise (old-style parameter declarations) only other
1990 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1991 assertion is accepted; otherwise (old-style parameter declarations)
1992 it is not. If NESTED is true, we are inside a function or parsing
1993 old-style parameter declarations; any functions encountered are
1994 nested functions and declaration specifiers are required; otherwise
1995 we are at top level and functions are normal functions and
1996 declaration specifiers may be optional. If EMPTY_OK is true, empty
1997 declarations are OK (subject to all other constraints); otherwise
1998 (old-style parameter declarations) they are diagnosed. If
1999 START_ATTR_OK is true, the declaration specifiers may start with
2000 attributes (GNU or standard); otherwise they may not.
2001 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
2002 declaration when parsing an Objective-C foreach statement.
2003 FALLTHRU_ATTR_P is used to signal whether this function parsed
2004 "__attribute__((fallthrough));". ATTRS are any standard attributes
2005 parsed in the caller (in contexts where such attributes had to be
2006 parsed to determine whether what follows is a declaration or a
2007 statement); HAVE_ATTRS says whether there were any such attributes
2011 declaration-specifiers init-declarator-list[opt] ;
2012 static_assert-declaration
2014 function-definition:
2015 declaration-specifiers[opt] declarator declaration-list[opt]
2020 declaration-list declaration
2022 init-declarator-list:
2024 init-declarator-list , init-declarator
2027 declarator simple-asm-expr[opt] gnu-attributes[opt]
2028 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
2032 nested-function-definition:
2033 declaration-specifiers declarator declaration-list[opt]
2039 gnu-attributes objc-class-definition
2040 gnu-attributes objc-category-definition
2041 gnu-attributes objc-protocol-definition
2043 The simple-asm-expr and gnu-attributes are GNU extensions.
2045 This function does not handle __extension__; that is handled in its
2046 callers. ??? Following the old parser, __extension__ may start
2047 external declarations, declarations in functions and declarations
2048 at the start of "for" loops, but not old-style parameter
2051 C99 requires declaration specifiers in a function definition; the
2052 absence is diagnosed through the diagnosis of implicit int. In GNU
2053 C we also allow but diagnose declarations without declaration
2054 specifiers, but only at top level (elsewhere they conflict with
2057 In Objective-C, declarations of the looping variable in a foreach
2058 statement are exceptionally terminated by 'in' (for example, 'for
2059 (NSObject *object in array) { ... }').
2064 threadprivate-directive
2068 gimple-function-definition:
2069 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
2070 declaration-list[opt] compound-statement
2072 rtl-function-definition:
2073 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
2074 declaration-list[opt] compound-statement */
2077 c_parser_declaration_or_fndef (c_parser
*parser
, bool fndef_ok
,
2078 bool static_assert_ok
, bool empty_ok
,
2079 bool nested
, bool start_attr_ok
,
2080 tree
*objc_foreach_object_declaration
2082 vec
<c_token
> *omp_declare_simd_clauses
2084 bool have_attrs
/* = false */,
2085 tree attrs
/* = NULL_TREE */,
2086 struct oacc_routine_data
*oacc_routine_data
2088 bool *fallthru_attr_p
/* = NULL */)
2090 struct c_declspecs
*specs
;
2092 tree all_prefix_attrs
;
2093 bool diagnosed_no_specs
= false;
2094 location_t here
= c_parser_peek_token (parser
)->location
;
2096 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
2098 if (static_assert_ok
2099 && c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
2101 c_parser_static_assert_declaration (parser
);
2104 specs
= build_null_declspecs ();
2106 /* Handle any standard attributes parsed in the caller. */
2109 declspecs_add_attrs (here
, specs
, attrs
);
2110 specs
->non_std_attrs_seen_p
= false;
2113 /* Try to detect an unknown type name when we have "A B" or "A *B". */
2114 if (c_parser_peek_token (parser
)->type
== CPP_NAME
2115 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
2116 && (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
2117 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
2118 && (!nested
|| !lookup_name (c_parser_peek_token (parser
)->value
)))
2120 tree name
= c_parser_peek_token (parser
)->value
;
2122 /* Issue a warning about NAME being an unknown type name, perhaps
2123 with some kind of hint.
2124 If the user forgot a "struct" etc, suggest inserting
2125 it. Otherwise, attempt to look for misspellings. */
2126 gcc_rich_location
richloc (here
);
2127 if (tag_exists_p (RECORD_TYPE
, name
))
2129 /* This is not C++ with its implicit typedef. */
2130 richloc
.add_fixit_insert_before ("struct ");
2132 "unknown type name %qE;"
2133 " use %<struct%> keyword to refer to the type",
2136 else if (tag_exists_p (UNION_TYPE
, name
))
2138 richloc
.add_fixit_insert_before ("union ");
2140 "unknown type name %qE;"
2141 " use %<union%> keyword to refer to the type",
2144 else if (tag_exists_p (ENUMERAL_TYPE
, name
))
2146 richloc
.add_fixit_insert_before ("enum ");
2148 "unknown type name %qE;"
2149 " use %<enum%> keyword to refer to the type",
2154 auto_diagnostic_group d
;
2155 name_hint hint
= lookup_name_fuzzy (name
, FUZZY_LOOKUP_TYPENAME
,
2157 if (const char *suggestion
= hint
.suggestion ())
2159 richloc
.add_fixit_replace (suggestion
);
2161 "unknown type name %qE; did you mean %qs?",
2165 error_at (here
, "unknown type name %qE", name
);
2168 /* Parse declspecs normally to get a correct pointer type, but avoid
2169 a further "fails to be a type name" error. Refuse nested functions
2170 since it is not how the user likely wants us to recover. */
2171 c_parser_peek_token (parser
)->type
= CPP_KEYWORD
;
2172 c_parser_peek_token (parser
)->keyword
= RID_VOID
;
2173 c_parser_peek_token (parser
)->value
= error_mark_node
;
2177 /* When there are standard attributes at the start of the
2178 declaration (to apply to the entity being declared), an
2179 init-declarator-list or function definition must be present. */
2180 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
2183 c_parser_declspecs (parser
, specs
, true, true, start_attr_ok
,
2184 true, true, start_attr_ok
, true, cla_nonabstract_decl
);
2187 c_parser_skip_to_end_of_block_or_statement (parser
);
2190 if (nested
&& !specs
->declspecs_seen_p
)
2192 c_parser_error (parser
, "expected declaration specifiers");
2193 c_parser_skip_to_end_of_block_or_statement (parser
);
2197 finish_declspecs (specs
);
2198 bool gnu_auto_type_p
= specs
->typespec_word
== cts_auto_type
;
2199 bool std_auto_type_p
= specs
->c2x_auto_p
;
2200 bool any_auto_type_p
= gnu_auto_type_p
|| std_auto_type_p
;
2201 gcc_assert (!(gnu_auto_type_p
&& std_auto_type_p
));
2202 const char *auto_type_keyword
= gnu_auto_type_p
? "__auto_type" : "auto";
2203 if (specs
->constexpr_p
)
2205 /* An underspecified declaration may not declare tags or members
2206 or structures or unions; it is undefined behavior to declare
2207 the members of an enumeration. Where the structure, union or
2208 enumeration type is declared within an initializer, this is
2209 diagnosed elsewhere. Diagnose here the case of declaring
2210 such a type in the type specifiers of a constexpr
2212 switch (specs
->typespec_kind
)
2214 case ctsk_tagfirstref
:
2215 case ctsk_tagfirstref_attrs
:
2216 error_at (here
, "%qT declared in underspecified object declaration",
2221 error_at (here
, "%qT defined in underspecified object declaration",
2229 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2231 bool handled_assume
= false;
2232 if (specs
->typespec_kind
== ctsk_none
2233 && lookup_attribute ("gnu", "assume", specs
->attrs
))
2235 handled_assume
= true;
2237 = handle_assume_attribute (here
, specs
->attrs
, nested
);
2239 if (any_auto_type_p
)
2240 error_at (here
, "%qs in empty declaration", auto_type_keyword
);
2241 else if (specs
->typespec_kind
== ctsk_none
2242 && attribute_fallthrough_p (specs
->attrs
))
2244 if (fallthru_attr_p
!= NULL
)
2245 *fallthru_attr_p
= true;
2248 tree fn
= build_call_expr_internal_loc (here
, IFN_FALLTHROUGH
,
2253 pedwarn (here
, OPT_Wattributes
,
2254 "%<fallthrough%> attribute at top level");
2257 && !(have_attrs
&& specs
->non_std_attrs_seen_p
)
2262 shadow_tag_warned (specs
, 1);
2263 if (!handled_assume
)
2264 pedwarn (here
, 0, "empty declaration");
2266 c_parser_consume_token (parser
);
2267 if (oacc_routine_data
)
2268 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2272 /* Provide better error recovery. Note that a type name here is usually
2273 better diagnosed as a redeclaration. */
2275 && specs
->typespec_kind
== ctsk_tagdef
2276 && c_parser_next_token_starts_declspecs (parser
)
2277 && !c_parser_next_token_is (parser
, CPP_NAME
))
2279 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
2280 parser
->error
= false;
2281 shadow_tag_warned (specs
, 1);
2284 else if (c_dialect_objc () && !any_auto_type_p
)
2286 /* Prefix attributes are an error on method decls. */
2287 switch (c_parser_peek_token (parser
)->type
)
2291 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2295 warning_at (c_parser_peek_token (parser
)->location
,
2297 "prefix attributes are ignored for methods");
2298 specs
->attrs
= NULL_TREE
;
2301 c_parser_objc_method_definition (parser
);
2303 c_parser_objc_methodproto (parser
);
2309 /* This is where we parse 'attributes @interface ...',
2310 'attributes @implementation ...', 'attributes @protocol ...'
2311 (where attributes could be, for example, __attribute__
2314 switch (c_parser_peek_token (parser
)->keyword
)
2316 case RID_AT_INTERFACE
:
2318 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2320 c_parser_objc_class_definition (parser
, specs
->attrs
);
2324 case RID_AT_IMPLEMENTATION
:
2326 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2330 warning_at (c_parser_peek_token (parser
)->location
,
2332 "prefix attributes are ignored for implementations");
2333 specs
->attrs
= NULL_TREE
;
2335 c_parser_objc_class_definition (parser
, NULL_TREE
);
2339 case RID_AT_PROTOCOL
:
2341 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2343 c_parser_objc_protocol_definition (parser
, specs
->attrs
);
2350 case RID_AT_PROPERTY
:
2353 c_parser_error (parser
, "unexpected attribute");
2354 specs
->attrs
= NULL
;
2361 else if (attribute_fallthrough_p (specs
->attrs
))
2362 warning_at (here
, OPT_Wattributes
,
2363 "%<fallthrough%> attribute not followed by %<;%>");
2364 else if (lookup_attribute ("gnu", "assume", specs
->attrs
))
2365 warning_at (here
, OPT_Wattributes
,
2366 "%<assume%> attribute not followed by %<;%>");
2368 pending_xref_error ();
2369 prefix_attrs
= specs
->attrs
;
2370 all_prefix_attrs
= prefix_attrs
;
2371 specs
->attrs
= NULL_TREE
;
2374 struct c_declarator
*declarator
;
2377 tree fnbody
= NULL_TREE
;
2378 tree underspec_name
= NULL_TREE
;
2379 /* Declaring either one or more declarators (in which case we
2380 should diagnose if there were no declaration specifiers) or a
2381 function definition (in which case the diagnostic for
2382 implicit int suffices). */
2383 declarator
= c_parser_declarator (parser
,
2384 specs
->typespec_kind
!= ctsk_none
,
2385 C_DTR_NORMAL
, &dummy
);
2386 if (declarator
== NULL
)
2388 if (omp_declare_simd_clauses
)
2389 c_finish_omp_declare_simd (parser
, NULL_TREE
, NULL_TREE
,
2390 omp_declare_simd_clauses
);
2391 if (oacc_routine_data
)
2392 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2393 c_parser_skip_to_end_of_block_or_statement (parser
);
2396 if (gnu_auto_type_p
&& declarator
->kind
!= cdk_id
)
2399 "%<__auto_type%> requires a plain identifier"
2401 c_parser_skip_to_end_of_block_or_statement (parser
);
2404 if (std_auto_type_p
)
2406 struct c_declarator
*d
= declarator
;
2407 while (d
->kind
== cdk_attrs
)
2409 if (d
->kind
!= cdk_id
)
2412 "%<auto%> requires a plain identifier, possibly with"
2413 " attributes, as declarator");
2414 c_parser_skip_to_end_of_block_or_statement (parser
);
2417 underspec_name
= d
->u
.id
.id
;
2419 else if (specs
->constexpr_p
)
2421 struct c_declarator
*d
= declarator
;
2422 while (d
->kind
!= cdk_id
)
2424 underspec_name
= d
->u
.id
.id
;
2426 if (c_parser_next_token_is (parser
, CPP_EQ
)
2427 || c_parser_next_token_is (parser
, CPP_COMMA
)
2428 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
2429 || c_parser_next_token_is_keyword (parser
, RID_ASM
)
2430 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
)
2431 || c_parser_next_token_is_keyword (parser
, RID_IN
))
2433 tree asm_name
= NULL_TREE
;
2434 tree postfix_attrs
= NULL_TREE
;
2435 if (!diagnosed_no_specs
&& !specs
->declspecs_seen_p
)
2437 diagnosed_no_specs
= true;
2438 pedwarn (here
, 0, "data definition has no type or storage class");
2440 /* Having seen a data definition, there cannot now be a
2441 function definition. */
2443 if (c_parser_next_token_is_keyword (parser
, RID_ASM
))
2444 asm_name
= c_parser_simple_asm_expr (parser
);
2445 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2447 postfix_attrs
= c_parser_gnu_attributes (parser
);
2448 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2450 /* This means there is an attribute specifier after
2451 the declarator in a function definition. Provide
2452 some more information for the user. */
2453 error_at (here
, "attributes should be specified before the "
2454 "declarator in a function definition");
2455 c_parser_skip_to_end_of_block_or_statement (parser
);
2459 if (c_parser_next_token_is (parser
, CPP_EQ
))
2463 location_t init_loc
;
2464 c_parser_consume_token (parser
);
2465 if (any_auto_type_p
)
2467 init_loc
= c_parser_peek_token (parser
)->location
;
2468 rich_location
richloc (line_table
, init_loc
);
2469 unsigned int underspec_state
= 0;
2470 if (std_auto_type_p
)
2472 start_underspecified_init (init_loc
, underspec_name
);
2473 start_init (NULL_TREE
, asm_name
,
2474 (global_bindings_p ()
2475 || specs
->storage_class
== csc_static
2476 || specs
->constexpr_p
),
2477 specs
->constexpr_p
, &richloc
);
2478 /* A parameter is initialized, which is invalid. Don't
2479 attempt to instrument the initializer. */
2480 int flag_sanitize_save
= flag_sanitize
;
2481 if (nested
&& !empty_ok
)
2483 init
= c_parser_expr_no_commas (parser
, NULL
);
2484 if (std_auto_type_p
)
2485 finish_underspecified_init (underspec_name
,
2487 flag_sanitize
= flag_sanitize_save
;
2489 && TREE_CODE (init
.value
) == COMPONENT_REF
2490 && DECL_C_BIT_FIELD (TREE_OPERAND (init
.value
, 1)))
2492 "%<__auto_type%> used with a bit-field"
2494 init
= convert_lvalue_to_rvalue (init_loc
, init
, true, true,
2496 tree init_type
= TREE_TYPE (init
.value
);
2497 bool vm_type
= c_type_variably_modified_p (init_type
);
2499 init
.value
= save_expr (init
.value
);
2501 specs
->typespec_kind
= ctsk_typeof
;
2502 specs
->locations
[cdw_typedef
] = init_loc
;
2503 specs
->typedef_p
= true;
2504 specs
->type
= init_type
;
2505 if (specs
->postfix_attrs
)
2507 /* Postfix [[]] attributes are valid with C2X
2508 auto, although not with __auto_type, and
2509 modify the type given by the initializer. */
2510 specs
->postfix_attrs
=
2511 c_warn_type_attributes (specs
->postfix_attrs
);
2512 decl_attributes (&specs
->type
, specs
->postfix_attrs
, 0);
2513 specs
->postfix_attrs
= NULL_TREE
;
2517 bool maybe_const
= true;
2518 tree type_expr
= c_fully_fold (init
.value
, false,
2520 specs
->expr_const_operands
&= maybe_const
;
2522 specs
->expr
= build2 (COMPOUND_EXPR
,
2523 TREE_TYPE (type_expr
),
2524 specs
->expr
, type_expr
);
2526 specs
->expr
= type_expr
;
2528 d
= start_decl (declarator
, specs
, true,
2529 chainon (postfix_attrs
, all_prefix_attrs
));
2531 d
= error_mark_node
;
2532 if (omp_declare_simd_clauses
)
2533 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2534 omp_declare_simd_clauses
);
2538 /* The declaration of the variable is in effect while
2539 its initializer is parsed, except for a constexpr
2541 init_loc
= c_parser_peek_token (parser
)->location
;
2542 rich_location
richloc (line_table
, init_loc
);
2543 unsigned int underspec_state
= 0;
2544 if (specs
->constexpr_p
)
2546 start_underspecified_init (init_loc
, underspec_name
);
2547 d
= start_decl (declarator
, specs
, true,
2548 chainon (postfix_attrs
,
2550 !specs
->constexpr_p
);
2552 d
= error_mark_node
;
2553 if (!specs
->constexpr_p
&& omp_declare_simd_clauses
)
2554 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2555 omp_declare_simd_clauses
);
2556 start_init (d
, asm_name
,
2557 TREE_STATIC (d
) || specs
->constexpr_p
,
2558 specs
->constexpr_p
, &richloc
);
2559 /* A parameter is initialized, which is invalid. Don't
2560 attempt to instrument the initializer. */
2561 int flag_sanitize_save
= flag_sanitize
;
2562 if (TREE_CODE (d
) == PARM_DECL
)
2564 init
= c_parser_initializer (parser
, d
);
2565 flag_sanitize
= flag_sanitize_save
;
2566 if (specs
->constexpr_p
)
2568 finish_underspecified_init (underspec_name
,
2571 if (omp_declare_simd_clauses
)
2572 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2573 omp_declare_simd_clauses
);
2577 if (oacc_routine_data
)
2578 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2579 if (d
!= error_mark_node
)
2581 maybe_warn_string_init (init_loc
, TREE_TYPE (d
), init
);
2582 finish_decl (d
, init_loc
, init
.value
,
2583 init
.original_type
, asm_name
);
2588 if (any_auto_type_p
|| specs
->constexpr_p
)
2591 "%qs requires an initialized data declaration",
2592 any_auto_type_p
? auto_type_keyword
: "constexpr");
2593 c_parser_skip_to_end_of_block_or_statement (parser
);
2597 location_t lastloc
= UNKNOWN_LOCATION
;
2598 tree attrs
= chainon (postfix_attrs
, all_prefix_attrs
);
2599 tree d
= start_decl (declarator
, specs
, false, attrs
, true,
2601 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2603 /* Find the innermost declarator that is neither cdk_id
2605 const struct c_declarator
*decl
= declarator
;
2606 const struct c_declarator
*last_non_id_attrs
= NULL
;
2614 last_non_id_attrs
= decl
;
2615 decl
= decl
->declarator
;
2619 decl
= decl
->declarator
;
2630 /* If it exists and is cdk_function declaration whose
2631 arguments have not been set yet, use its arguments. */
2632 if (last_non_id_attrs
2633 && last_non_id_attrs
->kind
== cdk_function
)
2635 tree parms
= last_non_id_attrs
->u
.arg_info
->parms
;
2636 if (DECL_ARGUMENTS (d
) == NULL_TREE
2637 && DECL_INITIAL (d
) == NULL_TREE
)
2638 DECL_ARGUMENTS (d
) = parms
;
2640 warn_parm_array_mismatch (lastloc
, d
, parms
);
2643 if (omp_declare_simd_clauses
)
2645 tree parms
= NULL_TREE
;
2646 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2648 struct c_declarator
*ce
= declarator
;
2650 if (ce
->kind
== cdk_function
)
2652 parms
= ce
->u
.arg_info
->parms
;
2656 ce
= ce
->declarator
;
2659 temp_store_parm_decls (d
, parms
);
2660 c_finish_omp_declare_simd (parser
, d
, parms
,
2661 omp_declare_simd_clauses
);
2663 temp_pop_parm_decls ();
2665 if (oacc_routine_data
)
2666 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2668 finish_decl (d
, UNKNOWN_LOCATION
, NULL_TREE
,
2669 NULL_TREE
, asm_name
);
2671 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2674 *objc_foreach_object_declaration
= d
;
2676 *objc_foreach_object_declaration
= error_mark_node
;
2679 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2681 if (any_auto_type_p
|| specs
->constexpr_p
)
2684 "%qs may only be used with a single declarator",
2685 any_auto_type_p
? auto_type_keyword
: "constexpr");
2686 c_parser_skip_to_end_of_block_or_statement (parser
);
2689 c_parser_consume_token (parser
);
2690 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2691 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
2694 all_prefix_attrs
= prefix_attrs
;
2697 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2699 c_parser_consume_token (parser
);
2702 else if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2704 /* This can only happen in Objective-C: we found the
2705 'in' that terminates the declaration inside an
2706 Objective-C foreach statement. Do not consume the
2707 token, so that the caller can use it to determine
2708 that this indeed is a foreach context. */
2713 c_parser_error (parser
, "expected %<,%> or %<;%>");
2714 c_parser_skip_to_end_of_block_or_statement (parser
);
2718 else if (any_auto_type_p
|| specs
->constexpr_p
)
2721 "%qs requires an initialized data declaration",
2722 any_auto_type_p
? auto_type_keyword
: "constexpr");
2723 c_parser_skip_to_end_of_block_or_statement (parser
);
2728 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, "
2729 "%<asm%> or %<__attribute__%>");
2730 c_parser_skip_to_end_of_block_or_statement (parser
);
2733 /* Function definition (nested or otherwise). */
2736 pedwarn (here
, OPT_Wpedantic
, "ISO C forbids nested functions");
2737 c_push_function_context ();
2739 if (!start_function (specs
, declarator
, all_prefix_attrs
))
2741 /* At this point we've consumed:
2742 declaration-specifiers declarator
2743 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2744 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2746 declaration-specifiers declarator
2747 aren't grokkable as a function definition, so we have
2749 gcc_assert (!c_parser_next_token_is (parser
, CPP_SEMICOLON
));
2750 if (c_parser_next_token_starts_declspecs (parser
))
2753 declaration-specifiers declarator decl-specs
2754 then assume we have a missing semicolon, which would
2756 declaration-specifiers declarator decl-specs
2759 <~~~~~~~~~ declaration ~~~~~~~~~~>
2760 Use c_parser_require to get an error with a fix-it hint. */
2761 c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>");
2762 parser
->error
= false;
2766 /* This can appear in many cases looking nothing like a
2767 function definition, so we don't give a more specific
2768 error suggesting there was one. */
2769 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2770 "or %<__attribute__%>");
2773 c_pop_function_context ();
2777 if (DECL_DECLARED_INLINE_P (current_function_decl
))
2778 tv
= TV_PARSE_INLINE
;
2781 auto_timevar
at (g_timer
, tv
);
2783 /* Parse old-style parameter declarations. ??? Attributes are
2784 not allowed to start declaration specifiers here because of a
2785 syntax conflict between a function declaration with attribute
2786 suffix and a function definition with an attribute prefix on
2787 first old-style parameter declaration. Following the old
2788 parser, they are not accepted on subsequent old-style
2789 parameter declarations either. However, there is no
2790 ambiguity after the first declaration, nor indeed on the
2791 first as long as we don't allow postfix attributes after a
2792 declarator with a nonempty identifier list in a definition;
2793 and postfix attributes have never been accepted here in
2794 function definitions either. */
2795 int save_debug_nonbind_markers_p
= debug_nonbind_markers_p
;
2796 debug_nonbind_markers_p
= 0;
2797 while (c_parser_next_token_is_not (parser
, CPP_EOF
)
2798 && c_parser_next_token_is_not (parser
, CPP_OPEN_BRACE
))
2799 c_parser_declaration_or_fndef (parser
, false, false, false,
2801 debug_nonbind_markers_p
= save_debug_nonbind_markers_p
;
2802 store_parm_decls ();
2803 if (omp_declare_simd_clauses
)
2804 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2805 omp_declare_simd_clauses
);
2806 if (oacc_routine_data
)
2807 c_finish_oacc_routine (oacc_routine_data
, current_function_decl
, true);
2808 location_t startloc
= c_parser_peek_token (parser
)->location
;
2809 DECL_STRUCT_FUNCTION (current_function_decl
)->function_start_locus
2811 location_t endloc
= startloc
;
2813 /* If the definition was marked with __RTL, use the RTL parser now,
2814 consuming the function body. */
2815 if (specs
->declspec_il
== cdil_rtl
)
2817 endloc
= c_parser_parse_rtl_body (parser
, specs
->gimple_or_rtl_pass
);
2819 /* Normally, store_parm_decls sets next_is_function_body,
2820 anticipating a function body. We need a push_scope/pop_scope
2821 pair to flush out this state, or subsequent function parsing
2826 finish_function (endloc
);
2829 /* If the definition was marked with __GIMPLE then parse the
2830 function body as GIMPLE. */
2831 else if (specs
->declspec_il
!= cdil_none
)
2833 bool saved
= in_late_binary_op
;
2834 in_late_binary_op
= true;
2835 c_parser_parse_gimple_body (parser
, specs
->gimple_or_rtl_pass
,
2837 specs
->entry_bb_count
);
2838 in_late_binary_op
= saved
;
2841 fnbody
= c_parser_compound_statement (parser
, &endloc
);
2842 tree fndecl
= current_function_decl
;
2845 tree decl
= current_function_decl
;
2846 /* Mark nested functions as needing static-chain initially.
2847 lower_nested_functions will recompute it but the
2848 DECL_STATIC_CHAIN flag is also used before that happens,
2849 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2850 DECL_STATIC_CHAIN (decl
) = 1;
2852 finish_function (endloc
);
2853 c_pop_function_context ();
2854 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl
), DECL_EXPR
, decl
));
2860 finish_function (endloc
);
2862 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2863 if (specs
->declspec_il
!= cdil_none
)
2864 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
2870 /* Parse an asm-definition (asm() outside a function body). This is a
2878 c_parser_asm_definition (c_parser
*parser
)
2880 tree asm_str
= c_parser_simple_asm_expr (parser
);
2882 symtab
->finalize_toplevel_asm (asm_str
);
2883 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
2886 /* Parse a static assertion (C11 6.7.10).
2888 static_assert-declaration:
2889 static_assert-declaration-no-semi ;
2893 c_parser_static_assert_declaration (c_parser
*parser
)
2895 c_parser_static_assert_declaration_no_semi (parser
);
2897 || !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
2898 c_parser_skip_to_end_of_block_or_statement (parser
);
2901 /* Parse a static assertion (C11 6.7.10), without the trailing
2904 static_assert-declaration-no-semi:
2905 _Static_assert ( constant-expression , string-literal )
2908 static_assert-declaration-no-semi:
2909 _Static_assert ( constant-expression )
2913 c_parser_static_assert_declaration_no_semi (c_parser
*parser
)
2915 location_t assert_loc
, value_loc
;
2917 tree string
= NULL_TREE
;
2919 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
));
2920 tree spelling
= c_parser_peek_token (parser
)->value
;
2921 assert_loc
= c_parser_peek_token (parser
)->location
;
2923 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2924 "ISO C99 does not support %qE", spelling
);
2926 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2927 "ISO C90 does not support %qE", spelling
);
2928 c_parser_consume_token (parser
);
2929 matching_parens parens
;
2930 if (!parens
.require_open (parser
))
2932 location_t value_tok_loc
= c_parser_peek_token (parser
)->location
;
2933 value
= convert_lvalue_to_rvalue (value_tok_loc
,
2934 c_parser_expr_no_commas (parser
, NULL
),
2936 value_loc
= EXPR_LOC_OR_LOC (value
, value_tok_loc
);
2937 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2939 c_parser_consume_token (parser
);
2940 switch (c_parser_peek_token (parser
)->type
)
2946 case CPP_UTF8STRING
:
2947 string
= c_parser_string_literal (parser
, false, true).value
;
2950 c_parser_error (parser
, "expected string literal");
2954 else if (flag_isoc11
)
2955 /* If pedantic for pre-C11, the use of _Static_assert itself will
2956 have been diagnosed, so do not also diagnose the use of this
2957 new C2X feature of _Static_assert. */
2958 pedwarn_c11 (assert_loc
, OPT_Wpedantic
,
2959 "ISO C11 does not support omitting the string in "
2961 parens
.require_close (parser
);
2963 if (!INTEGRAL_TYPE_P (TREE_TYPE (value
)))
2965 error_at (value_loc
, "expression in static assertion is not an integer");
2968 if (TREE_CODE (value
) != INTEGER_CST
)
2970 value
= c_fully_fold (value
, false, NULL
);
2971 /* Strip no-op conversions. */
2972 STRIP_TYPE_NOPS (value
);
2973 if (TREE_CODE (value
) == INTEGER_CST
)
2974 pedwarn (value_loc
, OPT_Wpedantic
, "expression in static assertion "
2975 "is not an integer constant expression");
2977 if (TREE_CODE (value
) != INTEGER_CST
)
2979 error_at (value_loc
, "expression in static assertion is not constant");
2982 constant_expression_warning (value
);
2983 if (integer_zerop (value
))
2986 error_at (assert_loc
, "static assertion failed: %E", string
);
2988 error_at (assert_loc
, "static assertion failed");
2992 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2993 6.7, C11 6.7), adding them to SPECS (which may already include some).
2994 Storage class specifiers are accepted iff SCSPEC_OK; type
2995 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2996 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2997 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2998 addition to the syntax shown, standard attributes are accepted at
2999 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
3000 unlike gnu-attributes, they are not accepted in the middle of the
3001 list. (This combines various different syntax productions in the C
3002 standard, and in some cases gnu-attributes and standard attributes
3003 at the start may already have been parsed before this function is
3006 declaration-specifiers:
3007 storage-class-specifier declaration-specifiers[opt]
3008 type-specifier declaration-specifiers[opt]
3009 type-qualifier declaration-specifiers[opt]
3010 function-specifier declaration-specifiers[opt]
3011 alignment-specifier declaration-specifiers[opt]
3013 Function specifiers (inline) are from C99, and are currently
3014 handled as storage class specifiers, as is __thread. Alignment
3015 specifiers are from C11.
3017 C90 6.5.1, C99 6.7.1, C11 6.7.1:
3018 storage-class-specifier:
3026 (_Thread_local is new in C11.)
3028 C99 6.7.4, C11 6.7.4:
3033 (_Noreturn is new in C11.)
3035 C90 6.5.2, C99 6.7.2, C11 6.7.2:
3048 [_Imaginary removed in C99 TC2]
3049 struct-or-union-specifier
3052 atomic-type-specifier
3054 (_Bool and _Complex are new in C99.)
3055 (atomic-type-specifier is new in C11.)
3057 C90 6.5.3, C99 6.7.3, C11 6.7.3:
3063 address-space-qualifier
3066 (restrict is new in C99.)
3067 (_Atomic is new in C11.)
3071 declaration-specifiers:
3072 gnu-attributes declaration-specifiers[opt]
3078 identifier recognized by the target
3080 storage-class-specifier:
3094 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
3095 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
3097 atomic-type-specifier
3098 _Atomic ( type-name )
3103 class-name objc-protocol-refs[opt]
3104 typedef-name objc-protocol-refs
3109 c_parser_declspecs (c_parser
*parser
, struct c_declspecs
*specs
,
3110 bool scspec_ok
, bool typespec_ok
, bool start_attr_ok
,
3111 bool alignspec_ok
, bool auto_type_ok
,
3112 bool start_std_attr_ok
, bool end_std_attr_ok
,
3113 enum c_lookahead_kind la
)
3115 bool attrs_ok
= start_attr_ok
;
3116 bool seen_type
= specs
->typespec_kind
!= ctsk_none
;
3119 gcc_assert (la
== cla_prefer_id
);
3121 if (start_std_attr_ok
3122 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3124 gcc_assert (!specs
->non_std_attrs_seen_p
);
3125 location_t loc
= c_parser_peek_token (parser
)->location
;
3126 tree attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3127 declspecs_add_attrs (loc
, specs
, attrs
);
3128 specs
->non_std_attrs_seen_p
= false;
3131 while (c_parser_next_token_is (parser
, CPP_NAME
)
3132 || c_parser_next_token_is (parser
, CPP_KEYWORD
)
3133 || (c_dialect_objc () && c_parser_next_token_is (parser
, CPP_LESS
)))
3135 struct c_typespec t
;
3138 location_t loc
= c_parser_peek_token (parser
)->location
;
3140 /* If we cannot accept a type, exit if the next token must start
3141 one. Also, if we already have seen a tagged definition,
3142 a typename would be an error anyway and likely the user
3143 has simply forgotten a semicolon, so we exit. */
3144 if ((!typespec_ok
|| specs
->typespec_kind
== ctsk_tagdef
)
3145 && c_parser_next_tokens_start_typename (parser
, la
)
3146 && !c_parser_next_token_is_qualifier (parser
)
3147 && !c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
))
3150 if (c_parser_next_token_is (parser
, CPP_NAME
))
3152 c_token
*name_token
= c_parser_peek_token (parser
);
3153 tree value
= name_token
->value
;
3154 c_id_kind kind
= name_token
->id_kind
;
3156 if (kind
== C_ID_ADDRSPACE
)
3159 = name_token
->keyword
- RID_FIRST_ADDR_SPACE
;
3160 declspecs_add_addrspace (name_token
->location
, specs
, as
);
3161 c_parser_consume_token (parser
);
3166 gcc_assert (!c_parser_next_token_is_qualifier (parser
));
3168 /* If we cannot accept a type, and the next token must start one,
3169 exit. Do the same if we already have seen a tagged definition,
3170 since it would be an error anyway and likely the user has simply
3171 forgotten a semicolon. */
3172 if (seen_type
|| !c_parser_next_tokens_start_typename (parser
, la
))
3175 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
3176 a C_ID_CLASSNAME. */
3177 c_parser_consume_token (parser
);
3180 if (kind
== C_ID_ID
)
3182 error_at (loc
, "unknown type name %qE", value
);
3183 t
.kind
= ctsk_typedef
;
3184 t
.spec
= error_mark_node
;
3186 else if (kind
== C_ID_TYPENAME
3187 && (!c_dialect_objc ()
3188 || c_parser_next_token_is_not (parser
, CPP_LESS
)))
3190 t
.kind
= ctsk_typedef
;
3191 /* For a typedef name, record the meaning, not the name.
3192 In case of 'foo foo, bar;'. */
3193 t
.spec
= lookup_name (value
);
3197 tree proto
= NULL_TREE
;
3198 gcc_assert (c_dialect_objc ());
3200 if (c_parser_next_token_is (parser
, CPP_LESS
))
3201 proto
= c_parser_objc_protocol_refs (parser
);
3202 t
.spec
= objc_get_protocol_qualified_type (value
, proto
);
3205 t
.expr_const_operands
= true;
3206 t
.has_enum_type_specifier
= false;
3207 declspecs_add_type (name_token
->location
, specs
, t
);
3210 if (c_parser_next_token_is (parser
, CPP_LESS
))
3212 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
3213 nisse@lysator.liu.se. */
3215 gcc_assert (c_dialect_objc ());
3216 if (!typespec_ok
|| seen_type
)
3218 proto
= c_parser_objc_protocol_refs (parser
);
3220 t
.spec
= objc_get_protocol_qualified_type (NULL_TREE
, proto
);
3222 t
.expr_const_operands
= true;
3223 t
.has_enum_type_specifier
= false;
3224 declspecs_add_type (loc
, specs
, t
);
3227 gcc_assert (c_parser_next_token_is (parser
, CPP_KEYWORD
));
3228 switch (c_parser_peek_token (parser
)->keyword
)
3242 /* TODO: Distinguish between function specifiers (inline, noreturn)
3243 and storage class specifiers, either here or in
3244 declspecs_add_scspec. */
3245 declspecs_add_scspec (loc
, specs
,
3246 c_parser_peek_token (parser
)->value
);
3247 c_parser_consume_token (parser
);
3279 if (c_dialect_objc ())
3280 parser
->objc_need_raw_identifier
= true;
3281 t
.kind
= ctsk_resword
;
3282 t
.spec
= c_parser_peek_token (parser
)->value
;
3284 t
.expr_const_operands
= true;
3285 t
.has_enum_type_specifier
= false;
3286 declspecs_add_type (loc
, specs
, t
);
3287 c_parser_consume_token (parser
);
3294 t
= c_parser_enum_specifier (parser
);
3295 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
3296 declspecs_add_type (loc
, specs
, t
);
3304 t
= c_parser_struct_or_union_specifier (parser
);
3305 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
3306 declspecs_add_type (loc
, specs
, t
);
3309 case RID_TYPEOF_UNQUAL
:
3310 /* ??? The old parser rejected typeof after other type
3311 specifiers, but is a syntax error the best way of
3313 if (!typespec_ok
|| seen_type
)
3317 t
= c_parser_typeof_specifier (parser
);
3318 declspecs_add_type (loc
, specs
, t
);
3321 /* C parser handling of Objective-C constructs needs
3322 checking for correct lvalue-to-rvalue conversions, and
3323 the code in build_modify_expr handling various
3324 Objective-C cases, and that in build_unary_op handling
3325 Objective-C cases for increment / decrement, also needs
3326 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3327 and objc_types_are_equivalent may also need updates. */
3328 if (c_dialect_objc ())
3329 sorry ("%<_Atomic%> in Objective-C");
3331 pedwarn_c99 (loc
, OPT_Wpedantic
,
3332 "ISO C99 does not support the %<_Atomic%> qualifier");
3334 pedwarn_c99 (loc
, OPT_Wpedantic
,
3335 "ISO C90 does not support the %<_Atomic%> qualifier");
3338 value
= c_parser_peek_token (parser
)->value
;
3339 c_parser_consume_token (parser
);
3340 if (typespec_ok
&& c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3342 /* _Atomic ( type-name ). */
3344 c_parser_consume_token (parser
);
3345 struct c_type_name
*type
= c_parser_type_name (parser
);
3346 t
.kind
= ctsk_typeof
;
3347 t
.spec
= error_mark_node
;
3349 t
.expr_const_operands
= true;
3350 t
.has_enum_type_specifier
= false;
3352 t
.spec
= groktypename (type
, &t
.expr
,
3353 &t
.expr_const_operands
);
3354 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3356 if (t
.spec
!= error_mark_node
)
3358 if (TREE_CODE (t
.spec
) == ARRAY_TYPE
)
3359 error_at (loc
, "%<_Atomic%>-qualified array type");
3360 else if (TREE_CODE (t
.spec
) == FUNCTION_TYPE
)
3361 error_at (loc
, "%<_Atomic%>-qualified function type");
3362 else if (TYPE_QUALS (t
.spec
) != TYPE_UNQUALIFIED
)
3363 error_at (loc
, "%<_Atomic%> applied to a qualified type");
3365 t
.spec
= c_build_qualified_type (t
.spec
, TYPE_QUAL_ATOMIC
);
3367 declspecs_add_type (loc
, specs
, t
);
3370 declspecs_add_qual (loc
, specs
, value
);
3376 declspecs_add_qual (loc
, specs
, c_parser_peek_token (parser
)->value
);
3377 c_parser_consume_token (parser
);
3382 attrs
= c_parser_gnu_attributes (parser
);
3383 declspecs_add_attrs (loc
, specs
, attrs
);
3388 align
= c_parser_alignas_specifier (parser
);
3389 declspecs_add_alignas (loc
, specs
, align
);
3393 error_at (loc
, "%<__GIMPLE%> only valid with %<-fgimple%>");
3394 c_parser_consume_token (parser
);
3395 specs
->declspec_il
= cdil_gimple
;
3396 specs
->locations
[cdw_gimple
] = loc
;
3397 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3400 c_parser_consume_token (parser
);
3401 specs
->declspec_il
= cdil_rtl
;
3402 specs
->locations
[cdw_rtl
] = loc
;
3403 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3411 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3412 specs
->postfix_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3415 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3418 enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3419 { enumerator-list } gnu-attributes[opt]
3420 enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
3421 { enumerator-list , } gnu-attributes[opt] enum-type-specifier[opt]
3422 enum gnu-attributes[opt] identifier
3424 The form with trailing comma is new in C99; enum-type-specifiers
3425 are new in C2x. The forms with gnu-attributes are GNU extensions.
3426 In GNU C, we accept any expression without commas in the syntax
3427 (assignment expressions, not just conditional expressions);
3428 assignment expressions will be diagnosed as non-constant.
3430 enum-type-specifier:
3431 : specifier-qualifier-list
3435 enumerator-list , enumerator
3438 enumeration-constant attribute-specifier-sequence[opt]
3439 enumeration-constant attribute-specifier-sequence[opt]
3440 = constant-expression
3445 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3446 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3447 = constant-expression
3451 static struct c_typespec
3452 c_parser_enum_specifier (c_parser
*parser
)
3454 struct c_typespec ret
;
3455 bool have_std_attrs
;
3456 tree std_attrs
= NULL_TREE
;
3458 tree ident
= NULL_TREE
;
3459 tree fixed_underlying_type
= NULL_TREE
;
3460 location_t enum_loc
;
3461 location_t ident_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3462 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ENUM
));
3463 c_parser_consume_token (parser
);
3464 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3466 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3467 attrs
= c_parser_gnu_attributes (parser
);
3468 enum_loc
= c_parser_peek_token (parser
)->location
;
3469 /* Set the location in case we create a decl now. */
3470 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3471 if (c_parser_next_token_is (parser
, CPP_NAME
))
3473 ident
= c_parser_peek_token (parser
)->value
;
3474 ident_loc
= c_parser_peek_token (parser
)->location
;
3475 enum_loc
= ident_loc
;
3476 c_parser_consume_token (parser
);
3478 if (c_parser_next_token_is (parser
, CPP_COLON
)
3479 /* Distinguish an enum-type-specifier from a bit-field
3480 declaration of the form "enum e : constant-expression;". */
3481 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
3483 pedwarn_c11 (enum_loc
, OPT_Wpedantic
,
3484 "ISO C does not support specifying %<enum%> underlying "
3485 "types before C2X");
3488 /* The tag is in scope during the enum-type-specifier (which
3489 may refer to the tag inside typeof). */
3490 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
,
3491 have_std_attrs
, std_attrs
, true);
3492 if (!ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
))
3493 error_at (enum_loc
, "%<enum%> declared both with and without "
3494 "fixed underlying type");
3498 /* There must be an enum definition, so this initialization
3499 (to avoid possible warnings about uninitialized data)
3500 will be replaced later (either with the results of that
3501 definition, or with the results of error handling for the
3502 case of no tag and no definition). */
3503 ret
.spec
= NULL_TREE
;
3504 ret
.kind
= ctsk_tagdef
;
3505 ret
.expr
= NULL_TREE
;
3506 ret
.expr_const_operands
= true;
3507 ret
.has_enum_type_specifier
= true;
3509 c_parser_consume_token (parser
);
3510 struct c_declspecs
*specs
= build_null_declspecs ();
3511 c_parser_declspecs (parser
, specs
, false, true, false, false, false,
3512 false, true, cla_prefer_id
);
3513 finish_declspecs (specs
);
3514 if (specs
->default_int_p
)
3515 error_at (enum_loc
, "no %<enum%> underlying type specified");
3516 else if (TREE_CODE (specs
->type
) != INTEGER_TYPE
3517 && TREE_CODE (specs
->type
) != BOOLEAN_TYPE
)
3519 error_at (enum_loc
, "invalid %<enum%> underlying type");
3520 specs
->type
= integer_type_node
;
3522 else if (specs
->restrict_p
)
3523 error_at (enum_loc
, "invalid use of %<restrict%>");
3524 fixed_underlying_type
= TYPE_MAIN_VARIANT (specs
->type
);
3527 /* The type specified must be consistent with any previously
3528 specified underlying type. If this is a newly declared
3529 type, it is now a complete type. */
3530 if (ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
)
3531 && ENUM_UNDERLYING_TYPE (ret
.spec
) == NULL_TREE
)
3533 TYPE_MIN_VALUE (ret
.spec
) =
3534 TYPE_MIN_VALUE (fixed_underlying_type
);
3535 TYPE_MAX_VALUE (ret
.spec
) =
3536 TYPE_MAX_VALUE (fixed_underlying_type
);
3537 TYPE_UNSIGNED (ret
.spec
) = TYPE_UNSIGNED (fixed_underlying_type
);
3538 SET_TYPE_ALIGN (ret
.spec
, TYPE_ALIGN (fixed_underlying_type
));
3539 TYPE_SIZE (ret
.spec
) = NULL_TREE
;
3540 TYPE_PRECISION (ret
.spec
) =
3541 TYPE_PRECISION (fixed_underlying_type
);
3542 ENUM_UNDERLYING_TYPE (ret
.spec
) = fixed_underlying_type
;
3543 layout_type (ret
.spec
);
3545 else if (ENUM_FIXED_UNDERLYING_TYPE_P (ret
.spec
)
3546 && !comptypes (fixed_underlying_type
,
3547 ENUM_UNDERLYING_TYPE (ret
.spec
)))
3549 error_at (enum_loc
, "%<enum%> underlying type incompatible with "
3550 "previous declaration");
3551 fixed_underlying_type
= ENUM_UNDERLYING_TYPE (ret
.spec
);
3555 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3557 /* Parse an enum definition. */
3558 struct c_enum_contents the_enum
;
3561 /* We chain the enumerators in reverse order, then put them in
3562 forward order at the end. */
3564 timevar_push (TV_PARSE_ENUM
);
3565 type
= start_enum (enum_loc
, &the_enum
, ident
, fixed_underlying_type
);
3567 c_parser_consume_token (parser
);
3575 location_t comma_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3576 location_t decl_loc
, value_loc
;
3577 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
3579 /* Give a nicer error for "enum {}". */
3580 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3583 error_at (c_parser_peek_token (parser
)->location
,
3584 "empty enum is invalid");
3585 parser
->error
= true;
3588 c_parser_error (parser
, "expected identifier");
3589 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3590 values
= error_mark_node
;
3593 token
= c_parser_peek_token (parser
);
3594 enum_id
= token
->value
;
3595 /* Set the location in case we create a decl now. */
3596 c_parser_set_source_position_from_token (token
);
3597 decl_loc
= value_loc
= token
->location
;
3598 c_parser_consume_token (parser
);
3599 /* Parse any specified attributes. */
3600 tree std_attrs
= NULL_TREE
;
3601 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3602 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3603 tree enum_attrs
= chainon (std_attrs
,
3604 c_parser_gnu_attributes (parser
));
3605 if (c_parser_next_token_is (parser
, CPP_EQ
))
3607 c_parser_consume_token (parser
);
3608 value_loc
= c_parser_peek_token (parser
)->location
;
3609 enum_value
= convert_lvalue_to_rvalue (value_loc
,
3610 (c_parser_expr_no_commas
3615 enum_value
= NULL_TREE
;
3616 enum_decl
= build_enumerator (decl_loc
, value_loc
,
3617 &the_enum
, enum_id
, enum_value
);
3619 decl_attributes (&TREE_PURPOSE (enum_decl
), enum_attrs
, 0);
3620 TREE_CHAIN (enum_decl
) = values
;
3623 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3625 comma_loc
= c_parser_peek_token (parser
)->location
;
3627 c_parser_consume_token (parser
);
3629 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3632 pedwarn_c90 (comma_loc
, OPT_Wpedantic
,
3633 "comma at end of enumerator list");
3634 c_parser_consume_token (parser
);
3639 c_parser_error (parser
, "expected %<,%> or %<}%>");
3640 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3641 values
= error_mark_node
;
3645 postfix_attrs
= c_parser_gnu_attributes (parser
);
3646 ret
.spec
= finish_enum (type
, nreverse (values
),
3648 chainon (attrs
, postfix_attrs
)));
3649 ret
.kind
= ctsk_tagdef
;
3650 ret
.expr
= NULL_TREE
;
3651 ret
.expr_const_operands
= true;
3652 ret
.has_enum_type_specifier
= fixed_underlying_type
!= NULL_TREE
;
3653 timevar_pop (TV_PARSE_ENUM
);
3658 c_parser_error (parser
, "expected %<{%>");
3659 ret
.spec
= error_mark_node
;
3660 ret
.kind
= ctsk_tagref
;
3661 ret
.expr
= NULL_TREE
;
3662 ret
.expr_const_operands
= true;
3663 ret
.has_enum_type_specifier
= false;
3666 /* Attributes may only appear when the members are defined or in
3667 certain forward declarations (treat enum forward declarations in
3668 GNU C analogously to struct and union forward declarations in
3670 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3671 c_parser_error (parser
, "expected %<;%>");
3672 if (fixed_underlying_type
== NULL_TREE
)
3674 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
, have_std_attrs
,
3676 /* In ISO C, enumerated types without a fixed underlying type
3677 can be referred to only if already defined. */
3678 if (pedantic
&& !COMPLETE_TYPE_P (ret
.spec
))
3681 pedwarn (enum_loc
, OPT_Wpedantic
,
3682 "ISO C forbids forward references to %<enum%> types");
3688 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3690 struct-or-union-specifier:
3691 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3692 identifier[opt] { struct-contents } gnu-attributes[opt]
3693 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3697 struct-declaration-list
3699 struct-declaration-list:
3700 struct-declaration ;
3701 struct-declaration-list struct-declaration ;
3708 struct-declaration-list struct-declaration
3710 struct-declaration-list:
3711 struct-declaration-list ;
3714 (Note that in the syntax here, unlike that in ISO C, the semicolons
3715 are included here rather than in struct-declaration, in order to
3716 describe the syntax with extra semicolons and missing semicolon at
3721 struct-declaration-list:
3722 @defs ( class-name )
3724 (Note this does not include a trailing semicolon, but can be
3725 followed by further declarations, and gets a pedwarn-if-pedantic
3726 when followed by a semicolon.) */
3728 static struct c_typespec
3729 c_parser_struct_or_union_specifier (c_parser
*parser
)
3731 struct c_typespec ret
;
3732 bool have_std_attrs
;
3733 tree std_attrs
= NULL_TREE
;
3735 tree ident
= NULL_TREE
;
3736 location_t struct_loc
;
3737 location_t ident_loc
= UNKNOWN_LOCATION
;
3738 enum tree_code code
;
3739 switch (c_parser_peek_token (parser
)->keyword
)
3750 struct_loc
= c_parser_peek_token (parser
)->location
;
3751 c_parser_consume_token (parser
);
3752 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3754 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3755 attrs
= c_parser_gnu_attributes (parser
);
3757 /* Set the location in case we create a decl now. */
3758 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3760 if (c_parser_next_token_is (parser
, CPP_NAME
))
3762 ident
= c_parser_peek_token (parser
)->value
;
3763 ident_loc
= c_parser_peek_token (parser
)->location
;
3764 struct_loc
= ident_loc
;
3765 c_parser_consume_token (parser
);
3767 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3769 /* Parse a struct or union definition. Start the scope of the
3770 tag before parsing components. */
3771 class c_struct_parse_info
*struct_info
;
3772 tree type
= start_struct (struct_loc
, code
, ident
, &struct_info
);
3774 /* We chain the components in reverse order, then put them in
3775 forward order at the end. Each struct-declaration may
3776 declare multiple components (comma-separated), so we must use
3777 chainon to join them, although when parsing each
3778 struct-declaration we can use TREE_CHAIN directly.
3780 The theory behind all this is that there will be more
3781 semicolon separated fields than comma separated fields, and
3782 so we'll be minimizing the number of node traversals required
3785 timevar_push (TV_PARSE_STRUCT
);
3786 contents
= NULL_TREE
;
3787 c_parser_consume_token (parser
);
3788 /* Handle the Objective-C @defs construct,
3789 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3790 if (c_parser_next_token_is_keyword (parser
, RID_AT_DEFS
))
3793 gcc_assert (c_dialect_objc ());
3794 c_parser_consume_token (parser
);
3795 matching_parens parens
;
3796 if (!parens
.require_open (parser
))
3798 if (c_parser_next_token_is (parser
, CPP_NAME
)
3799 && c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
)
3801 name
= c_parser_peek_token (parser
)->value
;
3802 c_parser_consume_token (parser
);
3806 c_parser_error (parser
, "expected class name");
3807 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
3810 parens
.skip_until_found_close (parser
);
3811 contents
= nreverse (objc_get_class_ivars (name
));
3814 /* Parse the struct-declarations and semicolons. Problems with
3815 semicolons are diagnosed here; empty structures are diagnosed
3820 /* Parse any stray semicolon. */
3821 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3823 location_t semicolon_loc
3824 = c_parser_peek_token (parser
)->location
;
3825 gcc_rich_location
richloc (semicolon_loc
);
3826 richloc
.add_fixit_remove ();
3827 pedwarn (&richloc
, OPT_Wpedantic
,
3828 "extra semicolon in struct or union specified");
3829 c_parser_consume_token (parser
);
3832 /* Stop if at the end of the struct or union contents. */
3833 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3835 c_parser_consume_token (parser
);
3838 /* Accept #pragmas at struct scope. */
3839 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
3841 c_parser_pragma (parser
, pragma_struct
, NULL
);
3844 /* Parse some comma-separated declarations, but not the
3845 trailing semicolon if any. */
3846 decls
= c_parser_struct_declaration (parser
);
3847 contents
= chainon (decls
, contents
);
3848 /* If no semicolon follows, either we have a parse error or
3849 are at the end of the struct or union and should
3851 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3852 c_parser_consume_token (parser
);
3855 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3856 pedwarn (c_parser_peek_token (parser
)->location
, 0,
3857 "no semicolon at end of struct or union");
3858 else if (parser
->error
3859 || !c_parser_next_token_starts_declspecs (parser
))
3861 c_parser_error (parser
, "expected %<;%>");
3862 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3866 /* If we come here, we have already emitted an error
3867 for an expected `;', identifier or `(', and we also
3868 recovered already. Go on with the next field. */
3871 postfix_attrs
= c_parser_gnu_attributes (parser
);
3872 ret
.spec
= finish_struct (struct_loc
, type
, nreverse (contents
),
3874 chainon (attrs
, postfix_attrs
)),
3876 ret
.kind
= ctsk_tagdef
;
3877 ret
.expr
= NULL_TREE
;
3878 ret
.expr_const_operands
= true;
3879 ret
.has_enum_type_specifier
= false;
3880 timevar_pop (TV_PARSE_STRUCT
);
3885 c_parser_error (parser
, "expected %<{%>");
3886 ret
.spec
= error_mark_node
;
3887 ret
.kind
= ctsk_tagref
;
3888 ret
.expr
= NULL_TREE
;
3889 ret
.expr_const_operands
= true;
3890 ret
.has_enum_type_specifier
= false;
3893 /* Attributes may only appear when the members are defined or in
3894 certain forward declarations. */
3895 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3896 c_parser_error (parser
, "expected %<;%>");
3897 /* ??? Existing practice is that GNU attributes are ignored after
3898 the struct or union keyword when not defining the members. */
3899 ret
= parser_xref_tag (ident_loc
, code
, ident
, have_std_attrs
, std_attrs
,
3904 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3905 *without* the trailing semicolon.
3908 attribute-specifier-sequence[opt] specifier-qualifier-list
3909 attribute-specifier-sequence[opt] struct-declarator-list
3910 static_assert-declaration-no-semi
3912 specifier-qualifier-list:
3913 type-specifier specifier-qualifier-list[opt]
3914 type-qualifier specifier-qualifier-list[opt]
3915 alignment-specifier specifier-qualifier-list[opt]
3916 gnu-attributes specifier-qualifier-list[opt]
3918 struct-declarator-list:
3920 struct-declarator-list , gnu-attributes[opt] struct-declarator
3923 declarator gnu-attributes[opt]
3924 declarator[opt] : constant-expression gnu-attributes[opt]
3929 __extension__ struct-declaration
3930 specifier-qualifier-list
3932 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3933 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3934 any expression without commas in the syntax (assignment
3935 expressions, not just conditional expressions); assignment
3936 expressions will be diagnosed as non-constant. */
3939 c_parser_struct_declaration (c_parser
*parser
)
3941 struct c_declspecs
*specs
;
3943 tree all_prefix_attrs
;
3945 location_t decl_loc
;
3946 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
3950 ext
= disable_extension_diagnostics ();
3951 c_parser_consume_token (parser
);
3952 decl
= c_parser_struct_declaration (parser
);
3953 restore_extension_diagnostics (ext
);
3956 if (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
3958 c_parser_static_assert_declaration_no_semi (parser
);
3961 specs
= build_null_declspecs ();
3962 decl_loc
= c_parser_peek_token (parser
)->location
;
3963 /* Strictly by the standard, we shouldn't allow _Alignas here,
3964 but it appears to have been intended to allow it there, so
3965 we're keeping it as it is until WG14 reaches a conclusion
3967 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3968 c_parser_declspecs (parser
, specs
, false, true, true,
3969 true, false, true, true, cla_nonabstract_decl
);
3972 if (!specs
->declspecs_seen_p
)
3974 c_parser_error (parser
, "expected specifier-qualifier-list");
3977 finish_declspecs (specs
);
3978 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3979 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3982 if (specs
->typespec_kind
== ctsk_none
)
3984 pedwarn (decl_loc
, OPT_Wpedantic
,
3985 "ISO C forbids member declarations with no members");
3986 shadow_tag_warned (specs
, pedantic
);
3991 /* Support for unnamed structs or unions as members of
3992 structs or unions (which is [a] useful and [b] supports
3996 ret
= grokfield (c_parser_peek_token (parser
)->location
,
3997 build_id_declarator (NULL_TREE
), specs
,
4000 decl_attributes (&ret
, attrs
, 0);
4005 /* Provide better error recovery. Note that a type name here is valid,
4006 and will be treated as a field name. */
4007 if (specs
->typespec_kind
== ctsk_tagdef
4008 && TREE_CODE (specs
->type
) != ENUMERAL_TYPE
4009 && c_parser_next_token_starts_declspecs (parser
)
4010 && !c_parser_next_token_is (parser
, CPP_NAME
))
4012 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
4013 parser
->error
= false;
4017 pending_xref_error ();
4018 prefix_attrs
= specs
->attrs
;
4019 all_prefix_attrs
= prefix_attrs
;
4020 specs
->attrs
= NULL_TREE
;
4024 /* Declaring one or more declarators or un-named bit-fields. */
4025 struct c_declarator
*declarator
;
4027 if (c_parser_next_token_is (parser
, CPP_COLON
))
4028 declarator
= build_id_declarator (NULL_TREE
);
4030 declarator
= c_parser_declarator (parser
,
4031 specs
->typespec_kind
!= ctsk_none
,
4032 C_DTR_NORMAL
, &dummy
);
4033 if (declarator
== NULL
)
4035 c_parser_skip_to_end_of_block_or_statement (parser
);
4038 if (c_parser_next_token_is (parser
, CPP_COLON
)
4039 || c_parser_next_token_is (parser
, CPP_COMMA
)
4040 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
4041 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
4042 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4044 tree postfix_attrs
= NULL_TREE
;
4045 tree width
= NULL_TREE
;
4047 if (c_parser_next_token_is (parser
, CPP_COLON
))
4049 c_parser_consume_token (parser
);
4050 location_t loc
= c_parser_peek_token (parser
)->location
;
4051 width
= convert_lvalue_to_rvalue (loc
,
4052 (c_parser_expr_no_commas
4056 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4057 postfix_attrs
= c_parser_gnu_attributes (parser
);
4058 d
= grokfield (c_parser_peek_token (parser
)->location
,
4059 declarator
, specs
, width
, &all_prefix_attrs
);
4060 decl_attributes (&d
, chainon (postfix_attrs
,
4061 all_prefix_attrs
), 0);
4062 DECL_CHAIN (d
) = decls
;
4064 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4065 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
4068 all_prefix_attrs
= prefix_attrs
;
4069 if (c_parser_next_token_is (parser
, CPP_COMMA
))
4070 c_parser_consume_token (parser
);
4071 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
4072 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
4074 /* Semicolon consumed in caller. */
4079 c_parser_error (parser
, "expected %<,%>, %<;%> or %<}%>");
4085 c_parser_error (parser
,
4086 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
4087 "%<__attribute__%>");
4094 /* Parse a typeof specifier (a GNU extension adopted in C2X).
4097 typeof ( expression )
4098 typeof ( type-name )
4099 typeof_unqual ( expression )
4100 typeof_unqual ( type-name )
4103 static struct c_typespec
4104 c_parser_typeof_specifier (c_parser
*parser
)
4108 struct c_typespec ret
;
4109 ret
.kind
= ctsk_typeof
;
4110 ret
.spec
= error_mark_node
;
4111 ret
.expr
= NULL_TREE
;
4112 ret
.expr_const_operands
= true;
4113 ret
.has_enum_type_specifier
= false;
4114 if (c_parser_next_token_is_keyword (parser
, RID_TYPEOF
))
4117 tree spelling
= c_parser_peek_token (parser
)->value
;
4118 is_std
= (flag_isoc2x
4119 && strcmp (IDENTIFIER_POINTER (spelling
), "typeof") == 0);
4123 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TYPEOF_UNQUAL
));
4127 c_parser_consume_token (parser
);
4128 c_inhibit_evaluation_warnings
++;
4130 matching_parens parens
;
4131 if (!parens
.require_open (parser
))
4133 c_inhibit_evaluation_warnings
--;
4137 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
4139 struct c_type_name
*type
= c_parser_type_name (parser
);
4140 c_inhibit_evaluation_warnings
--;
4144 ret
.spec
= groktypename (type
, &ret
.expr
, &ret
.expr_const_operands
);
4145 pop_maybe_used (c_type_variably_modified_p (ret
.spec
));
4151 location_t here
= c_parser_peek_token (parser
)->location
;
4152 struct c_expr expr
= c_parser_expression (parser
);
4153 c_inhibit_evaluation_warnings
--;
4155 if (TREE_CODE (expr
.value
) == COMPONENT_REF
4156 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
4157 error_at (here
, "%<typeof%> applied to a bit-field");
4158 mark_exp_read (expr
.value
);
4159 ret
.spec
= TREE_TYPE (expr
.value
);
4160 was_vm
= c_type_variably_modified_p (ret
.spec
);
4161 /* This is returned with the type so that when the type is
4162 evaluated, this can be evaluated. */
4164 ret
.expr
= c_fully_fold (expr
.value
, false, &ret
.expr_const_operands
);
4165 pop_maybe_used (was_vm
);
4167 parens
.skip_until_found_close (parser
);
4168 if (ret
.spec
!= error_mark_node
)
4170 if (is_unqual
&& TYPE_QUALS (ret
.spec
) != TYPE_UNQUALIFIED
)
4171 ret
.spec
= TYPE_MAIN_VARIANT (ret
.spec
);
4174 /* In ISO C terms, _Noreturn is not part of the type of
4175 expressions such as &abort, but in GCC it is represented
4176 internally as a type qualifier. */
4177 if (TREE_CODE (ret
.spec
) == FUNCTION_TYPE
4178 && TYPE_QUALS (ret
.spec
) != TYPE_UNQUALIFIED
)
4179 ret
.spec
= TYPE_MAIN_VARIANT (ret
.spec
);
4180 else if (FUNCTION_POINTER_TYPE_P (ret
.spec
)
4181 && TYPE_QUALS (TREE_TYPE (ret
.spec
)) != TYPE_UNQUALIFIED
)
4183 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (ret
.spec
)));
4189 /* Parse an alignment-specifier.
4193 alignment-specifier:
4194 _Alignas ( type-name )
4195 _Alignas ( constant-expression )
4199 c_parser_alignas_specifier (c_parser
* parser
)
4201 tree ret
= error_mark_node
;
4202 location_t loc
= c_parser_peek_token (parser
)->location
;
4203 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
));
4204 tree spelling
= c_parser_peek_token (parser
)->value
;
4205 c_parser_consume_token (parser
);
4207 pedwarn_c99 (loc
, OPT_Wpedantic
,
4208 "ISO C99 does not support %qE", spelling
);
4210 pedwarn_c99 (loc
, OPT_Wpedantic
,
4211 "ISO C90 does not support %qE", spelling
);
4212 matching_parens parens
;
4213 if (!parens
.require_open (parser
))
4215 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
4217 struct c_type_name
*type
= c_parser_type_name (parser
);
4219 ret
= c_sizeof_or_alignof_type (loc
, groktypename (type
, NULL
, NULL
),
4223 ret
= convert_lvalue_to_rvalue (loc
,
4224 c_parser_expr_no_commas (parser
, NULL
),
4226 parens
.skip_until_found_close (parser
);
4230 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
4231 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
4232 a typedef name may be redeclared; otherwise it may not. KIND
4233 indicates which kind of declarator is wanted. Returns a valid
4234 declarator except in the case of a syntax error in which case NULL is
4235 returned. *SEEN_ID is set to true if an identifier being declared is
4236 seen; this is used to diagnose bad forms of abstract array declarators
4237 and to determine whether an identifier list is syntactically permitted.
4240 pointer[opt] direct-declarator
4244 ( gnu-attributes[opt] declarator )
4245 direct-declarator array-declarator
4246 direct-declarator ( parameter-type-list )
4247 direct-declarator ( identifier-list[opt] )
4250 * type-qualifier-list[opt]
4251 * type-qualifier-list[opt] pointer
4253 type-qualifier-list:
4256 type-qualifier-list type-qualifier
4257 type-qualifier-list gnu-attributes
4260 [ type-qualifier-list[opt] assignment-expression[opt] ]
4261 [ static type-qualifier-list[opt] assignment-expression ]
4262 [ type-qualifier-list static assignment-expression ]
4263 [ type-qualifier-list[opt] * ]
4265 parameter-type-list:
4267 parameter-list , ...
4270 parameter-declaration
4271 parameter-list , parameter-declaration
4273 parameter-declaration:
4274 declaration-specifiers declarator gnu-attributes[opt]
4275 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
4279 identifier-list , identifier
4281 abstract-declarator:
4283 pointer[opt] direct-abstract-declarator
4285 direct-abstract-declarator:
4286 ( gnu-attributes[opt] abstract-declarator )
4287 direct-abstract-declarator[opt] array-declarator
4288 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
4293 direct-declarator ( parameter-forward-declarations
4294 parameter-type-list[opt] )
4296 direct-abstract-declarator:
4297 direct-abstract-declarator[opt] ( parameter-forward-declarations
4298 parameter-type-list[opt] )
4300 parameter-forward-declarations:
4302 parameter-forward-declarations parameter-list ;
4304 The uses of gnu-attributes shown above are GNU extensions.
4306 Some forms of array declarator are not included in C99 in the
4307 syntax for abstract declarators; these are disallowed elsewhere.
4308 This may be a defect (DR#289).
4310 This function also accepts an omitted abstract declarator as being
4311 an abstract declarator, although not part of the formal syntax. */
4313 struct c_declarator
*
4314 c_parser_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
4317 /* Parse any initial pointer part. */
4318 if (c_parser_next_token_is (parser
, CPP_MULT
))
4320 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4321 struct c_declarator
*inner
;
4322 c_parser_consume_token (parser
);
4323 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4324 false, false, true, false, cla_prefer_id
);
4325 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4329 return make_pointer_declarator (quals_attrs
, inner
);
4331 /* Now we have a direct declarator, direct abstract declarator or
4332 nothing (which counts as a direct abstract declarator here). */
4333 return c_parser_direct_declarator (parser
, type_seen_p
, kind
, seen_id
);
4336 /* Parse a direct declarator or direct abstract declarator; arguments
4337 as c_parser_declarator. */
4339 static struct c_declarator
*
4340 c_parser_direct_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
4343 /* The direct declarator must start with an identifier (possibly
4344 omitted) or a parenthesized declarator (possibly abstract). In
4345 an ordinary declarator, initial parentheses must start a
4346 parenthesized declarator. In an abstract declarator or parameter
4347 declarator, they could start a parenthesized declarator or a
4348 parameter list. To tell which, the open parenthesis and any
4349 following gnu-attributes must be read. If a declaration
4350 specifier or standard attributes follow, then it is a parameter
4351 list; if the specifier is a typedef name, there might be an
4352 ambiguity about redeclaring it, which is resolved in the
4353 direction of treating it as a typedef name. If a close
4354 parenthesis follows, it is also an empty parameter list, as the
4355 syntax does not permit empty abstract declarators. Otherwise, it
4356 is a parenthesized declarator (in which case the analysis may be
4357 repeated inside it, recursively).
4359 ??? There is an ambiguity in a parameter declaration "int
4360 (__attribute__((foo)) x)", where x is not a typedef name: it
4361 could be an abstract declarator for a function, or declare x with
4362 parentheses. The proper resolution of this ambiguity needs
4363 documenting. At present we follow an accident of the old
4364 parser's implementation, whereby the first parameter must have
4365 some declaration specifiers other than just gnu-attributes. Thus as
4366 a parameter declaration it is treated as a parenthesized
4367 parameter named x, and as an abstract declarator it is
4370 ??? Also following the old parser, gnu-attributes inside an empty
4371 parameter list are ignored, making it a list not yielding a
4372 prototype, rather than giving an error or making it have one
4373 parameter with implicit type int.
4375 ??? Also following the old parser, typedef names may be
4376 redeclared in declarators, but not Objective-C class names. */
4378 if (kind
!= C_DTR_ABSTRACT
4379 && c_parser_next_token_is (parser
, CPP_NAME
)
4381 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
4382 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
4383 || c_parser_peek_token (parser
)->id_kind
== C_ID_ID
))
4385 struct c_declarator
*inner
4386 = build_id_declarator (c_parser_peek_token (parser
)->value
);
4388 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
4389 c_parser_consume_token (parser
);
4390 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4391 inner
->u
.id
.attrs
= c_parser_std_attribute_specifier_sequence (parser
);
4392 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4395 if (kind
!= C_DTR_NORMAL
4396 && c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4397 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4399 struct c_declarator
*inner
= build_id_declarator (NULL_TREE
);
4400 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
4401 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4404 /* Either we are at the end of an abstract declarator, or we have
4407 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4410 struct c_declarator
*inner
;
4411 c_parser_consume_token (parser
);
4412 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4414 attrs
= c_parser_gnu_attributes (parser
);
4415 if (kind
!= C_DTR_NORMAL
4416 && (c_parser_next_token_starts_declspecs (parser
)
4418 && (c_parser_nth_token_starts_std_attributes (parser
, 1)
4419 || c_parser_next_token_is (parser
, CPP_ELLIPSIS
)))
4420 || c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
)))
4422 struct c_arg_info
*args
4423 = c_parser_parms_declarator (parser
, kind
== C_DTR_NORMAL
,
4424 attrs
, have_gnu_attrs
);
4429 inner
= build_id_declarator (NULL_TREE
);
4431 && args
->types
!= error_mark_node
4432 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4433 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4436 = c_parser_std_attribute_specifier_sequence (parser
);
4438 inner
= build_attrs_declarator (std_attrs
, inner
);
4440 inner
= build_function_declarator (args
, inner
);
4441 return c_parser_direct_declarator_inner (parser
, *seen_id
,
4445 /* A parenthesized declarator. */
4446 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4447 if (inner
!= NULL
&& attrs
!= NULL
)
4448 inner
= build_attrs_declarator (attrs
, inner
);
4449 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4451 c_parser_consume_token (parser
);
4455 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4459 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4466 if (kind
== C_DTR_NORMAL
)
4468 c_parser_error (parser
, "expected identifier or %<(%>");
4472 return build_id_declarator (NULL_TREE
);
4476 /* Parse part of a direct declarator or direct abstract declarator,
4477 given that some (in INNER) has already been parsed; ID_PRESENT is
4478 true if an identifier is present, false for an abstract
4481 static struct c_declarator
*
4482 c_parser_direct_declarator_inner (c_parser
*parser
, bool id_present
,
4483 struct c_declarator
*inner
)
4485 /* Parse a sequence of array declarators and parameter lists. */
4486 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4487 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4489 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
4490 struct c_declarator
*declarator
;
4491 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4494 struct c_expr dimen
;
4495 dimen
.value
= NULL_TREE
;
4496 dimen
.original_code
= ERROR_MARK
;
4497 dimen
.original_type
= NULL_TREE
;
4498 c_parser_consume_token (parser
);
4499 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4500 false, false, false, false, cla_prefer_id
);
4501 static_seen
= c_parser_next_token_is_keyword (parser
, RID_STATIC
);
4503 c_parser_consume_token (parser
);
4504 if (static_seen
&& !quals_attrs
->declspecs_seen_p
)
4505 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4506 false, false, false, false, cla_prefer_id
);
4507 if (!quals_attrs
->declspecs_seen_p
)
4509 /* If "static" is present, there must be an array dimension.
4510 Otherwise, there may be a dimension, "*", or no
4515 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4519 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4521 dimen
.value
= NULL_TREE
;
4524 else if (c_parser_next_token_is (parser
, CPP_MULT
))
4526 if (c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_SQUARE
)
4528 dimen
.value
= NULL_TREE
;
4530 c_parser_consume_token (parser
);
4535 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4541 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4544 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4545 c_parser_consume_token (parser
);
4548 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4553 dimen
= convert_lvalue_to_rvalue (brace_loc
, dimen
, true, true);
4554 declarator
= build_array_declarator (brace_loc
, dimen
.value
, quals_attrs
,
4555 static_seen
, star_seen
);
4556 if (declarator
== NULL
)
4558 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4561 = c_parser_std_attribute_specifier_sequence (parser
);
4563 inner
= build_attrs_declarator (std_attrs
, inner
);
4565 inner
= set_array_declarator_inner (declarator
, inner
);
4566 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4568 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4571 struct c_arg_info
*args
;
4572 c_parser_consume_token (parser
);
4573 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4575 attrs
= c_parser_gnu_attributes (parser
);
4576 args
= c_parser_parms_declarator (parser
, id_present
, attrs
,
4583 && args
->types
!= error_mark_node
4584 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4585 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4588 = c_parser_std_attribute_specifier_sequence (parser
);
4590 inner
= build_attrs_declarator (std_attrs
, inner
);
4592 inner
= build_function_declarator (args
, inner
);
4593 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4599 /* Parse a parameter list or identifier list, including the closing
4600 parenthesis but not the opening one. ATTRS are the gnu-attributes
4601 at the start of the list. ID_LIST_OK is true if an identifier list
4602 is acceptable; such a list must not have attributes at the start.
4603 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4604 attributes) were present (in which case standard attributes cannot
4607 static struct c_arg_info
*
4608 c_parser_parms_declarator (c_parser
*parser
, bool id_list_ok
, tree attrs
,
4609 bool have_gnu_attrs
)
4612 declare_parm_level ();
4613 /* If the list starts with an identifier, it is an identifier list.
4614 Otherwise, it is either a prototype list or an empty list. */
4617 && c_parser_next_token_is (parser
, CPP_NAME
)
4618 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4620 /* Look ahead to detect typos in type names. */
4621 && c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
4622 && c_parser_peek_2nd_token (parser
)->type
!= CPP_MULT
4623 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
4624 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_SQUARE
4625 && c_parser_peek_2nd_token (parser
)->type
!= CPP_KEYWORD
)
4627 tree list
= NULL_TREE
, *nextp
= &list
;
4628 while (c_parser_next_token_is (parser
, CPP_NAME
)
4629 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
4631 *nextp
= build_tree_list (NULL_TREE
,
4632 c_parser_peek_token (parser
)->value
);
4633 nextp
= & TREE_CHAIN (*nextp
);
4634 c_parser_consume_token (parser
);
4635 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
4637 c_parser_consume_token (parser
);
4638 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4640 c_parser_error (parser
, "expected identifier");
4644 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4646 struct c_arg_info
*ret
= build_arg_info ();
4648 c_parser_consume_token (parser
);
4654 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4662 struct c_arg_info
*ret
4663 = c_parser_parms_list_declarator (parser
, attrs
, NULL
, have_gnu_attrs
);
4669 /* Parse a parameter list (possibly empty), including the closing
4670 parenthesis but not the opening one. ATTRS are the gnu-attributes
4671 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4672 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4673 which means standard attributes cannot start the list. EXPR is
4674 NULL or an expression that needs to be evaluated for the side
4675 effects of array size expressions in the parameters. */
4677 static struct c_arg_info
*
4678 c_parser_parms_list_declarator (c_parser
*parser
, tree attrs
, tree expr
,
4679 bool have_gnu_attrs
)
4681 bool bad_parm
= false;
4683 /* ??? Following the old parser, forward parameter declarations may
4684 use abstract declarators, and if no real parameter declarations
4685 follow the forward declarations then this is not diagnosed. Also
4686 note as above that gnu-attributes are ignored as the only contents of
4687 the parentheses, or as the only contents after forward
4689 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4691 struct c_arg_info
*ret
= build_arg_info ();
4692 c_parser_consume_token (parser
);
4695 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
) && !have_gnu_attrs
)
4697 struct c_arg_info
*ret
= build_arg_info ();
4699 ret
->types
= NULL_TREE
;
4700 pedwarn_c11 (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
4701 "ISO C requires a named argument before %<...%> "
4703 c_parser_consume_token (parser
);
4704 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4706 ret
->no_named_args_stdarg_p
= true;
4707 c_parser_consume_token (parser
);
4712 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4717 /* Nonempty list of parameters, either terminated with semicolon
4718 (forward declarations; recurse) or with close parenthesis (normal
4719 function) or with ", ... )" (variadic function). */
4722 /* Parse a parameter. */
4723 struct c_parm
*parm
= c_parser_parameter_declaration (parser
, attrs
,
4726 have_gnu_attrs
= false;
4730 push_parm_decl (parm
, &expr
);
4731 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4734 c_parser_consume_token (parser
);
4735 mark_forward_parm_decls ();
4736 bool new_have_gnu_attrs
4737 = c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
);
4738 new_attrs
= c_parser_gnu_attributes (parser
);
4739 return c_parser_parms_list_declarator (parser
, new_attrs
, expr
,
4740 new_have_gnu_attrs
);
4742 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4744 c_parser_consume_token (parser
);
4748 return get_parm_info (false, expr
);
4750 if (!c_parser_require (parser
, CPP_COMMA
,
4751 "expected %<;%>, %<,%> or %<)%>",
4752 UNKNOWN_LOCATION
, false))
4754 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4757 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4759 c_parser_consume_token (parser
);
4760 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4762 c_parser_consume_token (parser
);
4766 return get_parm_info (true, expr
);
4770 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4778 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4779 start of the declaration if it is the first parameter;
4780 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4783 static struct c_parm
*
4784 c_parser_parameter_declaration (c_parser
*parser
, tree attrs
,
4785 bool have_gnu_attrs
)
4787 struct c_declspecs
*specs
;
4788 struct c_declarator
*declarator
;
4790 tree postfix_attrs
= NULL_TREE
;
4793 /* Accept #pragmas between parameter declarations. */
4794 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
4795 c_parser_pragma (parser
, pragma_param
, NULL
);
4797 if (!c_parser_next_token_starts_declspecs (parser
)
4798 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4800 c_token
*token
= c_parser_peek_token (parser
);
4803 c_parser_set_source_position_from_token (token
);
4804 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
4806 auto_diagnostic_group d
;
4807 name_hint hint
= lookup_name_fuzzy (token
->value
,
4808 FUZZY_LOOKUP_TYPENAME
,
4810 if (const char *suggestion
= hint
.suggestion ())
4812 gcc_rich_location
richloc (token
->location
);
4813 richloc
.add_fixit_replace (suggestion
);
4815 "unknown type name %qE; did you mean %qs?",
4816 token
->value
, suggestion
);
4819 error_at (token
->location
, "unknown type name %qE", token
->value
);
4820 parser
->error
= true;
4822 /* ??? In some Objective-C cases '...' isn't applicable so there
4823 should be a different message. */
4825 c_parser_error (parser
,
4826 "expected declaration specifiers or %<...%>");
4827 c_parser_skip_to_end_of_parameter (parser
);
4831 location_t start_loc
= c_parser_peek_token (parser
)->location
;
4833 specs
= build_null_declspecs ();
4836 declspecs_add_attrs (input_location
, specs
, attrs
);
4839 c_parser_declspecs (parser
, specs
, true, true, true, true, false,
4840 !have_gnu_attrs
, true, cla_nonabstract_decl
);
4841 finish_declspecs (specs
);
4842 pending_xref_error ();
4843 prefix_attrs
= specs
->attrs
;
4844 specs
->attrs
= NULL_TREE
;
4845 declarator
= c_parser_declarator (parser
,
4846 specs
->typespec_kind
!= ctsk_none
,
4847 C_DTR_PARM
, &dummy
);
4848 if (declarator
== NULL
)
4850 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
4853 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4854 postfix_attrs
= c_parser_gnu_attributes (parser
);
4856 /* Generate a location for the parameter, ranging from the start of the
4857 initial token to the end of the final token.
4859 If we have a identifier, then use it for the caret location, e.g.
4861 extern int callee (int one, int (*two)(int, int), float three);
4862 ~~~~~~^~~~~~~~~~~~~~
4864 otherwise, reuse the start location for the caret location e.g.:
4866 extern int callee (int one, int (*)(int, int), float three);
4869 location_t end_loc
= parser
->last_token_location
;
4871 /* Find any cdk_id declarator; determine if we have an identifier. */
4872 c_declarator
*id_declarator
= declarator
;
4873 while (id_declarator
&& id_declarator
->kind
!= cdk_id
)
4874 id_declarator
= id_declarator
->declarator
;
4875 location_t caret_loc
= (id_declarator
->u
.id
.id
4876 ? id_declarator
->id_loc
4878 location_t param_loc
= make_location (caret_loc
, start_loc
, end_loc
);
4880 return build_c_parm (specs
, chainon (postfix_attrs
, prefix_attrs
),
4881 declarator
, param_loc
);
4884 /* Parse a string literal in an asm expression. It should not be
4885 translated, and wide string literals are an error although
4886 permitted by the syntax. This is a GNU extension.
4893 c_parser_asm_string_literal (c_parser
*parser
)
4896 int save_flag
= warn_overlength_strings
;
4897 warn_overlength_strings
= 0;
4898 str
= c_parser_string_literal (parser
, false, false).value
;
4899 warn_overlength_strings
= save_flag
;
4903 /* Parse a simple asm expression. This is used in restricted
4904 contexts, where a full expression with inputs and outputs does not
4905 make sense. This is a GNU extension.
4908 asm ( asm-string-literal )
4912 c_parser_simple_asm_expr (c_parser
*parser
)
4915 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
4916 c_parser_consume_token (parser
);
4917 matching_parens parens
;
4918 if (!parens
.require_open (parser
))
4920 str
= c_parser_asm_string_literal (parser
);
4921 if (!parens
.require_close (parser
))
4923 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4930 c_parser_gnu_attribute_any_word (c_parser
*parser
)
4932 tree attr_name
= NULL_TREE
;
4934 if (c_parser_next_token_is (parser
, CPP_KEYWORD
))
4936 /* ??? See comment above about what keywords are accepted here. */
4938 switch (c_parser_peek_token (parser
)->keyword
)
4969 case RID_TRANSACTION_ATOMIC
:
4970 case RID_TRANSACTION_CANCEL
:
4987 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4988 attr_name
= ridpointers
[(int) c_parser_peek_token (parser
)->keyword
];
4990 else if (c_parser_next_token_is (parser
, CPP_NAME
))
4991 attr_name
= c_parser_peek_token (parser
)->value
;
4996 /* Parse attribute arguments. This is a common form of syntax
4997 covering all currently valid GNU and standard attributes.
4999 gnu-attribute-arguments:
5001 identifier , nonempty-expr-list
5004 where the "identifier" must not be declared as a type. ??? Why not
5005 allow identifiers declared as types to start the arguments? */
5008 c_parser_attribute_arguments (c_parser
*parser
, bool takes_identifier
,
5009 bool require_string
, bool assume_attr
,
5010 bool allow_empty_args
)
5012 vec
<tree
, va_gc
> *expr_list
;
5014 /* Parse the attribute contents. If they start with an
5015 identifier which is followed by a comma or close
5016 parenthesis, then the arguments start with that
5017 identifier; otherwise they are an expression list.
5018 In objective-c the identifier may be a classname. */
5019 if (c_parser_next_token_is (parser
, CPP_NAME
)
5020 && (c_parser_peek_token (parser
)->id_kind
== C_ID_ID
5021 || (c_dialect_objc ()
5022 && c_parser_peek_token (parser
)->id_kind
5024 && ((c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
5025 || (c_parser_peek_2nd_token (parser
)->type
5026 == CPP_CLOSE_PAREN
))
5027 && (takes_identifier
5028 || (c_dialect_objc ()
5030 && c_parser_peek_token (parser
)->id_kind
5031 == C_ID_CLASSNAME
)))
5033 tree arg1
= c_parser_peek_token (parser
)->value
;
5034 c_parser_consume_token (parser
);
5035 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5036 attr_args
= build_tree_list (NULL_TREE
, arg1
);
5040 c_parser_consume_token (parser
);
5041 expr_list
= c_parser_expr_list (parser
, false, true,
5042 NULL
, NULL
, NULL
, NULL
);
5043 tree_list
= build_tree_list_vec (expr_list
);
5044 attr_args
= tree_cons (NULL_TREE
, arg1
, tree_list
);
5045 release_tree_vector (expr_list
);
5050 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5052 if (!allow_empty_args
)
5053 error_at (c_parser_peek_token (parser
)->location
,
5054 "parentheses must be omitted if "
5055 "attribute argument list is empty");
5056 attr_args
= NULL_TREE
;
5058 else if (require_string
)
5060 /* The only valid argument for this attribute is a string
5061 literal. Handle this specially here to avoid accepting
5062 string literals with excess parentheses. */
5063 tree string
= c_parser_string_literal (parser
, false, true).value
;
5064 attr_args
= build_tree_list (NULL_TREE
, string
);
5066 else if (assume_attr
)
5069 = c_parser_conditional_expression (parser
, NULL
, NULL_TREE
).value
;
5070 if (!c_parser_next_token_is (parser
, CPP_COMMA
))
5071 attr_args
= build_tree_list (NULL_TREE
, cond
);
5075 c_parser_consume_token (parser
);
5076 expr_list
= c_parser_expr_list (parser
, false, true,
5077 NULL
, NULL
, NULL
, NULL
);
5078 tree_list
= build_tree_list_vec (expr_list
);
5079 attr_args
= tree_cons (NULL_TREE
, cond
, tree_list
);
5080 release_tree_vector (expr_list
);
5085 expr_list
= c_parser_expr_list (parser
, false, true,
5086 NULL
, NULL
, NULL
, NULL
);
5087 attr_args
= build_tree_list_vec (expr_list
);
5088 release_tree_vector (expr_list
);
5094 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
5098 gnu-attributes gnu-attribute
5101 __attribute__ ( ( gnu-attribute-list ) )
5105 gnu-attribute_list , gnu-attrib
5110 any-word ( gnu-attribute-arguments )
5112 where "any-word" may be any identifier (including one declared as a
5113 type), a reserved word storage class specifier, type specifier or
5114 type qualifier. ??? This still leaves out most reserved keywords
5115 (following the old parser), shouldn't we include them?
5116 When EXPECT_COMMA is true, expect the attribute to be preceded
5117 by a comma and fail if it isn't.
5118 When EMPTY_OK is true, allow and consume any number of consecutive
5119 commas with no attributes in between. */
5122 c_parser_gnu_attribute (c_parser
*parser
, tree attrs
,
5123 bool expect_comma
= false, bool empty_ok
= true)
5125 bool comma_first
= c_parser_next_token_is (parser
, CPP_COMMA
);
5127 && !c_parser_next_token_is (parser
, CPP_NAME
)
5128 && !c_parser_next_token_is (parser
, CPP_KEYWORD
))
5131 while (c_parser_next_token_is (parser
, CPP_COMMA
))
5133 c_parser_consume_token (parser
);
5138 tree attr_name
= c_parser_gnu_attribute_any_word (parser
);
5139 if (attr_name
== NULL_TREE
)
5142 attr_name
= canonicalize_attr_name (attr_name
);
5143 c_parser_consume_token (parser
);
5146 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
5148 if (expect_comma
&& !comma_first
)
5150 /* A comma is missing between the last attribute on the chain
5152 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5154 return error_mark_node
;
5156 attr
= build_tree_list (attr_name
, NULL_TREE
);
5157 /* Add this attribute to the list. */
5158 attrs
= chainon (attrs
, attr
);
5161 c_parser_consume_token (parser
);
5164 = c_parser_attribute_arguments (parser
,
5165 attribute_takes_identifier_p (attr_name
),
5167 is_attribute_p ("assume", attr_name
),
5170 attr
= build_tree_list (attr_name
, attr_args
);
5171 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5172 c_parser_consume_token (parser
);
5175 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5177 return error_mark_node
;
5180 if (expect_comma
&& !comma_first
)
5182 /* A comma is missing between the last attribute on the chain
5184 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5186 return error_mark_node
;
5189 /* Add this attribute to the list. */
5190 attrs
= chainon (attrs
, attr
);
5195 c_parser_gnu_attributes (c_parser
*parser
)
5197 tree attrs
= NULL_TREE
;
5198 while (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
5200 bool save_translate_strings_p
= parser
->translate_strings_p
;
5201 parser
->translate_strings_p
= false;
5202 /* Consume the `__attribute__' keyword. */
5203 c_parser_consume_token (parser
);
5204 /* Look for the two `(' tokens. */
5205 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
5207 parser
->translate_strings_p
= save_translate_strings_p
;
5210 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
5212 parser
->translate_strings_p
= save_translate_strings_p
;
5213 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
5216 /* Parse the attribute list. Require a comma between successive
5217 (possibly empty) attributes. */
5218 for (bool expect_comma
= false; ; expect_comma
= true)
5220 /* Parse a single attribute. */
5221 tree attr
= c_parser_gnu_attribute (parser
, attrs
, expect_comma
);
5222 if (attr
== error_mark_node
)
5229 /* Look for the two `)' tokens. */
5230 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5231 c_parser_consume_token (parser
);
5234 parser
->translate_strings_p
= save_translate_strings_p
;
5235 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5239 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
5240 c_parser_consume_token (parser
);
5243 parser
->translate_strings_p
= save_translate_strings_p
;
5244 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
5248 parser
->translate_strings_p
= save_translate_strings_p
;
5254 /* Parse an optional balanced token sequence.
5256 balanced-token-sequence:
5258 balanced-token-sequence balanced-token
5261 ( balanced-token-sequence[opt] )
5262 [ balanced-token-sequence[opt] ]
5263 { balanced-token-sequence[opt] }
5264 any token other than ()[]{}
5268 c_parser_balanced_token_sequence (c_parser
*parser
)
5272 c_token
*token
= c_parser_peek_token (parser
);
5273 switch (token
->type
)
5275 case CPP_OPEN_BRACE
:
5277 matching_braces braces
;
5278 braces
.consume_open (parser
);
5279 c_parser_balanced_token_sequence (parser
);
5280 braces
.require_close (parser
);
5284 case CPP_OPEN_PAREN
:
5286 matching_parens parens
;
5287 parens
.consume_open (parser
);
5288 c_parser_balanced_token_sequence (parser
);
5289 parens
.require_close (parser
);
5293 case CPP_OPEN_SQUARE
:
5294 c_parser_consume_token (parser
);
5295 c_parser_balanced_token_sequence (parser
);
5296 c_parser_require (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5299 case CPP_CLOSE_BRACE
:
5300 case CPP_CLOSE_PAREN
:
5301 case CPP_CLOSE_SQUARE
:
5306 c_parser_consume_pragma (parser
);
5307 c_parser_skip_to_pragma_eol (parser
, false);
5311 c_parser_consume_token (parser
);
5317 /* Parse standard (C2X) attributes (including GNU attributes in the
5320 attribute-specifier-sequence:
5321 attribute-specifier-sequence[opt] attribute-specifier
5323 attribute-specifier:
5324 [ [ attribute-list ] ]
5328 attribute-list, attribute[opt]
5331 attribute-token attribute-argument-clause[opt]
5335 attribute-prefixed-token
5340 attribute-prefixed-token:
5341 attribute-prefix :: identifier
5346 attribute-argument-clause:
5347 ( balanced-token-sequence[opt] )
5349 Keywords are accepted as identifiers for this purpose.
5353 c_parser_std_attribute (c_parser
*parser
, bool for_tm
)
5355 c_token
*token
= c_parser_peek_token (parser
);
5356 tree ns
, name
, attribute
;
5358 /* Parse the attribute-token. */
5359 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
5361 c_parser_error (parser
, "expected identifier");
5362 return error_mark_node
;
5364 name
= canonicalize_attr_name (token
->value
);
5365 c_parser_consume_token (parser
);
5366 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
5369 c_parser_consume_token (parser
);
5370 token
= c_parser_peek_token (parser
);
5371 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
5373 c_parser_error (parser
, "expected identifier");
5374 return error_mark_node
;
5376 name
= canonicalize_attr_name (token
->value
);
5377 c_parser_consume_token (parser
);
5381 attribute
= build_tree_list (build_tree_list (ns
, name
), NULL_TREE
);
5383 /* Parse the arguments, if any. */
5384 const attribute_spec
*as
= lookup_attribute_spec (TREE_PURPOSE (attribute
));
5385 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
5388 location_t open_loc
= c_parser_peek_token (parser
)->location
;
5389 matching_parens parens
;
5390 parens
.consume_open (parser
);
5391 if ((as
&& as
->max_length
== 0)
5392 /* Special-case the transactional-memory attribute "outer",
5393 which is specially handled but not registered as an
5394 attribute, to avoid allowing arbitrary balanced token
5395 sequences as arguments. */
5396 || is_attribute_p ("outer", name
))
5398 error_at (open_loc
, "%qE attribute does not take any arguments", name
);
5399 parens
.skip_until_found_close (parser
);
5400 return error_mark_node
;
5402 /* If this is a fake attribute created to handle -Wno-attributes,
5403 we must skip parsing the arguments. */
5404 if (as
&& !attribute_ignored_p (as
))
5406 bool takes_identifier
5408 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
5409 && attribute_takes_identifier_p (name
));
5412 && (strcmp (IDENTIFIER_POINTER (name
), "deprecated") == 0
5413 || strcmp (IDENTIFIER_POINTER (name
), "nodiscard") == 0));
5416 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
5417 && strcmp (IDENTIFIER_POINTER (name
), "assume") == 0);
5418 TREE_VALUE (attribute
)
5419 = c_parser_attribute_arguments (parser
, takes_identifier
,
5420 require_string
, assume_attr
, false);
5423 c_parser_balanced_token_sequence (parser
);
5424 parens
.require_close (parser
);
5427 if (ns
== NULL_TREE
&& !for_tm
&& !as
)
5429 /* An attribute with standard syntax and no namespace specified
5430 is a constraint violation if it is not one of the known
5431 standard attributes. Diagnose it here with a pedwarn and
5432 then discard it to prevent a duplicate warning later. */
5433 pedwarn (input_location
, OPT_Wattributes
, "%qE attribute ignored",
5435 return error_mark_node
;
5441 c_parser_std_attribute_specifier (c_parser
*parser
, bool for_tm
)
5443 location_t loc
= c_parser_peek_token (parser
)->location
;
5444 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
5446 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
5448 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5452 pedwarn_c11 (loc
, OPT_Wpedantic
,
5453 "ISO C does not support %<[[]]%> attributes before C2X");
5454 tree attributes
= NULL_TREE
;
5457 c_token
*token
= c_parser_peek_token (parser
);
5458 if (token
->type
== CPP_CLOSE_SQUARE
)
5460 if (token
->type
== CPP_COMMA
)
5462 c_parser_consume_token (parser
);
5465 tree attribute
= c_parser_std_attribute (parser
, for_tm
);
5466 if (attribute
!= error_mark_node
)
5468 TREE_CHAIN (attribute
) = attributes
;
5469 attributes
= attribute
;
5471 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5474 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5475 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5476 return nreverse (attributes
);
5479 /* Look past an optional balanced token sequence of raw look-ahead
5480 tokens starting with the *Nth token. *N is updated to point to the
5481 following token. Return true if such a sequence was found, false
5482 if the tokens parsed were not balanced. */
5485 c_parser_check_balanced_raw_token_sequence (c_parser
*parser
, unsigned int *n
)
5489 c_token
*token
= c_parser_peek_nth_token_raw (parser
, *n
);
5490 switch (token
->type
)
5492 case CPP_OPEN_BRACE
:
5495 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5497 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5498 if (token
->type
== CPP_CLOSE_BRACE
)
5508 case CPP_OPEN_PAREN
:
5511 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5513 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5514 if (token
->type
== CPP_CLOSE_PAREN
)
5524 case CPP_OPEN_SQUARE
:
5527 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5529 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5530 if (token
->type
== CPP_CLOSE_SQUARE
)
5540 case CPP_CLOSE_BRACE
:
5541 case CPP_CLOSE_PAREN
:
5542 case CPP_CLOSE_SQUARE
:
5553 /* Return whether standard attributes start with the Nth token. */
5556 c_parser_nth_token_starts_std_attributes (c_parser
*parser
, unsigned int n
)
5558 if (!(c_parser_peek_nth_token (parser
, n
)->type
== CPP_OPEN_SQUARE
5559 && c_parser_peek_nth_token (parser
, n
+ 1)->type
== CPP_OPEN_SQUARE
))
5561 /* In C, '[[' must start attributes. In Objective-C, we need to
5562 check whether '[[' is matched by ']]'. */
5563 if (!c_dialect_objc ())
5566 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
5568 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
5569 if (token
->type
!= CPP_CLOSE_SQUARE
)
5571 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
5572 return token
->type
== CPP_CLOSE_SQUARE
;
5576 c_parser_std_attribute_specifier_sequence (c_parser
*parser
)
5578 tree attributes
= NULL_TREE
;
5581 tree attrs
= c_parser_std_attribute_specifier (parser
, false);
5582 attributes
= chainon (attributes
, attrs
);
5584 while (c_parser_nth_token_starts_std_attributes (parser
, 1));
5588 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5589 says whether alignment specifiers are OK (only in cases that might
5590 be the type name of a compound literal).
5593 specifier-qualifier-list abstract-declarator[opt]
5596 struct c_type_name
*
5597 c_parser_type_name (c_parser
*parser
, bool alignas_ok
)
5599 struct c_declspecs
*specs
= build_null_declspecs ();
5600 struct c_declarator
*declarator
;
5601 struct c_type_name
*ret
;
5603 c_parser_declspecs (parser
, specs
, false, true, true, alignas_ok
, false,
5604 false, true, cla_prefer_type
);
5605 if (!specs
->declspecs_seen_p
)
5607 c_parser_error (parser
, "expected specifier-qualifier-list");
5610 if (specs
->type
!= error_mark_node
)
5612 pending_xref_error ();
5613 finish_declspecs (specs
);
5615 declarator
= c_parser_declarator (parser
,
5616 specs
->typespec_kind
!= ctsk_none
,
5617 C_DTR_ABSTRACT
, &dummy
);
5618 if (declarator
== NULL
)
5620 ret
= XOBNEW (&parser_obstack
, struct c_type_name
);
5622 ret
->declarator
= declarator
;
5626 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5629 assignment-expression
5630 { initializer-list }
5631 { initializer-list , }
5634 designation[opt] initializer
5635 initializer-list , designation[opt] initializer
5642 designator-list designator
5649 [ constant-expression ]
5661 [ constant-expression ... constant-expression ]
5663 Any expression without commas is accepted in the syntax for the
5664 constant-expressions, with non-constant expressions rejected later.
5666 DECL is the declaration we're parsing this initializer for.
5668 This function is only used for top-level initializers; for nested
5669 ones, see c_parser_initval. */
5671 static struct c_expr
5672 c_parser_initializer (c_parser
*parser
, tree decl
)
5674 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
5675 return c_parser_braced_init (parser
, NULL_TREE
, false, NULL
, decl
);
5679 location_t loc
= c_parser_peek_token (parser
)->location
;
5680 if (decl
!= error_mark_node
&& C_DECL_VARIABLE_SIZE (decl
))
5682 "variable-sized object may not be initialized except "
5683 "with an empty initializer");
5684 ret
= c_parser_expr_no_commas (parser
, NULL
);
5685 /* This is handled mostly by gimplify.cc, but we have to deal with
5686 not warning about int x = x; as it is a GCC extension to turn off
5687 this warning but only if warn_init_self is zero. */
5689 && !DECL_EXTERNAL (decl
)
5690 && !TREE_STATIC (decl
)
5691 && ret
.value
== decl
5692 && !warning_enabled_at (DECL_SOURCE_LOCATION (decl
), OPT_Winit_self
))
5693 suppress_warning (decl
, OPT_Winit_self
);
5694 if (TREE_CODE (ret
.value
) != STRING_CST
5695 && (TREE_CODE (ret
.value
) != COMPOUND_LITERAL_EXPR
5696 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
5698 ret
= convert_lvalue_to_rvalue (loc
, ret
, true, true, true);
5703 /* The location of the last comma within the current initializer list,
5704 or UNKNOWN_LOCATION if not within one. */
5706 location_t last_init_list_comma
;
5708 /* Parse a braced initializer list. TYPE is the type specified for a
5709 compound literal, and NULL_TREE for other initializers and for
5710 nested braced lists. NESTED_P is true for nested braced lists,
5711 false for the list of a compound literal or the list that is the
5712 top-level initializer in a declaration. DECL is the declaration for
5713 the top-level initializer for a declaration, otherwise NULL_TREE. */
5715 static struct c_expr
5716 c_parser_braced_init (c_parser
*parser
, tree type
, bool nested_p
,
5717 struct obstack
*outer_obstack
, tree decl
)
5720 struct obstack braced_init_obstack
;
5721 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
5722 gcc_obstack_init (&braced_init_obstack
);
5723 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
5724 matching_braces braces
;
5725 braces
.consume_open (parser
);
5728 finish_implicit_inits (brace_loc
, outer_obstack
);
5729 push_init_level (brace_loc
, 0, &braced_init_obstack
);
5732 really_start_incremental_init (type
);
5733 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5735 pedwarn_c11 (brace_loc
, OPT_Wpedantic
,
5736 "ISO C forbids empty initializer braces before C2X");
5740 if (decl
&& decl
!= error_mark_node
&& C_DECL_VARIABLE_SIZE (decl
))
5741 error_at (brace_loc
,
5742 "variable-sized object may not be initialized except "
5743 "with an empty initializer");
5744 /* Parse a non-empty initializer list, possibly with a trailing
5748 c_parser_initelt (parser
, &braced_init_obstack
);
5751 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5753 last_init_list_comma
= c_parser_peek_token (parser
)->location
;
5754 c_parser_consume_token (parser
);
5758 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5762 c_token
*next_tok
= c_parser_peek_token (parser
);
5763 if (next_tok
->type
!= CPP_CLOSE_BRACE
)
5766 ret
.original_code
= ERROR_MARK
;
5767 ret
.original_type
= NULL
;
5768 braces
.skip_until_found_close (parser
);
5769 pop_init_level (brace_loc
, 0, &braced_init_obstack
, last_init_list_comma
);
5770 obstack_free (&braced_init_obstack
, NULL
);
5773 location_t close_loc
= next_tok
->location
;
5774 c_parser_consume_token (parser
);
5775 ret
= pop_init_level (brace_loc
, 0, &braced_init_obstack
, close_loc
);
5776 obstack_free (&braced_init_obstack
, NULL
);
5777 set_c_expr_source_range (&ret
, brace_loc
, close_loc
);
5781 /* Parse a nested initializer, including designators. */
5784 c_parser_initelt (c_parser
*parser
, struct obstack
* braced_init_obstack
)
5786 /* Parse any designator or designator list. A single array
5787 designator may have the subsequent "=" omitted in GNU C, but a
5788 longer list or a structure member designator may not. */
5789 if (c_parser_next_token_is (parser
, CPP_NAME
)
5790 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
5792 /* Old-style structure member designator. */
5793 set_init_label (c_parser_peek_token (parser
)->location
,
5794 c_parser_peek_token (parser
)->value
,
5795 c_parser_peek_token (parser
)->location
,
5796 braced_init_obstack
);
5797 /* Use the colon as the error location. */
5798 pedwarn (c_parser_peek_2nd_token (parser
)->location
, OPT_Wpedantic
,
5799 "obsolete use of designated initializer with %<:%>");
5800 c_parser_consume_token (parser
);
5801 c_parser_consume_token (parser
);
5805 /* des_seen is 0 if there have been no designators, 1 if there
5806 has been a single array designator and 2 otherwise. */
5808 /* Location of a designator. */
5809 location_t des_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5810 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
5811 || c_parser_next_token_is (parser
, CPP_DOT
))
5813 int des_prev
= des_seen
;
5815 des_loc
= c_parser_peek_token (parser
)->location
;
5818 if (c_parser_next_token_is (parser
, CPP_DOT
))
5821 c_parser_consume_token (parser
);
5822 if (c_parser_next_token_is (parser
, CPP_NAME
))
5824 set_init_label (des_loc
, c_parser_peek_token (parser
)->value
,
5825 c_parser_peek_token (parser
)->location
,
5826 braced_init_obstack
);
5827 c_parser_consume_token (parser
);
5833 init
.original_code
= ERROR_MARK
;
5834 init
.original_type
= NULL
;
5835 c_parser_error (parser
, "expected identifier");
5836 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5837 process_init_element (input_location
, init
, false,
5838 braced_init_obstack
);
5844 struct c_expr first_expr
;
5846 location_t ellipsis_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5847 location_t array_index_loc
= UNKNOWN_LOCATION
;
5848 /* ??? Following the old parser, [ objc-receiver
5849 objc-message-args ] is accepted as an initializer,
5850 being distinguished from a designator by what follows
5851 the first assignment expression inside the square
5852 brackets, but after a first array designator a
5853 subsequent square bracket is for Objective-C taken to
5854 start an expression, using the obsolete form of
5855 designated initializer without '=', rather than
5856 possibly being a second level of designation: in LALR
5857 terms, the '[' is shifted rather than reducing
5858 designator to designator-list. */
5859 if (des_prev
== 1 && c_dialect_objc ())
5861 des_seen
= des_prev
;
5864 if (des_prev
== 0 && c_dialect_objc ())
5866 /* This might be an array designator or an
5867 Objective-C message expression. If the former,
5868 continue parsing here; if the latter, parse the
5869 remainder of the initializer given the starting
5870 primary-expression. ??? It might make sense to
5871 distinguish when des_prev == 1 as well; see
5872 previous comment. */
5874 struct c_expr mexpr
;
5875 c_parser_consume_token (parser
);
5876 if (c_parser_peek_token (parser
)->type
== CPP_NAME
5877 && ((c_parser_peek_token (parser
)->id_kind
5879 || (c_parser_peek_token (parser
)->id_kind
5880 == C_ID_CLASSNAME
)))
5882 /* Type name receiver. */
5883 tree id
= c_parser_peek_token (parser
)->value
;
5884 c_parser_consume_token (parser
);
5885 rec
= objc_get_class_reference (id
);
5886 goto parse_message_args
;
5888 array_index_loc
= c_parser_peek_token (parser
)->location
;
5889 first_expr
= c_parser_expr_no_commas (parser
, NULL
);
5890 mark_exp_read (first_expr
.value
);
5891 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
)
5892 || c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5893 goto array_desig_after_first
;
5894 first
= first_expr
.value
;
5895 /* Expression receiver. So far only one part
5896 without commas has been parsed; there might be
5897 more of the expression. */
5899 while (c_parser_next_token_is (parser
, CPP_COMMA
))
5902 location_t comma_loc
, exp_loc
;
5903 comma_loc
= c_parser_peek_token (parser
)->location
;
5904 c_parser_consume_token (parser
);
5905 exp_loc
= c_parser_peek_token (parser
)->location
;
5906 next
= c_parser_expr_no_commas (parser
, NULL
);
5907 next
= convert_lvalue_to_rvalue (exp_loc
, next
,
5909 rec
= build_compound_expr (comma_loc
, rec
, next
.value
);
5912 /* Now parse the objc-message-args. */
5913 args
= c_parser_objc_message_args (parser
);
5914 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5917 = objc_build_message_expr (rec
, args
);
5918 mexpr
.original_code
= ERROR_MARK
;
5919 mexpr
.original_type
= NULL
;
5920 mexpr
.m_decimal
= 0;
5921 /* Now parse and process the remainder of the
5922 initializer, starting with this message
5923 expression as a primary-expression. */
5924 c_parser_initval (parser
, &mexpr
, braced_init_obstack
);
5927 c_parser_consume_token (parser
);
5928 array_index_loc
= c_parser_peek_token (parser
)->location
;
5929 first_expr
= c_parser_expr_no_commas (parser
, NULL
);
5930 mark_exp_read (first_expr
.value
);
5931 array_desig_after_first
:
5932 first_expr
= convert_lvalue_to_rvalue (array_index_loc
,
5935 first
= first_expr
.value
;
5936 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5938 ellipsis_loc
= c_parser_peek_token (parser
)->location
;
5939 c_parser_consume_token (parser
);
5940 second
= convert_lvalue_to_rvalue (ellipsis_loc
,
5941 (c_parser_expr_no_commas
5944 mark_exp_read (second
);
5948 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5950 c_parser_consume_token (parser
);
5951 set_init_index (array_index_loc
, first
, second
,
5952 braced_init_obstack
);
5954 pedwarn (ellipsis_loc
, OPT_Wpedantic
,
5955 "ISO C forbids specifying range of elements to initialize");
5958 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5964 if (c_parser_next_token_is (parser
, CPP_EQ
))
5966 pedwarn_c90 (des_loc
, OPT_Wpedantic
,
5967 "ISO C90 forbids specifying subobject "
5969 c_parser_consume_token (parser
);
5974 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
5975 "obsolete use of designated initializer without %<=%>");
5980 init
.original_code
= ERROR_MARK
;
5981 init
.original_type
= NULL
;
5982 c_parser_error (parser
, "expected %<=%>");
5983 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5984 process_init_element (input_location
, init
, false,
5985 braced_init_obstack
);
5991 c_parser_initval (parser
, NULL
, braced_init_obstack
);
5994 /* Parse a nested initializer; as c_parser_initializer but parses
5995 initializers within braced lists, after any designators have been
5996 applied. If AFTER is not NULL then it is an Objective-C message
5997 expression which is the primary-expression starting the
6001 c_parser_initval (c_parser
*parser
, struct c_expr
*after
,
6002 struct obstack
* braced_init_obstack
)
6005 gcc_assert (!after
|| c_dialect_objc ());
6006 location_t loc
= c_parser_peek_token (parser
)->location
;
6008 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
) && !after
)
6009 init
= c_parser_braced_init (parser
, NULL_TREE
, true,
6010 braced_init_obstack
, NULL_TREE
);
6013 init
= c_parser_expr_no_commas (parser
, after
);
6014 if (init
.value
!= NULL_TREE
6015 && TREE_CODE (init
.value
) != STRING_CST
6016 && (TREE_CODE (init
.value
) != COMPOUND_LITERAL_EXPR
6017 || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
6019 init
= convert_lvalue_to_rvalue (loc
, init
, true, true, true);
6021 process_init_element (loc
, init
, false, braced_init_obstack
);
6024 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
6025 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
6028 { block-item-list[opt] }
6029 { label-declarations block-item-list }
6033 block-item-list block-item
6046 { label-declarations block-item-list }
6049 __extension__ nested-declaration
6050 nested-function-definition
6054 label-declarations label-declaration
6057 __label__ identifier-list ;
6059 Allowing the mixing of declarations and code is new in C99. The
6060 GNU syntax also permits (not shown above) labels at the end of
6061 compound statements, which yield an error. We don't allow labels
6062 on declarations; this might seem like a natural extension, but
6063 there would be a conflict between gnu-attributes on the label and
6064 prefix gnu-attributes on the declaration. ??? The syntax follows the
6065 old parser in requiring something after label declarations.
6066 Although they are erroneous if the labels declared aren't defined,
6067 is it useful for the syntax to be this way?
6088 cancellation-point-directive */
6091 c_parser_compound_statement (c_parser
*parser
, location_t
*endlocp
)
6094 location_t brace_loc
;
6095 brace_loc
= c_parser_peek_token (parser
)->location
;
6096 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
6098 /* Ensure a scope is entered and left anyway to avoid confusion
6099 if we have just prepared to enter a function body. */
6100 stmt
= c_begin_compound_stmt (true);
6101 c_end_compound_stmt (brace_loc
, stmt
, true);
6102 return error_mark_node
;
6104 stmt
= c_begin_compound_stmt (true);
6105 location_t end_loc
= c_parser_compound_statement_nostart (parser
);
6109 return c_end_compound_stmt (brace_loc
, stmt
, true);
6112 /* Parse a compound statement except for the opening brace. This is
6113 used for parsing both compound statements and statement expressions
6114 (which follow different paths to handling the opening). */
6117 c_parser_compound_statement_nostart (c_parser
*parser
)
6119 bool last_stmt
= false;
6120 bool last_label
= false;
6121 bool save_valid_for_pragma
= valid_location_for_stdc_pragma_p ();
6122 location_t label_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
6123 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
6125 location_t endloc
= c_parser_peek_token (parser
)->location
;
6126 add_debug_begin_stmt (endloc
);
6127 c_parser_consume_token (parser
);
6130 mark_valid_location_for_stdc_pragma (true);
6131 if (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
6133 /* Read zero or more forward-declarations for labels that nested
6134 functions can jump to. */
6135 mark_valid_location_for_stdc_pragma (false);
6136 while (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
6138 label_loc
= c_parser_peek_token (parser
)->location
;
6139 c_parser_consume_token (parser
);
6140 /* Any identifiers, including those declared as type names,
6145 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
6147 c_parser_error (parser
, "expected identifier");
6151 = declare_label (c_parser_peek_token (parser
)->value
);
6152 C_DECLARED_LABEL_FLAG (label
) = 1;
6153 add_stmt (build_stmt (label_loc
, DECL_EXPR
, label
));
6154 c_parser_consume_token (parser
);
6155 if (c_parser_next_token_is (parser
, CPP_COMMA
))
6156 c_parser_consume_token (parser
);
6160 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
6162 pedwarn (label_loc
, OPT_Wpedantic
, "ISO C forbids label declarations");
6164 /* We must now have at least one statement, label or declaration. */
6165 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
6167 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
6168 c_parser_error (parser
, "expected declaration or statement");
6169 location_t endloc
= c_parser_peek_token (parser
)->location
;
6170 c_parser_consume_token (parser
);
6173 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_BRACE
))
6175 location_t loc
= c_parser_peek_token (parser
)->location
;
6176 loc
= expansion_point_location_if_in_system_header (loc
);
6177 /* Standard attributes may start a label, statement or declaration. */
6179 = c_parser_nth_token_starts_std_attributes (parser
, 1);
6180 tree std_attrs
= NULL_TREE
;
6182 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
6183 if (c_parser_next_token_is_keyword (parser
, RID_CASE
)
6184 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
6185 || (c_parser_next_token_is (parser
, CPP_NAME
)
6186 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
6188 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
6189 label_loc
= c_parser_peek_2nd_token (parser
)->location
;
6191 label_loc
= c_parser_peek_token (parser
)->location
;
6194 mark_valid_location_for_stdc_pragma (false);
6195 c_parser_label (parser
, std_attrs
);
6197 else if (c_parser_next_tokens_start_declaration (parser
)
6199 && c_parser_next_token_is (parser
, CPP_SEMICOLON
)))
6202 pedwarn_c11 (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
6203 "a label can only be part of a statement and "
6204 "a declaration is not a statement");
6206 mark_valid_location_for_stdc_pragma (false);
6207 bool fallthru_attr_p
= false;
6208 c_parser_declaration_or_fndef (parser
, true, !have_std_attrs
,
6209 true, true, true, NULL
,
6210 NULL
, have_std_attrs
, std_attrs
,
6211 NULL
, &fallthru_attr_p
);
6213 if (last_stmt
&& !fallthru_attr_p
)
6214 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
6215 "ISO C90 forbids mixed declarations and code");
6216 last_stmt
= fallthru_attr_p
;
6219 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
6221 /* __extension__ can start a declaration, but is also an
6222 unary operator that can start an expression. Consume all
6223 but the last of a possible series of __extension__ to
6224 determine which. If standard attributes have already
6225 been seen, it must start a statement, not a declaration,
6226 but standard attributes starting a declaration may appear
6227 after __extension__. */
6228 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
6229 && (c_parser_peek_2nd_token (parser
)->keyword
6231 c_parser_consume_token (parser
);
6233 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
6234 || c_parser_nth_token_starts_std_attributes (parser
, 2)))
6237 ext
= disable_extension_diagnostics ();
6238 c_parser_consume_token (parser
);
6240 mark_valid_location_for_stdc_pragma (false);
6241 c_parser_declaration_or_fndef (parser
, true, true, true, true,
6243 /* Following the old parser, __extension__ does not
6244 disable this diagnostic. */
6245 restore_extension_diagnostics (ext
);
6247 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
6248 "ISO C90 forbids mixed declarations and code");
6254 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
6257 c_parser_error (parser
, "expected declaration or statement");
6258 /* External pragmas, and some omp pragmas, are not associated
6259 with regular c code, and so are not to be considered statements
6260 syntactically. This ensures that the user doesn't put them
6261 places that would turn into syntax errors if the directive
6263 if (c_parser_pragma (parser
,
6264 last_label
? pragma_stmt
: pragma_compound
,
6266 last_label
= false, last_stmt
= true;
6268 else if (c_parser_next_token_is (parser
, CPP_EOF
))
6270 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
6271 c_parser_error (parser
, "expected declaration or statement");
6272 return c_parser_peek_token (parser
)->location
;
6274 else if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6276 if (parser
->in_if_block
)
6278 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
6279 error_at (loc
, "expected %<}%> before %<else%>");
6280 return c_parser_peek_token (parser
)->location
;
6284 error_at (loc
, "%<else%> without a previous %<if%>");
6285 c_parser_consume_token (parser
);
6292 c_warn_unused_attributes (std_attrs
);
6295 mark_valid_location_for_stdc_pragma (false);
6296 c_parser_statement_after_labels (parser
, NULL
);
6299 parser
->error
= false;
6302 pedwarn_c11 (label_loc
, OPT_Wpedantic
, "label at end of compound statement");
6303 location_t endloc
= c_parser_peek_token (parser
)->location
;
6304 c_parser_consume_token (parser
);
6305 /* Restore the value we started with. */
6306 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
6310 /* Parse all consecutive labels, possibly preceded by standard
6311 attributes. In this context, a statement is required, not a
6312 declaration, so attributes must be followed by a statement that is
6313 not just a semicolon. */
6316 c_parser_all_labels (c_parser
*parser
)
6318 tree std_attrs
= NULL
;
6319 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
6321 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
6322 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6323 c_parser_error (parser
, "expected statement");
6325 while (c_parser_next_token_is_keyword (parser
, RID_CASE
)
6326 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
6327 || (c_parser_next_token_is (parser
, CPP_NAME
)
6328 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
6330 c_parser_label (parser
, std_attrs
);
6332 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
6334 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
6335 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6336 c_parser_error (parser
, "expected statement");
6340 c_warn_unused_attributes (std_attrs
);
6343 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
6346 identifier : gnu-attributes[opt]
6347 case constant-expression :
6353 case constant-expression ... constant-expression :
6355 The use of gnu-attributes on labels is a GNU extension. The syntax in
6356 GNU C accepts any expressions without commas, non-constant
6357 expressions being rejected later. Any standard
6358 attribute-specifier-sequence before the first label has been parsed
6359 in the caller, to distinguish statements from declarations. Any
6360 attribute-specifier-sequence after the label is parsed in this
6363 c_parser_label (c_parser
*parser
, tree std_attrs
)
6365 location_t loc1
= c_parser_peek_token (parser
)->location
;
6366 tree label
= NULL_TREE
;
6368 /* Remember whether this case or a user-defined label is allowed to fall
6370 bool fallthrough_p
= c_parser_peek_token (parser
)->flags
& PREV_FALLTHROUGH
;
6372 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
6375 c_parser_consume_token (parser
);
6376 exp1
= convert_lvalue_to_rvalue (loc1
,
6377 c_parser_expr_no_commas (parser
, NULL
),
6379 if (c_parser_next_token_is (parser
, CPP_COLON
))
6381 c_parser_consume_token (parser
);
6382 label
= do_case (loc1
, exp1
, NULL_TREE
, std_attrs
);
6384 else if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
6386 c_parser_consume_token (parser
);
6387 exp2
= convert_lvalue_to_rvalue (loc1
,
6388 c_parser_expr_no_commas (parser
,
6391 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
6392 label
= do_case (loc1
, exp1
, exp2
, std_attrs
);
6395 c_parser_error (parser
, "expected %<:%> or %<...%>");
6397 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
6399 c_parser_consume_token (parser
);
6400 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
6401 label
= do_case (loc1
, NULL_TREE
, NULL_TREE
, std_attrs
);
6405 tree name
= c_parser_peek_token (parser
)->value
;
6408 location_t loc2
= c_parser_peek_token (parser
)->location
;
6409 gcc_assert (c_parser_next_token_is (parser
, CPP_NAME
));
6410 c_parser_consume_token (parser
);
6411 gcc_assert (c_parser_next_token_is (parser
, CPP_COLON
));
6412 c_parser_consume_token (parser
);
6413 attrs
= c_parser_gnu_attributes (parser
);
6414 tlab
= define_label (loc2
, name
);
6417 decl_attributes (&tlab
, attrs
, 0);
6418 decl_attributes (&tlab
, std_attrs
, 0);
6419 label
= add_stmt (build_stmt (loc1
, LABEL_EXPR
, tlab
));
6422 && c_parser_next_tokens_start_declaration (parser
))
6423 warning_at (loc2
, OPT_Wattributes
, "GNU-style attribute between"
6424 " label and declaration appertains to the label");
6428 if (TREE_CODE (label
) == LABEL_EXPR
)
6429 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label
)) = fallthrough_p
;
6431 FALLTHROUGH_LABEL_P (CASE_LABEL (label
)) = fallthrough_p
;
6435 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
6439 attribute-specifier-sequence[opt] compound-statement
6440 expression-statement
6441 attribute-specifier-sequence[opt] selection-statement
6442 attribute-specifier-sequence[opt] iteration-statement
6443 attribute-specifier-sequence[opt] jump-statement
6446 attribute-specifier-sequence[opt] label statement
6448 expression-statement:
6450 attribute-specifier-sequence expression ;
6452 selection-statement:
6456 iteration-statement:
6465 return expression[opt] ;
6470 attribute-specifier-sequence[opt] asm-statement
6475 expression-statement:
6481 attribute-specifier-sequence[opt] objc-throw-statement
6482 attribute-specifier-sequence[opt] objc-try-catch-statement
6483 attribute-specifier-sequence[opt] objc-synchronized-statement
6485 objc-throw-statement:
6492 attribute-specifier-sequence[opt] openacc-construct
6501 parallel-directive structured-block
6504 kernels-directive structured-block
6507 data-directive structured-block
6510 loop-directive structured-block
6515 attribute-specifier-sequence[opt] openmp-construct
6524 parallel-for-construct
6525 parallel-for-simd-construct
6526 parallel-sections-construct
6533 parallel-directive structured-block
6536 for-directive iteration-statement
6539 simd-directive iteration-statements
6542 for-simd-directive iteration-statements
6545 sections-directive section-scope
6548 single-directive structured-block
6550 parallel-for-construct:
6551 parallel-for-directive iteration-statement
6553 parallel-for-simd-construct:
6554 parallel-for-simd-directive iteration-statement
6556 parallel-sections-construct:
6557 parallel-sections-directive section-scope
6560 master-directive structured-block
6563 critical-directive structured-block
6566 atomic-directive expression-statement
6569 ordered-directive structured-block
6571 Transactional Memory:
6574 attribute-specifier-sequence[opt] transaction-statement
6575 attribute-specifier-sequence[opt] transaction-cancel-statement
6577 IF_P is used to track whether there's a (possibly labeled) if statement
6578 which is not enclosed in braces and has an else clause. This is used to
6579 implement -Wparentheses. */
6582 c_parser_statement (c_parser
*parser
, bool *if_p
, location_t
*loc_after_labels
)
6584 c_parser_all_labels (parser
);
6585 if (loc_after_labels
)
6586 *loc_after_labels
= c_parser_peek_token (parser
)->location
;
6587 c_parser_statement_after_labels (parser
, if_p
, NULL
);
6590 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6591 of if-else-if conditions. All labels and standard attributes have
6592 been parsed in the caller.
6594 IF_P is used to track whether there's a (possibly labeled) if statement
6595 which is not enclosed in braces and has an else clause. This is used to
6596 implement -Wparentheses. */
6599 c_parser_statement_after_labels (c_parser
*parser
, bool *if_p
,
6602 location_t loc
= c_parser_peek_token (parser
)->location
;
6603 tree stmt
= NULL_TREE
;
6604 bool in_if_block
= parser
->in_if_block
;
6605 parser
->in_if_block
= false;
6609 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_BRACE
)
6610 add_debug_begin_stmt (loc
);
6613 switch (c_parser_peek_token (parser
)->type
)
6615 case CPP_OPEN_BRACE
:
6616 add_stmt (c_parser_compound_statement (parser
));
6619 switch (c_parser_peek_token (parser
)->keyword
)
6622 c_parser_if_statement (parser
, if_p
, chain
);
6625 c_parser_switch_statement (parser
, if_p
);
6628 c_parser_while_statement (parser
, false, 0, if_p
);
6631 c_parser_do_statement (parser
, false, 0);
6634 c_parser_for_statement (parser
, false, 0, if_p
);
6637 c_parser_consume_token (parser
);
6638 if (c_parser_next_token_is (parser
, CPP_NAME
))
6640 stmt
= c_finish_goto_label (loc
,
6641 c_parser_peek_token (parser
)->value
);
6642 c_parser_consume_token (parser
);
6644 else if (c_parser_next_token_is (parser
, CPP_MULT
))
6648 c_parser_consume_token (parser
);
6649 val
= c_parser_expression (parser
);
6650 val
= convert_lvalue_to_rvalue (loc
, val
, false, true);
6651 stmt
= c_finish_goto_ptr (loc
, val
);
6654 c_parser_error (parser
, "expected identifier or %<*%>");
6655 goto expect_semicolon
;
6657 c_parser_consume_token (parser
);
6658 stmt
= c_finish_bc_stmt (loc
, objc_foreach_continue_label
, false);
6659 goto expect_semicolon
;
6661 c_parser_consume_token (parser
);
6662 stmt
= c_finish_bc_stmt (loc
, objc_foreach_break_label
, true);
6663 goto expect_semicolon
;
6665 c_parser_consume_token (parser
);
6666 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6668 stmt
= c_finish_return (loc
, NULL_TREE
, NULL_TREE
);
6669 c_parser_consume_token (parser
);
6673 location_t xloc
= c_parser_peek_token (parser
)->location
;
6674 struct c_expr expr
= c_parser_expression_conv (parser
);
6675 mark_exp_read (expr
.value
);
6676 stmt
= c_finish_return (EXPR_LOC_OR_LOC (expr
.value
, xloc
),
6677 expr
.value
, expr
.original_type
);
6678 goto expect_semicolon
;
6682 stmt
= c_parser_asm_statement (parser
);
6684 case RID_TRANSACTION_ATOMIC
:
6685 case RID_TRANSACTION_RELAXED
:
6686 stmt
= c_parser_transaction (parser
,
6687 c_parser_peek_token (parser
)->keyword
);
6689 case RID_TRANSACTION_CANCEL
:
6690 stmt
= c_parser_transaction_cancel (parser
);
6691 goto expect_semicolon
;
6693 gcc_assert (c_dialect_objc ());
6694 c_parser_consume_token (parser
);
6695 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6697 stmt
= objc_build_throw_stmt (loc
, NULL_TREE
);
6698 c_parser_consume_token (parser
);
6702 struct c_expr expr
= c_parser_expression (parser
);
6703 expr
= convert_lvalue_to_rvalue (loc
, expr
, false, false);
6704 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
6705 stmt
= objc_build_throw_stmt (loc
, expr
.value
);
6706 goto expect_semicolon
;
6710 gcc_assert (c_dialect_objc ());
6711 c_parser_objc_try_catch_finally_statement (parser
);
6713 case RID_AT_SYNCHRONIZED
:
6714 gcc_assert (c_dialect_objc ());
6715 c_parser_objc_synchronized_statement (parser
);
6719 /* Allow '__attribute__((fallthrough));' or
6720 '__attribute__((assume(cond)));'. */
6721 tree attrs
= c_parser_gnu_attributes (parser
);
6722 bool has_assume
= lookup_attribute ("assume", attrs
);
6725 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6726 attrs
= handle_assume_attribute (loc
, attrs
, true);
6729 warning_at (loc
, OPT_Wattributes
,
6730 "%<assume%> attribute not followed by %<;%>");
6734 if (attribute_fallthrough_p (attrs
))
6736 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6738 tree fn
= build_call_expr_internal_loc (loc
,
6743 c_parser_consume_token (parser
);
6746 warning_at (loc
, OPT_Wattributes
,
6747 "%<fallthrough%> attribute not followed "
6750 else if (has_assume
)
6752 c_parser_consume_token (parser
);
6753 else if (attrs
!= NULL_TREE
)
6754 warning_at (loc
, OPT_Wattributes
,
6755 "only attribute %<fallthrough%> or %<assume%> can "
6756 "be applied to a null statement");
6764 c_parser_consume_token (parser
);
6766 case CPP_CLOSE_PAREN
:
6767 case CPP_CLOSE_SQUARE
:
6768 /* Avoid infinite loop in error recovery:
6769 c_parser_skip_until_found stops at a closing nesting
6770 delimiter without consuming it, but here we need to consume
6771 it to proceed further. */
6772 c_parser_error (parser
, "expected statement");
6773 c_parser_consume_token (parser
);
6776 if (!c_parser_pragma (parser
, pragma_stmt
, if_p
))
6781 stmt
= c_finish_expr_stmt (loc
, c_parser_expression_conv (parser
).value
);
6783 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
6786 /* Two cases cannot and do not have line numbers associated: If stmt
6787 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6788 cannot hold line numbers. But that's OK because the statement
6789 will either be changed to a MODIFY_EXPR during gimplification of
6790 the statement expr, or discarded. If stmt was compound, but
6791 without new variables, we will have skipped the creation of a
6792 BIND and will have a bare STATEMENT_LIST. But that's OK because
6793 (recursively) all of the component statements should already have
6794 line numbers assigned. ??? Can we discard no-op statements
6796 if (EXPR_LOCATION (stmt
) == UNKNOWN_LOCATION
)
6797 protected_set_expr_location (stmt
, loc
);
6799 parser
->in_if_block
= in_if_block
;
6802 /* Parse the condition from an if, do, while or for statements. */
6805 c_parser_condition (c_parser
*parser
)
6807 location_t loc
= c_parser_peek_token (parser
)->location
;
6809 cond
= c_parser_expression_conv (parser
).value
;
6810 cond
= c_objc_common_truthvalue_conversion (loc
, cond
);
6811 cond
= c_fully_fold (cond
, false, NULL
);
6812 if (warn_sequence_point
)
6813 verify_sequence_points (cond
);
6817 /* Parse a parenthesized condition from an if, do or while statement.
6823 c_parser_paren_condition (c_parser
*parser
)
6826 matching_parens parens
;
6827 if (!parens
.require_open (parser
))
6828 return error_mark_node
;
6829 cond
= c_parser_condition (parser
);
6830 parens
.skip_until_found_close (parser
);
6834 /* Parse a statement which is a block in C99.
6836 IF_P is used to track whether there's a (possibly labeled) if statement
6837 which is not enclosed in braces and has an else clause. This is used to
6838 implement -Wparentheses. */
6841 c_parser_c99_block_statement (c_parser
*parser
, bool *if_p
,
6842 location_t
*loc_after_labels
)
6844 tree block
= c_begin_compound_stmt (flag_isoc99
);
6845 location_t loc
= c_parser_peek_token (parser
)->location
;
6846 c_parser_statement (parser
, if_p
, loc_after_labels
);
6847 return c_end_compound_stmt (loc
, block
, flag_isoc99
);
6850 /* Parse the body of an if statement. This is just parsing a
6851 statement but (a) it is a block in C99, (b) we track whether the
6852 body is an if statement for the sake of -Wparentheses warnings, (c)
6853 we handle an empty body specially for the sake of -Wempty-body
6854 warnings, and (d) we call parser_compound_statement directly
6855 because c_parser_statement_after_labels resets
6856 parser->in_if_block.
6858 IF_P is used to track whether there's a (possibly labeled) if statement
6859 which is not enclosed in braces and has an else clause. This is used to
6860 implement -Wparentheses. */
6863 c_parser_if_body (c_parser
*parser
, bool *if_p
,
6864 const token_indent_info
&if_tinfo
)
6866 tree block
= c_begin_compound_stmt (flag_isoc99
);
6867 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6868 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6869 token_indent_info body_tinfo
6870 = get_token_indent_info (c_parser_peek_token (parser
));
6872 c_parser_all_labels (parser
);
6873 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6875 location_t loc
= c_parser_peek_token (parser
)->location
;
6876 add_stmt (build_empty_stmt (loc
));
6877 c_parser_consume_token (parser
);
6878 if (!c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6879 warning_at (loc
, OPT_Wempty_body
,
6880 "suggest braces around empty body in an %<if%> statement");
6882 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6883 add_stmt (c_parser_compound_statement (parser
));
6886 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6887 c_parser_statement_after_labels (parser
, if_p
);
6890 token_indent_info next_tinfo
6891 = get_token_indent_info (c_parser_peek_token (parser
));
6892 warn_for_misleading_indentation (if_tinfo
, body_tinfo
, next_tinfo
);
6893 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6894 && next_tinfo
.type
!= CPP_SEMICOLON
)
6895 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6896 if_tinfo
.location
, RID_IF
);
6898 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6901 /* Parse the else body of an if statement. This is just parsing a
6902 statement but (a) it is a block in C99, (b) we handle an empty body
6903 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6904 of if-else-if conditions. */
6907 c_parser_else_body (c_parser
*parser
, const token_indent_info
&else_tinfo
,
6910 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6911 tree block
= c_begin_compound_stmt (flag_isoc99
);
6912 token_indent_info body_tinfo
6913 = get_token_indent_info (c_parser_peek_token (parser
));
6914 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6916 c_parser_all_labels (parser
);
6917 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6919 location_t loc
= c_parser_peek_token (parser
)->location
;
6922 "suggest braces around empty body in an %<else%> statement");
6923 add_stmt (build_empty_stmt (loc
));
6924 c_parser_consume_token (parser
);
6928 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6929 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6930 c_parser_statement_after_labels (parser
, NULL
, chain
);
6933 token_indent_info next_tinfo
6934 = get_token_indent_info (c_parser_peek_token (parser
));
6935 warn_for_misleading_indentation (else_tinfo
, body_tinfo
, next_tinfo
);
6936 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6937 && next_tinfo
.type
!= CPP_SEMICOLON
)
6938 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6939 else_tinfo
.location
, RID_ELSE
);
6941 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6944 /* We might need to reclassify any previously-lexed identifier, e.g.
6945 when we've left a for loop with an if-statement without else in the
6946 body - we might have used a wrong scope for the token. See PR67784. */
6949 c_parser_maybe_reclassify_token (c_parser
*parser
)
6951 if (c_parser_next_token_is (parser
, CPP_NAME
))
6953 c_token
*token
= c_parser_peek_token (parser
);
6955 if (token
->id_kind
!= C_ID_CLASSNAME
)
6957 tree decl
= lookup_name (token
->value
);
6959 token
->id_kind
= C_ID_ID
;
6962 if (TREE_CODE (decl
) == TYPE_DECL
)
6963 token
->id_kind
= C_ID_TYPENAME
;
6965 else if (c_dialect_objc ())
6967 tree objc_interface_decl
= objc_is_class_name (token
->value
);
6968 /* Objective-C class names are in the same namespace as
6969 variables and typedefs, and hence are shadowed by local
6971 if (objc_interface_decl
)
6973 token
->value
= objc_interface_decl
;
6974 token
->id_kind
= C_ID_CLASSNAME
;
6981 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6984 if ( expression ) statement
6985 if ( expression ) statement else statement
6987 CHAIN is a vector of if-else-if conditions.
6988 IF_P is used to track whether there's a (possibly labeled) if statement
6989 which is not enclosed in braces and has an else clause. This is used to
6990 implement -Wparentheses. */
6993 c_parser_if_statement (c_parser
*parser
, bool *if_p
, vec
<tree
> *chain
)
6998 bool nested_if
= false;
6999 tree first_body
, second_body
;
7002 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_IF
));
7003 token_indent_info if_tinfo
7004 = get_token_indent_info (c_parser_peek_token (parser
));
7005 c_parser_consume_token (parser
);
7006 block
= c_begin_compound_stmt (flag_isoc99
);
7007 loc
= c_parser_peek_token (parser
)->location
;
7008 cond
= c_parser_paren_condition (parser
);
7009 in_if_block
= parser
->in_if_block
;
7010 parser
->in_if_block
= true;
7011 first_body
= c_parser_if_body (parser
, &nested_if
, if_tinfo
);
7012 parser
->in_if_block
= in_if_block
;
7014 if (warn_duplicated_cond
)
7015 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond
), cond
, &chain
);
7017 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
7019 token_indent_info else_tinfo
7020 = get_token_indent_info (c_parser_peek_token (parser
));
7021 c_parser_consume_token (parser
);
7022 if (warn_duplicated_cond
)
7024 if (c_parser_next_token_is_keyword (parser
, RID_IF
)
7027 /* We've got "if (COND) else if (COND2)". Start the
7028 condition chain and add COND as the first element. */
7029 chain
= new vec
<tree
> ();
7030 if (!CONSTANT_CLASS_P (cond
) && !TREE_SIDE_EFFECTS (cond
))
7031 chain
->safe_push (cond
);
7033 else if (!c_parser_next_token_is_keyword (parser
, RID_IF
))
7034 /* This is if-else without subsequent if. Zap the condition
7035 chain; we would have already warned at this point. */
7038 second_body
= c_parser_else_body (parser
, else_tinfo
, chain
);
7039 /* Set IF_P to true to indicate that this if statement has an
7040 else clause. This may trigger the Wparentheses warning
7041 below when we get back up to the parent if statement. */
7047 second_body
= NULL_TREE
;
7049 /* Diagnose an ambiguous else if if-then-else is nested inside
7052 warning_at (loc
, OPT_Wdangling_else
,
7053 "suggest explicit braces to avoid ambiguous %<else%>");
7055 if (warn_duplicated_cond
)
7056 /* This if statement does not have an else clause. We don't
7057 need the condition chain anymore. */
7060 c_finish_if_stmt (loc
, cond
, first_body
, second_body
);
7061 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
7063 c_parser_maybe_reclassify_token (parser
);
7066 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
7069 switch (expression) statement
7073 c_parser_switch_statement (c_parser
*parser
, bool *if_p
)
7076 tree block
, expr
, body
;
7077 unsigned char save_in_statement
;
7078 location_t switch_loc
= c_parser_peek_token (parser
)->location
;
7079 location_t switch_cond_loc
;
7080 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SWITCH
));
7081 c_parser_consume_token (parser
);
7082 block
= c_begin_compound_stmt (flag_isoc99
);
7083 bool explicit_cast_p
= false;
7084 matching_parens parens
;
7085 if (parens
.require_open (parser
))
7087 switch_cond_loc
= c_parser_peek_token (parser
)->location
;
7088 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
7089 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
7090 explicit_cast_p
= true;
7091 ce
= c_parser_expression (parser
);
7092 ce
= convert_lvalue_to_rvalue (switch_cond_loc
, ce
, true, true);
7094 /* ??? expr has no valid location? */
7095 parens
.skip_until_found_close (parser
);
7099 switch_cond_loc
= UNKNOWN_LOCATION
;
7100 expr
= error_mark_node
;
7101 ce
.original_type
= error_mark_node
;
7103 c_start_switch (switch_loc
, switch_cond_loc
, expr
, explicit_cast_p
);
7104 save_in_statement
= in_statement
;
7105 in_statement
|= IN_SWITCH_STMT
;
7106 location_t loc_after_labels
;
7107 bool open_brace_p
= c_parser_peek_token (parser
)->type
== CPP_OPEN_BRACE
;
7108 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
7109 location_t next_loc
= c_parser_peek_token (parser
)->location
;
7110 if (!open_brace_p
&& c_parser_peek_token (parser
)->type
!= CPP_SEMICOLON
)
7111 warn_for_multistatement_macros (loc_after_labels
, next_loc
, switch_loc
,
7113 c_finish_switch (body
, ce
.original_type
);
7114 in_statement
= save_in_statement
;
7115 add_stmt (c_end_compound_stmt (switch_loc
, block
, flag_isoc99
));
7116 c_parser_maybe_reclassify_token (parser
);
7119 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
7122 while (expression) statement
7124 IF_P is used to track whether there's a (possibly labeled) if statement
7125 which is not enclosed in braces and has an else clause. This is used to
7126 implement -Wparentheses. */
7129 c_parser_while_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
7132 tree block
, cond
, body
;
7133 unsigned char save_in_statement
;
7135 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_WHILE
));
7136 token_indent_info while_tinfo
7137 = get_token_indent_info (c_parser_peek_token (parser
));
7138 c_parser_consume_token (parser
);
7139 block
= c_begin_compound_stmt (flag_isoc99
);
7140 loc
= c_parser_peek_token (parser
)->location
;
7141 cond
= c_parser_paren_condition (parser
);
7142 if (ivdep
&& cond
!= error_mark_node
)
7143 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
7144 build_int_cst (integer_type_node
,
7145 annot_expr_ivdep_kind
),
7147 if (unroll
&& cond
!= error_mark_node
)
7148 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
7149 build_int_cst (integer_type_node
,
7150 annot_expr_unroll_kind
),
7151 build_int_cst (integer_type_node
, unroll
));
7152 save_in_statement
= in_statement
;
7153 in_statement
= IN_ITERATION_STMT
;
7155 token_indent_info body_tinfo
7156 = get_token_indent_info (c_parser_peek_token (parser
));
7158 location_t loc_after_labels
;
7159 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
7160 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
7161 add_stmt (build_stmt (loc
, WHILE_STMT
, cond
, body
));
7162 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
7163 c_parser_maybe_reclassify_token (parser
);
7165 token_indent_info next_tinfo
7166 = get_token_indent_info (c_parser_peek_token (parser
));
7167 warn_for_misleading_indentation (while_tinfo
, body_tinfo
, next_tinfo
);
7169 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
7170 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
7171 while_tinfo
.location
, RID_WHILE
);
7173 in_statement
= save_in_statement
;
7176 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
7179 do statement while ( expression ) ;
7183 c_parser_do_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
)
7185 tree block
, cond
, body
;
7186 unsigned char save_in_statement
;
7188 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_DO
));
7189 c_parser_consume_token (parser
);
7190 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7191 warning_at (c_parser_peek_token (parser
)->location
,
7193 "suggest braces around empty body in %<do%> statement");
7194 block
= c_begin_compound_stmt (flag_isoc99
);
7195 loc
= c_parser_peek_token (parser
)->location
;
7196 save_in_statement
= in_statement
;
7197 in_statement
= IN_ITERATION_STMT
;
7198 body
= c_parser_c99_block_statement (parser
, NULL
);
7199 c_parser_require_keyword (parser
, RID_WHILE
, "expected %<while%>");
7200 in_statement
= save_in_statement
;
7201 cond
= c_parser_paren_condition (parser
);
7202 if (ivdep
&& cond
!= error_mark_node
)
7203 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
7204 build_int_cst (integer_type_node
,
7205 annot_expr_ivdep_kind
),
7207 if (unroll
&& cond
!= error_mark_node
)
7208 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
7209 build_int_cst (integer_type_node
,
7210 annot_expr_unroll_kind
),
7211 build_int_cst (integer_type_node
, unroll
));
7212 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
7213 c_parser_skip_to_end_of_block_or_statement (parser
);
7215 add_stmt (build_stmt (loc
, DO_STMT
, cond
, body
));
7216 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
7219 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
7222 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
7223 for ( nested-declaration expression[opt] ; expression[opt] ) statement
7225 The form with a declaration is new in C99.
7227 ??? In accordance with the old parser, the declaration may be a
7228 nested function, which is then rejected in check_for_loop_decls,
7229 but does it make any sense for this to be included in the grammar?
7230 Note in particular that the nested function does not include a
7231 trailing ';', whereas the "declaration" production includes one.
7232 Also, can we reject bad declarations earlier and cheaper than
7233 check_for_loop_decls?
7235 In Objective-C, there are two additional variants:
7238 for ( expression in expresssion ) statement
7239 for ( declaration in expression ) statement
7241 This is inconsistent with C, because the second variant is allowed
7242 even if c99 is not enabled.
7244 The rest of the comment documents these Objective-C foreach-statement.
7246 Here is the canonical example of the first variant:
7247 for (object in array) { do something with object }
7248 we call the first expression ("object") the "object_expression" and
7249 the second expression ("array") the "collection_expression".
7250 object_expression must be an lvalue of type "id" (a generic Objective-C
7251 object) because the loop works by assigning to object_expression the
7252 various objects from the collection_expression. collection_expression
7253 must evaluate to something of type "id" which responds to the method
7254 countByEnumeratingWithState:objects:count:.
7256 The canonical example of the second variant is:
7257 for (id object in array) { do something with object }
7258 which is completely equivalent to
7261 for (object in array) { do something with object }
7263 Note that initizializing 'object' in some way (eg, "for ((object =
7264 xxx) in array) { do something with object }") is possibly
7265 technically valid, but completely pointless as 'object' will be
7266 assigned to something else as soon as the loop starts. We should
7267 most likely reject it (TODO).
7269 The beginning of the Objective-C foreach-statement looks exactly
7270 like the beginning of the for-statement, and we can tell it is a
7271 foreach-statement only because the initial declaration or
7272 expression is terminated by 'in' instead of ';'.
7274 IF_P is used to track whether there's a (possibly labeled) if statement
7275 which is not enclosed in braces and has an else clause. This is used to
7276 implement -Wparentheses. */
7279 c_parser_for_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
7282 tree block
, cond
, incr
, body
;
7283 unsigned char save_in_statement
;
7284 tree save_objc_foreach_break_label
, save_objc_foreach_continue_label
;
7285 /* The following are only used when parsing an ObjC foreach statement. */
7286 tree object_expression
;
7287 /* Silence the bogus uninitialized warning. */
7288 tree collection_expression
= NULL
;
7289 location_t loc
= c_parser_peek_token (parser
)->location
;
7290 location_t for_loc
= loc
;
7291 bool is_foreach_statement
= false;
7292 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
7293 token_indent_info for_tinfo
7294 = get_token_indent_info (c_parser_peek_token (parser
));
7295 c_parser_consume_token (parser
);
7296 /* Open a compound statement in Objective-C as well, just in case this is
7297 as foreach expression. */
7298 block
= c_begin_compound_stmt (flag_isoc99
|| c_dialect_objc ());
7299 cond
= error_mark_node
;
7300 incr
= error_mark_node
;
7301 matching_parens parens
;
7302 if (parens
.require_open (parser
))
7304 /* Parse the initialization declaration or expression. */
7305 object_expression
= error_mark_node
;
7306 parser
->objc_could_be_foreach_context
= c_dialect_objc ();
7307 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7309 parser
->objc_could_be_foreach_context
= false;
7310 c_parser_consume_token (parser
);
7311 c_finish_expr_stmt (loc
, NULL_TREE
);
7313 else if (c_parser_next_tokens_start_declaration (parser
)
7314 || c_parser_nth_token_starts_std_attributes (parser
, 1))
7316 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
7317 &object_expression
);
7318 parser
->objc_could_be_foreach_context
= false;
7320 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
7322 c_parser_consume_token (parser
);
7323 is_foreach_statement
= true;
7324 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
7325 c_parser_error (parser
, "multiple iterating variables in "
7326 "fast enumeration");
7329 check_for_loop_decls (for_loc
, flag_isoc99
);
7331 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
7333 /* __extension__ can start a declaration, but is also an
7334 unary operator that can start an expression. Consume all
7335 but the last of a possible series of __extension__ to
7337 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
7338 && (c_parser_peek_2nd_token (parser
)->keyword
7340 c_parser_consume_token (parser
);
7341 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
7342 || c_parser_nth_token_starts_std_attributes (parser
, 2))
7345 ext
= disable_extension_diagnostics ();
7346 c_parser_consume_token (parser
);
7347 c_parser_declaration_or_fndef (parser
, true, true, true, true,
7348 true, &object_expression
);
7349 parser
->objc_could_be_foreach_context
= false;
7351 restore_extension_diagnostics (ext
);
7352 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
7354 c_parser_consume_token (parser
);
7355 is_foreach_statement
= true;
7356 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
7357 c_parser_error (parser
, "multiple iterating variables in "
7358 "fast enumeration");
7361 check_for_loop_decls (for_loc
, flag_isoc99
);
7371 tree init_expression
;
7372 ce
= c_parser_expression (parser
);
7373 init_expression
= ce
.value
;
7374 parser
->objc_could_be_foreach_context
= false;
7375 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
7377 c_parser_consume_token (parser
);
7378 is_foreach_statement
= true;
7379 if (! lvalue_p (init_expression
))
7380 c_parser_error (parser
, "invalid iterating variable in "
7381 "fast enumeration");
7383 = c_fully_fold (init_expression
, false, NULL
);
7387 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
7388 init_expression
= ce
.value
;
7389 c_finish_expr_stmt (loc
, init_expression
);
7390 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
7395 /* Parse the loop condition. In the case of a foreach
7396 statement, there is no loop condition. */
7397 gcc_assert (!parser
->objc_could_be_foreach_context
);
7398 if (!is_foreach_statement
)
7400 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7404 c_parser_error (parser
, "missing loop condition in loop "
7405 "with %<GCC ivdep%> pragma");
7406 cond
= error_mark_node
;
7410 c_parser_error (parser
, "missing loop condition in loop "
7411 "with %<GCC unroll%> pragma");
7412 cond
= error_mark_node
;
7416 c_parser_consume_token (parser
);
7422 cond
= c_parser_condition (parser
);
7423 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
7426 if (ivdep
&& cond
!= error_mark_node
)
7427 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
7428 build_int_cst (integer_type_node
,
7429 annot_expr_ivdep_kind
),
7431 if (unroll
&& cond
!= error_mark_node
)
7432 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
7433 build_int_cst (integer_type_node
,
7434 annot_expr_unroll_kind
),
7435 build_int_cst (integer_type_node
, unroll
));
7437 /* Parse the increment expression (the third expression in a
7438 for-statement). In the case of a foreach-statement, this is
7439 the expression that follows the 'in'. */
7440 loc
= c_parser_peek_token (parser
)->location
;
7441 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7443 if (is_foreach_statement
)
7445 c_parser_error (parser
,
7446 "missing collection in fast enumeration");
7447 collection_expression
= error_mark_node
;
7450 incr
= c_process_expr_stmt (loc
, NULL_TREE
);
7454 if (is_foreach_statement
)
7455 collection_expression
7456 = c_fully_fold (c_parser_expression (parser
).value
, false, NULL
);
7459 struct c_expr ce
= c_parser_expression (parser
);
7460 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
7461 incr
= c_process_expr_stmt (loc
, ce
.value
);
7464 parens
.skip_until_found_close (parser
);
7466 save_in_statement
= in_statement
;
7467 if (is_foreach_statement
)
7469 in_statement
= IN_OBJC_FOREACH
;
7470 save_objc_foreach_break_label
= objc_foreach_break_label
;
7471 save_objc_foreach_continue_label
= objc_foreach_continue_label
;
7472 objc_foreach_break_label
= create_artificial_label (loc
);
7473 objc_foreach_continue_label
= create_artificial_label (loc
);
7476 in_statement
= IN_ITERATION_STMT
;
7478 token_indent_info body_tinfo
7479 = get_token_indent_info (c_parser_peek_token (parser
));
7481 location_t loc_after_labels
;
7482 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
7483 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
7485 if (is_foreach_statement
)
7486 objc_finish_foreach_loop (for_loc
, object_expression
,
7487 collection_expression
, body
,
7488 objc_foreach_break_label
,
7489 objc_foreach_continue_label
);
7491 add_stmt (build_stmt (for_loc
, FOR_STMT
, NULL_TREE
, cond
, incr
,
7493 add_stmt (c_end_compound_stmt (for_loc
, block
,
7494 flag_isoc99
|| c_dialect_objc ()));
7495 c_parser_maybe_reclassify_token (parser
);
7497 token_indent_info next_tinfo
7498 = get_token_indent_info (c_parser_peek_token (parser
));
7499 warn_for_misleading_indentation (for_tinfo
, body_tinfo
, next_tinfo
);
7501 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
7502 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
7503 for_tinfo
.location
, RID_FOR
);
7505 in_statement
= save_in_statement
;
7506 if (is_foreach_statement
)
7508 objc_foreach_break_label
= save_objc_foreach_break_label
;
7509 objc_foreach_continue_label
= save_objc_foreach_continue_label
;
7513 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7514 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7523 asm-qualifier-list asm-qualifier
7527 asm asm-qualifier-list[opt] ( asm-argument ) ;
7531 asm-string-literal : asm-operands[opt]
7532 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7533 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7535 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7538 The form with asm-goto-operands is valid if and only if the
7539 asm-qualifier-list contains goto, and is the only allowed form in that case.
7540 Duplicate asm-qualifiers are not allowed.
7542 The :: token is considered equivalent to two consecutive : tokens. */
7545 c_parser_asm_statement (c_parser
*parser
)
7547 tree str
, outputs
, inputs
, clobbers
, labels
, ret
;
7549 location_t asm_loc
= c_parser_peek_token (parser
)->location
;
7550 int section
, nsections
;
7552 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
7553 c_parser_consume_token (parser
);
7555 /* Handle the asm-qualifier-list. */
7556 location_t volatile_loc
= UNKNOWN_LOCATION
;
7557 location_t inline_loc
= UNKNOWN_LOCATION
;
7558 location_t goto_loc
= UNKNOWN_LOCATION
;
7561 c_token
*token
= c_parser_peek_token (parser
);
7562 location_t loc
= token
->location
;
7563 switch (token
->keyword
)
7568 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7569 inform (volatile_loc
, "first seen here");
7573 c_parser_consume_token (parser
);
7579 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7580 inform (inline_loc
, "first seen here");
7584 c_parser_consume_token (parser
);
7590 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7591 inform (goto_loc
, "first seen here");
7595 c_parser_consume_token (parser
);
7600 error_at (loc
, "%qE is not a valid %<asm%> qualifier", token
->value
);
7601 c_parser_consume_token (parser
);
7610 bool is_volatile
= (volatile_loc
!= UNKNOWN_LOCATION
);
7611 bool is_inline
= (inline_loc
!= UNKNOWN_LOCATION
);
7612 bool is_goto
= (goto_loc
!= UNKNOWN_LOCATION
);
7616 matching_parens parens
;
7617 if (!parens
.require_open (parser
))
7620 str
= c_parser_asm_string_literal (parser
);
7621 if (str
== NULL_TREE
)
7622 goto error_close_paren
;
7625 outputs
= NULL_TREE
;
7627 clobbers
= NULL_TREE
;
7630 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7633 /* Parse each colon-delimited section of operands. */
7634 nsections
= 3 + is_goto
;
7635 for (section
= 0; section
< nsections
; ++section
)
7637 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
7640 if (section
== nsections
)
7642 c_parser_error (parser
, "expected %<)%>");
7643 goto error_close_paren
;
7645 c_parser_consume_token (parser
);
7647 else if (!c_parser_require (parser
, CPP_COLON
,
7649 ? G_("expected %<:%>")
7650 : G_("expected %<:%> or %<)%>"),
7651 UNKNOWN_LOCATION
, is_goto
))
7652 goto error_close_paren
;
7654 /* Once past any colon, we're no longer a simple asm. */
7657 if ((!c_parser_next_token_is (parser
, CPP_COLON
)
7658 && !c_parser_next_token_is (parser
, CPP_SCOPE
)
7659 && !c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7664 outputs
= c_parser_asm_operands (parser
);
7667 inputs
= c_parser_asm_operands (parser
);
7670 clobbers
= c_parser_asm_clobbers (parser
);
7673 labels
= c_parser_asm_goto_operands (parser
);
7679 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7684 if (!parens
.require_close (parser
))
7686 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7690 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
7691 c_parser_skip_to_end_of_block_or_statement (parser
);
7693 ret
= build_asm_stmt (is_volatile
,
7694 build_asm_expr (asm_loc
, str
, outputs
, inputs
,
7695 clobbers
, labels
, simple
, is_inline
));
7701 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7705 /* Parse asm operands, a GNU extension.
7709 asm-operands , asm-operand
7712 asm-string-literal ( expression )
7713 [ identifier ] asm-string-literal ( expression )
7717 c_parser_asm_operands (c_parser
*parser
)
7719 tree list
= NULL_TREE
;
7724 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
7726 c_parser_consume_token (parser
);
7727 if (c_parser_next_token_is (parser
, CPP_NAME
))
7729 tree id
= c_parser_peek_token (parser
)->value
;
7730 c_parser_consume_token (parser
);
7731 name
= build_string (IDENTIFIER_LENGTH (id
),
7732 IDENTIFIER_POINTER (id
));
7736 c_parser_error (parser
, "expected identifier");
7737 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
7740 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
7745 str
= c_parser_asm_string_literal (parser
);
7746 if (str
== NULL_TREE
)
7748 matching_parens parens
;
7749 if (!parens
.require_open (parser
))
7751 expr
= c_parser_expression (parser
);
7752 mark_exp_read (expr
.value
);
7753 if (!parens
.require_close (parser
))
7755 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7758 list
= chainon (list
, build_tree_list (build_tree_list (name
, str
),
7760 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7761 c_parser_consume_token (parser
);
7768 /* Parse asm clobbers, a GNU extension.
7772 asm-clobbers , asm-string-literal
7776 c_parser_asm_clobbers (c_parser
*parser
)
7778 tree list
= NULL_TREE
;
7781 tree str
= c_parser_asm_string_literal (parser
);
7783 list
= tree_cons (NULL_TREE
, str
, list
);
7786 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7787 c_parser_consume_token (parser
);
7794 /* Parse asm goto labels, a GNU extension.
7798 asm-goto-operands , identifier
7802 c_parser_asm_goto_operands (c_parser
*parser
)
7804 tree list
= NULL_TREE
;
7809 if (c_parser_next_token_is (parser
, CPP_NAME
))
7811 c_token
*tok
= c_parser_peek_token (parser
);
7813 label
= lookup_label_for_goto (tok
->location
, name
);
7814 c_parser_consume_token (parser
);
7815 TREE_USED (label
) = 1;
7819 c_parser_error (parser
, "expected identifier");
7823 name
= build_string (IDENTIFIER_LENGTH (name
),
7824 IDENTIFIER_POINTER (name
));
7825 list
= tree_cons (name
, label
, list
);
7826 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7827 c_parser_consume_token (parser
);
7829 return nreverse (list
);
7833 /* Parse a possibly concatenated sequence of string literals.
7834 TRANSLATE says whether to translate them to the execution character
7835 set; WIDE_OK says whether any kind of prefixed string literal is
7836 permitted in this context. This code is based on that in
7840 c_parser_string_literal (c_parser
*parser
, bool translate
, bool wide_ok
)
7844 struct obstack str_ob
;
7845 struct obstack loc_ob
;
7846 cpp_string str
, istr
, *strs
;
7848 location_t loc
, last_tok_loc
;
7849 enum cpp_ttype type
;
7850 tree value
, string_tree
;
7852 tok
= c_parser_peek_token (parser
);
7853 loc
= tok
->location
;
7854 last_tok_loc
= linemap_resolve_location (line_table
, loc
,
7855 LRK_MACRO_DEFINITION_LOCATION
,
7864 case CPP_UTF8STRING
:
7865 string_tree
= tok
->value
;
7869 c_parser_error (parser
, "expected string literal");
7871 ret
.value
= NULL_TREE
;
7872 ret
.original_code
= ERROR_MARK
;
7873 ret
.original_type
= NULL_TREE
;
7877 /* Try to avoid the overhead of creating and destroying an obstack
7878 for the common case of just one string. */
7879 switch (c_parser_peek_2nd_token (parser
)->type
)
7882 c_parser_consume_token (parser
);
7883 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7884 str
.len
= TREE_STRING_LENGTH (string_tree
);
7893 case CPP_UTF8STRING
:
7894 gcc_obstack_init (&str_ob
);
7895 gcc_obstack_init (&loc_ob
);
7899 c_parser_consume_token (parser
);
7901 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7902 str
.len
= TREE_STRING_LENGTH (string_tree
);
7903 if (type
!= tok
->type
)
7905 if (type
== CPP_STRING
)
7907 else if (tok
->type
!= CPP_STRING
)
7908 error ("unsupported non-standard concatenation "
7909 "of string literals");
7911 obstack_grow (&str_ob
, &str
, sizeof (cpp_string
));
7912 obstack_grow (&loc_ob
, &last_tok_loc
, sizeof (location_t
));
7913 tok
= c_parser_peek_token (parser
);
7914 string_tree
= tok
->value
;
7916 = linemap_resolve_location (line_table
, tok
->location
,
7917 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
7919 while (tok
->type
== CPP_STRING
7920 || tok
->type
== CPP_WSTRING
7921 || tok
->type
== CPP_STRING16
7922 || tok
->type
== CPP_STRING32
7923 || tok
->type
== CPP_UTF8STRING
);
7924 strs
= (cpp_string
*) obstack_finish (&str_ob
);
7927 if (count
> 1 && !in_system_header_at (input_location
))
7928 warning (OPT_Wtraditional
,
7929 "traditional C rejects string constant concatenation");
7931 if ((type
== CPP_STRING
|| wide_ok
)
7933 ? cpp_interpret_string
: cpp_interpret_string_notranslate
)
7934 (parse_in
, strs
, count
, &istr
, type
)))
7936 value
= build_string (istr
.len
, (const char *) istr
.text
);
7937 free (CONST_CAST (unsigned char *, istr
.text
));
7940 location_t
*locs
= (location_t
*) obstack_finish (&loc_ob
);
7941 gcc_assert (g_string_concat_db
);
7942 g_string_concat_db
->record_string_concatenation (count
, locs
);
7947 if (type
!= CPP_STRING
&& !wide_ok
)
7949 error_at (loc
, "a wide string is invalid in this context");
7952 /* Callers cannot generally handle error_mark_node in this
7953 context, so return the empty string instead. An error has
7954 been issued, either above or from cpp_interpret_string. */
7959 case CPP_UTF8STRING
:
7960 if (type
== CPP_UTF8STRING
&& flag_char8_t
)
7962 value
= build_string (TYPE_PRECISION (char8_type_node
)
7963 / TYPE_PRECISION (char_type_node
),
7964 ""); /* char8_t is 8 bits */
7967 value
= build_string (1, "");
7970 value
= build_string (TYPE_PRECISION (char16_type_node
)
7971 / TYPE_PRECISION (char_type_node
),
7972 "\0"); /* char16_t is 16 bits */
7975 value
= build_string (TYPE_PRECISION (char32_type_node
)
7976 / TYPE_PRECISION (char_type_node
),
7977 "\0\0\0"); /* char32_t is 32 bits */
7980 value
= build_string (TYPE_PRECISION (wchar_type_node
)
7981 / TYPE_PRECISION (char_type_node
),
7982 "\0\0\0"); /* widest supported wchar_t
7992 TREE_TYPE (value
) = char_array_type_node
;
7994 case CPP_UTF8STRING
:
7996 TREE_TYPE (value
) = char8_array_type_node
;
7998 TREE_TYPE (value
) = char_array_type_node
;
8001 TREE_TYPE (value
) = char16_array_type_node
;
8004 TREE_TYPE (value
) = char32_array_type_node
;
8007 TREE_TYPE (value
) = wchar_array_type_node
;
8009 value
= fix_string_type (value
);
8013 obstack_free (&str_ob
, 0);
8014 obstack_free (&loc_ob
, 0);
8018 ret
.original_code
= STRING_CST
;
8019 ret
.original_type
= NULL_TREE
;
8020 set_c_expr_source_range (&ret
, get_range_from_loc (line_table
, loc
));
8022 parser
->seen_string_literal
= true;
8026 /* Parse an expression other than a compound expression; that is, an
8027 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
8028 AFTER is not NULL then it is an Objective-C message expression which
8029 is the primary-expression starting the expression as an initializer.
8031 assignment-expression:
8032 conditional-expression
8033 unary-expression assignment-operator assignment-expression
8035 assignment-operator: one of
8036 = *= /= %= += -= <<= >>= &= ^= |=
8038 In GNU C we accept any conditional expression on the LHS and
8039 diagnose the invalid lvalue rather than producing a syntax
8042 static struct c_expr
8043 c_parser_expr_no_commas (c_parser
*parser
, struct c_expr
*after
,
8044 tree omp_atomic_lhs
)
8046 struct c_expr lhs
, rhs
, ret
;
8047 enum tree_code code
;
8048 location_t op_location
, exp_location
;
8049 bool save_in_omp_for
= c_in_omp_for
;
8050 c_in_omp_for
= false;
8051 gcc_assert (!after
|| c_dialect_objc ());
8052 lhs
= c_parser_conditional_expression (parser
, after
, omp_atomic_lhs
);
8053 op_location
= c_parser_peek_token (parser
)->location
;
8054 switch (c_parser_peek_token (parser
)->type
)
8063 code
= TRUNC_DIV_EXPR
;
8066 code
= TRUNC_MOD_EXPR
;
8081 code
= BIT_AND_EXPR
;
8084 code
= BIT_XOR_EXPR
;
8087 code
= BIT_IOR_EXPR
;
8090 c_in_omp_for
= save_in_omp_for
;
8093 c_parser_consume_token (parser
);
8094 exp_location
= c_parser_peek_token (parser
)->location
;
8095 rhs
= c_parser_expr_no_commas (parser
, NULL
);
8096 rhs
= convert_lvalue_to_rvalue (exp_location
, rhs
, true, true);
8098 ret
.value
= build_modify_expr (op_location
, lhs
.value
, lhs
.original_type
,
8099 code
, exp_location
, rhs
.value
,
8102 set_c_expr_source_range (&ret
, lhs
.get_start (), rhs
.get_finish ());
8103 if (code
== NOP_EXPR
)
8104 ret
.original_code
= MODIFY_EXPR
;
8107 suppress_warning (ret
.value
, OPT_Wparentheses
);
8108 ret
.original_code
= ERROR_MARK
;
8110 ret
.original_type
= NULL
;
8111 c_in_omp_for
= save_in_omp_for
;
8115 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
8116 AFTER is not NULL then it is an Objective-C message expression which is
8117 the primary-expression starting the expression as an initializer.
8119 conditional-expression:
8120 logical-OR-expression
8121 logical-OR-expression ? expression : conditional-expression
8125 conditional-expression:
8126 logical-OR-expression ? : conditional-expression
8129 static struct c_expr
8130 c_parser_conditional_expression (c_parser
*parser
, struct c_expr
*after
,
8131 tree omp_atomic_lhs
)
8133 struct c_expr cond
, exp1
, exp2
, ret
;
8134 location_t start
, cond_loc
, colon_loc
;
8136 gcc_assert (!after
|| c_dialect_objc ());
8138 cond
= c_parser_binary_expression (parser
, after
, omp_atomic_lhs
);
8140 if (c_parser_next_token_is_not (parser
, CPP_QUERY
))
8142 if (cond
.value
!= error_mark_node
)
8143 start
= cond
.get_start ();
8145 start
= UNKNOWN_LOCATION
;
8146 cond_loc
= c_parser_peek_token (parser
)->location
;
8147 cond
= convert_lvalue_to_rvalue (cond_loc
, cond
, true, true);
8148 c_parser_consume_token (parser
);
8149 if (c_parser_next_token_is (parser
, CPP_COLON
))
8151 tree eptype
= NULL_TREE
;
8153 location_t middle_loc
= c_parser_peek_token (parser
)->location
;
8154 pedwarn (middle_loc
, OPT_Wpedantic
,
8155 "ISO C forbids omitting the middle term of a %<?:%> expression");
8156 if (TREE_CODE (cond
.value
) == EXCESS_PRECISION_EXPR
)
8158 eptype
= TREE_TYPE (cond
.value
);
8159 cond
.value
= TREE_OPERAND (cond
.value
, 0);
8161 tree e
= cond
.value
;
8162 while (TREE_CODE (e
) == COMPOUND_EXPR
)
8163 e
= TREE_OPERAND (e
, 1);
8164 warn_for_omitted_condop (middle_loc
, e
);
8165 /* Make sure first operand is calculated only once. */
8166 exp1
.value
= save_expr (default_conversion (cond
.value
));
8168 exp1
.value
= build1 (EXCESS_PRECISION_EXPR
, eptype
, exp1
.value
);
8169 exp1
.original_type
= NULL
;
8170 exp1
.src_range
= cond
.src_range
;
8171 cond
.value
= c_objc_common_truthvalue_conversion (cond_loc
, exp1
.value
);
8172 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_true_node
;
8177 = c_objc_common_truthvalue_conversion
8178 (cond_loc
, default_conversion (cond
.value
));
8179 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_false_node
;
8180 exp1
= c_parser_expression_conv (parser
);
8181 mark_exp_read (exp1
.value
);
8182 c_inhibit_evaluation_warnings
+=
8183 ((cond
.value
== truthvalue_true_node
)
8184 - (cond
.value
== truthvalue_false_node
));
8187 colon_loc
= c_parser_peek_token (parser
)->location
;
8188 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
8190 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
8192 ret
.original_code
= ERROR_MARK
;
8193 ret
.original_type
= NULL
;
8197 location_t exp2_loc
= c_parser_peek_token (parser
)->location
;
8198 exp2
= c_parser_conditional_expression (parser
, NULL
, NULL_TREE
);
8199 exp2
= convert_lvalue_to_rvalue (exp2_loc
, exp2
, true, true);
8201 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
8202 location_t loc1
= make_location (exp1
.get_start (), exp1
.src_range
);
8203 location_t loc2
= make_location (exp2
.get_start (), exp2
.src_range
);
8204 if (UNLIKELY (omp_atomic_lhs
!= NULL
)
8205 && (TREE_CODE (cond
.value
) == GT_EXPR
8206 || TREE_CODE (cond
.value
) == LT_EXPR
8207 || TREE_CODE (cond
.value
) == EQ_EXPR
)
8208 && c_tree_equal (exp2
.value
, omp_atomic_lhs
)
8209 && (c_tree_equal (TREE_OPERAND (cond
.value
, 0), omp_atomic_lhs
)
8210 || c_tree_equal (TREE_OPERAND (cond
.value
, 1), omp_atomic_lhs
)))
8211 ret
.value
= build3_loc (colon_loc
, COND_EXPR
, TREE_TYPE (omp_atomic_lhs
),
8212 cond
.value
, exp1
.value
, exp2
.value
);
8215 = build_conditional_expr (colon_loc
, cond
.value
,
8216 cond
.original_code
== C_MAYBE_CONST_EXPR
,
8217 exp1
.value
, exp1
.original_type
, loc1
,
8218 exp2
.value
, exp2
.original_type
, loc2
);
8219 ret
.original_code
= ERROR_MARK
;
8220 if (exp1
.value
== error_mark_node
|| exp2
.value
== error_mark_node
)
8221 ret
.original_type
= NULL
;
8226 /* If both sides are enum type, the default conversion will have
8227 made the type of the result be an integer type. We want to
8228 remember the enum types we started with. */
8229 t1
= exp1
.original_type
? exp1
.original_type
: TREE_TYPE (exp1
.value
);
8230 t2
= exp2
.original_type
? exp2
.original_type
: TREE_TYPE (exp2
.value
);
8231 ret
.original_type
= ((t1
!= error_mark_node
8232 && t2
!= error_mark_node
8233 && (TYPE_MAIN_VARIANT (t1
)
8234 == TYPE_MAIN_VARIANT (t2
)))
8238 set_c_expr_source_range (&ret
, start
, exp2
.get_finish ());
8243 /* Parse a binary expression; that is, a logical-OR-expression (C90
8244 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
8245 NULL then it is an Objective-C message expression which is the
8246 primary-expression starting the expression as an initializer.
8248 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
8249 when it should be the unfolded lhs. In a valid OpenMP source,
8250 one of the operands of the toplevel binary expression must be equal
8251 to it. In that case, just return a build2 created binary operation
8252 rather than result of parser_build_binary_op.
8254 multiplicative-expression:
8256 multiplicative-expression * cast-expression
8257 multiplicative-expression / cast-expression
8258 multiplicative-expression % cast-expression
8260 additive-expression:
8261 multiplicative-expression
8262 additive-expression + multiplicative-expression
8263 additive-expression - multiplicative-expression
8267 shift-expression << additive-expression
8268 shift-expression >> additive-expression
8270 relational-expression:
8272 relational-expression < shift-expression
8273 relational-expression > shift-expression
8274 relational-expression <= shift-expression
8275 relational-expression >= shift-expression
8277 equality-expression:
8278 relational-expression
8279 equality-expression == relational-expression
8280 equality-expression != relational-expression
8284 AND-expression & equality-expression
8286 exclusive-OR-expression:
8288 exclusive-OR-expression ^ AND-expression
8290 inclusive-OR-expression:
8291 exclusive-OR-expression
8292 inclusive-OR-expression | exclusive-OR-expression
8294 logical-AND-expression:
8295 inclusive-OR-expression
8296 logical-AND-expression && inclusive-OR-expression
8298 logical-OR-expression:
8299 logical-AND-expression
8300 logical-OR-expression || logical-AND-expression
8303 static struct c_expr
8304 c_parser_binary_expression (c_parser
*parser
, struct c_expr
*after
,
8305 tree omp_atomic_lhs
)
8307 /* A binary expression is parsed using operator-precedence parsing,
8308 with the operands being cast expressions. All the binary
8309 operators are left-associative. Thus a binary expression is of
8312 E0 op1 E1 op2 E2 ...
8314 which we represent on a stack. On the stack, the precedence
8315 levels are strictly increasing. When a new operator is
8316 encountered of higher precedence than that at the top of the
8317 stack, it is pushed; its LHS is the top expression, and its RHS
8318 is everything parsed until it is popped. When a new operator is
8319 encountered with precedence less than or equal to that at the top
8320 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
8321 by the result of the operation until the operator at the top of
8322 the stack has lower precedence than the new operator or there is
8323 only one element on the stack; then the top expression is the LHS
8324 of the new operator. In the case of logical AND and OR
8325 expressions, we also need to adjust c_inhibit_evaluation_warnings
8326 as appropriate when the operators are pushed and popped. */
8329 /* The expression at this stack level. */
8331 /* The precedence of the operator on its left, PREC_NONE at the
8332 bottom of the stack. */
8333 enum c_parser_prec prec
;
8334 /* The operation on its left. */
8336 /* The source location of this operation. */
8338 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
8342 /* Location of the binary operator. */
8343 location_t binary_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
8346 switch (stack[sp].op) \
8348 case TRUTH_ANDIF_EXPR: \
8349 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
8350 == truthvalue_false_node); \
8352 case TRUTH_ORIF_EXPR: \
8353 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
8354 == truthvalue_true_node); \
8356 case TRUNC_DIV_EXPR: \
8357 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
8358 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
8359 && (stack[sp].expr.original_code == SIZEOF_EXPR \
8360 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
8362 tree type0 = stack[sp - 1].sizeof_arg; \
8363 tree type1 = stack[sp].sizeof_arg; \
8364 tree first_arg = type0; \
8365 if (!TYPE_P (type0)) \
8366 type0 = TREE_TYPE (type0); \
8367 if (!TYPE_P (type1)) \
8368 type1 = TREE_TYPE (type1); \
8369 if (POINTER_TYPE_P (type0) \
8370 && comptypes (TREE_TYPE (type0), type1) \
8371 && !(TREE_CODE (first_arg) == PARM_DECL \
8372 && C_ARRAY_PARAMETER (first_arg) \
8373 && warn_sizeof_array_argument)) \
8375 auto_diagnostic_group d; \
8376 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
8377 "division %<sizeof (%T) / sizeof (%T)%> " \
8378 "does not compute the number of array " \
8381 if (DECL_P (first_arg)) \
8382 inform (DECL_SOURCE_LOCATION (first_arg), \
8383 "first %<sizeof%> operand was declared here"); \
8385 else if (TREE_CODE (type0) == ARRAY_TYPE \
8386 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
8387 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
8388 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
8389 stack[sp].sizeof_arg, type1); \
8395 stack[sp - 1].expr \
8396 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
8397 stack[sp - 1].expr, true, true); \
8399 = convert_lvalue_to_rvalue (stack[sp].loc, \
8400 stack[sp].expr, true, true); \
8401 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
8402 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
8403 && ((1 << stack[sp].prec) \
8404 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
8405 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
8406 | (1 << PREC_ADD) | (1 << PREC_MULT) \
8407 | (1 << PREC_EQ)))) \
8408 || ((c_parser_next_token_is (parser, CPP_QUERY) \
8409 || (omp_atomic_lhs == void_list_node \
8410 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
8411 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
8412 && stack[sp].op != TRUNC_MOD_EXPR \
8413 && stack[sp].op != GE_EXPR \
8414 && stack[sp].op != LE_EXPR \
8415 && stack[sp].op != NE_EXPR \
8416 && stack[0].expr.value != error_mark_node \
8417 && stack[1].expr.value != error_mark_node \
8418 && (omp_atomic_lhs == void_list_node \
8419 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
8420 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
8421 || (stack[sp].op == EQ_EXPR \
8422 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
8424 tree t = make_node (stack[1].op); \
8425 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
8426 TREE_OPERAND (t, 0) = stack[0].expr.value; \
8427 TREE_OPERAND (t, 1) = stack[1].expr.value; \
8428 stack[0].expr.value = t; \
8429 stack[0].expr.m_decimal = 0; \
8432 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
8434 stack[sp - 1].expr, \
8438 gcc_assert (!after
|| c_dialect_objc ());
8439 stack
[0].loc
= c_parser_peek_token (parser
)->location
;
8440 stack
[0].expr
= c_parser_cast_expression (parser
, after
);
8441 stack
[0].prec
= PREC_NONE
;
8442 stack
[0].sizeof_arg
= c_last_sizeof_arg
;
8446 enum c_parser_prec oprec
;
8447 enum tree_code ocode
;
8448 source_range src_range
;
8451 switch (c_parser_peek_token (parser
)->type
)
8459 ocode
= TRUNC_DIV_EXPR
;
8463 ocode
= TRUNC_MOD_EXPR
;
8475 ocode
= LSHIFT_EXPR
;
8479 ocode
= RSHIFT_EXPR
;
8493 case CPP_GREATER_EQ
:
8506 oprec
= PREC_BITAND
;
8507 ocode
= BIT_AND_EXPR
;
8510 oprec
= PREC_BITXOR
;
8511 ocode
= BIT_XOR_EXPR
;
8515 ocode
= BIT_IOR_EXPR
;
8518 oprec
= PREC_LOGAND
;
8519 ocode
= TRUTH_ANDIF_EXPR
;
8523 ocode
= TRUTH_ORIF_EXPR
;
8526 /* Not a binary operator, so end of the binary
8530 binary_loc
= c_parser_peek_token (parser
)->location
;
8531 while (oprec
<= stack
[sp
].prec
)
8533 c_parser_consume_token (parser
);
8536 case TRUTH_ANDIF_EXPR
:
8537 src_range
= stack
[sp
].expr
.src_range
;
8539 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
8540 stack
[sp
].expr
, true, true);
8541 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
8542 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
8543 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
8544 == truthvalue_false_node
);
8545 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
8547 case TRUTH_ORIF_EXPR
:
8548 src_range
= stack
[sp
].expr
.src_range
;
8550 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
8551 stack
[sp
].expr
, true, true);
8552 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
8553 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
8554 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
8555 == truthvalue_true_node
);
8556 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
8562 stack
[sp
].loc
= binary_loc
;
8563 stack
[sp
].expr
= c_parser_cast_expression (parser
, NULL
);
8564 stack
[sp
].prec
= oprec
;
8565 stack
[sp
].op
= ocode
;
8566 stack
[sp
].sizeof_arg
= c_last_sizeof_arg
;
8571 return stack
[0].expr
;
8575 /* Parse any storage class specifiers after an open parenthesis in a
8576 context where a compound literal is permitted. */
8578 static struct c_declspecs
*
8579 c_parser_compound_literal_scspecs (c_parser
*parser
)
8581 bool seen_scspec
= false;
8582 struct c_declspecs
*specs
= build_null_declspecs ();
8583 while (c_parser_next_token_is (parser
, CPP_KEYWORD
))
8585 switch (c_parser_peek_token (parser
)->keyword
)
8592 declspecs_add_scspec (c_parser_peek_token (parser
)->location
,
8593 specs
, c_parser_peek_token (parser
)->value
);
8594 c_parser_consume_token (parser
);
8601 return seen_scspec
? specs
: NULL
;
8604 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8605 is not NULL then it is an Objective-C message expression which is the
8606 primary-expression starting the expression as an initializer.
8610 ( type-name ) unary-expression
8613 static struct c_expr
8614 c_parser_cast_expression (c_parser
*parser
, struct c_expr
*after
)
8616 location_t cast_loc
= c_parser_peek_token (parser
)->location
;
8617 gcc_assert (!after
|| c_dialect_objc ());
8619 return c_parser_postfix_expression_after_primary (parser
,
8621 /* If the expression begins with a parenthesized type name, it may
8622 be either a cast or a compound literal; we need to see whether
8623 the next character is '{' to tell the difference. If not, it is
8624 an unary expression. Full detection of unknown typenames here
8625 would require a 3-token lookahead. */
8626 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8627 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
8629 struct c_declspecs
*scspecs
;
8630 struct c_type_name
*type_name
;
8633 matching_parens parens
;
8634 parens
.consume_open (parser
);
8635 scspecs
= c_parser_compound_literal_scspecs (parser
);
8636 type_name
= c_parser_type_name (parser
, true);
8637 parens
.skip_until_found_close (parser
);
8638 if (type_name
== NULL
)
8641 ret
.original_code
= ERROR_MARK
;
8642 ret
.original_type
= NULL
;
8646 /* Save casted types in the function's used types hash table. */
8647 used_types_insert (type_name
->specs
->type
);
8649 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8650 return c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
8654 error_at (cast_loc
, "storage class specifier in cast");
8655 if (type_name
->specs
->alignas_p
)
8656 error_at (type_name
->specs
->locations
[cdw_alignas
],
8657 "alignment specified for type name in cast");
8659 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
8660 expr
= c_parser_cast_expression (parser
, NULL
);
8661 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
8663 ret
.value
= c_cast_expr (cast_loc
, type_name
, expr
.value
);
8664 if (ret
.value
&& expr
.value
)
8665 set_c_expr_source_range (&ret
, cast_loc
, expr
.get_finish ());
8666 ret
.original_code
= ERROR_MARK
;
8667 ret
.original_type
= NULL
;
8672 return c_parser_unary_expression (parser
);
8675 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8681 unary-operator cast-expression
8682 sizeof unary-expression
8683 sizeof ( type-name )
8685 unary-operator: one of
8691 __alignof__ unary-expression
8692 __alignof__ ( type-name )
8695 (C11 permits _Alignof with type names only.)
8697 unary-operator: one of
8698 __extension__ __real__ __imag__
8700 Transactional Memory:
8703 transaction-expression
8705 In addition, the GNU syntax treats ++ and -- as unary operators, so
8706 they may be applied to cast expressions with errors for non-lvalues
8709 static struct c_expr
8710 c_parser_unary_expression (c_parser
*parser
)
8713 struct c_expr ret
, op
;
8714 location_t op_loc
= c_parser_peek_token (parser
)->location
;
8717 ret
.original_code
= ERROR_MARK
;
8718 ret
.original_type
= NULL
;
8719 switch (c_parser_peek_token (parser
)->type
)
8722 c_parser_consume_token (parser
);
8723 exp_loc
= c_parser_peek_token (parser
)->location
;
8724 op
= c_parser_cast_expression (parser
, NULL
);
8726 op
= default_function_array_read_conversion (exp_loc
, op
);
8727 return parser_build_unary_op (op_loc
, PREINCREMENT_EXPR
, op
);
8728 case CPP_MINUS_MINUS
:
8729 c_parser_consume_token (parser
);
8730 exp_loc
= c_parser_peek_token (parser
)->location
;
8731 op
= c_parser_cast_expression (parser
, NULL
);
8733 op
= default_function_array_read_conversion (exp_loc
, op
);
8734 return parser_build_unary_op (op_loc
, PREDECREMENT_EXPR
, op
);
8736 c_parser_consume_token (parser
);
8737 op
= c_parser_cast_expression (parser
, NULL
);
8738 mark_exp_read (op
.value
);
8739 return parser_build_unary_op (op_loc
, ADDR_EXPR
, op
);
8742 c_parser_consume_token (parser
);
8743 exp_loc
= c_parser_peek_token (parser
)->location
;
8744 op
= c_parser_cast_expression (parser
, NULL
);
8745 finish
= op
.get_finish ();
8746 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8747 location_t combined_loc
= make_location (op_loc
, op_loc
, finish
);
8748 ret
.value
= build_indirect_ref (combined_loc
, op
.value
, RO_UNARY_STAR
);
8749 ret
.src_range
.m_start
= op_loc
;
8750 ret
.src_range
.m_finish
= finish
;
8755 if (!c_dialect_objc () && !in_system_header_at (input_location
))
8758 "traditional C rejects the unary plus operator");
8759 c_parser_consume_token (parser
);
8760 exp_loc
= c_parser_peek_token (parser
)->location
;
8761 op
= c_parser_cast_expression (parser
, NULL
);
8762 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8763 return parser_build_unary_op (op_loc
, CONVERT_EXPR
, op
);
8765 c_parser_consume_token (parser
);
8766 exp_loc
= c_parser_peek_token (parser
)->location
;
8767 op
= c_parser_cast_expression (parser
, NULL
);
8768 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8769 return parser_build_unary_op (op_loc
, NEGATE_EXPR
, op
);
8771 c_parser_consume_token (parser
);
8772 exp_loc
= c_parser_peek_token (parser
)->location
;
8773 op
= c_parser_cast_expression (parser
, NULL
);
8774 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8775 return parser_build_unary_op (op_loc
, BIT_NOT_EXPR
, op
);
8777 c_parser_consume_token (parser
);
8778 exp_loc
= c_parser_peek_token (parser
)->location
;
8779 op
= c_parser_cast_expression (parser
, NULL
);
8780 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8781 return parser_build_unary_op (op_loc
, TRUTH_NOT_EXPR
, op
);
8783 /* Refer to the address of a label as a pointer. */
8784 c_parser_consume_token (parser
);
8785 if (c_parser_next_token_is (parser
, CPP_NAME
))
8787 ret
.value
= finish_label_address_expr
8788 (c_parser_peek_token (parser
)->value
, op_loc
);
8789 set_c_expr_source_range (&ret
, op_loc
,
8790 c_parser_peek_token (parser
)->get_finish ());
8791 c_parser_consume_token (parser
);
8795 c_parser_error (parser
, "expected identifier");
8800 switch (c_parser_peek_token (parser
)->keyword
)
8803 return c_parser_sizeof_expression (parser
);
8805 return c_parser_alignof_expression (parser
);
8806 case RID_BUILTIN_HAS_ATTRIBUTE
:
8807 return c_parser_has_attribute_expression (parser
);
8809 c_parser_consume_token (parser
);
8810 ext
= disable_extension_diagnostics ();
8811 ret
= c_parser_cast_expression (parser
, NULL
);
8812 restore_extension_diagnostics (ext
);
8815 c_parser_consume_token (parser
);
8816 exp_loc
= c_parser_peek_token (parser
)->location
;
8817 op
= c_parser_cast_expression (parser
, NULL
);
8818 op
= default_function_array_conversion (exp_loc
, op
);
8819 return parser_build_unary_op (op_loc
, REALPART_EXPR
, op
);
8821 c_parser_consume_token (parser
);
8822 exp_loc
= c_parser_peek_token (parser
)->location
;
8823 op
= c_parser_cast_expression (parser
, NULL
);
8824 op
= default_function_array_conversion (exp_loc
, op
);
8825 return parser_build_unary_op (op_loc
, IMAGPART_EXPR
, op
);
8826 case RID_TRANSACTION_ATOMIC
:
8827 case RID_TRANSACTION_RELAXED
:
8828 return c_parser_transaction_expression (parser
,
8829 c_parser_peek_token (parser
)->keyword
);
8831 return c_parser_postfix_expression (parser
);
8834 return c_parser_postfix_expression (parser
);
8838 /* Parse a sizeof expression. */
8840 static struct c_expr
8841 c_parser_sizeof_expression (c_parser
*parser
)
8844 struct c_expr result
;
8845 location_t expr_loc
;
8846 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SIZEOF
));
8849 location_t finish
= UNKNOWN_LOCATION
;
8851 start
= c_parser_peek_token (parser
)->location
;
8853 c_parser_consume_token (parser
);
8854 c_inhibit_evaluation_warnings
++;
8856 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8857 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
8859 /* Either sizeof ( type-name ) or sizeof unary-expression
8860 starting with a compound literal. */
8861 struct c_declspecs
*scspecs
;
8862 struct c_type_name
*type_name
;
8863 matching_parens parens
;
8864 parens
.consume_open (parser
);
8865 expr_loc
= c_parser_peek_token (parser
)->location
;
8866 scspecs
= c_parser_compound_literal_scspecs (parser
);
8867 type_name
= c_parser_type_name (parser
, true);
8868 parens
.skip_until_found_close (parser
);
8869 finish
= parser
->tokens_buf
[0].location
;
8870 if (type_name
== NULL
)
8873 c_inhibit_evaluation_warnings
--;
8876 ret
.original_code
= ERROR_MARK
;
8877 ret
.original_type
= NULL
;
8880 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8882 expr
= c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
8885 finish
= expr
.get_finish ();
8888 /* sizeof ( type-name ). */
8890 error_at (expr_loc
, "storage class specifier in %<sizeof%>");
8891 if (type_name
->specs
->alignas_p
)
8892 error_at (type_name
->specs
->locations
[cdw_alignas
],
8893 "alignment specified for type name in %<sizeof%>");
8894 c_inhibit_evaluation_warnings
--;
8896 result
= c_expr_sizeof_type (expr_loc
, type_name
);
8900 expr_loc
= c_parser_peek_token (parser
)->location
;
8901 expr
= c_parser_unary_expression (parser
);
8902 finish
= expr
.get_finish ();
8904 c_inhibit_evaluation_warnings
--;
8906 mark_exp_read (expr
.value
);
8907 if (TREE_CODE (expr
.value
) == COMPONENT_REF
8908 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
8909 error_at (expr_loc
, "%<sizeof%> applied to a bit-field");
8910 result
= c_expr_sizeof_expr (expr_loc
, expr
);
8912 if (finish
== UNKNOWN_LOCATION
)
8914 set_c_expr_source_range (&result
, start
, finish
);
8918 /* Parse an alignof expression. */
8920 static struct c_expr
8921 c_parser_alignof_expression (c_parser
*parser
)
8924 location_t start_loc
= c_parser_peek_token (parser
)->location
;
8926 tree alignof_spelling
= c_parser_peek_token (parser
)->value
;
8927 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNOF
));
8928 bool is_c11_alignof
= (strcmp (IDENTIFIER_POINTER (alignof_spelling
),
8930 || strcmp (IDENTIFIER_POINTER (alignof_spelling
),
8932 /* A diagnostic is not required for the use of this identifier in
8933 the implementation namespace; only diagnose it for the C11 or C2X
8934 spelling because of existing code using the other spellings. */
8938 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C99 does not support %qE",
8941 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C90 does not support %qE",
8944 c_parser_consume_token (parser
);
8945 c_inhibit_evaluation_warnings
++;
8947 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8948 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
8950 /* Either __alignof__ ( type-name ) or __alignof__
8951 unary-expression starting with a compound literal. */
8953 struct c_declspecs
*scspecs
;
8954 struct c_type_name
*type_name
;
8956 matching_parens parens
;
8957 parens
.consume_open (parser
);
8958 loc
= c_parser_peek_token (parser
)->location
;
8959 scspecs
= c_parser_compound_literal_scspecs (parser
);
8960 type_name
= c_parser_type_name (parser
, true);
8961 end_loc
= c_parser_peek_token (parser
)->location
;
8962 parens
.skip_until_found_close (parser
);
8963 if (type_name
== NULL
)
8966 c_inhibit_evaluation_warnings
--;
8969 ret
.original_code
= ERROR_MARK
;
8970 ret
.original_type
= NULL
;
8973 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8975 expr
= c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
8980 /* alignof ( type-name ). */
8982 error_at (loc
, "storage class specifier in %qE", alignof_spelling
);
8983 if (type_name
->specs
->alignas_p
)
8984 error_at (type_name
->specs
->locations
[cdw_alignas
],
8985 "alignment specified for type name in %qE",
8987 c_inhibit_evaluation_warnings
--;
8989 ret
.value
= c_sizeof_or_alignof_type (loc
, groktypename (type_name
,
8991 false, is_c11_alignof
, 1);
8992 ret
.original_code
= ERROR_MARK
;
8993 ret
.original_type
= NULL
;
8994 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
9001 expr
= c_parser_unary_expression (parser
);
9002 end_loc
= expr
.src_range
.m_finish
;
9004 mark_exp_read (expr
.value
);
9005 c_inhibit_evaluation_warnings
--;
9009 OPT_Wpedantic
, "ISO C does not allow %<%E (expression)%>",
9011 ret
.value
= c_alignof_expr (start_loc
, expr
.value
);
9012 ret
.original_code
= ERROR_MARK
;
9013 ret
.original_type
= NULL
;
9014 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
9020 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
9023 static struct c_expr
9024 c_parser_has_attribute_expression (c_parser
*parser
)
9026 gcc_assert (c_parser_next_token_is_keyword (parser
,
9027 RID_BUILTIN_HAS_ATTRIBUTE
));
9028 location_t start
= c_parser_peek_token (parser
)->location
;
9029 c_parser_consume_token (parser
);
9031 c_inhibit_evaluation_warnings
++;
9033 matching_parens parens
;
9034 if (!parens
.require_open (parser
))
9036 c_inhibit_evaluation_warnings
--;
9039 struct c_expr result
;
9040 result
.set_error ();
9041 result
.original_code
= ERROR_MARK
;
9042 result
.original_type
= NULL
;
9046 /* Treat the type argument the same way as in typeof for the purposes
9047 of warnings. FIXME: Generalize this so the warning refers to
9048 __builtin_has_attribute rather than typeof. */
9051 /* The first operand: one of DECL, EXPR, or TYPE. */
9052 tree oper
= NULL_TREE
;
9053 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
9055 struct c_type_name
*tname
= c_parser_type_name (parser
);
9059 oper
= groktypename (tname
, NULL
, NULL
);
9060 pop_maybe_used (c_type_variably_modified_p (oper
));
9065 struct c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
9066 c_inhibit_evaluation_warnings
--;
9068 if (cexpr
.value
!= error_mark_node
)
9070 mark_exp_read (cexpr
.value
);
9072 tree etype
= TREE_TYPE (oper
);
9073 bool was_vm
= c_type_variably_modified_p (etype
);
9074 /* This is returned with the type so that when the type is
9075 evaluated, this can be evaluated. */
9077 oper
= c_fully_fold (oper
, false, NULL
);
9078 pop_maybe_used (was_vm
);
9082 struct c_expr result
;
9083 result
.original_code
= ERROR_MARK
;
9084 result
.original_type
= NULL
;
9086 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9088 /* Consume the closing parenthesis if that's the next token
9089 in the likely case the built-in was invoked with fewer
9090 than two arguments. */
9091 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
9092 c_parser_consume_token (parser
);
9093 c_inhibit_evaluation_warnings
--;
9094 result
.set_error ();
9098 bool save_translate_strings_p
= parser
->translate_strings_p
;
9100 location_t atloc
= c_parser_peek_token (parser
)->location
;
9101 /* Parse a single attribute. Require no leading comma and do not
9102 allow empty attributes. */
9103 tree attr
= c_parser_gnu_attribute (parser
, NULL_TREE
, false, false);
9105 parser
->translate_strings_p
= save_translate_strings_p
;
9107 location_t finish
= c_parser_peek_token (parser
)->location
;
9108 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
9109 c_parser_consume_token (parser
);
9112 c_parser_error (parser
, "expected identifier");
9113 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9115 result
.set_error ();
9121 error_at (atloc
, "expected identifier");
9122 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9124 result
.set_error ();
9128 result
.original_code
= INTEGER_CST
;
9129 result
.original_type
= boolean_type_node
;
9131 if (has_attribute (atloc
, oper
, attr
, default_conversion
))
9132 result
.value
= boolean_true_node
;
9134 result
.value
= boolean_false_node
;
9136 set_c_expr_source_range (&result
, start
, finish
);
9137 result
.m_decimal
= 0;
9141 /* Helper function to read arguments of builtins which are interfaces
9142 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
9143 others. The name of the builtin is passed using BNAME parameter.
9144 Function returns true if there were no errors while parsing and
9145 stores the arguments in CEXPR_LIST. If it returns true,
9146 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
9149 c_parser_get_builtin_args (c_parser
*parser
, const char *bname
,
9150 vec
<c_expr_t
, va_gc
> **ret_cexpr_list
,
9152 location_t
*out_close_paren_loc
)
9154 location_t loc
= c_parser_peek_token (parser
)->location
;
9155 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9157 bool saved_force_folding_builtin_constant_p
;
9159 *ret_cexpr_list
= NULL
;
9160 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
9162 error_at (loc
, "cannot take address of %qs", bname
);
9166 c_parser_consume_token (parser
);
9168 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
9170 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
9171 c_parser_consume_token (parser
);
9175 saved_force_folding_builtin_constant_p
9176 = force_folding_builtin_constant_p
;
9177 force_folding_builtin_constant_p
|= choose_expr_p
;
9178 expr
= c_parser_expr_no_commas (parser
, NULL
);
9179 force_folding_builtin_constant_p
9180 = saved_force_folding_builtin_constant_p
;
9181 vec_alloc (cexpr_list
, 1);
9182 vec_safe_push (cexpr_list
, expr
);
9183 while (c_parser_next_token_is (parser
, CPP_COMMA
))
9185 c_parser_consume_token (parser
);
9186 expr
= c_parser_expr_no_commas (parser
, NULL
);
9187 vec_safe_push (cexpr_list
, expr
);
9190 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
9191 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
9194 *ret_cexpr_list
= cexpr_list
;
9198 /* This represents a single generic-association. */
9200 struct c_generic_association
9202 /* The location of the starting token of the type. */
9203 location_t type_location
;
9204 /* The association's type, or NULL_TREE for 'default'. */
9206 /* The association's expression. */
9207 struct c_expr expression
;
9210 /* Parse a generic-selection. (C11 6.5.1.1).
9213 _Generic ( assignment-expression , generic-assoc-list )
9217 generic-assoc-list , generic-association
9219 generic-association:
9220 type-name : assignment-expression
9221 default : assignment-expression
9224 static struct c_expr
9225 c_parser_generic_selection (c_parser
*parser
)
9227 struct c_expr selector
, error_expr
;
9229 struct c_generic_association matched_assoc
;
9230 int match_found
= -1;
9231 location_t generic_loc
, selector_loc
;
9233 error_expr
.original_code
= ERROR_MARK
;
9234 error_expr
.original_type
= NULL
;
9235 error_expr
.set_error ();
9236 matched_assoc
.type_location
= UNKNOWN_LOCATION
;
9237 matched_assoc
.type
= NULL_TREE
;
9238 matched_assoc
.expression
= error_expr
;
9240 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_GENERIC
));
9241 generic_loc
= c_parser_peek_token (parser
)->location
;
9242 c_parser_consume_token (parser
);
9244 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
9245 "ISO C99 does not support %<_Generic%>");
9247 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
9248 "ISO C90 does not support %<_Generic%>");
9250 matching_parens parens
;
9251 if (!parens
.require_open (parser
))
9254 c_inhibit_evaluation_warnings
++;
9255 selector_loc
= c_parser_peek_token (parser
)->location
;
9256 selector
= c_parser_expr_no_commas (parser
, NULL
);
9257 selector
= default_function_array_conversion (selector_loc
, selector
);
9258 c_inhibit_evaluation_warnings
--;
9260 if (selector
.value
== error_mark_node
)
9262 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9265 mark_exp_read (selector
.value
);
9266 selector_type
= TREE_TYPE (selector
.value
);
9267 /* In ISO C terms, rvalues (including the controlling expression of
9268 _Generic) do not have qualified types. */
9269 if (TREE_CODE (selector_type
) != ARRAY_TYPE
)
9270 selector_type
= TYPE_MAIN_VARIANT (selector_type
);
9271 /* In ISO C terms, _Noreturn is not part of the type of expressions
9272 such as &abort, but in GCC it is represented internally as a type
9274 if (FUNCTION_POINTER_TYPE_P (selector_type
)
9275 && TYPE_QUALS (TREE_TYPE (selector_type
)) != TYPE_UNQUALIFIED
)
9277 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type
)));
9279 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9281 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9285 auto_vec
<c_generic_association
> associations
;
9288 struct c_generic_association assoc
, *iter
;
9290 c_token
*token
= c_parser_peek_token (parser
);
9292 assoc
.type_location
= token
->location
;
9293 if (token
->type
== CPP_KEYWORD
&& token
->keyword
== RID_DEFAULT
)
9295 c_parser_consume_token (parser
);
9296 assoc
.type
= NULL_TREE
;
9300 struct c_type_name
*type_name
;
9302 type_name
= c_parser_type_name (parser
);
9303 if (type_name
== NULL
)
9305 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9308 assoc
.type
= groktypename (type_name
, NULL
, NULL
);
9309 if (assoc
.type
== error_mark_node
)
9311 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9315 if (TREE_CODE (assoc
.type
) == FUNCTION_TYPE
)
9316 error_at (assoc
.type_location
,
9317 "%<_Generic%> association has function type");
9318 else if (!COMPLETE_TYPE_P (assoc
.type
))
9319 error_at (assoc
.type_location
,
9320 "%<_Generic%> association has incomplete type");
9322 if (c_type_variably_modified_p (assoc
.type
))
9323 error_at (assoc
.type_location
,
9324 "%<_Generic%> association has "
9325 "variable length type");
9328 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
9330 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9334 assoc
.expression
= c_parser_expr_no_commas (parser
, NULL
);
9335 if (assoc
.expression
.value
== error_mark_node
)
9337 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9341 for (ix
= 0; associations
.iterate (ix
, &iter
); ++ix
)
9343 if (assoc
.type
== NULL_TREE
)
9345 if (iter
->type
== NULL_TREE
)
9347 error_at (assoc
.type_location
,
9348 "duplicate %<default%> case in %<_Generic%>");
9349 inform (iter
->type_location
, "original %<default%> is here");
9352 else if (iter
->type
!= NULL_TREE
)
9354 if (comptypes (assoc
.type
, iter
->type
))
9356 error_at (assoc
.type_location
,
9357 "%<_Generic%> specifies two compatible types");
9358 inform (iter
->type_location
, "compatible type is here");
9363 if (assoc
.type
== NULL_TREE
)
9365 if (match_found
< 0)
9367 matched_assoc
= assoc
;
9368 match_found
= associations
.length ();
9371 else if (comptypes (assoc
.type
, selector_type
))
9373 if (match_found
< 0 || matched_assoc
.type
== NULL_TREE
)
9375 matched_assoc
= assoc
;
9376 match_found
= associations
.length ();
9380 error_at (assoc
.type_location
,
9381 "%<_Generic%> selector matches multiple associations");
9382 inform (matched_assoc
.type_location
,
9383 "other match is here");
9387 associations
.safe_push (assoc
);
9389 if (c_parser_peek_token (parser
)->type
!= CPP_COMMA
)
9391 c_parser_consume_token (parser
);
9395 struct c_generic_association
*iter
;
9396 FOR_EACH_VEC_ELT (associations
, ix
, iter
)
9397 if (ix
!= (unsigned) match_found
)
9398 mark_exp_read (iter
->expression
.value
);
9400 if (!parens
.require_close (parser
))
9402 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9406 if (match_found
< 0)
9408 error_at (selector_loc
, "%<_Generic%> selector of type %qT is not "
9409 "compatible with any association",
9414 return matched_assoc
.expression
;
9417 /* Check the validity of a function pointer argument *EXPR (argument
9418 position POS) to __builtin_tgmath. Return the number of function
9419 arguments if possibly valid; return 0 having reported an error if
9423 check_tgmath_function (c_expr
*expr
, unsigned int pos
)
9425 tree type
= TREE_TYPE (expr
->value
);
9426 if (!FUNCTION_POINTER_TYPE_P (type
))
9428 error_at (expr
->get_location (),
9429 "argument %u of %<__builtin_tgmath%> is not a function pointer",
9433 type
= TREE_TYPE (type
);
9434 if (!prototype_p (type
))
9436 error_at (expr
->get_location (),
9437 "argument %u of %<__builtin_tgmath%> is unprototyped", pos
);
9440 if (stdarg_p (type
))
9442 error_at (expr
->get_location (),
9443 "argument %u of %<__builtin_tgmath%> has variable arguments",
9447 unsigned int nargs
= 0;
9448 function_args_iterator iter
;
9450 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9452 if (t
== void_type_node
)
9458 error_at (expr
->get_location (),
9459 "argument %u of %<__builtin_tgmath%> has no arguments", pos
);
9465 /* Ways in which a parameter or return value of a type-generic macro
9466 may vary between the different functions the macro may call. */
9467 enum tgmath_parm_kind
9469 tgmath_fixed
, tgmath_real
, tgmath_complex
9472 /* Helper function for c_parser_postfix_expression. Parse predefined
9475 static struct c_expr
9476 c_parser_predefined_identifier (c_parser
*parser
)
9478 location_t loc
= c_parser_peek_token (parser
)->location
;
9479 switch (c_parser_peek_token (parser
)->keyword
)
9481 case RID_FUNCTION_NAME
:
9482 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
9483 "identifier", "__FUNCTION__");
9485 case RID_PRETTY_FUNCTION_NAME
:
9486 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
9487 "identifier", "__PRETTY_FUNCTION__");
9489 case RID_C99_FUNCTION_NAME
:
9490 pedwarn_c90 (loc
, OPT_Wpedantic
, "ISO C90 does not support "
9491 "%<__func__%> predefined identifier");
9498 expr
.original_code
= ERROR_MARK
;
9499 expr
.original_type
= NULL
;
9500 expr
.value
= fname_decl (loc
, c_parser_peek_token (parser
)->keyword
,
9501 c_parser_peek_token (parser
)->value
);
9502 set_c_expr_source_range (&expr
, loc
, loc
);
9504 c_parser_consume_token (parser
);
9508 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
9509 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
9510 call c_parser_postfix_expression_after_paren_type on encountering them.
9514 postfix-expression [ expression ]
9515 postfix-expression ( argument-expression-list[opt] )
9516 postfix-expression . identifier
9517 postfix-expression -> identifier
9518 postfix-expression ++
9519 postfix-expression --
9520 ( storage-class-specifiers[opt] type-name ) { initializer-list[opt] }
9521 ( storage-class-specifiers[opt] type-name ) { initializer-list , }
9523 argument-expression-list:
9525 argument-expression-list , argument-expression
9538 (treated as a keyword in GNU C)
9541 ( compound-statement )
9542 __builtin_va_arg ( assignment-expression , type-name )
9543 __builtin_offsetof ( type-name , offsetof-member-designator )
9544 __builtin_choose_expr ( assignment-expression ,
9545 assignment-expression ,
9546 assignment-expression )
9547 __builtin_types_compatible_p ( type-name , type-name )
9548 __builtin_tgmath ( expr-list )
9549 __builtin_complex ( assignment-expression , assignment-expression )
9550 __builtin_shuffle ( assignment-expression , assignment-expression )
9551 __builtin_shuffle ( assignment-expression ,
9552 assignment-expression ,
9553 assignment-expression, )
9554 __builtin_convertvector ( assignment-expression , type-name )
9555 __builtin_assoc_barrier ( assignment-expression )
9557 offsetof-member-designator:
9559 offsetof-member-designator . identifier
9560 offsetof-member-designator [ expression ]
9565 [ objc-receiver objc-message-args ]
9566 @selector ( objc-selector-arg )
9567 @protocol ( identifier )
9568 @encode ( type-name )
9570 Classname . identifier
9573 static struct c_expr
9574 c_parser_postfix_expression (c_parser
*parser
)
9576 struct c_expr expr
, e1
;
9577 struct c_type_name
*t1
, *t2
;
9578 location_t loc
= c_parser_peek_token (parser
)->location
;
9579 source_range tok_range
= c_parser_peek_token (parser
)->get_range ();
9580 expr
.original_code
= ERROR_MARK
;
9581 expr
.original_type
= NULL
;
9583 switch (c_parser_peek_token (parser
)->type
)
9586 expr
.value
= c_parser_peek_token (parser
)->value
;
9587 set_c_expr_source_range (&expr
, tok_range
);
9588 loc
= c_parser_peek_token (parser
)->location
;
9589 expr
.m_decimal
= c_parser_peek_token (parser
)->flags
& DECIMAL_INT
;
9590 c_parser_consume_token (parser
);
9591 if (TREE_CODE (expr
.value
) == FIXED_CST
9592 && !targetm
.fixed_point_supported_p ())
9594 error_at (loc
, "fixed-point types not supported for this target");
9603 expr
.value
= c_parser_peek_token (parser
)->value
;
9604 /* For the purpose of warning when a pointer is compared with
9605 a zero character constant. */
9606 expr
.original_type
= char_type_node
;
9607 set_c_expr_source_range (&expr
, tok_range
);
9608 c_parser_consume_token (parser
);
9614 case CPP_UTF8STRING
:
9615 expr
= c_parser_string_literal (parser
, parser
->translate_strings_p
,
9618 case CPP_OBJC_STRING
:
9619 gcc_assert (c_dialect_objc ());
9621 = objc_build_string_object (c_parser_peek_token (parser
)->value
);
9622 set_c_expr_source_range (&expr
, tok_range
);
9623 c_parser_consume_token (parser
);
9626 switch (c_parser_peek_token (parser
)->id_kind
)
9630 tree id
= c_parser_peek_token (parser
)->value
;
9631 c_parser_consume_token (parser
);
9632 expr
.value
= build_external_ref (loc
, id
,
9633 (c_parser_peek_token (parser
)->type
9635 &expr
.original_type
);
9636 set_c_expr_source_range (&expr
, tok_range
);
9639 case C_ID_CLASSNAME
:
9641 /* Here we parse the Objective-C 2.0 Class.name dot
9643 tree class_name
= c_parser_peek_token (parser
)->value
;
9645 c_parser_consume_token (parser
);
9646 gcc_assert (c_dialect_objc ());
9647 if (!c_parser_require (parser
, CPP_DOT
, "expected %<.%>"))
9652 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9654 c_parser_error (parser
, "expected identifier");
9658 c_token
*component_tok
= c_parser_peek_token (parser
);
9659 component
= component_tok
->value
;
9660 location_t end_loc
= component_tok
->get_finish ();
9661 c_parser_consume_token (parser
);
9662 expr
.value
= objc_build_class_component_ref (class_name
,
9664 set_c_expr_source_range (&expr
, loc
, end_loc
);
9668 c_parser_error (parser
, "expected expression");
9673 case CPP_OPEN_PAREN
:
9674 /* A parenthesized expression, statement expression or compound
9676 if (c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_BRACE
)
9678 /* A statement expression. */
9680 location_t brace_loc
;
9681 c_parser_consume_token (parser
);
9682 brace_loc
= c_parser_peek_token (parser
)->location
;
9683 c_parser_consume_token (parser
);
9684 /* If we've not yet started the current function's statement list,
9685 or we're in the parameter scope of an old-style function
9686 declaration, statement expressions are not allowed. */
9687 if (!building_stmt_list_p () || old_style_parameter_scope ())
9689 error_at (loc
, "braced-group within expression allowed "
9690 "only inside a function");
9691 parser
->error
= true;
9692 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
9693 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9697 stmt
= c_begin_stmt_expr ();
9698 c_parser_compound_statement_nostart (parser
);
9699 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9700 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9702 pedwarn (loc
, OPT_Wpedantic
,
9703 "ISO C forbids braced-groups within expressions");
9704 expr
.value
= c_finish_stmt_expr (brace_loc
, stmt
);
9705 set_c_expr_source_range (&expr
, loc
, close_loc
);
9706 mark_exp_read (expr
.value
);
9710 /* A parenthesized expression. */
9711 location_t loc_open_paren
= c_parser_peek_token (parser
)->location
;
9712 c_parser_consume_token (parser
);
9713 expr
= c_parser_expression (parser
);
9714 if (TREE_CODE (expr
.value
) == MODIFY_EXPR
)
9715 suppress_warning (expr
.value
, OPT_Wparentheses
);
9716 if (expr
.original_code
!= C_MAYBE_CONST_EXPR
9717 && expr
.original_code
!= SIZEOF_EXPR
)
9718 expr
.original_code
= ERROR_MARK
;
9719 /* Remember that we saw ( ) around the sizeof. */
9720 if (expr
.original_code
== SIZEOF_EXPR
)
9721 expr
.original_code
= PAREN_SIZEOF_EXPR
;
9722 /* Don't change EXPR.ORIGINAL_TYPE. */
9723 location_t loc_close_paren
= c_parser_peek_token (parser
)->location
;
9724 set_c_expr_source_range (&expr
, loc_open_paren
, loc_close_paren
);
9725 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9726 "expected %<)%>", loc_open_paren
);
9730 switch (c_parser_peek_token (parser
)->keyword
)
9732 case RID_FUNCTION_NAME
:
9733 case RID_PRETTY_FUNCTION_NAME
:
9734 case RID_C99_FUNCTION_NAME
:
9735 expr
= c_parser_predefined_identifier (parser
);
9739 location_t start_loc
= loc
;
9740 c_parser_consume_token (parser
);
9741 matching_parens parens
;
9742 if (!parens
.require_open (parser
))
9747 e1
= c_parser_expr_no_commas (parser
, NULL
);
9748 mark_exp_read (e1
.value
);
9749 e1
.value
= c_fully_fold (e1
.value
, false, NULL
);
9750 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9752 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9756 loc
= c_parser_peek_token (parser
)->location
;
9757 t1
= c_parser_type_name (parser
);
9758 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9759 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9767 tree type_expr
= NULL_TREE
;
9768 expr
.value
= c_build_va_arg (start_loc
, e1
.value
, loc
,
9769 groktypename (t1
, &type_expr
, NULL
));
9772 expr
.value
= build2 (C_MAYBE_CONST_EXPR
,
9773 TREE_TYPE (expr
.value
), type_expr
,
9775 C_MAYBE_CONST_EXPR_NON_CONST (expr
.value
) = true;
9777 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
9783 c_parser_consume_token (parser
);
9784 matching_parens parens
;
9785 if (!parens
.require_open (parser
))
9790 t1
= c_parser_type_name (parser
);
9792 parser
->error
= true;
9793 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9794 gcc_assert (parser
->error
);
9797 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9801 tree type
= groktypename (t1
, NULL
, NULL
);
9803 if (type
== error_mark_node
)
9804 offsetof_ref
= error_mark_node
;
9807 offsetof_ref
= build1 (INDIRECT_REF
, type
, null_pointer_node
);
9808 SET_EXPR_LOCATION (offsetof_ref
, loc
);
9810 /* Parse the second argument to __builtin_offsetof. We
9811 must have one identifier, and beyond that we want to
9812 accept sub structure and sub array references. */
9813 if (c_parser_next_token_is (parser
, CPP_NAME
))
9815 c_token
*comp_tok
= c_parser_peek_token (parser
);
9817 = build_component_ref (loc
, offsetof_ref
, comp_tok
->value
,
9818 comp_tok
->location
, UNKNOWN_LOCATION
);
9819 c_parser_consume_token (parser
);
9820 while (c_parser_next_token_is (parser
, CPP_DOT
)
9821 || c_parser_next_token_is (parser
,
9823 || c_parser_next_token_is (parser
,
9826 if (c_parser_next_token_is (parser
, CPP_DEREF
))
9828 loc
= c_parser_peek_token (parser
)->location
;
9829 offsetof_ref
= build_array_ref (loc
,
9834 else if (c_parser_next_token_is (parser
, CPP_DOT
))
9837 c_parser_consume_token (parser
);
9838 if (c_parser_next_token_is_not (parser
,
9841 c_parser_error (parser
, "expected identifier");
9844 c_token
*comp_tok
= c_parser_peek_token (parser
);
9846 = build_component_ref (loc
, offsetof_ref
,
9850 c_parser_consume_token (parser
);
9856 loc
= c_parser_peek_token (parser
)->location
;
9857 c_parser_consume_token (parser
);
9858 ce
= c_parser_expression (parser
);
9859 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
9861 idx
= c_fully_fold (idx
, false, NULL
);
9862 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
9864 offsetof_ref
= build_array_ref (loc
, offsetof_ref
, idx
);
9869 c_parser_error (parser
, "expected identifier");
9870 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9871 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9873 expr
.value
= fold_offsetof (offsetof_ref
);
9874 set_c_expr_source_range (&expr
, loc
, end_loc
);
9877 case RID_CHOOSE_EXPR
:
9879 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9880 c_expr_t
*e1_p
, *e2_p
, *e3_p
;
9882 location_t close_paren_loc
;
9884 c_parser_consume_token (parser
);
9885 if (!c_parser_get_builtin_args (parser
,
9886 "__builtin_choose_expr",
9894 if (vec_safe_length (cexpr_list
) != 3)
9896 error_at (loc
, "wrong number of arguments to "
9897 "%<__builtin_choose_expr%>");
9902 e1_p
= &(*cexpr_list
)[0];
9903 e2_p
= &(*cexpr_list
)[1];
9904 e3_p
= &(*cexpr_list
)[2];
9907 mark_exp_read (e2_p
->value
);
9908 mark_exp_read (e3_p
->value
);
9909 if (TREE_CODE (c
) != INTEGER_CST
9910 || !INTEGRAL_TYPE_P (TREE_TYPE (c
)))
9912 "first argument to %<__builtin_choose_expr%> not"
9914 constant_expression_warning (c
);
9915 expr
= integer_zerop (c
) ? *e3_p
: *e2_p
;
9916 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9919 case RID_TYPES_COMPATIBLE_P
:
9921 c_parser_consume_token (parser
);
9922 matching_parens parens
;
9923 if (!parens
.require_open (parser
))
9928 t1
= c_parser_type_name (parser
);
9934 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9936 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9940 t2
= c_parser_type_name (parser
);
9946 location_t close_paren_loc
= c_parser_peek_token (parser
)->location
;
9947 parens
.skip_until_found_close (parser
);
9949 e1
= groktypename (t1
, NULL
, NULL
);
9950 e2
= groktypename (t2
, NULL
, NULL
);
9951 if (e1
== error_mark_node
|| e2
== error_mark_node
)
9957 e1
= TYPE_MAIN_VARIANT (e1
);
9958 e2
= TYPE_MAIN_VARIANT (e2
);
9961 = comptypes (e1
, e2
) ? integer_one_node
: integer_zero_node
;
9962 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9965 case RID_BUILTIN_TGMATH
:
9967 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9968 location_t close_paren_loc
;
9970 c_parser_consume_token (parser
);
9971 if (!c_parser_get_builtin_args (parser
,
9980 if (vec_safe_length (cexpr_list
) < 3)
9982 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9989 FOR_EACH_VEC_ELT (*cexpr_list
, i
, p
)
9990 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
9991 unsigned int nargs
= check_tgmath_function (&(*cexpr_list
)[0], 1);
9997 if (vec_safe_length (cexpr_list
) < nargs
)
9999 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
10003 unsigned int num_functions
= vec_safe_length (cexpr_list
) - nargs
;
10004 if (num_functions
< 2)
10006 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
10011 /* The first NUM_FUNCTIONS expressions are the function
10012 pointers. The remaining NARGS expressions are the
10013 arguments that are to be passed to one of those
10014 functions, chosen following <tgmath.h> rules. */
10015 for (unsigned int j
= 1; j
< num_functions
; j
++)
10017 unsigned int this_nargs
10018 = check_tgmath_function (&(*cexpr_list
)[j
], j
+ 1);
10019 if (this_nargs
== 0)
10024 if (this_nargs
!= nargs
)
10026 error_at ((*cexpr_list
)[j
].get_location (),
10027 "argument %u of %<__builtin_tgmath%> has "
10028 "wrong number of arguments", j
+ 1);
10034 /* The functions all have the same number of arguments.
10035 Determine whether arguments and return types vary in
10036 ways permitted for <tgmath.h> functions. */
10037 /* The first entry in each of these vectors is for the
10038 return type, subsequent entries for parameter
10040 auto_vec
<enum tgmath_parm_kind
> parm_kind (nargs
+ 1);
10041 auto_vec
<tree
> parm_first (nargs
+ 1);
10042 auto_vec
<bool> parm_complex (nargs
+ 1);
10043 auto_vec
<bool> parm_varies (nargs
+ 1);
10044 tree first_type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[0].value
));
10045 tree first_ret
= TYPE_MAIN_VARIANT (TREE_TYPE (first_type
));
10046 parm_first
.quick_push (first_ret
);
10047 parm_complex
.quick_push (TREE_CODE (first_ret
) == COMPLEX_TYPE
);
10048 parm_varies
.quick_push (false);
10049 function_args_iterator iter
;
10051 unsigned int argpos
;
10052 FOREACH_FUNCTION_ARGS (first_type
, t
, iter
)
10054 if (t
== void_type_node
)
10056 parm_first
.quick_push (TYPE_MAIN_VARIANT (t
));
10057 parm_complex
.quick_push (TREE_CODE (t
) == COMPLEX_TYPE
);
10058 parm_varies
.quick_push (false);
10060 for (unsigned int j
= 1; j
< num_functions
; j
++)
10062 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
10063 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
10064 if (ret
!= parm_first
[0])
10066 parm_varies
[0] = true;
10067 if (!SCALAR_FLOAT_TYPE_P (parm_first
[0])
10068 && !COMPLEX_FLOAT_TYPE_P (parm_first
[0]))
10070 error_at ((*cexpr_list
)[0].get_location (),
10071 "invalid type-generic return type for "
10072 "argument %u of %<__builtin_tgmath%>",
10077 if (!SCALAR_FLOAT_TYPE_P (ret
)
10078 && !COMPLEX_FLOAT_TYPE_P (ret
))
10080 error_at ((*cexpr_list
)[j
].get_location (),
10081 "invalid type-generic return type for "
10082 "argument %u of %<__builtin_tgmath%>",
10088 if (TREE_CODE (ret
) == COMPLEX_TYPE
)
10089 parm_complex
[0] = true;
10091 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
10093 if (t
== void_type_node
)
10095 t
= TYPE_MAIN_VARIANT (t
);
10096 if (t
!= parm_first
[argpos
])
10098 parm_varies
[argpos
] = true;
10099 if (!SCALAR_FLOAT_TYPE_P (parm_first
[argpos
])
10100 && !COMPLEX_FLOAT_TYPE_P (parm_first
[argpos
]))
10102 error_at ((*cexpr_list
)[0].get_location (),
10103 "invalid type-generic type for "
10104 "argument %u of argument %u of "
10105 "%<__builtin_tgmath%>", argpos
, 1);
10109 if (!SCALAR_FLOAT_TYPE_P (t
)
10110 && !COMPLEX_FLOAT_TYPE_P (t
))
10112 error_at ((*cexpr_list
)[j
].get_location (),
10113 "invalid type-generic type for "
10114 "argument %u of argument %u of "
10115 "%<__builtin_tgmath%>", argpos
, j
+ 1);
10120 if (TREE_CODE (t
) == COMPLEX_TYPE
)
10121 parm_complex
[argpos
] = true;
10125 enum tgmath_parm_kind max_variation
= tgmath_fixed
;
10126 for (unsigned int j
= 0; j
<= nargs
; j
++)
10128 enum tgmath_parm_kind this_kind
;
10129 if (parm_varies
[j
])
10131 if (parm_complex
[j
])
10132 max_variation
= this_kind
= tgmath_complex
;
10135 this_kind
= tgmath_real
;
10136 if (max_variation
!= tgmath_complex
)
10137 max_variation
= tgmath_real
;
10141 this_kind
= tgmath_fixed
;
10142 parm_kind
.quick_push (this_kind
);
10144 if (max_variation
== tgmath_fixed
)
10146 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
10147 "all have the same type");
10152 /* Identify a parameter (not the return type) that varies,
10153 including with complex types if any variation includes
10154 complex types; there must be at least one such
10156 unsigned int tgarg
= 0;
10157 for (unsigned int j
= 1; j
<= nargs
; j
++)
10158 if (parm_kind
[j
] == max_variation
)
10165 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
10166 "lack type-generic parameter");
10171 /* Determine the type of the relevant parameter for each
10173 auto_vec
<tree
> tg_type (num_functions
);
10174 for (unsigned int j
= 0; j
< num_functions
; j
++)
10176 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
10178 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
10180 if (argpos
== tgarg
)
10182 tg_type
.quick_push (TYPE_MAIN_VARIANT (t
));
10189 /* Verify that the corresponding types are different for
10190 all the listed functions. Also determine whether all
10191 the types are complex, whether all the types are
10192 standard or binary, and whether all the types are
10194 bool all_complex
= true;
10195 bool all_binary
= true;
10196 bool all_decimal
= true;
10197 hash_set
<tree
> tg_types
;
10198 FOR_EACH_VEC_ELT (tg_type
, i
, t
)
10200 if (TREE_CODE (t
) == COMPLEX_TYPE
)
10201 all_decimal
= false;
10204 all_complex
= false;
10205 if (DECIMAL_FLOAT_TYPE_P (t
))
10206 all_binary
= false;
10208 all_decimal
= false;
10210 if (tg_types
.add (t
))
10212 error_at ((*cexpr_list
)[i
].get_location (),
10213 "duplicate type-generic parameter type for "
10214 "function argument %u of %<__builtin_tgmath%>",
10221 /* Verify that other parameters and the return type whose
10222 types vary have their types varying in the correct
10224 for (unsigned int j
= 0; j
< num_functions
; j
++)
10226 tree exp_type
= tg_type
[j
];
10227 tree exp_real_type
= exp_type
;
10228 if (TREE_CODE (exp_type
) == COMPLEX_TYPE
)
10229 exp_real_type
= TREE_TYPE (exp_type
);
10230 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
10231 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
10232 if ((parm_kind
[0] == tgmath_complex
&& ret
!= exp_type
)
10233 || (parm_kind
[0] == tgmath_real
&& ret
!= exp_real_type
))
10235 error_at ((*cexpr_list
)[j
].get_location (),
10236 "bad return type for function argument %u "
10237 "of %<__builtin_tgmath%>", j
+ 1);
10242 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
10244 if (t
== void_type_node
)
10246 t
= TYPE_MAIN_VARIANT (t
);
10247 if ((parm_kind
[argpos
] == tgmath_complex
10249 || (parm_kind
[argpos
] == tgmath_real
10250 && t
!= exp_real_type
))
10252 error_at ((*cexpr_list
)[j
].get_location (),
10253 "bad type for argument %u of "
10254 "function argument %u of "
10255 "%<__builtin_tgmath%>", argpos
, j
+ 1);
10263 /* The functions listed are a valid set of functions for a
10264 <tgmath.h> macro to select between. Identify the
10265 matching function, if any. First, the argument types
10266 must be combined following <tgmath.h> rules. Integer
10267 types are treated as _Decimal64 if any type-generic
10268 argument is decimal, or if the only alternatives for
10269 type-generic arguments are of decimal types, and are
10270 otherwise treated as _Float32x (or _Complex _Float32x
10271 for complex integer types) if any type-generic argument
10272 has _FloatNx type, otherwise as double (or _Complex
10273 double for complex integer types). After that
10274 adjustment, types are combined following the usual
10275 arithmetic conversions. If the function only accepts
10276 complex arguments, a complex type is produced. */
10277 bool arg_complex
= all_complex
;
10278 bool arg_binary
= all_binary
;
10279 bool arg_int_decimal
= all_decimal
;
10280 bool arg_int_floatnx
= false;
10281 for (unsigned int j
= 1; j
<= nargs
; j
++)
10283 if (parm_kind
[j
] == tgmath_fixed
)
10285 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
10286 tree type
= TREE_TYPE (ce
->value
);
10287 if (!INTEGRAL_TYPE_P (type
)
10288 && !SCALAR_FLOAT_TYPE_P (type
)
10289 && TREE_CODE (type
) != COMPLEX_TYPE
)
10291 error_at (ce
->get_location (),
10292 "invalid type of argument %u of type-generic "
10297 if (DECIMAL_FLOAT_TYPE_P (type
))
10299 arg_int_decimal
= true;
10302 error_at (ce
->get_location (),
10303 "decimal floating-point argument %u to "
10304 "complex-only type-generic function", j
);
10308 else if (all_binary
)
10310 error_at (ce
->get_location (),
10311 "decimal floating-point argument %u to "
10312 "binary-only type-generic function", j
);
10316 else if (arg_complex
)
10318 error_at (ce
->get_location (),
10319 "both complex and decimal floating-point "
10320 "arguments to type-generic function");
10324 else if (arg_binary
)
10326 error_at (ce
->get_location (),
10327 "both binary and decimal floating-point "
10328 "arguments to type-generic function");
10333 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
10335 arg_complex
= true;
10336 if (COMPLEX_FLOAT_TYPE_P (type
))
10340 error_at (ce
->get_location (),
10341 "complex argument %u to "
10342 "decimal-only type-generic function", j
);
10346 else if (arg_int_decimal
)
10348 error_at (ce
->get_location (),
10349 "both complex and decimal floating-point "
10350 "arguments to type-generic function");
10355 else if (SCALAR_FLOAT_TYPE_P (type
))
10360 error_at (ce
->get_location (),
10361 "binary argument %u to "
10362 "decimal-only type-generic function", j
);
10366 else if (arg_int_decimal
)
10368 error_at (ce
->get_location (),
10369 "both binary and decimal floating-point "
10370 "arguments to type-generic function");
10375 tree rtype
= TYPE_MAIN_VARIANT (type
);
10376 if (TREE_CODE (rtype
) == COMPLEX_TYPE
)
10377 rtype
= TREE_TYPE (rtype
);
10378 if (SCALAR_FLOAT_TYPE_P (rtype
))
10379 for (unsigned int j
= 0; j
< NUM_FLOATNX_TYPES
; j
++)
10380 if (rtype
== FLOATNX_TYPE_NODE (j
))
10382 arg_int_floatnx
= true;
10386 tree arg_real
= NULL_TREE
;
10387 for (unsigned int j
= 1; j
<= nargs
; j
++)
10389 if (parm_kind
[j
] == tgmath_fixed
)
10391 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
10392 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (ce
->value
));
10393 if (TREE_CODE (type
) == COMPLEX_TYPE
)
10394 type
= TREE_TYPE (type
);
10395 if (INTEGRAL_TYPE_P (type
))
10396 type
= (arg_int_decimal
10397 ? dfloat64_type_node
10399 ? float32x_type_node
10400 : double_type_node
);
10401 if (arg_real
== NULL_TREE
)
10404 arg_real
= common_type (arg_real
, type
);
10405 if (arg_real
== error_mark_node
)
10411 tree arg_type
= (arg_complex
10412 ? build_complex_type (arg_real
)
10415 /* Look for a function to call with type-generic parameter
10417 c_expr_t
*fn
= NULL
;
10418 for (unsigned int j
= 0; j
< num_functions
; j
++)
10420 if (tg_type
[j
] == arg_type
)
10422 fn
= &(*cexpr_list
)[j
];
10427 && parm_kind
[0] == tgmath_fixed
10428 && SCALAR_FLOAT_TYPE_P (parm_first
[0]))
10430 /* Presume this is a macro that rounds its result to a
10431 narrower type, and look for the first function with
10432 at least the range and precision of the argument
10434 for (unsigned int j
= 0; j
< num_functions
; j
++)
10437 != (TREE_CODE (tg_type
[j
]) == COMPLEX_TYPE
))
10439 tree real_tg_type
= (arg_complex
10440 ? TREE_TYPE (tg_type
[j
])
10442 if (DECIMAL_FLOAT_TYPE_P (arg_real
)
10443 != DECIMAL_FLOAT_TYPE_P (real_tg_type
))
10445 scalar_float_mode arg_mode
10446 = SCALAR_FLOAT_TYPE_MODE (arg_real
);
10447 scalar_float_mode tg_mode
10448 = SCALAR_FLOAT_TYPE_MODE (real_tg_type
);
10449 const real_format
*arg_fmt
= REAL_MODE_FORMAT (arg_mode
);
10450 const real_format
*tg_fmt
= REAL_MODE_FORMAT (tg_mode
);
10451 if (arg_fmt
->b
== tg_fmt
->b
10452 && arg_fmt
->p
<= tg_fmt
->p
10453 && arg_fmt
->emax
<= tg_fmt
->emax
10454 && (arg_fmt
->emin
- arg_fmt
->p
10455 >= tg_fmt
->emin
- tg_fmt
->p
))
10457 fn
= &(*cexpr_list
)[j
];
10464 error_at (loc
, "no matching function for type-generic call");
10469 /* Construct a call to FN. */
10470 vec
<tree
, va_gc
> *args
;
10471 vec_alloc (args
, nargs
);
10472 vec
<tree
, va_gc
> *origtypes
;
10473 vec_alloc (origtypes
, nargs
);
10474 auto_vec
<location_t
> arg_loc (nargs
);
10475 for (unsigned int j
= 0; j
< nargs
; j
++)
10477 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
];
10478 args
->quick_push (ce
->value
);
10479 arg_loc
.quick_push (ce
->get_location ());
10480 origtypes
->quick_push (ce
->original_type
);
10482 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fn
->value
,
10484 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10487 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN
:
10489 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10492 location_t close_paren_loc
;
10494 c_parser_consume_token (parser
);
10495 if (!c_parser_get_builtin_args (parser
,
10496 "__builtin_call_with_static_chain",
10497 &cexpr_list
, false,
10503 if (vec_safe_length (cexpr_list
) != 2)
10505 error_at (loc
, "wrong number of arguments to "
10506 "%<__builtin_call_with_static_chain%>");
10511 expr
= (*cexpr_list
)[0];
10512 e2_p
= &(*cexpr_list
)[1];
10513 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
10514 chain_value
= e2_p
->value
;
10515 mark_exp_read (chain_value
);
10517 if (TREE_CODE (expr
.value
) != CALL_EXPR
)
10518 error_at (loc
, "first argument to "
10519 "%<__builtin_call_with_static_chain%> "
10520 "must be a call expression");
10521 else if (TREE_CODE (TREE_TYPE (chain_value
)) != POINTER_TYPE
)
10522 error_at (loc
, "second argument to "
10523 "%<__builtin_call_with_static_chain%> "
10524 "must be a pointer type");
10526 CALL_EXPR_STATIC_CHAIN (expr
.value
) = chain_value
;
10527 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10530 case RID_BUILTIN_COMPLEX
:
10532 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10533 c_expr_t
*e1_p
, *e2_p
;
10534 location_t close_paren_loc
;
10536 c_parser_consume_token (parser
);
10537 if (!c_parser_get_builtin_args (parser
,
10538 "__builtin_complex",
10539 &cexpr_list
, false,
10546 if (vec_safe_length (cexpr_list
) != 2)
10548 error_at (loc
, "wrong number of arguments to "
10549 "%<__builtin_complex%>");
10554 e1_p
= &(*cexpr_list
)[0];
10555 e2_p
= &(*cexpr_list
)[1];
10557 *e1_p
= convert_lvalue_to_rvalue (loc
, *e1_p
, true, true);
10558 if (TREE_CODE (e1_p
->value
) == EXCESS_PRECISION_EXPR
)
10559 e1_p
->value
= convert (TREE_TYPE (e1_p
->value
),
10560 TREE_OPERAND (e1_p
->value
, 0));
10561 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
10562 if (TREE_CODE (e2_p
->value
) == EXCESS_PRECISION_EXPR
)
10563 e2_p
->value
= convert (TREE_TYPE (e2_p
->value
),
10564 TREE_OPERAND (e2_p
->value
, 0));
10565 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
10566 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
10567 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
))
10568 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
)))
10570 error_at (loc
, "%<__builtin_complex%> operand "
10571 "not of real binary floating-point type");
10575 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p
->value
))
10576 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p
->value
)))
10579 "%<__builtin_complex%> operands of different types");
10583 pedwarn_c90 (loc
, OPT_Wpedantic
,
10584 "ISO C90 does not support complex types");
10585 expr
.value
= build2_loc (loc
, COMPLEX_EXPR
,
10588 (TREE_TYPE (e1_p
->value
))),
10589 e1_p
->value
, e2_p
->value
);
10590 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10593 case RID_BUILTIN_SHUFFLE
:
10595 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10598 location_t close_paren_loc
;
10600 c_parser_consume_token (parser
);
10601 if (!c_parser_get_builtin_args (parser
,
10602 "__builtin_shuffle",
10603 &cexpr_list
, false,
10610 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
10611 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
10613 if (vec_safe_length (cexpr_list
) == 2)
10614 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10616 (*cexpr_list
)[1].value
);
10618 else if (vec_safe_length (cexpr_list
) == 3)
10619 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10620 (*cexpr_list
)[1].value
,
10621 (*cexpr_list
)[2].value
);
10624 error_at (loc
, "wrong number of arguments to "
10625 "%<__builtin_shuffle%>");
10628 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10631 case RID_BUILTIN_SHUFFLEVECTOR
:
10633 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10636 location_t close_paren_loc
;
10638 c_parser_consume_token (parser
);
10639 if (!c_parser_get_builtin_args (parser
,
10640 "__builtin_shufflevector",
10641 &cexpr_list
, false,
10648 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
10649 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
10651 if (vec_safe_length (cexpr_list
) < 3)
10653 error_at (loc
, "wrong number of arguments to "
10654 "%<__builtin_shuffle%>");
10659 auto_vec
<tree
, 16> mask
;
10660 for (i
= 2; i
< cexpr_list
->length (); ++i
)
10661 mask
.safe_push ((*cexpr_list
)[i
].value
);
10662 expr
.value
= c_build_shufflevector (loc
, (*cexpr_list
)[0].value
,
10663 (*cexpr_list
)[1].value
,
10666 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10669 case RID_BUILTIN_CONVERTVECTOR
:
10671 location_t start_loc
= loc
;
10672 c_parser_consume_token (parser
);
10673 matching_parens parens
;
10674 if (!parens
.require_open (parser
))
10679 e1
= c_parser_expr_no_commas (parser
, NULL
);
10680 mark_exp_read (e1
.value
);
10681 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10683 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10687 loc
= c_parser_peek_token (parser
)->location
;
10688 t1
= c_parser_type_name (parser
);
10689 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10690 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10696 tree type_expr
= NULL_TREE
;
10697 expr
.value
= c_build_vec_convert (start_loc
, e1
.value
, loc
,
10698 groktypename (t1
, &type_expr
,
10700 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10704 case RID_BUILTIN_ASSOC_BARRIER
:
10706 location_t start_loc
= loc
;
10707 c_parser_consume_token (parser
);
10708 matching_parens parens
;
10709 if (!parens
.require_open (parser
))
10714 e1
= c_parser_expr_no_commas (parser
, NULL
);
10715 mark_exp_read (e1
.value
);
10716 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10717 parens
.skip_until_found_close (parser
);
10718 expr
= parser_build_unary_op (loc
, PAREN_EXPR
, e1
);
10719 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10722 case RID_AT_SELECTOR
:
10724 gcc_assert (c_dialect_objc ());
10725 c_parser_consume_token (parser
);
10726 matching_parens parens
;
10727 if (!parens
.require_open (parser
))
10732 tree sel
= c_parser_objc_selector_arg (parser
);
10733 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10734 parens
.skip_until_found_close (parser
);
10735 expr
.value
= objc_build_selector_expr (loc
, sel
);
10736 set_c_expr_source_range (&expr
, loc
, close_loc
);
10739 case RID_AT_PROTOCOL
:
10741 gcc_assert (c_dialect_objc ());
10742 c_parser_consume_token (parser
);
10743 matching_parens parens
;
10744 if (!parens
.require_open (parser
))
10749 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10751 c_parser_error (parser
, "expected identifier");
10752 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10756 tree id
= c_parser_peek_token (parser
)->value
;
10757 c_parser_consume_token (parser
);
10758 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10759 parens
.skip_until_found_close (parser
);
10760 expr
.value
= objc_build_protocol_expr (id
);
10761 set_c_expr_source_range (&expr
, loc
, close_loc
);
10764 case RID_AT_ENCODE
:
10766 /* Extension to support C-structures in the archiver. */
10767 gcc_assert (c_dialect_objc ());
10768 c_parser_consume_token (parser
);
10769 matching_parens parens
;
10770 if (!parens
.require_open (parser
))
10775 t1
= c_parser_type_name (parser
);
10779 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10782 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10783 parens
.skip_until_found_close (parser
);
10784 tree type
= groktypename (t1
, NULL
, NULL
);
10785 expr
.value
= objc_build_encode_expr (type
);
10786 set_c_expr_source_range (&expr
, loc
, close_loc
);
10790 expr
= c_parser_generic_selection (parser
);
10792 case RID_OMP_ALL_MEMORY
:
10793 gcc_assert (flag_openmp
);
10794 c_parser_consume_token (parser
);
10795 error_at (loc
, "%<omp_all_memory%> may only be used in OpenMP "
10796 "%<depend%> clause");
10799 /* C23 'nullptr' literal. */
10801 c_parser_consume_token (parser
);
10802 expr
.value
= nullptr_node
;
10803 set_c_expr_source_range (&expr
, tok_range
);
10804 pedwarn_c11 (loc
, OPT_Wpedantic
,
10805 "ISO C does not support %qs before C2X", "nullptr");
10808 c_parser_consume_token (parser
);
10809 expr
.value
= boolean_true_node
;
10810 set_c_expr_source_range (&expr
, tok_range
);
10813 c_parser_consume_token (parser
);
10814 expr
.value
= boolean_false_node
;
10815 set_c_expr_source_range (&expr
, tok_range
);
10818 c_parser_error (parser
, "expected expression");
10823 case CPP_OPEN_SQUARE
:
10824 if (c_dialect_objc ())
10826 tree receiver
, args
;
10827 c_parser_consume_token (parser
);
10828 receiver
= c_parser_objc_receiver (parser
);
10829 args
= c_parser_objc_message_args (parser
);
10830 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10831 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10833 expr
.value
= objc_build_message_expr (receiver
, args
);
10834 set_c_expr_source_range (&expr
, loc
, close_loc
);
10837 /* Else fall through to report error. */
10840 c_parser_error (parser
, "expected expression");
10845 return c_parser_postfix_expression_after_primary
10846 (parser
, EXPR_LOC_OR_LOC (expr
.value
, loc
), expr
);
10849 /* Parse a postfix expression after a parenthesized type name: the
10850 brace-enclosed initializer of a compound literal, possibly followed
10851 by some postfix operators. This is separate because it is not
10852 possible to tell until after the type name whether a cast
10853 expression has a cast or a compound literal, or whether the operand
10854 of sizeof is a parenthesized type name or starts with a compound
10855 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10856 location of the first token after the parentheses around the type
10859 static struct c_expr
10860 c_parser_postfix_expression_after_paren_type (c_parser
*parser
,
10861 struct c_declspecs
*scspecs
,
10862 struct c_type_name
*type_name
,
10863 location_t type_loc
)
10866 struct c_expr init
;
10868 struct c_expr expr
;
10869 location_t start_loc
;
10870 tree type_expr
= NULL_TREE
;
10871 bool type_expr_const
= true;
10872 bool constexpr_p
= scspecs
? scspecs
->constexpr_p
: false;
10873 unsigned int underspec_state
= 0;
10874 check_compound_literal_type (type_loc
, type_name
);
10875 rich_location
richloc (line_table
, type_loc
);
10876 start_loc
= c_parser_peek_token (parser
)->location
;
10879 underspec_state
= start_underspecified_init (start_loc
, NULL_TREE
);
10880 /* A constexpr compound literal is subject to the constraints on
10881 underspecified declarations, which may not declare tags or
10882 members or structures or unions; it is undefined behavior to
10883 declare the members of an enumeration. Where the structure,
10884 union or enumeration type is declared within the compound
10885 literal initializer, this is diagnosed elsewhere as a result
10886 of the above call to start_underspecified_init. Diagnose
10887 here the case of declaring such a type in the type specifiers
10888 of the compound literal. */
10889 switch (type_name
->specs
->typespec_kind
)
10891 case ctsk_tagfirstref
:
10892 case ctsk_tagfirstref_attrs
:
10893 error_at (type_loc
, "%qT declared in %<constexpr%> compound literal",
10894 type_name
->specs
->type
);
10898 error_at (type_loc
, "%qT defined in %<constexpr%> compound literal",
10899 type_name
->specs
->type
);
10906 start_init (NULL_TREE
, NULL
,
10907 (global_bindings_p ()
10908 || (scspecs
&& scspecs
->storage_class
== csc_static
)
10909 || constexpr_p
), constexpr_p
, &richloc
);
10910 type
= groktypename (type_name
, &type_expr
, &type_expr_const
);
10911 if (type
!= error_mark_node
&& C_TYPE_VARIABLE_SIZE (type
))
10913 error_at (type_loc
, "compound literal has variable size");
10914 type
= error_mark_node
;
10916 else if (TREE_CODE (type
) == FUNCTION_TYPE
)
10918 error_at (type_loc
, "compound literal has function type");
10919 type
= error_mark_node
;
10921 if (constexpr_p
&& type
!= error_mark_node
)
10923 tree type_no_array
= strip_array_types (type
);
10924 /* The type of a constexpr object must not be variably modified
10925 (which applies to all compound literals), volatile, atomic or
10926 restrict qualified or have a member with such a qualifier.
10927 const qualification is implicitly added. */
10928 if (TYPE_QUALS (type_no_array
)
10929 & (TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
| TYPE_QUAL_ATOMIC
))
10930 error_at (type_loc
, "invalid qualifiers for %<constexpr%> object");
10931 else if (RECORD_OR_UNION_TYPE_P (type_no_array
)
10932 && C_TYPE_FIELDS_NON_CONSTEXPR (type_no_array
))
10933 error_at (type_loc
, "invalid qualifiers for field of "
10934 "%<constexpr%> object");
10935 type
= c_build_qualified_type (type
,
10936 (TYPE_QUALS (type_no_array
)
10937 | TYPE_QUAL_CONST
));
10939 init
= c_parser_braced_init (parser
, type
, false, NULL
, NULL_TREE
);
10941 finish_underspecified_init (NULL_TREE
, underspec_state
);
10943 maybe_warn_string_init (type_loc
, type
, init
);
10945 if (type
!= error_mark_node
10946 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type
))
10947 && current_function_decl
)
10949 error ("compound literal qualified by address-space qualifier");
10950 type
= error_mark_node
;
10953 if (!pedwarn_c90 (start_loc
, OPT_Wpedantic
,
10954 "ISO C90 forbids compound literals") && scspecs
)
10955 pedwarn_c11 (start_loc
, OPT_Wpedantic
,
10956 "ISO C forbids storage class specifiers in compound literals "
10958 non_const
= ((init
.value
&& TREE_CODE (init
.value
) == CONSTRUCTOR
)
10959 ? CONSTRUCTOR_NON_CONST (init
.value
)
10960 : init
.original_code
== C_MAYBE_CONST_EXPR
);
10961 non_const
|= !type_expr_const
;
10962 unsigned int alignas_align
= 0;
10963 if (type
!= error_mark_node
10964 && type_name
->specs
->align_log
!= -1)
10966 alignas_align
= 1U << type_name
->specs
->align_log
;
10967 if (alignas_align
< min_align_of_type (type
))
10969 error_at (type_name
->specs
->locations
[cdw_alignas
],
10970 "%<_Alignas%> specifiers cannot reduce "
10971 "alignment of compound literal");
10975 expr
.value
= build_compound_literal (start_loc
, type
, init
.value
, non_const
,
10976 alignas_align
, scspecs
);
10977 set_c_expr_source_range (&expr
, init
.src_range
);
10978 expr
.m_decimal
= 0;
10979 expr
.original_code
= ERROR_MARK
;
10980 expr
.original_type
= NULL
;
10981 if (type
!= error_mark_node
10982 && expr
.value
!= error_mark_node
10985 if (TREE_CODE (expr
.value
) == C_MAYBE_CONST_EXPR
)
10987 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr
.value
) == NULL_TREE
);
10988 C_MAYBE_CONST_EXPR_PRE (expr
.value
) = type_expr
;
10992 gcc_assert (!non_const
);
10993 expr
.value
= build2 (C_MAYBE_CONST_EXPR
, type
,
10994 type_expr
, expr
.value
);
10997 return c_parser_postfix_expression_after_primary (parser
, start_loc
, expr
);
11000 /* Callback function for sizeof_pointer_memaccess_warning to compare
11004 sizeof_ptr_memacc_comptypes (tree type1
, tree type2
)
11006 return comptypes (type1
, type2
) == 1;
11009 /* Warn for patterns where abs-like function appears to be used incorrectly,
11010 gracefully ignore any non-abs-like function. The warning location should
11011 be LOC. FNDECL is the declaration of called function, it must be a
11012 BUILT_IN_NORMAL function. ARG is the first and only argument of the
11016 warn_for_abs (location_t loc
, tree fndecl
, tree arg
)
11018 /* Avoid warning in unreachable subexpressions. */
11019 if (c_inhibit_evaluation_warnings
)
11022 tree atype
= TREE_TYPE (arg
);
11024 /* Casts from pointers (and thus arrays and fndecls) will generate
11025 -Wint-conversion warnings. Most other wrong types hopefully lead to type
11026 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
11027 types and possibly other exotic types. */
11028 if (!INTEGRAL_TYPE_P (atype
)
11029 && !SCALAR_FLOAT_TYPE_P (atype
)
11030 && TREE_CODE (atype
) != COMPLEX_TYPE
)
11033 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
11038 case BUILT_IN_LABS
:
11039 case BUILT_IN_LLABS
:
11040 case BUILT_IN_IMAXABS
:
11041 if (!INTEGRAL_TYPE_P (atype
))
11043 if (SCALAR_FLOAT_TYPE_P (atype
))
11044 warning_at (loc
, OPT_Wabsolute_value
,
11045 "using integer absolute value function %qD when "
11046 "argument is of floating-point type %qT",
11048 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
11049 warning_at (loc
, OPT_Wabsolute_value
,
11050 "using integer absolute value function %qD when "
11051 "argument is of complex type %qT", fndecl
, atype
);
11053 gcc_unreachable ();
11056 if (TYPE_UNSIGNED (atype
))
11057 warning_at (loc
, OPT_Wabsolute_value
,
11058 "taking the absolute value of unsigned type %qT "
11059 "has no effect", atype
);
11062 CASE_FLT_FN (BUILT_IN_FABS
):
11063 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS
):
11064 if (!SCALAR_FLOAT_TYPE_P (atype
)
11065 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype
)))
11067 if (INTEGRAL_TYPE_P (atype
))
11068 warning_at (loc
, OPT_Wabsolute_value
,
11069 "using floating-point absolute value function %qD "
11070 "when argument is of integer type %qT", fndecl
, atype
);
11071 else if (DECIMAL_FLOAT_TYPE_P (atype
))
11072 warning_at (loc
, OPT_Wabsolute_value
,
11073 "using floating-point absolute value function %qD "
11074 "when argument is of decimal floating-point type %qT",
11076 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
11077 warning_at (loc
, OPT_Wabsolute_value
,
11078 "using floating-point absolute value function %qD when "
11079 "argument is of complex type %qT", fndecl
, atype
);
11081 gcc_unreachable ();
11086 CASE_FLT_FN (BUILT_IN_CABS
):
11087 if (TREE_CODE (atype
) != COMPLEX_TYPE
)
11089 if (INTEGRAL_TYPE_P (atype
))
11090 warning_at (loc
, OPT_Wabsolute_value
,
11091 "using complex absolute value function %qD when "
11092 "argument is of integer type %qT", fndecl
, atype
);
11093 else if (SCALAR_FLOAT_TYPE_P (atype
))
11094 warning_at (loc
, OPT_Wabsolute_value
,
11095 "using complex absolute value function %qD when "
11096 "argument is of floating-point type %qT",
11099 gcc_unreachable ();
11105 case BUILT_IN_FABSD32
:
11106 case BUILT_IN_FABSD64
:
11107 case BUILT_IN_FABSD128
:
11108 if (!DECIMAL_FLOAT_TYPE_P (atype
))
11110 if (INTEGRAL_TYPE_P (atype
))
11111 warning_at (loc
, OPT_Wabsolute_value
,
11112 "using decimal floating-point absolute value "
11113 "function %qD when argument is of integer type %qT",
11115 else if (SCALAR_FLOAT_TYPE_P (atype
))
11116 warning_at (loc
, OPT_Wabsolute_value
,
11117 "using decimal floating-point absolute value "
11118 "function %qD when argument is of floating-point "
11119 "type %qT", fndecl
, atype
);
11120 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
11121 warning_at (loc
, OPT_Wabsolute_value
,
11122 "using decimal floating-point absolute value "
11123 "function %qD when argument is of complex type %qT",
11126 gcc_unreachable ();
11135 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl
)))
11138 tree ftype
= TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
11139 if (TREE_CODE (atype
) == COMPLEX_TYPE
)
11141 gcc_assert (TREE_CODE (ftype
) == COMPLEX_TYPE
);
11142 atype
= TREE_TYPE (atype
);
11143 ftype
= TREE_TYPE (ftype
);
11146 if (TYPE_PRECISION (ftype
) < TYPE_PRECISION (atype
))
11147 warning_at (loc
, OPT_Wabsolute_value
,
11148 "absolute value function %qD given an argument of type %qT "
11149 "but has parameter of type %qT which may cause truncation "
11150 "of value", fndecl
, atype
, ftype
);
11154 /* Parse a postfix expression after the initial primary or compound
11155 literal; that is, parse a series of postfix operators.
11157 EXPR_LOC is the location of the primary expression. */
11159 static struct c_expr
11160 c_parser_postfix_expression_after_primary (c_parser
*parser
,
11161 location_t expr_loc
,
11162 struct c_expr expr
)
11164 struct c_expr orig_expr
;
11166 location_t sizeof_arg_loc
[3], comp_loc
;
11167 tree sizeof_arg
[3];
11168 unsigned int literal_zero_mask
;
11170 vec
<tree
, va_gc
> *exprlist
;
11171 vec
<tree
, va_gc
> *origtypes
= NULL
;
11172 vec
<location_t
> arg_loc
= vNULL
;
11178 location_t op_loc
= c_parser_peek_token (parser
)->location
;
11179 switch (c_parser_peek_token (parser
)->type
)
11181 case CPP_OPEN_SQUARE
:
11182 /* Array reference. */
11183 c_parser_consume_token (parser
);
11184 idx
= c_parser_expression (parser
).value
;
11185 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
11187 start
= expr
.get_start ();
11188 finish
= parser
->tokens_buf
[0].location
;
11189 expr
.value
= build_array_ref (op_loc
, expr
.value
, idx
);
11190 set_c_expr_source_range (&expr
, start
, finish
);
11191 expr
.original_code
= ERROR_MARK
;
11192 expr
.original_type
= NULL
;
11193 expr
.m_decimal
= 0;
11195 case CPP_OPEN_PAREN
:
11196 /* Function call. */
11198 matching_parens parens
;
11199 parens
.consume_open (parser
);
11200 for (i
= 0; i
< 3; i
++)
11202 sizeof_arg
[i
] = NULL_TREE
;
11203 sizeof_arg_loc
[i
] = UNKNOWN_LOCATION
;
11205 literal_zero_mask
= 0;
11206 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
11209 exprlist
= c_parser_expr_list (parser
, true, false, &origtypes
,
11210 sizeof_arg_loc
, sizeof_arg
,
11211 &arg_loc
, &literal_zero_mask
);
11212 parens
.skip_until_found_close (parser
);
11215 mark_exp_read (expr
.value
);
11216 if (warn_sizeof_pointer_memaccess
)
11217 sizeof_pointer_memaccess_warning (sizeof_arg_loc
,
11218 expr
.value
, exprlist
,
11220 sizeof_ptr_memacc_comptypes
);
11221 if (TREE_CODE (expr
.value
) == FUNCTION_DECL
)
11223 if (fndecl_built_in_p (expr
.value
, BUILT_IN_MEMSET
)
11224 && vec_safe_length (exprlist
) == 3)
11226 tree arg0
= (*exprlist
)[0];
11227 tree arg2
= (*exprlist
)[2];
11228 warn_for_memset (expr_loc
, arg0
, arg2
, literal_zero_mask
);
11230 if (warn_absolute_value
11231 && fndecl_built_in_p (expr
.value
, BUILT_IN_NORMAL
)
11232 && vec_safe_length (exprlist
) == 1)
11233 warn_for_abs (expr_loc
, expr
.value
, (*exprlist
)[0]);
11236 start
= expr
.get_start ();
11237 finish
= parser
->tokens_buf
[0].get_finish ();
11239 = c_build_function_call_vec (expr_loc
, arg_loc
, expr
.value
,
11240 exprlist
, origtypes
);
11241 set_c_expr_source_range (&expr
, start
, finish
);
11242 expr
.m_decimal
= 0;
11244 expr
.original_code
= ERROR_MARK
;
11245 if (TREE_CODE (expr
.value
) == INTEGER_CST
11246 && TREE_CODE (orig_expr
.value
) == FUNCTION_DECL
11247 && fndecl_built_in_p (orig_expr
.value
, BUILT_IN_CONSTANT_P
))
11248 expr
.original_code
= C_MAYBE_CONST_EXPR
;
11249 expr
.original_type
= NULL
;
11252 release_tree_vector (exprlist
);
11253 release_tree_vector (origtypes
);
11255 arg_loc
.release ();
11258 /* Structure element reference. */
11259 c_parser_consume_token (parser
);
11260 expr
= default_function_array_conversion (expr_loc
, expr
);
11261 if (c_parser_next_token_is (parser
, CPP_NAME
))
11263 c_token
*comp_tok
= c_parser_peek_token (parser
);
11264 ident
= comp_tok
->value
;
11265 comp_loc
= comp_tok
->location
;
11269 c_parser_error (parser
, "expected identifier");
11271 expr
.original_code
= ERROR_MARK
;
11272 expr
.original_type
= NULL
;
11275 start
= expr
.get_start ();
11276 finish
= c_parser_peek_token (parser
)->get_finish ();
11277 c_parser_consume_token (parser
);
11278 expr
.value
= build_component_ref (op_loc
, expr
.value
, ident
,
11279 comp_loc
, UNKNOWN_LOCATION
);
11280 set_c_expr_source_range (&expr
, start
, finish
);
11281 expr
.original_code
= ERROR_MARK
;
11282 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
11283 expr
.original_type
= NULL
;
11286 /* Remember the original type of a bitfield. */
11287 tree field
= TREE_OPERAND (expr
.value
, 1);
11288 if (TREE_CODE (field
) != FIELD_DECL
)
11289 expr
.original_type
= NULL
;
11291 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
11293 expr
.m_decimal
= 0;
11296 /* Structure element reference. */
11297 c_parser_consume_token (parser
);
11298 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, false);
11299 if (c_parser_next_token_is (parser
, CPP_NAME
))
11301 c_token
*comp_tok
= c_parser_peek_token (parser
);
11302 ident
= comp_tok
->value
;
11303 comp_loc
= comp_tok
->location
;
11307 c_parser_error (parser
, "expected identifier");
11309 expr
.original_code
= ERROR_MARK
;
11310 expr
.original_type
= NULL
;
11313 start
= expr
.get_start ();
11314 finish
= c_parser_peek_token (parser
)->get_finish ();
11315 c_parser_consume_token (parser
);
11316 expr
.value
= build_component_ref (op_loc
,
11317 build_indirect_ref (op_loc
,
11321 expr
.get_location ());
11322 set_c_expr_source_range (&expr
, start
, finish
);
11323 expr
.original_code
= ERROR_MARK
;
11324 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
11325 expr
.original_type
= NULL
;
11328 /* Remember the original type of a bitfield. */
11329 tree field
= TREE_OPERAND (expr
.value
, 1);
11330 if (TREE_CODE (field
) != FIELD_DECL
)
11331 expr
.original_type
= NULL
;
11333 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
11335 expr
.m_decimal
= 0;
11337 case CPP_PLUS_PLUS
:
11338 /* Postincrement. */
11339 start
= expr
.get_start ();
11340 finish
= c_parser_peek_token (parser
)->get_finish ();
11341 c_parser_consume_token (parser
);
11342 expr
= default_function_array_read_conversion (expr_loc
, expr
);
11343 expr
.value
= build_unary_op (op_loc
, POSTINCREMENT_EXPR
,
11344 expr
.value
, false);
11345 set_c_expr_source_range (&expr
, start
, finish
);
11346 expr
.original_code
= ERROR_MARK
;
11347 expr
.original_type
= NULL
;
11349 case CPP_MINUS_MINUS
:
11350 /* Postdecrement. */
11351 start
= expr
.get_start ();
11352 finish
= c_parser_peek_token (parser
)->get_finish ();
11353 c_parser_consume_token (parser
);
11354 expr
= default_function_array_read_conversion (expr_loc
, expr
);
11355 expr
.value
= build_unary_op (op_loc
, POSTDECREMENT_EXPR
,
11356 expr
.value
, false);
11357 set_c_expr_source_range (&expr
, start
, finish
);
11358 expr
.original_code
= ERROR_MARK
;
11359 expr
.original_type
= NULL
;
11367 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
11370 assignment-expression
11371 expression , assignment-expression
11374 static struct c_expr
11375 c_parser_expression (c_parser
*parser
)
11377 location_t tloc
= c_parser_peek_token (parser
)->location
;
11378 struct c_expr expr
;
11379 expr
= c_parser_expr_no_commas (parser
, NULL
);
11380 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11381 expr
= convert_lvalue_to_rvalue (tloc
, expr
, true, false);
11382 while (c_parser_next_token_is (parser
, CPP_COMMA
))
11384 struct c_expr next
;
11386 location_t loc
= c_parser_peek_token (parser
)->location
;
11387 location_t expr_loc
;
11388 c_parser_consume_token (parser
);
11389 expr_loc
= c_parser_peek_token (parser
)->location
;
11390 lhsval
= expr
.value
;
11391 while (TREE_CODE (lhsval
) == COMPOUND_EXPR
11392 || TREE_CODE (lhsval
) == NOP_EXPR
)
11394 if (TREE_CODE (lhsval
) == COMPOUND_EXPR
)
11395 lhsval
= TREE_OPERAND (lhsval
, 1);
11397 lhsval
= TREE_OPERAND (lhsval
, 0);
11399 if (DECL_P (lhsval
) || handled_component_p (lhsval
))
11400 mark_exp_read (lhsval
);
11401 next
= c_parser_expr_no_commas (parser
, NULL
);
11402 next
= convert_lvalue_to_rvalue (expr_loc
, next
, true, false);
11403 expr
.value
= build_compound_expr (loc
, expr
.value
, next
.value
);
11404 expr
.original_code
= COMPOUND_EXPR
;
11405 expr
.original_type
= next
.original_type
;
11406 expr
.m_decimal
= 0;
11411 /* Parse an expression and convert functions or arrays to pointers and
11412 lvalues to rvalues. */
11414 static struct c_expr
11415 c_parser_expression_conv (c_parser
*parser
)
11417 struct c_expr expr
;
11418 location_t loc
= c_parser_peek_token (parser
)->location
;
11419 expr
= c_parser_expression (parser
);
11420 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, false);
11424 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
11425 argument is a literal zero alone and if so, set it in literal_zero_mask. */
11428 c_parser_check_literal_zero (c_parser
*parser
, unsigned *literal_zero_mask
,
11431 if (idx
>= HOST_BITS_PER_INT
)
11434 c_token
*tok
= c_parser_peek_token (parser
);
11443 /* If a parameter is literal zero alone, remember it
11444 for -Wmemset-transposed-args warning. */
11445 if (integer_zerop (tok
->value
)
11446 && !TREE_OVERFLOW (tok
->value
)
11447 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
11448 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
11449 *literal_zero_mask
|= 1U << idx
;
11455 /* Parse a non-empty list of expressions. If CONVERT_P, convert
11456 functions and arrays to pointers and lvalues to rvalues. If
11457 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
11458 locations of function arguments into this vector.
11460 nonempty-expr-list:
11461 assignment-expression
11462 nonempty-expr-list , assignment-expression
11465 static vec
<tree
, va_gc
> *
11466 c_parser_expr_list (c_parser
*parser
, bool convert_p
, bool fold_p
,
11467 vec
<tree
, va_gc
> **p_orig_types
,
11468 location_t
*sizeof_arg_loc
, tree
*sizeof_arg
,
11469 vec
<location_t
> *locations
,
11470 unsigned int *literal_zero_mask
)
11472 vec
<tree
, va_gc
> *ret
;
11473 vec
<tree
, va_gc
> *orig_types
;
11474 struct c_expr expr
;
11475 unsigned int idx
= 0;
11477 ret
= make_tree_vector ();
11478 if (p_orig_types
== NULL
)
11481 orig_types
= make_tree_vector ();
11483 if (literal_zero_mask
)
11484 c_parser_check_literal_zero (parser
, literal_zero_mask
, 0);
11485 expr
= c_parser_expr_no_commas (parser
, NULL
);
11487 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true, true);
11489 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
11490 ret
->quick_push (expr
.value
);
11492 orig_types
->quick_push (expr
.original_type
);
11494 locations
->safe_push (expr
.get_location ());
11495 if (sizeof_arg
!= NULL
11496 && (expr
.original_code
== SIZEOF_EXPR
11497 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
11499 sizeof_arg
[0] = c_last_sizeof_arg
;
11500 sizeof_arg_loc
[0] = c_last_sizeof_loc
;
11502 while (c_parser_next_token_is (parser
, CPP_COMMA
))
11504 c_parser_consume_token (parser
);
11505 if (literal_zero_mask
)
11506 c_parser_check_literal_zero (parser
, literal_zero_mask
, idx
+ 1);
11507 expr
= c_parser_expr_no_commas (parser
, NULL
);
11509 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true,
11512 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
11513 vec_safe_push (ret
, expr
.value
);
11515 vec_safe_push (orig_types
, expr
.original_type
);
11517 locations
->safe_push (expr
.get_location ());
11519 && sizeof_arg
!= NULL
11520 && (expr
.original_code
== SIZEOF_EXPR
11521 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
11523 sizeof_arg
[idx
] = c_last_sizeof_arg
;
11524 sizeof_arg_loc
[idx
] = c_last_sizeof_loc
;
11528 *p_orig_types
= orig_types
;
11532 /* Parse Objective-C-specific constructs. */
11534 /* Parse an objc-class-definition.
11536 objc-class-definition:
11537 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
11538 objc-class-instance-variables[opt] objc-methodprotolist @end
11539 @implementation identifier objc-superclass[opt]
11540 objc-class-instance-variables[opt]
11541 @interface identifier ( identifier ) objc-protocol-refs[opt]
11542 objc-methodprotolist @end
11543 @interface identifier ( ) objc-protocol-refs[opt]
11544 objc-methodprotolist @end
11545 @implementation identifier ( identifier )
11550 "@interface identifier (" must start "@interface identifier (
11551 identifier ) ...": objc-methodprotolist in the first production may
11552 not start with a parenthesized identifier as a declarator of a data
11553 definition with no declaration specifiers if the objc-superclass,
11554 objc-protocol-refs and objc-class-instance-variables are omitted. */
11557 c_parser_objc_class_definition (c_parser
*parser
, tree attributes
)
11562 if (c_parser_next_token_is_keyword (parser
, RID_AT_INTERFACE
))
11564 else if (c_parser_next_token_is_keyword (parser
, RID_AT_IMPLEMENTATION
))
11567 gcc_unreachable ();
11569 c_parser_consume_token (parser
);
11570 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11572 c_parser_error (parser
, "expected identifier");
11575 id1
= c_parser_peek_token (parser
)->value
;
11576 location_t loc1
= c_parser_peek_token (parser
)->location
;
11577 c_parser_consume_token (parser
);
11578 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11580 /* We have a category or class extension. */
11582 tree proto
= NULL_TREE
;
11583 matching_parens parens
;
11584 parens
.consume_open (parser
);
11585 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11587 if (iface_p
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
11589 /* We have a class extension. */
11594 c_parser_error (parser
, "expected identifier or %<)%>");
11595 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
11601 id2
= c_parser_peek_token (parser
)->value
;
11602 c_parser_consume_token (parser
);
11604 parens
.skip_until_found_close (parser
);
11607 objc_start_category_implementation (id1
, id2
);
11610 if (c_parser_next_token_is (parser
, CPP_LESS
))
11611 proto
= c_parser_objc_protocol_refs (parser
);
11612 objc_start_category_interface (id1
, id2
, proto
, attributes
);
11613 c_parser_objc_methodprotolist (parser
);
11614 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
11615 objc_finish_interface ();
11618 if (c_parser_next_token_is (parser
, CPP_COLON
))
11620 c_parser_consume_token (parser
);
11621 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11623 c_parser_error (parser
, "expected identifier");
11626 superclass
= c_parser_peek_token (parser
)->value
;
11627 c_parser_consume_token (parser
);
11630 superclass
= NULL_TREE
;
11633 tree proto
= NULL_TREE
;
11634 if (c_parser_next_token_is (parser
, CPP_LESS
))
11635 proto
= c_parser_objc_protocol_refs (parser
);
11636 objc_start_class_interface (id1
, loc1
, superclass
, proto
, attributes
);
11639 objc_start_class_implementation (id1
, superclass
);
11640 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11641 c_parser_objc_class_instance_variables (parser
);
11644 objc_continue_interface ();
11645 c_parser_objc_methodprotolist (parser
);
11646 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
11647 objc_finish_interface ();
11651 objc_continue_implementation ();
11656 /* Parse objc-class-instance-variables.
11658 objc-class-instance-variables:
11659 { objc-instance-variable-decl-list[opt] }
11661 objc-instance-variable-decl-list:
11662 objc-visibility-spec
11663 objc-instance-variable-decl ;
11665 objc-instance-variable-decl-list objc-visibility-spec
11666 objc-instance-variable-decl-list objc-instance-variable-decl ;
11667 objc-instance-variable-decl-list ;
11669 objc-visibility-spec:
11674 objc-instance-variable-decl:
11679 c_parser_objc_class_instance_variables (c_parser
*parser
)
11681 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
11682 c_parser_consume_token (parser
);
11683 while (c_parser_next_token_is_not (parser
, CPP_EOF
))
11686 /* Parse any stray semicolon. */
11687 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11689 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11690 "extra semicolon");
11691 c_parser_consume_token (parser
);
11694 /* Stop if at the end of the instance variables. */
11695 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
11697 c_parser_consume_token (parser
);
11700 /* Parse any objc-visibility-spec. */
11701 if (c_parser_next_token_is_keyword (parser
, RID_AT_PRIVATE
))
11703 c_parser_consume_token (parser
);
11704 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE
);
11707 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROTECTED
))
11709 c_parser_consume_token (parser
);
11710 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED
);
11713 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PUBLIC
))
11715 c_parser_consume_token (parser
);
11716 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC
);
11719 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PACKAGE
))
11721 c_parser_consume_token (parser
);
11722 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE
);
11725 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
11727 c_parser_pragma (parser
, pragma_external
, NULL
);
11731 /* Parse some comma-separated declarations. */
11732 decls
= c_parser_struct_declaration (parser
);
11735 /* There is a syntax error. We want to skip the offending
11736 tokens up to the next ';' (included) or '}'
11739 /* First, skip manually a ')' or ']'. This is because they
11740 reduce the nesting level, so c_parser_skip_until_found()
11741 wouldn't be able to skip past them. */
11742 c_token
*token
= c_parser_peek_token (parser
);
11743 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_CLOSE_SQUARE
)
11744 c_parser_consume_token (parser
);
11746 /* Then, do the standard skipping. */
11747 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11749 /* We hopefully recovered. Start normal parsing again. */
11750 parser
->error
= false;
11755 /* Comma-separated instance variables are chained together
11756 in reverse order; add them one by one. */
11757 tree ivar
= nreverse (decls
);
11758 for (; ivar
; ivar
= DECL_CHAIN (ivar
))
11759 objc_add_instance_variable (copy_node (ivar
));
11761 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11765 /* Parse an objc-class-declaration.
11767 objc-class-declaration:
11768 @class identifier-list ;
11772 c_parser_objc_class_declaration (c_parser
*parser
)
11774 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_CLASS
));
11775 c_parser_consume_token (parser
);
11776 /* Any identifiers, including those declared as type names, are OK
11781 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11783 c_parser_error (parser
, "expected identifier");
11784 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11785 parser
->error
= false;
11788 id
= c_parser_peek_token (parser
)->value
;
11789 objc_declare_class (id
);
11790 c_parser_consume_token (parser
);
11791 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11792 c_parser_consume_token (parser
);
11796 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11799 /* Parse an objc-alias-declaration.
11801 objc-alias-declaration:
11802 @compatibility_alias identifier identifier ;
11806 c_parser_objc_alias_declaration (c_parser
*parser
)
11809 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_ALIAS
));
11810 c_parser_consume_token (parser
);
11811 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11813 c_parser_error (parser
, "expected identifier");
11814 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11817 id1
= c_parser_peek_token (parser
)->value
;
11818 c_parser_consume_token (parser
);
11819 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11821 c_parser_error (parser
, "expected identifier");
11822 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11825 id2
= c_parser_peek_token (parser
)->value
;
11826 c_parser_consume_token (parser
);
11827 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11828 objc_declare_alias (id1
, id2
);
11831 /* Parse an objc-protocol-definition.
11833 objc-protocol-definition:
11834 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11835 @protocol identifier-list ;
11837 "@protocol identifier ;" should be resolved as "@protocol
11838 identifier-list ;": objc-methodprotolist may not start with a
11839 semicolon in the first alternative if objc-protocol-refs are
11843 c_parser_objc_protocol_definition (c_parser
*parser
, tree attributes
)
11845 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROTOCOL
));
11847 c_parser_consume_token (parser
);
11848 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11850 c_parser_error (parser
, "expected identifier");
11853 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
11854 || c_parser_peek_2nd_token (parser
)->type
== CPP_SEMICOLON
)
11856 /* Any identifiers, including those declared as type names, are
11861 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11863 c_parser_error (parser
, "expected identifier");
11866 id
= c_parser_peek_token (parser
)->value
;
11867 objc_declare_protocol (id
, attributes
);
11868 c_parser_consume_token (parser
);
11869 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11870 c_parser_consume_token (parser
);
11874 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11878 tree id
= c_parser_peek_token (parser
)->value
;
11879 tree proto
= NULL_TREE
;
11880 c_parser_consume_token (parser
);
11881 if (c_parser_next_token_is (parser
, CPP_LESS
))
11882 proto
= c_parser_objc_protocol_refs (parser
);
11883 parser
->objc_pq_context
= true;
11884 objc_start_protocol (id
, proto
, attributes
);
11885 c_parser_objc_methodprotolist (parser
);
11886 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
11887 parser
->objc_pq_context
= false;
11888 objc_finish_interface ();
11892 /* Parse an objc-method-type.
11898 Return true if it is a class method (+) and false if it is
11899 an instance method (-).
11902 c_parser_objc_method_type (c_parser
*parser
)
11904 switch (c_parser_peek_token (parser
)->type
)
11907 c_parser_consume_token (parser
);
11910 c_parser_consume_token (parser
);
11913 gcc_unreachable ();
11917 /* Parse an objc-method-definition.
11919 objc-method-definition:
11920 objc-method-type objc-method-decl ;[opt] compound-statement
11924 c_parser_objc_method_definition (c_parser
*parser
)
11926 bool is_class_method
= c_parser_objc_method_type (parser
);
11927 tree decl
, attributes
= NULL_TREE
, expr
= NULL_TREE
;
11928 parser
->objc_pq_context
= true;
11929 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11931 if (decl
== error_mark_node
)
11932 return; /* Bail here. */
11934 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11936 c_parser_consume_token (parser
);
11937 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11938 "extra semicolon in method definition specified");
11941 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11943 c_parser_error (parser
, "expected %<{%>");
11947 parser
->objc_pq_context
= false;
11948 if (objc_start_method_definition (is_class_method
, decl
, attributes
, expr
))
11950 add_stmt (c_parser_compound_statement (parser
));
11951 objc_finish_method_definition (current_function_decl
);
11955 /* This code is executed when we find a method definition
11956 outside of an @implementation context (or invalid for other
11957 reasons). Parse the method (to keep going) but do not emit
11960 c_parser_compound_statement (parser
);
11964 /* Parse an objc-methodprotolist.
11966 objc-methodprotolist:
11968 objc-methodprotolist objc-methodproto
11969 objc-methodprotolist declaration
11970 objc-methodprotolist ;
11974 The declaration is a data definition, which may be missing
11975 declaration specifiers under the same rules and diagnostics as
11976 other data definitions outside functions, and the stray semicolon
11977 is diagnosed the same way as a stray semicolon outside a
11981 c_parser_objc_methodprotolist (c_parser
*parser
)
11985 /* The list is terminated by @end. */
11986 switch (c_parser_peek_token (parser
)->type
)
11988 case CPP_SEMICOLON
:
11989 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11990 "ISO C does not allow extra %<;%> outside of a function");
11991 c_parser_consume_token (parser
);
11995 c_parser_objc_methodproto (parser
);
11998 c_parser_pragma (parser
, pragma_external
, NULL
);
12003 if (c_parser_next_token_is_keyword (parser
, RID_AT_END
))
12005 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
))
12006 c_parser_objc_at_property_declaration (parser
);
12007 else if (c_parser_next_token_is_keyword (parser
, RID_AT_OPTIONAL
))
12009 objc_set_method_opt (true);
12010 c_parser_consume_token (parser
);
12012 else if (c_parser_next_token_is_keyword (parser
, RID_AT_REQUIRED
))
12014 objc_set_method_opt (false);
12015 c_parser_consume_token (parser
);
12018 c_parser_declaration_or_fndef (parser
, false, false, true,
12025 /* Parse an objc-methodproto.
12028 objc-method-type objc-method-decl ;
12032 c_parser_objc_methodproto (c_parser
*parser
)
12034 bool is_class_method
= c_parser_objc_method_type (parser
);
12035 tree decl
, attributes
= NULL_TREE
;
12037 /* Remember protocol qualifiers in prototypes. */
12038 parser
->objc_pq_context
= true;
12039 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
12041 /* Forget protocol qualifiers now. */
12042 parser
->objc_pq_context
= false;
12044 /* Do not allow the presence of attributes to hide an erroneous
12045 method implementation in the interface section. */
12046 if (!c_parser_next_token_is (parser
, CPP_SEMICOLON
))
12048 c_parser_error (parser
, "expected %<;%>");
12052 if (decl
!= error_mark_node
)
12053 objc_add_method_declaration (is_class_method
, decl
, attributes
);
12055 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12058 /* If we are at a position that method attributes may be present, check that
12059 there are not any parsed already (a syntax error) and then collect any
12060 specified at the current location. Finally, if new attributes were present,
12061 check that the next token is legal ( ';' for decls and '{' for defs). */
12064 c_parser_objc_maybe_method_attributes (c_parser
* parser
, tree
* attributes
)
12069 c_parser_error (parser
,
12070 "method attributes must be specified at the end only");
12071 *attributes
= NULL_TREE
;
12075 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
12076 *attributes
= c_parser_gnu_attributes (parser
);
12078 /* If there were no attributes here, just report any earlier error. */
12079 if (*attributes
== NULL_TREE
|| bad
)
12082 /* If the attributes are followed by a ; or {, then just report any earlier
12084 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
12085 || c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
12088 /* We've got attributes, but not at the end. */
12089 c_parser_error (parser
,
12090 "expected %<;%> or %<{%> after method attribute definition");
12094 /* Parse an objc-method-decl.
12097 ( objc-type-name ) objc-selector
12099 ( objc-type-name ) objc-keyword-selector objc-optparmlist
12100 objc-keyword-selector objc-optparmlist
12103 objc-keyword-selector:
12105 objc-keyword-selector objc-keyword-decl
12108 objc-selector : ( objc-type-name ) identifier
12109 objc-selector : identifier
12110 : ( objc-type-name ) identifier
12114 objc-optparms objc-optellipsis
12118 objc-opt-parms , parameter-declaration
12126 c_parser_objc_method_decl (c_parser
*parser
, bool is_class_method
,
12127 tree
*attributes
, tree
*expr
)
12129 tree type
= NULL_TREE
;
12131 tree parms
= NULL_TREE
;
12132 bool ellipsis
= false;
12133 bool attr_err
= false;
12135 *attributes
= NULL_TREE
;
12136 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
12138 matching_parens parens
;
12139 parens
.consume_open (parser
);
12140 type
= c_parser_objc_type_name (parser
);
12141 parens
.skip_until_found_close (parser
);
12143 sel
= c_parser_objc_selector (parser
);
12144 /* If there is no selector, or a colon follows, we have an
12145 objc-keyword-selector. If there is a selector, and a colon does
12146 not follow, that selector ends the objc-method-decl. */
12147 if (!sel
|| c_parser_next_token_is (parser
, CPP_COLON
))
12150 tree list
= NULL_TREE
;
12153 tree atype
= NULL_TREE
, id
, keyworddecl
;
12154 tree param_attr
= NULL_TREE
;
12155 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
12157 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
12159 c_parser_consume_token (parser
);
12160 atype
= c_parser_objc_type_name (parser
);
12161 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
12164 /* New ObjC allows attributes on method parameters. */
12165 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
12166 param_attr
= c_parser_gnu_attributes (parser
);
12167 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12169 c_parser_error (parser
, "expected identifier");
12170 return error_mark_node
;
12172 id
= c_parser_peek_token (parser
)->value
;
12173 c_parser_consume_token (parser
);
12174 keyworddecl
= objc_build_keyword_decl (tsel
, atype
, id
, param_attr
);
12175 list
= chainon (list
, keyworddecl
);
12176 tsel
= c_parser_objc_selector (parser
);
12177 if (!tsel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
12181 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
12183 /* Parse the optional parameter list. Optional Objective-C
12184 method parameters follow the C syntax, and may include '...'
12185 to denote a variable number of arguments. */
12186 parms
= make_node (TREE_LIST
);
12187 while (c_parser_next_token_is (parser
, CPP_COMMA
))
12189 struct c_parm
*parm
;
12190 c_parser_consume_token (parser
);
12191 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
12194 c_parser_consume_token (parser
);
12195 attr_err
|= c_parser_objc_maybe_method_attributes
12196 (parser
, attributes
) ;
12199 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
12202 parms
= chainon (parms
,
12203 build_tree_list (NULL_TREE
, grokparm (parm
, expr
)));
12208 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
12212 c_parser_error (parser
, "objective-c method declaration is expected");
12213 return error_mark_node
;
12217 return error_mark_node
;
12219 return objc_build_method_signature (is_class_method
, type
, sel
, parms
, ellipsis
);
12222 /* Parse an objc-type-name.
12225 objc-type-qualifiers[opt] type-name
12226 objc-type-qualifiers[opt]
12228 objc-type-qualifiers:
12229 objc-type-qualifier
12230 objc-type-qualifiers objc-type-qualifier
12232 objc-type-qualifier: one of
12233 in out inout bycopy byref oneway
12237 c_parser_objc_type_name (c_parser
*parser
)
12239 tree quals
= NULL_TREE
;
12240 struct c_type_name
*type_name
= NULL
;
12241 tree type
= NULL_TREE
;
12244 c_token
*token
= c_parser_peek_token (parser
);
12245 if (token
->type
== CPP_KEYWORD
12246 && (token
->keyword
== RID_IN
12247 || token
->keyword
== RID_OUT
12248 || token
->keyword
== RID_INOUT
12249 || token
->keyword
== RID_BYCOPY
12250 || token
->keyword
== RID_BYREF
12251 || token
->keyword
== RID_ONEWAY
))
12253 quals
= chainon (build_tree_list (NULL_TREE
, token
->value
), quals
);
12254 c_parser_consume_token (parser
);
12259 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
12260 type_name
= c_parser_type_name (parser
);
12262 type
= groktypename (type_name
, NULL
, NULL
);
12264 /* If the type is unknown, and error has already been produced and
12265 we need to recover from the error. In that case, use NULL_TREE
12266 for the type, as if no type had been specified; this will use the
12267 default type ('id') which is good for error recovery. */
12268 if (type
== error_mark_node
)
12271 return build_tree_list (quals
, type
);
12274 /* Parse objc-protocol-refs.
12276 objc-protocol-refs:
12277 < identifier-list >
12281 c_parser_objc_protocol_refs (c_parser
*parser
)
12283 tree list
= NULL_TREE
;
12284 gcc_assert (c_parser_next_token_is (parser
, CPP_LESS
));
12285 c_parser_consume_token (parser
);
12286 /* Any identifiers, including those declared as type names, are OK
12291 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12293 c_parser_error (parser
, "expected identifier");
12296 id
= c_parser_peek_token (parser
)->value
;
12297 list
= chainon (list
, build_tree_list (NULL_TREE
, id
));
12298 c_parser_consume_token (parser
);
12299 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12300 c_parser_consume_token (parser
);
12304 c_parser_require (parser
, CPP_GREATER
, "expected %<>%>");
12308 /* Parse an objc-try-catch-finally-statement.
12310 objc-try-catch-finally-statement:
12311 @try compound-statement objc-catch-list[opt]
12312 @try compound-statement objc-catch-list[opt] @finally compound-statement
12315 @catch ( objc-catch-parameter-declaration ) compound-statement
12316 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
12318 objc-catch-parameter-declaration:
12319 parameter-declaration
12322 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
12324 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
12325 for C++. Keep them in sync. */
12328 c_parser_objc_try_catch_finally_statement (c_parser
*parser
)
12330 location_t location
;
12333 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_TRY
));
12334 c_parser_consume_token (parser
);
12335 location
= c_parser_peek_token (parser
)->location
;
12336 objc_maybe_warn_exceptions (location
);
12337 stmt
= c_parser_compound_statement (parser
);
12338 objc_begin_try_stmt (location
, stmt
);
12340 while (c_parser_next_token_is_keyword (parser
, RID_AT_CATCH
))
12342 struct c_parm
*parm
;
12343 tree parameter_declaration
= error_mark_node
;
12344 bool seen_open_paren
= false;
12346 c_parser_consume_token (parser
);
12347 matching_parens parens
;
12348 if (!parens
.require_open (parser
))
12349 seen_open_paren
= true;
12350 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
12352 /* We have "@catch (...)" (where the '...' are literally
12353 what is in the code). Skip the '...'.
12354 parameter_declaration is set to NULL_TREE, and
12355 objc_being_catch_clauses() knows that that means
12357 c_parser_consume_token (parser
);
12358 parameter_declaration
= NULL_TREE
;
12362 /* We have "@catch (NSException *exception)" or something
12363 like that. Parse the parameter declaration. */
12364 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
12366 parameter_declaration
= error_mark_node
;
12368 parameter_declaration
= grokparm (parm
, NULL
);
12370 if (seen_open_paren
)
12371 parens
.require_close (parser
);
12374 /* If there was no open parenthesis, we are recovering from
12375 an error, and we are trying to figure out what mistake
12376 the user has made. */
12378 /* If there is an immediate closing parenthesis, the user
12379 probably forgot the opening one (ie, they typed "@catch
12380 NSException *e)". Parse the closing parenthesis and keep
12382 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
12383 c_parser_consume_token (parser
);
12385 /* If these is no immediate closing parenthesis, the user
12386 probably doesn't know that parenthesis are required at
12387 all (ie, they typed "@catch NSException *e"). So, just
12388 forget about the closing parenthesis and keep going. */
12390 objc_begin_catch_clause (parameter_declaration
);
12391 if (c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
12392 c_parser_compound_statement_nostart (parser
);
12393 objc_finish_catch_clause ();
12395 if (c_parser_next_token_is_keyword (parser
, RID_AT_FINALLY
))
12397 c_parser_consume_token (parser
);
12398 location
= c_parser_peek_token (parser
)->location
;
12399 stmt
= c_parser_compound_statement (parser
);
12400 objc_build_finally_clause (location
, stmt
);
12402 objc_finish_try_stmt ();
12405 /* Parse an objc-synchronized-statement.
12407 objc-synchronized-statement:
12408 @synchronized ( expression ) compound-statement
12412 c_parser_objc_synchronized_statement (c_parser
*parser
)
12416 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNCHRONIZED
));
12417 c_parser_consume_token (parser
);
12418 loc
= c_parser_peek_token (parser
)->location
;
12419 objc_maybe_warn_exceptions (loc
);
12420 matching_parens parens
;
12421 if (parens
.require_open (parser
))
12423 struct c_expr ce
= c_parser_expression (parser
);
12424 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
12426 expr
= c_fully_fold (expr
, false, NULL
);
12427 parens
.skip_until_found_close (parser
);
12430 expr
= error_mark_node
;
12431 stmt
= c_parser_compound_statement (parser
);
12432 objc_build_synchronized (loc
, expr
, stmt
);
12435 /* Parse an objc-selector; return NULL_TREE without an error if the
12436 next token is not an objc-selector.
12441 enum struct union if else while do for switch case default
12442 break continue return goto asm sizeof typeof typeof_unqual __alignof
12443 unsigned long const short volatile signed restrict _Complex
12444 in out inout bycopy byref oneway int char float double void _Bool
12447 ??? Why this selection of keywords but not, for example, storage
12448 class specifiers? */
12451 c_parser_objc_selector (c_parser
*parser
)
12453 c_token
*token
= c_parser_peek_token (parser
);
12454 tree value
= token
->value
;
12455 if (token
->type
== CPP_NAME
)
12457 c_parser_consume_token (parser
);
12460 if (token
->type
!= CPP_KEYWORD
)
12462 switch (token
->keyword
)
12482 case RID_TYPEOF_UNQUAL
:
12502 CASE_RID_FLOATN_NX
:
12506 case RID_AUTO_TYPE
:
12511 c_parser_consume_token (parser
);
12518 /* Parse an objc-selector-arg.
12522 objc-keywordname-list
12524 objc-keywordname-list:
12526 objc-keywordname-list objc-keywordname
12534 c_parser_objc_selector_arg (c_parser
*parser
)
12536 tree sel
= c_parser_objc_selector (parser
);
12537 tree list
= NULL_TREE
;
12539 && c_parser_next_token_is_not (parser
, CPP_COLON
)
12540 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
12544 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
12546 c_parser_consume_token (parser
);
12547 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
12548 list
= chainon (list
, build_tree_list (NULL_TREE
, NULL_TREE
));
12552 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
12554 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
12556 sel
= c_parser_objc_selector (parser
);
12558 && c_parser_next_token_is_not (parser
, CPP_COLON
)
12559 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
12565 /* Parse an objc-receiver.
12574 c_parser_objc_receiver (c_parser
*parser
)
12576 location_t loc
= c_parser_peek_token (parser
)->location
;
12578 if (c_parser_peek_token (parser
)->type
== CPP_NAME
12579 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
12580 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
12582 tree id
= c_parser_peek_token (parser
)->value
;
12583 c_parser_consume_token (parser
);
12584 return objc_get_class_reference (id
);
12586 struct c_expr ce
= c_parser_expression (parser
);
12587 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
12588 return c_fully_fold (ce
.value
, false, NULL
);
12591 /* Parse objc-message-args.
12595 objc-keywordarg-list
12597 objc-keywordarg-list:
12599 objc-keywordarg-list objc-keywordarg
12602 objc-selector : objc-keywordexpr
12607 c_parser_objc_message_args (c_parser
*parser
)
12609 tree sel
= c_parser_objc_selector (parser
);
12610 tree list
= NULL_TREE
;
12611 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
12616 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
12617 return error_mark_node
;
12618 keywordexpr
= c_parser_objc_keywordexpr (parser
);
12619 list
= chainon (list
, build_tree_list (sel
, keywordexpr
));
12620 sel
= c_parser_objc_selector (parser
);
12621 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
12627 /* Parse an objc-keywordexpr.
12634 c_parser_objc_keywordexpr (c_parser
*parser
)
12637 vec
<tree
, va_gc
> *expr_list
= c_parser_expr_list (parser
, true, true,
12638 NULL
, NULL
, NULL
, NULL
);
12639 if (vec_safe_length (expr_list
) == 1)
12641 /* Just return the expression, remove a level of
12643 ret
= (*expr_list
)[0];
12647 /* We have a comma expression, we will collapse later. */
12648 ret
= build_tree_list_vec (expr_list
);
12650 release_tree_vector (expr_list
);
12654 /* A check, needed in several places, that ObjC interface, implementation or
12655 method definitions are not prefixed by incorrect items. */
12657 c_parser_objc_diagnose_bad_element_prefix (c_parser
*parser
,
12658 struct c_declspecs
*specs
)
12660 if (!specs
->declspecs_seen_p
|| specs
->non_sc_seen_p
12661 || specs
->typespec_kind
!= ctsk_none
)
12663 c_parser_error (parser
,
12664 "no type or storage class may be specified here,");
12665 c_parser_skip_to_end_of_block_or_statement (parser
);
12671 /* Parse an Objective-C @property declaration. The syntax is:
12673 objc-property-declaration:
12674 '@property' objc-property-attributes[opt] struct-declaration ;
12676 objc-property-attributes:
12677 '(' objc-property-attribute-list ')'
12679 objc-property-attribute-list:
12680 objc-property-attribute
12681 objc-property-attribute-list, objc-property-attribute
12683 objc-property-attribute
12684 'getter' = identifier
12685 'setter' = identifier
12694 @property NSString *name;
12695 @property (readonly) id object;
12696 @property (retain, nonatomic, getter=getTheName) id name;
12697 @property int a, b, c;
12699 PS: This function is identical to cp_parser_objc_at_propery_declaration
12700 for C++. Keep them in sync. */
12702 c_parser_objc_at_property_declaration (c_parser
*parser
)
12704 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
));
12705 location_t loc
= c_parser_peek_token (parser
)->location
;
12706 c_parser_consume_token (parser
); /* Eat '@property'. */
12708 /* Parse the optional attribute list.
12710 A list of parsed, but not verified, attributes. */
12711 vec
<property_attribute_info
*> prop_attr_list
= vNULL
;
12713 bool syntax_error
= false;
12714 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
12716 matching_parens parens
;
12718 location_t attr_start
= c_parser_peek_token (parser
)->location
;
12720 parens
.consume_open (parser
);
12722 /* Property attribute keywords are valid now. */
12723 parser
->objc_property_attr_context
= true;
12725 /* Allow @property (), with a warning. */
12726 location_t attr_end
= c_parser_peek_token (parser
)->location
;
12728 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
12730 location_t attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
12731 warning_at (attr_comb
, OPT_Wattributes
,
12732 "empty property attribute list");
12737 c_token
*token
= c_parser_peek_token (parser
);
12738 attr_start
= token
->location
;
12739 attr_end
= get_finish (token
->location
);
12740 location_t attr_comb
= make_location (attr_start
, attr_start
,
12743 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_COMMA
)
12745 warning_at (attr_comb
, OPT_Wattributes
,
12746 "missing property attribute");
12747 if (token
->type
== CPP_CLOSE_PAREN
)
12749 c_parser_consume_token (parser
);
12753 tree attr_name
= NULL_TREE
;
12754 enum rid keyword
= RID_MAX
; /* Not a valid property attribute. */
12755 bool add_at
= false;
12756 if (token
->type
== CPP_KEYWORD
)
12758 keyword
= token
->keyword
;
12759 if (OBJC_IS_AT_KEYWORD (keyword
))
12761 /* For '@' keywords the token value has the keyword,
12762 prepend the '@' for diagnostics. */
12763 attr_name
= token
->value
;
12767 attr_name
= ridpointers
[(int)keyword
];
12769 else if (token
->type
== CPP_NAME
)
12770 attr_name
= token
->value
;
12771 c_parser_consume_token (parser
);
12773 enum objc_property_attribute_kind prop_kind
12774 = objc_prop_attr_kind_for_rid (keyword
);
12775 property_attribute_info
*prop
12776 = new property_attribute_info (attr_name
, attr_comb
, prop_kind
);
12777 prop_attr_list
.safe_push (prop
);
12780 switch (prop
->prop_kind
)
12783 case OBJC_PROPERTY_ATTR_UNKNOWN
:
12785 error_at (attr_comb
, "unknown property attribute %<%s%s%>",
12786 add_at
? "@" : "", IDENTIFIER_POINTER (attr_name
));
12788 error_at (attr_comb
, "unknown property attribute");
12789 prop
->parse_error
= syntax_error
= true;
12792 case OBJC_PROPERTY_ATTR_GETTER
:
12793 case OBJC_PROPERTY_ATTR_SETTER
:
12794 if (c_parser_next_token_is_not (parser
, CPP_EQ
))
12796 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
12797 error_at (attr_comb
, "expected %<=%> after Objective-C %qE",
12799 prop
->parse_error
= syntax_error
= true;
12802 token
= c_parser_peek_token (parser
);
12803 attr_end
= token
->location
;
12804 c_parser_consume_token (parser
); /* eat the = */
12805 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12807 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
12808 error_at (attr_comb
, "expected %qE selector name",
12810 prop
->parse_error
= syntax_error
= true;
12813 /* Get the end of the method name, and consume the name. */
12814 token
= c_parser_peek_token (parser
);
12815 attr_end
= get_finish (token
->location
);
12816 meth_name
= token
->value
;
12817 c_parser_consume_token (parser
);
12818 if (prop
->prop_kind
== OBJC_PROPERTY_ATTR_SETTER
)
12820 if (c_parser_next_token_is_not (parser
, CPP_COLON
))
12822 attr_comb
= make_location (attr_end
, attr_start
,
12824 error_at (attr_comb
, "setter method names must"
12825 " terminate with %<:%>");
12826 prop
->parse_error
= syntax_error
= true;
12830 attr_end
= get_finish (c_parser_peek_token
12831 (parser
)->location
);
12832 c_parser_consume_token (parser
);
12834 attr_comb
= make_location (attr_start
, attr_start
,
12838 attr_comb
= make_location (attr_start
, attr_start
,
12840 prop
->ident
= meth_name
;
12841 /* Updated location including all that was successfully
12843 prop
->prop_loc
= attr_comb
;
12847 /* If we see a comma here, then keep going - even if we already
12848 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12849 this makes a more useful output and avoid spurious warnings about
12850 missing attributes that are, in fact, specified after the one with
12851 the syntax error. */
12852 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12853 c_parser_consume_token (parser
);
12857 parser
->objc_property_attr_context
= false;
12859 if (syntax_error
&& c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
12860 /* We don't really want to chew the whole of the file looking for a
12861 matching closing parenthesis, so we will try to read the decl and
12862 let the error handling for that close out the statement. */
12865 syntax_error
= false, parens
.skip_until_found_close (parser
);
12868 /* 'properties' is the list of properties that we read. Usually a
12869 single one, but maybe more (eg, in "@property int a, b, c;" there
12871 tree properties
= c_parser_struct_declaration (parser
);
12873 if (properties
== error_mark_node
)
12874 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12877 if (properties
== NULL_TREE
)
12878 c_parser_error (parser
, "expected identifier");
12881 /* Comma-separated properties are chained together in reverse order;
12882 add them one by one. */
12883 properties
= nreverse (properties
);
12884 for (; properties
; properties
= TREE_CHAIN (properties
))
12885 objc_add_property_declaration (loc
, copy_node (properties
),
12888 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12891 while (!prop_attr_list
.is_empty())
12892 delete prop_attr_list
.pop ();
12893 prop_attr_list
.release ();
12894 parser
->error
= false;
12897 /* Parse an Objective-C @synthesize declaration. The syntax is:
12899 objc-synthesize-declaration:
12900 @synthesize objc-synthesize-identifier-list ;
12902 objc-synthesize-identifier-list:
12903 objc-synthesize-identifier
12904 objc-synthesize-identifier-list, objc-synthesize-identifier
12906 objc-synthesize-identifier
12908 identifier = identifier
12911 @synthesize MyProperty;
12912 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12914 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12915 for C++. Keep them in sync.
12918 c_parser_objc_at_synthesize_declaration (c_parser
*parser
)
12920 tree list
= NULL_TREE
;
12922 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNTHESIZE
));
12923 loc
= c_parser_peek_token (parser
)->location
;
12925 c_parser_consume_token (parser
);
12928 tree property
, ivar
;
12929 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12931 c_parser_error (parser
, "expected identifier");
12932 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12933 /* Once we find the semicolon, we can resume normal parsing.
12934 We have to reset parser->error manually because
12935 c_parser_skip_until_found() won't reset it for us if the
12936 next token is precisely a semicolon. */
12937 parser
->error
= false;
12940 property
= c_parser_peek_token (parser
)->value
;
12941 c_parser_consume_token (parser
);
12942 if (c_parser_next_token_is (parser
, CPP_EQ
))
12944 c_parser_consume_token (parser
);
12945 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12947 c_parser_error (parser
, "expected identifier");
12948 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12949 parser
->error
= false;
12952 ivar
= c_parser_peek_token (parser
)->value
;
12953 c_parser_consume_token (parser
);
12957 list
= chainon (list
, build_tree_list (ivar
, property
));
12958 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12959 c_parser_consume_token (parser
);
12963 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12964 objc_add_synthesize_declaration (loc
, list
);
12967 /* Parse an Objective-C @dynamic declaration. The syntax is:
12969 objc-dynamic-declaration:
12970 @dynamic identifier-list ;
12973 @dynamic MyProperty;
12974 @dynamic MyProperty, AnotherProperty;
12976 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12977 for C++. Keep them in sync.
12980 c_parser_objc_at_dynamic_declaration (c_parser
*parser
)
12982 tree list
= NULL_TREE
;
12984 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_DYNAMIC
));
12985 loc
= c_parser_peek_token (parser
)->location
;
12987 c_parser_consume_token (parser
);
12991 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12993 c_parser_error (parser
, "expected identifier");
12994 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12995 parser
->error
= false;
12998 property
= c_parser_peek_token (parser
)->value
;
12999 list
= chainon (list
, build_tree_list (NULL_TREE
, property
));
13000 c_parser_consume_token (parser
);
13001 if (c_parser_next_token_is (parser
, CPP_COMMA
))
13002 c_parser_consume_token (parser
);
13006 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
13007 objc_add_dynamic_declaration (loc
, list
);
13011 /* Parse a pragma GCC ivdep. */
13014 c_parse_pragma_ivdep (c_parser
*parser
)
13016 c_parser_consume_pragma (parser
);
13017 c_parser_skip_to_pragma_eol (parser
);
13021 /* Parse a pragma GCC unroll. */
13023 static unsigned short
13024 c_parser_pragma_unroll (c_parser
*parser
)
13026 unsigned short unroll
;
13027 c_parser_consume_pragma (parser
);
13028 location_t location
= c_parser_peek_token (parser
)->location
;
13029 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
13030 mark_exp_read (expr
);
13031 expr
= c_fully_fold (expr
, false, NULL
);
13032 HOST_WIDE_INT lunroll
= 0;
13033 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
13034 || TREE_CODE (expr
) != INTEGER_CST
13035 || (lunroll
= tree_to_shwi (expr
)) < 0
13036 || lunroll
>= USHRT_MAX
)
13038 error_at (location
, "%<#pragma GCC unroll%> requires an"
13039 " assignment-expression that evaluates to a non-negative"
13040 " integral constant less than %u", USHRT_MAX
);
13045 unroll
= (unsigned short)lunroll
;
13050 c_parser_skip_to_pragma_eol (parser
);
13054 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
13055 should be considered, statements. ALLOW_STMT is true if we're within
13056 the context of a function and such pragmas are to be allowed. Returns
13057 true if we actually parsed such a pragma. */
13060 c_parser_pragma (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
13063 const char *construct
= NULL
;
13065 input_location
= c_parser_peek_token (parser
)->location
;
13066 id
= c_parser_peek_token (parser
)->pragma_kind
;
13067 gcc_assert (id
!= PRAGMA_NONE
);
13071 case PRAGMA_OACC_DECLARE
:
13072 c_parser_oacc_declare (parser
);
13075 case PRAGMA_OACC_ENTER_DATA
:
13076 if (context
!= pragma_compound
)
13078 construct
= "acc enter data";
13080 if (context
== pragma_stmt
)
13082 error_at (c_parser_peek_token (parser
)->location
,
13083 "%<#pragma %s%> may only be used in compound "
13084 "statements", construct
);
13085 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
13090 c_parser_oacc_enter_exit_data (parser
, true);
13093 case PRAGMA_OACC_EXIT_DATA
:
13094 if (context
!= pragma_compound
)
13096 construct
= "acc exit data";
13099 c_parser_oacc_enter_exit_data (parser
, false);
13102 case PRAGMA_OACC_ROUTINE
:
13103 if (context
!= pragma_external
)
13105 error_at (c_parser_peek_token (parser
)->location
,
13106 "%<#pragma acc routine%> must be at file scope");
13107 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
13110 c_parser_oacc_routine (parser
, context
);
13113 case PRAGMA_OACC_UPDATE
:
13114 if (context
!= pragma_compound
)
13116 construct
= "acc update";
13119 c_parser_oacc_update (parser
);
13122 case PRAGMA_OMP_BARRIER
:
13123 if (context
!= pragma_compound
)
13125 construct
= "omp barrier";
13128 c_parser_omp_barrier (parser
);
13131 case PRAGMA_OMP_DEPOBJ
:
13132 if (context
!= pragma_compound
)
13134 construct
= "omp depobj";
13137 c_parser_omp_depobj (parser
);
13140 case PRAGMA_OMP_FLUSH
:
13141 if (context
!= pragma_compound
)
13143 construct
= "omp flush";
13146 c_parser_omp_flush (parser
);
13149 case PRAGMA_OMP_TASKWAIT
:
13150 if (context
!= pragma_compound
)
13152 construct
= "omp taskwait";
13155 c_parser_omp_taskwait (parser
);
13158 case PRAGMA_OMP_TASKYIELD
:
13159 if (context
!= pragma_compound
)
13161 construct
= "omp taskyield";
13164 c_parser_omp_taskyield (parser
);
13167 case PRAGMA_OMP_CANCEL
:
13168 if (context
!= pragma_compound
)
13170 construct
= "omp cancel";
13173 c_parser_omp_cancel (parser
);
13176 case PRAGMA_OMP_CANCELLATION_POINT
:
13177 return c_parser_omp_cancellation_point (parser
, context
);
13179 case PRAGMA_OMP_THREADPRIVATE
:
13180 c_parser_omp_threadprivate (parser
);
13183 case PRAGMA_OMP_TARGET
:
13184 return c_parser_omp_target (parser
, context
, if_p
);
13186 case PRAGMA_OMP_BEGIN
:
13187 c_parser_omp_begin (parser
);
13190 case PRAGMA_OMP_END
:
13191 c_parser_omp_end (parser
);
13194 case PRAGMA_OMP_SCAN
:
13195 error_at (c_parser_peek_token (parser
)->location
,
13196 "%<#pragma omp scan%> may only be used in "
13197 "a loop construct with %<inscan%> %<reduction%> clause");
13198 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
13201 case PRAGMA_OMP_SECTION
:
13202 error_at (c_parser_peek_token (parser
)->location
,
13203 "%<#pragma omp section%> may only be used in "
13204 "%<#pragma omp sections%> construct");
13205 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
13208 case PRAGMA_OMP_DECLARE
:
13209 return c_parser_omp_declare (parser
, context
);
13211 case PRAGMA_OMP_REQUIRES
:
13212 if (context
!= pragma_external
)
13214 error_at (c_parser_peek_token (parser
)->location
,
13215 "%<#pragma %s%> may only be used at file scope",
13217 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
13220 c_parser_omp_requires (parser
);
13223 case PRAGMA_OMP_ASSUMES
:
13224 if (context
!= pragma_external
)
13226 error_at (c_parser_peek_token (parser
)->location
,
13227 "%<#pragma %s%> may only be used at file scope",
13229 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
13232 c_parser_omp_assumes (parser
);
13235 case PRAGMA_OMP_NOTHING
:
13236 c_parser_omp_nothing (parser
);
13239 case PRAGMA_OMP_ERROR
:
13240 return c_parser_omp_error (parser
, context
);
13242 case PRAGMA_OMP_ORDERED
:
13243 return c_parser_omp_ordered (parser
, context
, if_p
);
13247 const bool ivdep
= c_parse_pragma_ivdep (parser
);
13248 unsigned short unroll
;
13249 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_UNROLL
)
13250 unroll
= c_parser_pragma_unroll (parser
);
13253 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
13254 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
13255 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
13257 c_parser_error (parser
, "for, while or do statement expected");
13260 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
13261 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
13262 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
13263 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
13265 c_parser_do_statement (parser
, ivdep
, unroll
);
13269 case PRAGMA_UNROLL
:
13271 unsigned short unroll
= c_parser_pragma_unroll (parser
);
13273 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_IVDEP
)
13274 ivdep
= c_parse_pragma_ivdep (parser
);
13277 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
13278 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
13279 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
13281 c_parser_error (parser
, "for, while or do statement expected");
13284 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
13285 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
13286 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
13287 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
13289 c_parser_do_statement (parser
, ivdep
, unroll
);
13293 case PRAGMA_GCC_PCH_PREPROCESS
:
13294 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
13295 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
13298 case PRAGMA_OACC_WAIT
:
13299 if (context
!= pragma_compound
)
13301 construct
= "acc wait";
13304 /* FALL THROUGH. */
13307 if (id
< PRAGMA_FIRST_EXTERNAL
)
13309 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
13312 c_parser_error (parser
, "expected declaration specifiers");
13313 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
13316 c_parser_omp_construct (parser
, if_p
);
13322 c_parser_consume_pragma (parser
);
13323 c_invoke_pragma_handler (id
);
13325 /* Skip to EOL, but suppress any error message. Those will have been
13326 generated by the handler routine through calling error, as opposed
13327 to calling c_parser_error. */
13328 parser
->error
= true;
13329 c_parser_skip_to_pragma_eol (parser
);
13334 /* The interface the pragma parsers have to the lexer. */
13337 pragma_lex (tree
*value
, location_t
*loc
)
13339 c_token
*tok
= c_parser_peek_token (the_parser
);
13340 enum cpp_ttype ret
= tok
->type
;
13342 *value
= tok
->value
;
13344 *loc
= tok
->location
;
13346 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
13348 else if (ret
== CPP_STRING
)
13349 *value
= c_parser_string_literal (the_parser
, false, false).value
;
13352 if (ret
== CPP_KEYWORD
)
13354 c_parser_consume_token (the_parser
);
13361 c_parser_pragma_pch_preprocess (c_parser
*parser
)
13365 parser
->lex_joined_string
= true;
13366 c_parser_consume_pragma (parser
);
13367 if (c_parser_next_token_is (parser
, CPP_STRING
))
13369 name
= c_parser_peek_token (parser
)->value
;
13370 c_parser_consume_token (parser
);
13373 c_parser_error (parser
, "expected string literal");
13374 c_parser_skip_to_pragma_eol (parser
);
13375 parser
->lex_joined_string
= false;
13378 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
13381 /* OpenACC and OpenMP parsing routines. */
13383 /* Returns name of the next clause.
13384 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
13385 the token is not consumed. Otherwise appropriate pragma_omp_clause is
13386 returned and the token is consumed. */
13388 static pragma_omp_clause
13389 c_parser_omp_clause_name (c_parser
*parser
)
13391 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
13393 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
13394 result
= PRAGMA_OACC_CLAUSE_AUTO
;
13395 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
13396 result
= PRAGMA_OMP_CLAUSE_IF
;
13397 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
13398 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
13399 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
13400 result
= PRAGMA_OMP_CLAUSE_FOR
;
13401 else if (c_parser_next_token_is (parser
, CPP_NAME
))
13403 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13408 if (!strcmp ("affinity", p
))
13409 result
= PRAGMA_OMP_CLAUSE_AFFINITY
;
13410 else if (!strcmp ("aligned", p
))
13411 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
13412 else if (!strcmp ("allocate", p
))
13413 result
= PRAGMA_OMP_CLAUSE_ALLOCATE
;
13414 else if (!strcmp ("async", p
))
13415 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
13416 else if (!strcmp ("attach", p
))
13417 result
= PRAGMA_OACC_CLAUSE_ATTACH
;
13420 if (!strcmp ("bind", p
))
13421 result
= PRAGMA_OMP_CLAUSE_BIND
;
13424 if (!strcmp ("collapse", p
))
13425 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
13426 else if (!strcmp ("copy", p
))
13427 result
= PRAGMA_OACC_CLAUSE_COPY
;
13428 else if (!strcmp ("copyin", p
))
13429 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
13430 else if (!strcmp ("copyout", p
))
13431 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
13432 else if (!strcmp ("copyprivate", p
))
13433 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
13434 else if (!strcmp ("create", p
))
13435 result
= PRAGMA_OACC_CLAUSE_CREATE
;
13438 if (!strcmp ("defaultmap", p
))
13439 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
13440 else if (!strcmp ("delete", p
))
13441 result
= PRAGMA_OACC_CLAUSE_DELETE
;
13442 else if (!strcmp ("depend", p
))
13443 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
13444 else if (!strcmp ("detach", p
))
13445 result
= PRAGMA_OACC_CLAUSE_DETACH
;
13446 else if (!strcmp ("device", p
))
13447 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
13448 else if (!strcmp ("deviceptr", p
))
13449 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
13450 else if (!strcmp ("device_resident", p
))
13451 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
13452 else if (!strcmp ("device_type", p
))
13453 result
= PRAGMA_OMP_CLAUSE_DEVICE_TYPE
;
13454 else if (!strcmp ("dist_schedule", p
))
13455 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
13456 else if (!strcmp ("doacross", p
))
13457 result
= PRAGMA_OMP_CLAUSE_DOACROSS
;
13460 if (!strcmp ("enter", p
))
13461 result
= PRAGMA_OMP_CLAUSE_ENTER
;
13464 if (!strcmp ("filter", p
))
13465 result
= PRAGMA_OMP_CLAUSE_FILTER
;
13466 else if (!strcmp ("final", p
))
13467 result
= PRAGMA_OMP_CLAUSE_FINAL
;
13468 else if (!strcmp ("finalize", p
))
13469 result
= PRAGMA_OACC_CLAUSE_FINALIZE
;
13470 else if (!strcmp ("firstprivate", p
))
13471 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
13472 else if (!strcmp ("from", p
))
13473 result
= PRAGMA_OMP_CLAUSE_FROM
;
13476 if (!strcmp ("gang", p
))
13477 result
= PRAGMA_OACC_CLAUSE_GANG
;
13478 else if (!strcmp ("grainsize", p
))
13479 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
13482 if (!strcmp ("has_device_addr", p
))
13483 result
= PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
;
13484 else if (!strcmp ("hint", p
))
13485 result
= PRAGMA_OMP_CLAUSE_HINT
;
13486 else if (!strcmp ("host", p
))
13487 result
= PRAGMA_OACC_CLAUSE_HOST
;
13490 if (!strcmp ("if_present", p
))
13491 result
= PRAGMA_OACC_CLAUSE_IF_PRESENT
;
13492 else if (!strcmp ("in_reduction", p
))
13493 result
= PRAGMA_OMP_CLAUSE_IN_REDUCTION
;
13494 else if (!strcmp ("inbranch", p
))
13495 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
13496 else if (!strcmp ("independent", p
))
13497 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
13498 else if (!strcmp ("is_device_ptr", p
))
13499 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
13502 if (!strcmp ("lastprivate", p
))
13503 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
13504 else if (!strcmp ("linear", p
))
13505 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
13506 else if (!strcmp ("link", p
))
13507 result
= PRAGMA_OMP_CLAUSE_LINK
;
13510 if (!strcmp ("map", p
))
13511 result
= PRAGMA_OMP_CLAUSE_MAP
;
13512 else if (!strcmp ("mergeable", p
))
13513 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
13516 if (!strcmp ("no_create", p
))
13517 result
= PRAGMA_OACC_CLAUSE_NO_CREATE
;
13518 else if (!strcmp ("nogroup", p
))
13519 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
13520 else if (!strcmp ("nohost", p
))
13521 result
= PRAGMA_OACC_CLAUSE_NOHOST
;
13522 else if (!strcmp ("nontemporal", p
))
13523 result
= PRAGMA_OMP_CLAUSE_NONTEMPORAL
;
13524 else if (!strcmp ("notinbranch", p
))
13525 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
13526 else if (!strcmp ("nowait", p
))
13527 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
13528 else if (!strcmp ("num_gangs", p
))
13529 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
13530 else if (!strcmp ("num_tasks", p
))
13531 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
13532 else if (!strcmp ("num_teams", p
))
13533 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
13534 else if (!strcmp ("num_threads", p
))
13535 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
13536 else if (!strcmp ("num_workers", p
))
13537 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
13540 if (!strcmp ("ordered", p
))
13541 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
13542 else if (!strcmp ("order", p
))
13543 result
= PRAGMA_OMP_CLAUSE_ORDER
;
13546 if (!strcmp ("parallel", p
))
13547 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
13548 else if (!strcmp ("present", p
))
13549 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
13550 /* As of OpenACC 2.5, these are now aliases of the non-present_or
13552 else if (!strcmp ("present_or_copy", p
)
13553 || !strcmp ("pcopy", p
))
13554 result
= PRAGMA_OACC_CLAUSE_COPY
;
13555 else if (!strcmp ("present_or_copyin", p
)
13556 || !strcmp ("pcopyin", p
))
13557 result
= PRAGMA_OACC_CLAUSE_COPYIN
;
13558 else if (!strcmp ("present_or_copyout", p
)
13559 || !strcmp ("pcopyout", p
))
13560 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
13561 else if (!strcmp ("present_or_create", p
)
13562 || !strcmp ("pcreate", p
))
13563 result
= PRAGMA_OACC_CLAUSE_CREATE
;
13564 else if (!strcmp ("priority", p
))
13565 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
13566 else if (!strcmp ("private", p
))
13567 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
13568 else if (!strcmp ("proc_bind", p
))
13569 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
13572 if (!strcmp ("reduction", p
))
13573 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
13576 if (!strcmp ("safelen", p
))
13577 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
13578 else if (!strcmp ("schedule", p
))
13579 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
13580 else if (!strcmp ("sections", p
))
13581 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
13582 else if (!strcmp ("self", p
)) /* "self" is a synonym for "host". */
13583 result
= PRAGMA_OACC_CLAUSE_HOST
;
13584 else if (!strcmp ("seq", p
))
13585 result
= PRAGMA_OACC_CLAUSE_SEQ
;
13586 else if (!strcmp ("shared", p
))
13587 result
= PRAGMA_OMP_CLAUSE_SHARED
;
13588 else if (!strcmp ("simd", p
))
13589 result
= PRAGMA_OMP_CLAUSE_SIMD
;
13590 else if (!strcmp ("simdlen", p
))
13591 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
13594 if (!strcmp ("task_reduction", p
))
13595 result
= PRAGMA_OMP_CLAUSE_TASK_REDUCTION
;
13596 else if (!strcmp ("taskgroup", p
))
13597 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
13598 else if (!strcmp ("thread_limit", p
))
13599 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
13600 else if (!strcmp ("threads", p
))
13601 result
= PRAGMA_OMP_CLAUSE_THREADS
;
13602 else if (!strcmp ("tile", p
))
13603 result
= PRAGMA_OACC_CLAUSE_TILE
;
13604 else if (!strcmp ("to", p
))
13605 result
= PRAGMA_OMP_CLAUSE_TO
;
13608 if (!strcmp ("uniform", p
))
13609 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
13610 else if (!strcmp ("untied", p
))
13611 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
13612 else if (!strcmp ("use_device", p
))
13613 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
13614 else if (!strcmp ("use_device_addr", p
))
13615 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
;
13616 else if (!strcmp ("use_device_ptr", p
))
13617 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
13620 if (!strcmp ("vector", p
))
13621 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
13622 else if (!strcmp ("vector_length", p
))
13623 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
13626 if (!strcmp ("wait", p
))
13627 result
= PRAGMA_OACC_CLAUSE_WAIT
;
13628 else if (!strcmp ("worker", p
))
13629 result
= PRAGMA_OACC_CLAUSE_WORKER
;
13634 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
13635 c_parser_consume_token (parser
);
13640 /* Validate that a clause of the given type does not already exist. */
13643 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
13646 if (tree c
= omp_find_clause (clauses
, code
))
13647 error_at (OMP_CLAUSE_LOCATION (c
), "too many %qs clauses", name
);
13651 Parse wait clause or wait directive parameters. */
13654 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
13656 vec
<tree
, va_gc
> *args
;
13659 matching_parens parens
;
13660 if (!parens
.require_open (parser
))
13663 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
13664 args_tree
= build_tree_list_vec (args
);
13666 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
13668 tree targ
= TREE_VALUE (t
);
13670 if (targ
!= error_mark_node
)
13672 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
13674 c_parser_error (parser
, "expression must be integral");
13675 targ
= error_mark_node
;
13679 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
13681 OMP_CLAUSE_DECL (c
) = targ
;
13682 OMP_CLAUSE_CHAIN (c
) = list
;
13688 release_tree_vector (args
);
13689 parens
.require_close (parser
);
13693 /* OpenACC 2.0, OpenMP 2.5:
13696 variable-list , identifier
13698 If KIND is nonzero, create the appropriate node and install the
13699 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
13700 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
13702 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
13703 return the list created.
13705 The optional ALLOW_DEREF argument is true if list items can use the deref
13710 tree low_bound
, length
;
13713 omp_dim (tree lb
, tree len
, location_t lo
, bool nc
)
13714 : low_bound (lb
), length (len
), loc (lo
), no_colon (nc
) {}
13718 c_parser_omp_variable_list (c_parser
*parser
,
13719 location_t clause_loc
,
13720 enum omp_clause_code kind
, tree list
,
13721 bool allow_deref
= false)
13723 auto_vec
<omp_dim
> dims
;
13724 bool array_section_p
;
13725 auto_vec
<c_token
> tokens
;
13726 unsigned int tokens_avail
= 0;
13731 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13733 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
13734 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
13736 struct c_expr expr
;
13737 if (kind
== OMP_CLAUSE_DEPEND
13738 && c_parser_next_token_is_keyword (parser
,
13739 RID_OMP_ALL_MEMORY
)
13740 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
13741 || (c_parser_peek_2nd_token (parser
)->type
13742 == CPP_CLOSE_PAREN
)))
13744 expr
.value
= ridpointers
[RID_OMP_ALL_MEMORY
];
13745 c_parser_consume_token (parser
);
13748 expr
= c_parser_expr_no_commas (parser
, NULL
);
13749 if (expr
.value
!= error_mark_node
)
13751 tree u
= build_omp_clause (clause_loc
, kind
);
13752 OMP_CLAUSE_DECL (u
) = expr
.value
;
13753 OMP_CLAUSE_CHAIN (u
) = list
;
13757 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
13760 c_parser_consume_token (parser
);
13765 tokens
.truncate (0);
13766 unsigned int nesting_depth
= 0;
13769 c_token
*token
= c_parser_peek_token (parser
);
13770 switch (token
->type
)
13773 case CPP_PRAGMA_EOL
:
13775 case CPP_OPEN_BRACE
:
13776 case CPP_OPEN_PAREN
:
13777 case CPP_OPEN_SQUARE
:
13780 case CPP_CLOSE_BRACE
:
13781 case CPP_CLOSE_PAREN
:
13782 case CPP_CLOSE_SQUARE
:
13783 if (nesting_depth
-- == 0)
13787 if (nesting_depth
== 0)
13792 tokens
.safe_push (*token
);
13793 c_parser_consume_token (parser
);
13799 /* Make sure nothing tries to read past the end of the tokens. */
13801 memset (&eof_token
, 0, sizeof (eof_token
));
13802 eof_token
.type
= CPP_EOF
;
13803 tokens
.safe_push (eof_token
);
13804 tokens
.safe_push (eof_token
);
13806 tokens_avail
= parser
->tokens_avail
;
13807 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
13808 parser
->tokens
= tokens
.address ();
13809 parser
->tokens_avail
= tokens
.length ();
13812 tree t
= NULL_TREE
;
13814 if (c_parser_next_token_is (parser
, CPP_NAME
)
13815 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
13817 t
= lookup_name (c_parser_peek_token (parser
)->value
);
13819 if (t
== NULL_TREE
)
13821 undeclared_variable (c_parser_peek_token (parser
)->location
,
13822 c_parser_peek_token (parser
)->value
);
13823 t
= error_mark_node
;
13826 c_parser_consume_token (parser
);
13828 else if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
13829 && (c_parser_peek_token (parser
)->keyword
== RID_FUNCTION_NAME
13830 || (c_parser_peek_token (parser
)->keyword
13831 == RID_PRETTY_FUNCTION_NAME
)
13832 || (c_parser_peek_token (parser
)->keyword
13833 == RID_C99_FUNCTION_NAME
)))
13834 t
= c_parser_predefined_identifier (parser
).value
;
13838 c_parser_error (parser
, "expected identifier");
13842 if (t
== error_mark_node
)
13844 else if (kind
!= 0)
13848 case OMP_CLAUSE__CACHE_
:
13849 /* The OpenACC cache directive explicitly only allows "array
13850 elements or subarrays". */
13851 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
13853 c_parser_error (parser
, "expected %<[%>");
13854 t
= error_mark_node
;
13858 case OMP_CLAUSE_MAP
:
13859 case OMP_CLAUSE_FROM
:
13860 case OMP_CLAUSE_TO
:
13861 start_component_ref
:
13862 while (c_parser_next_token_is (parser
, CPP_DOT
)
13864 && c_parser_next_token_is (parser
, CPP_DEREF
)))
13866 location_t op_loc
= c_parser_peek_token (parser
)->location
;
13867 location_t arrow_loc
= UNKNOWN_LOCATION
;
13868 if (c_parser_next_token_is (parser
, CPP_DEREF
))
13872 t_expr
.original_code
= ERROR_MARK
;
13873 t_expr
.original_type
= NULL
;
13874 set_c_expr_source_range (&t_expr
, op_loc
, op_loc
);
13875 t_expr
.m_decimal
= 0;
13876 t_expr
= convert_lvalue_to_rvalue (op_loc
, t_expr
,
13878 t
= build_indirect_ref (op_loc
, t_expr
.value
, RO_ARROW
);
13879 arrow_loc
= t_expr
.get_location ();
13881 c_parser_consume_token (parser
);
13882 if (!c_parser_next_token_is (parser
, CPP_NAME
))
13884 c_parser_error (parser
, "expected identifier");
13885 t
= error_mark_node
;
13889 c_token
*comp_tok
= c_parser_peek_token (parser
);
13890 tree ident
= comp_tok
->value
;
13891 location_t comp_loc
= comp_tok
->location
;
13892 c_parser_consume_token (parser
);
13893 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
,
13897 case OMP_CLAUSE_AFFINITY
:
13898 case OMP_CLAUSE_DEPEND
:
13899 case OMP_CLAUSE_REDUCTION
:
13900 case OMP_CLAUSE_IN_REDUCTION
:
13901 case OMP_CLAUSE_TASK_REDUCTION
:
13902 case OMP_CLAUSE_HAS_DEVICE_ADDR
:
13903 array_section_p
= false;
13905 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
13907 location_t loc
= UNKNOWN_LOCATION
;
13908 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
13909 bool no_colon
= false;
13911 c_parser_consume_token (parser
);
13912 if (!c_parser_next_token_is (parser
, CPP_COLON
))
13914 location_t expr_loc
13915 = c_parser_peek_token (parser
)->location
;
13916 c_expr expr
= c_parser_expression (parser
);
13917 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13919 low_bound
= expr
.value
;
13922 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13924 length
= integer_one_node
;
13929 /* Look for `:'. */
13930 if (!c_parser_require (parser
, CPP_COLON
,
13933 t
= error_mark_node
;
13936 array_section_p
= true;
13937 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13939 location_t expr_loc
13940 = c_parser_peek_token (parser
)->location
;
13941 c_expr expr
= c_parser_expression (parser
);
13942 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13944 length
= expr
.value
;
13947 /* Look for the closing `]'. */
13948 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
13951 t
= error_mark_node
;
13955 dims
.safe_push (omp_dim (low_bound
, length
, loc
, no_colon
));
13958 if (t
!= error_mark_node
)
13960 if ((kind
== OMP_CLAUSE_MAP
13961 || kind
== OMP_CLAUSE_FROM
13962 || kind
== OMP_CLAUSE_TO
)
13963 && !array_section_p
13964 && (c_parser_next_token_is (parser
, CPP_DOT
)
13966 && c_parser_next_token_is (parser
,
13969 for (unsigned i
= 0; i
< dims
.length (); i
++)
13971 gcc_assert (dims
[i
].length
== integer_one_node
);
13972 t
= build_array_ref (dims
[i
].loc
,
13973 t
, dims
[i
].low_bound
);
13975 goto start_component_ref
;
13978 for (unsigned i
= 0; i
< dims
.length (); i
++)
13979 t
= tree_cons (dims
[i
].low_bound
, dims
[i
].length
, t
);
13982 if ((kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13983 && t
!= error_mark_node
13984 && parser
->tokens_avail
!= 2)
13986 if (array_section_p
)
13988 error_at (c_parser_peek_token (parser
)->location
,
13989 "expected %<)%> or %<,%>");
13990 t
= error_mark_node
;
13994 parser
->tokens
= tokens
.address ();
13995 parser
->tokens_avail
= tokens
.length ();
13997 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
13998 if (t
!= error_mark_node
&& parser
->tokens_avail
!= 2)
14000 error_at (c_parser_peek_token (parser
)->location
,
14001 "expected %<)%> or %<,%>");
14002 t
= error_mark_node
;
14011 if (t
!= error_mark_node
)
14013 tree u
= build_omp_clause (clause_loc
, kind
);
14014 OMP_CLAUSE_DECL (u
) = t
;
14015 OMP_CLAUSE_CHAIN (u
) = list
;
14020 list
= tree_cons (t
, NULL_TREE
, list
);
14022 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
14024 parser
->tokens
= &parser
->tokens_buf
[0];
14025 parser
->tokens_avail
= tokens_avail
;
14027 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
14030 c_parser_consume_token (parser
);
14037 /* Similarly, but expect leading and trailing parenthesis. This is a very
14038 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
14039 argument is true if list items can use the deref (->) operator. */
14042 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
14043 tree list
, bool allow_deref
= false)
14045 /* The clauses location. */
14046 location_t loc
= c_parser_peek_token (parser
)->location
;
14048 matching_parens parens
;
14049 if (parens
.require_open (parser
))
14051 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
, allow_deref
);
14052 parens
.skip_until_found_close (parser
);
14058 copy ( variable-list )
14059 copyin ( variable-list )
14060 copyout ( variable-list )
14061 create ( variable-list )
14062 delete ( variable-list )
14063 present ( variable-list )
14066 no_create ( variable-list )
14067 attach ( variable-list )
14068 detach ( variable-list ) */
14071 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
14074 enum gomp_map_kind kind
;
14077 case PRAGMA_OACC_CLAUSE_ATTACH
:
14078 kind
= GOMP_MAP_ATTACH
;
14080 case PRAGMA_OACC_CLAUSE_COPY
:
14081 kind
= GOMP_MAP_TOFROM
;
14083 case PRAGMA_OACC_CLAUSE_COPYIN
:
14084 kind
= GOMP_MAP_TO
;
14086 case PRAGMA_OACC_CLAUSE_COPYOUT
:
14087 kind
= GOMP_MAP_FROM
;
14089 case PRAGMA_OACC_CLAUSE_CREATE
:
14090 kind
= GOMP_MAP_ALLOC
;
14092 case PRAGMA_OACC_CLAUSE_DELETE
:
14093 kind
= GOMP_MAP_RELEASE
;
14095 case PRAGMA_OACC_CLAUSE_DETACH
:
14096 kind
= GOMP_MAP_DETACH
;
14098 case PRAGMA_OACC_CLAUSE_DEVICE
:
14099 kind
= GOMP_MAP_FORCE_TO
;
14101 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
14102 kind
= GOMP_MAP_DEVICE_RESIDENT
;
14104 case PRAGMA_OACC_CLAUSE_HOST
:
14105 kind
= GOMP_MAP_FORCE_FROM
;
14107 case PRAGMA_OACC_CLAUSE_LINK
:
14108 kind
= GOMP_MAP_LINK
;
14110 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
14111 kind
= GOMP_MAP_IF_PRESENT
;
14113 case PRAGMA_OACC_CLAUSE_PRESENT
:
14114 kind
= GOMP_MAP_FORCE_PRESENT
;
14117 gcc_unreachable ();
14120 nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_MAP
, list
, true);
14122 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
14123 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
14129 deviceptr ( variable-list ) */
14132 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
14134 location_t loc
= c_parser_peek_token (parser
)->location
;
14137 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
14138 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
14139 variable-list must only allow for pointer variables. */
14140 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
14141 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
14143 tree v
= TREE_PURPOSE (t
);
14145 /* FIXME diagnostics: Ideally we should keep individual
14146 locations for all the variables in the var list to make the
14147 following errors more precise. Perhaps
14148 c_parser_omp_var_list_parens() should construct a list of
14149 locations to go along with the var list. */
14151 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
14152 error_at (loc
, "%qD is not a variable", v
);
14153 else if (TREE_TYPE (v
) == error_mark_node
)
14155 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
14156 error_at (loc
, "%qD is not a pointer variable", v
);
14158 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
14159 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
14160 OMP_CLAUSE_DECL (u
) = v
;
14161 OMP_CLAUSE_CHAIN (u
) = list
;
14168 /* OpenACC 2.0, OpenMP 3.0:
14169 collapse ( constant-expression ) */
14172 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
14174 tree c
, num
= error_mark_node
;
14178 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
14179 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
14181 loc
= c_parser_peek_token (parser
)->location
;
14182 matching_parens parens
;
14183 if (parens
.require_open (parser
))
14185 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
14186 parens
.skip_until_found_close (parser
);
14188 if (num
== error_mark_node
)
14190 mark_exp_read (num
);
14191 num
= c_fully_fold (num
, false, NULL
);
14192 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
14193 || !tree_fits_shwi_p (num
)
14194 || (n
= tree_to_shwi (num
)) <= 0
14198 "collapse argument needs positive constant integer expression");
14201 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
14202 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
14203 OMP_CLAUSE_CHAIN (c
) = list
;
14208 copyin ( variable-list ) */
14211 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
14213 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
14217 copyprivate ( variable-list ) */
14220 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
14222 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
14226 default ( none | shared )
14229 default ( private | firstprivate )
14232 default ( none | present ) */
14235 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
14237 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
14238 location_t loc
= c_parser_peek_token (parser
)->location
;
14241 matching_parens parens
;
14242 if (!parens
.require_open (parser
))
14244 if (c_parser_next_token_is (parser
, CPP_NAME
))
14246 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14251 if (strcmp ("none", p
) != 0)
14253 kind
= OMP_CLAUSE_DEFAULT_NONE
;
14259 if (strcmp ("present", p
) != 0)
14261 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
14265 if (strcmp ("private", p
) != 0)
14267 kind
= OMP_CLAUSE_DEFAULT_PRIVATE
;
14272 if (strcmp ("firstprivate", p
) != 0 || is_oacc
)
14274 kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
14278 if (strcmp ("shared", p
) != 0 || is_oacc
)
14280 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
14287 c_parser_consume_token (parser
);
14293 c_parser_error (parser
, "expected %<none%> or %<present%>");
14295 c_parser_error (parser
, "expected %<none%>, %<shared%>, "
14296 "%<private%> or %<firstprivate%>");
14298 parens
.skip_until_found_close (parser
);
14300 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
14303 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
14304 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
14305 OMP_CLAUSE_CHAIN (c
) = list
;
14306 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
14312 firstprivate ( variable-list ) */
14315 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
14317 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
14321 final ( expression ) */
14324 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
14326 location_t loc
= c_parser_peek_token (parser
)->location
;
14327 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14329 matching_parens parens
;
14331 if (!parens
.require_open (parser
))
14332 t
= error_mark_node
;
14335 location_t eloc
= c_parser_peek_token (parser
)->location
;
14336 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14337 t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
14338 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
14339 t
= c_fully_fold (t
, false, NULL
);
14340 parens
.skip_until_found_close (parser
);
14343 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
14345 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
14346 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
14347 OMP_CLAUSE_CHAIN (c
) = list
;
14351 c_parser_error (parser
, "expected %<(%>");
14356 /* OpenACC, OpenMP 2.5:
14360 if ( directive-name-modifier : expression )
14362 directive-name-modifier:
14363 parallel | task | taskloop | target data | target | target update
14364 | target enter data | target exit data
14367 directive-name-modifier:
14368 ... | simd | cancel */
14371 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
14373 location_t location
= c_parser_peek_token (parser
)->location
;
14374 enum tree_code if_modifier
= ERROR_MARK
;
14376 matching_parens parens
;
14377 if (!parens
.require_open (parser
))
14380 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
14382 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14384 if (strcmp (p
, "cancel") == 0)
14385 if_modifier
= VOID_CST
;
14386 else if (strcmp (p
, "parallel") == 0)
14387 if_modifier
= OMP_PARALLEL
;
14388 else if (strcmp (p
, "simd") == 0)
14389 if_modifier
= OMP_SIMD
;
14390 else if (strcmp (p
, "task") == 0)
14391 if_modifier
= OMP_TASK
;
14392 else if (strcmp (p
, "taskloop") == 0)
14393 if_modifier
= OMP_TASKLOOP
;
14394 else if (strcmp (p
, "target") == 0)
14396 if_modifier
= OMP_TARGET
;
14397 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
14399 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
14400 if (strcmp ("data", p
) == 0)
14401 if_modifier
= OMP_TARGET_DATA
;
14402 else if (strcmp ("update", p
) == 0)
14403 if_modifier
= OMP_TARGET_UPDATE
;
14404 else if (strcmp ("enter", p
) == 0)
14405 if_modifier
= OMP_TARGET_ENTER_DATA
;
14406 else if (strcmp ("exit", p
) == 0)
14407 if_modifier
= OMP_TARGET_EXIT_DATA
;
14408 if (if_modifier
!= OMP_TARGET
)
14411 c_parser_consume_token (parser
);
14415 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
14416 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
14418 if_modifier
= ERROR_MARK
;
14420 if (if_modifier
== OMP_TARGET_ENTER_DATA
14421 || if_modifier
== OMP_TARGET_EXIT_DATA
)
14423 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
14425 p
= IDENTIFIER_POINTER
14426 (c_parser_peek_2nd_token (parser
)->value
);
14427 if (strcmp ("data", p
) == 0)
14431 c_parser_consume_token (parser
);
14435 = c_parser_peek_2nd_token (parser
)->location
;
14436 error_at (loc
, "expected %<data%>");
14437 if_modifier
= ERROR_MARK
;
14442 if (if_modifier
!= ERROR_MARK
)
14444 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14446 c_parser_consume_token (parser
);
14447 c_parser_consume_token (parser
);
14453 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
14454 error_at (loc
, "expected %<:%>");
14456 if_modifier
= ERROR_MARK
;
14461 location_t loc
= c_parser_peek_token (parser
)->location
;
14462 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14463 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
14464 tree t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
), c
;
14465 t
= c_fully_fold (t
, false, NULL
);
14466 parens
.skip_until_found_close (parser
);
14468 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
14469 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
14471 if (if_modifier
!= ERROR_MARK
14472 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
14474 const char *p
= NULL
;
14475 switch (if_modifier
)
14477 case VOID_CST
: p
= "cancel"; break;
14478 case OMP_PARALLEL
: p
= "parallel"; break;
14479 case OMP_SIMD
: p
= "simd"; break;
14480 case OMP_TASK
: p
= "task"; break;
14481 case OMP_TASKLOOP
: p
= "taskloop"; break;
14482 case OMP_TARGET_DATA
: p
= "target data"; break;
14483 case OMP_TARGET
: p
= "target"; break;
14484 case OMP_TARGET_UPDATE
: p
= "target update"; break;
14485 case OMP_TARGET_ENTER_DATA
: p
= "target enter data"; break;
14486 case OMP_TARGET_EXIT_DATA
: p
= "target exit data"; break;
14487 default: gcc_unreachable ();
14489 error_at (location
, "too many %<if%> clauses with %qs modifier",
14493 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
14496 error_at (location
, "too many %<if%> clauses");
14498 error_at (location
, "too many %<if%> clauses without modifier");
14501 else if (if_modifier
== ERROR_MARK
14502 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
14504 error_at (location
, "if any %<if%> clause has modifier, then all "
14505 "%<if%> clauses have to use modifier");
14510 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
14511 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
14512 OMP_CLAUSE_IF_EXPR (c
) = t
;
14513 OMP_CLAUSE_CHAIN (c
) = list
;
14518 lastprivate ( variable-list )
14521 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
14524 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
14526 /* The clauses location. */
14527 location_t loc
= c_parser_peek_token (parser
)->location
;
14529 if (c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
14531 bool conditional
= false;
14532 if (c_parser_next_token_is (parser
, CPP_NAME
)
14533 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14536 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14537 if (strcmp (p
, "conditional") == 0)
14539 conditional
= true;
14540 c_parser_consume_token (parser
);
14541 c_parser_consume_token (parser
);
14544 tree nlist
= c_parser_omp_variable_list (parser
, loc
,
14545 OMP_CLAUSE_LASTPRIVATE
, list
);
14546 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
14548 for (tree c
= nlist
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
14549 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 1;
14559 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
14563 /* FIXME: Should we allow duplicates? */
14564 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
14566 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
14567 OMP_CLAUSE_MERGEABLE
);
14568 OMP_CLAUSE_CHAIN (c
) = list
;
14577 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
14580 location_t loc
= c_parser_peek_token (parser
)->location
;
14582 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
14584 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
14585 OMP_CLAUSE_CHAIN (c
) = list
;
14590 num_threads ( expression ) */
14593 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
14595 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
14596 matching_parens parens
;
14597 if (parens
.require_open (parser
))
14599 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14600 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14601 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14602 tree c
, t
= expr
.value
;
14603 t
= c_fully_fold (t
, false, NULL
);
14605 parens
.skip_until_found_close (parser
);
14607 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14609 c_parser_error (parser
, "expected integer expression");
14613 /* Attempt to statically determine when the number isn't positive. */
14614 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14615 build_int_cst (TREE_TYPE (t
), 0));
14616 protected_set_expr_location (c
, expr_loc
);
14617 if (c
== boolean_true_node
)
14619 warning_at (expr_loc
, 0,
14620 "%<num_threads%> value must be positive");
14621 t
= integer_one_node
;
14624 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
14626 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
14627 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
14628 OMP_CLAUSE_CHAIN (c
) = list
;
14636 num_tasks ( expression )
14639 num_tasks ( strict : expression ) */
14642 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
14644 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
14645 matching_parens parens
;
14646 if (parens
.require_open (parser
))
14648 bool strict
= false;
14649 if (c_parser_next_token_is (parser
, CPP_NAME
)
14650 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
14651 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
14655 c_parser_consume_token (parser
);
14656 c_parser_consume_token (parser
);
14659 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14660 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14661 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14662 tree c
, t
= expr
.value
;
14663 t
= c_fully_fold (t
, false, NULL
);
14665 parens
.skip_until_found_close (parser
);
14667 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14669 c_parser_error (parser
, "expected integer expression");
14673 /* Attempt to statically determine when the number isn't positive. */
14674 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14675 build_int_cst (TREE_TYPE (t
), 0));
14676 if (CAN_HAVE_LOCATION_P (c
))
14677 SET_EXPR_LOCATION (c
, expr_loc
);
14678 if (c
== boolean_true_node
)
14680 warning_at (expr_loc
, 0, "%<num_tasks%> value must be positive");
14681 t
= integer_one_node
;
14684 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
14686 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
14687 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
14688 OMP_CLAUSE_NUM_TASKS_STRICT (c
) = strict
;
14689 OMP_CLAUSE_CHAIN (c
) = list
;
14697 grainsize ( expression )
14700 grainsize ( strict : expression ) */
14703 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
14705 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
14706 matching_parens parens
;
14707 if (parens
.require_open (parser
))
14709 bool strict
= false;
14710 if (c_parser_next_token_is (parser
, CPP_NAME
)
14711 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
14712 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
14716 c_parser_consume_token (parser
);
14717 c_parser_consume_token (parser
);
14720 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14721 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14722 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14723 tree c
, t
= expr
.value
;
14724 t
= c_fully_fold (t
, false, NULL
);
14726 parens
.skip_until_found_close (parser
);
14728 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14730 c_parser_error (parser
, "expected integer expression");
14734 /* Attempt to statically determine when the number isn't positive. */
14735 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14736 build_int_cst (TREE_TYPE (t
), 0));
14737 if (CAN_HAVE_LOCATION_P (c
))
14738 SET_EXPR_LOCATION (c
, expr_loc
);
14739 if (c
== boolean_true_node
)
14741 warning_at (expr_loc
, 0, "%<grainsize%> value must be positive");
14742 t
= integer_one_node
;
14745 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
14747 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
14748 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
14749 OMP_CLAUSE_GRAINSIZE_STRICT (c
) = strict
;
14750 OMP_CLAUSE_CHAIN (c
) = list
;
14758 priority ( expression ) */
14761 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
14763 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
14764 matching_parens parens
;
14765 if (parens
.require_open (parser
))
14767 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14768 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14769 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14770 tree c
, t
= expr
.value
;
14771 t
= c_fully_fold (t
, false, NULL
);
14773 parens
.skip_until_found_close (parser
);
14775 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14777 c_parser_error (parser
, "expected integer expression");
14781 /* Attempt to statically determine when the number isn't
14783 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
14784 build_int_cst (TREE_TYPE (t
), 0));
14785 if (CAN_HAVE_LOCATION_P (c
))
14786 SET_EXPR_LOCATION (c
, expr_loc
);
14787 if (c
== boolean_true_node
)
14789 warning_at (expr_loc
, 0, "%<priority%> value must be non-negative");
14790 t
= integer_one_node
;
14793 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
14795 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
14796 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
14797 OMP_CLAUSE_CHAIN (c
) = list
;
14805 hint ( expression ) */
14808 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
14810 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
14811 matching_parens parens
;
14812 if (parens
.require_open (parser
))
14814 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14815 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14816 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14817 tree c
, t
= expr
.value
;
14818 t
= c_fully_fold (t
, false, NULL
);
14819 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
14820 || TREE_CODE (t
) != INTEGER_CST
14821 || tree_int_cst_sgn (t
) == -1)
14823 c_parser_error (parser
, "expected constant integer expression "
14824 "with valid sync-hint value");
14827 parens
.skip_until_found_close (parser
);
14828 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
14830 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
14831 OMP_CLAUSE_HINT_EXPR (c
) = t
;
14832 OMP_CLAUSE_CHAIN (c
) = list
;
14840 filter ( integer-expression ) */
14843 c_parser_omp_clause_filter (c_parser
*parser
, tree list
)
14845 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
14846 matching_parens parens
;
14847 if (parens
.require_open (parser
))
14849 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14850 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14851 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14852 tree c
, t
= expr
.value
;
14853 t
= c_fully_fold (t
, false, NULL
);
14854 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14856 c_parser_error (parser
, "expected integer expression");
14859 parens
.skip_until_found_close (parser
);
14860 check_no_duplicate_clause (list
, OMP_CLAUSE_FILTER
, "filter");
14862 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_FILTER
);
14863 OMP_CLAUSE_FILTER_EXPR (c
) = t
;
14864 OMP_CLAUSE_CHAIN (c
) = list
;
14872 defaultmap ( tofrom : scalar )
14875 defaultmap ( implicit-behavior [ : variable-category ] ) */
14878 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
14880 location_t loc
= c_parser_peek_token (parser
)->location
;
14883 enum omp_clause_defaultmap_kind behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
14884 enum omp_clause_defaultmap_kind category
14885 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
14887 matching_parens parens
;
14888 if (!parens
.require_open (parser
))
14890 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
14892 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
14895 c_parser_error (parser
, "expected %<alloc%>, %<to%>, %<from%>, "
14896 "%<tofrom%>, %<firstprivate%>, %<none%> "
14901 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14906 if (strcmp ("alloc", p
) == 0)
14907 behavior
= OMP_CLAUSE_DEFAULTMAP_ALLOC
;
14909 goto invalid_behavior
;
14913 if (strcmp ("default", p
) == 0)
14914 behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
14916 goto invalid_behavior
;
14920 if (strcmp ("firstprivate", p
) == 0)
14921 behavior
= OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
14922 else if (strcmp ("from", p
) == 0)
14923 behavior
= OMP_CLAUSE_DEFAULTMAP_FROM
;
14925 goto invalid_behavior
;
14929 if (strcmp ("none", p
) == 0)
14930 behavior
= OMP_CLAUSE_DEFAULTMAP_NONE
;
14932 goto invalid_behavior
;
14936 if (strcmp ("tofrom", p
) == 0)
14937 behavior
= OMP_CLAUSE_DEFAULTMAP_TOFROM
;
14938 else if (strcmp ("to", p
) == 0)
14939 behavior
= OMP_CLAUSE_DEFAULTMAP_TO
;
14941 goto invalid_behavior
;
14945 goto invalid_behavior
;
14947 c_parser_consume_token (parser
);
14949 if (!c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
14951 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14953 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14956 c_parser_error (parser
, "expected %<scalar%>, %<aggregate%> or "
14960 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14964 if (strcmp ("aggregate", p
) == 0)
14965 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
;
14967 goto invalid_category
;
14971 if (strcmp ("pointer", p
) == 0)
14972 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
;
14974 goto invalid_category
;
14978 if (strcmp ("scalar", p
) == 0)
14979 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
;
14981 goto invalid_category
;
14985 goto invalid_category
;
14988 c_parser_consume_token (parser
);
14990 parens
.skip_until_found_close (parser
);
14992 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
14993 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEFAULTMAP
14994 && (category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14995 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
) == category
14996 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
14997 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)))
14999 enum omp_clause_defaultmap_kind cat
= category
;
15000 location_t loc
= OMP_CLAUSE_LOCATION (c
);
15001 if (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
15002 cat
= OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
);
15006 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
15009 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
15012 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
15015 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
15019 gcc_unreachable ();
15022 error_at (loc
, "too many %<defaultmap%> clauses with %qs category",
15025 error_at (loc
, "too many %<defaultmap%> clauses with unspecified "
15030 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
15031 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c
, behavior
, category
);
15032 OMP_CLAUSE_CHAIN (c
) = list
;
15036 parens
.skip_until_found_close (parser
);
15041 use_device ( variable-list )
15044 use_device_ptr ( variable-list ) */
15047 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
15049 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
15054 use_device_addr ( variable-list ) */
15057 c_parser_omp_clause_use_device_addr (c_parser
*parser
, tree list
)
15059 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_ADDR
,
15064 has_device_addr ( variable-list ) */
15067 c_parser_omp_clause_has_device_addr (c_parser
*parser
, tree list
)
15069 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_HAS_DEVICE_ADDR
,
15074 is_device_ptr ( variable-list ) */
15077 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
15079 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
15083 num_gangs ( expression )
15084 num_workers ( expression )
15085 vector_length ( expression ) */
15088 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
15091 location_t loc
= c_parser_peek_token (parser
)->location
;
15093 matching_parens parens
;
15094 if (!parens
.require_open (parser
))
15097 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15098 c_expr expr
= c_parser_expression (parser
);
15099 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15100 tree c
, t
= expr
.value
;
15101 t
= c_fully_fold (t
, false, NULL
);
15103 parens
.skip_until_found_close (parser
);
15105 if (t
== error_mark_node
)
15107 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15109 error_at (expr_loc
, "%qs expression must be integral",
15110 omp_clause_code_name
[code
]);
15114 /* Attempt to statically determine when the number isn't positive. */
15115 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
15116 build_int_cst (TREE_TYPE (t
), 0));
15117 protected_set_expr_location (c
, expr_loc
);
15118 if (c
== boolean_true_node
)
15120 warning_at (expr_loc
, 0,
15121 "%qs value must be positive",
15122 omp_clause_code_name
[code
]);
15123 t
= integer_one_node
;
15126 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15128 c
= build_omp_clause (loc
, code
);
15129 OMP_CLAUSE_OPERAND (c
, 0) = t
;
15130 OMP_CLAUSE_CHAIN (c
) = list
;
15136 gang [( gang-arg-list )]
15137 worker [( [num:] int-expr )]
15138 vector [( [length:] int-expr )]
15140 where gang-arg is one of:
15145 and size-expr may be:
15152 c_parser_oacc_shape_clause (c_parser
*parser
, location_t loc
,
15153 omp_clause_code kind
,
15154 const char *str
, tree list
)
15156 const char *id
= "num";
15157 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
15159 if (kind
== OMP_CLAUSE_VECTOR
)
15162 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
15164 c_parser_consume_token (parser
);
15168 c_token
*next
= c_parser_peek_token (parser
);
15171 /* Gang static argument. */
15172 if (kind
== OMP_CLAUSE_GANG
15173 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
15175 c_parser_consume_token (parser
);
15177 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15178 goto cleanup_error
;
15181 if (ops
[idx
] != NULL_TREE
)
15183 c_parser_error (parser
, "too many %<static%> arguments");
15184 goto cleanup_error
;
15187 /* Check for the '*' argument. */
15188 if (c_parser_next_token_is (parser
, CPP_MULT
)
15189 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
15190 || c_parser_peek_2nd_token (parser
)->type
15191 == CPP_CLOSE_PAREN
))
15193 c_parser_consume_token (parser
);
15194 ops
[idx
] = integer_minus_one_node
;
15196 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15198 c_parser_consume_token (parser
);
15205 /* Worker num: argument and vector length: arguments. */
15206 else if (c_parser_next_token_is (parser
, CPP_NAME
)
15207 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
15208 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
15210 c_parser_consume_token (parser
); /* id */
15211 c_parser_consume_token (parser
); /* ':' */
15214 /* Now collect the actual argument. */
15215 if (ops
[idx
] != NULL_TREE
)
15217 c_parser_error (parser
, "unexpected argument");
15218 goto cleanup_error
;
15221 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15222 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
15223 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
15224 tree expr
= cexpr
.value
;
15225 if (expr
== error_mark_node
)
15226 goto cleanup_error
;
15228 expr
= c_fully_fold (expr
, false, NULL
);
15230 /* Attempt to statically determine when the number isn't a
15231 positive integer. */
15233 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
15235 c_parser_error (parser
, "expected integer expression");
15239 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
15240 build_int_cst (TREE_TYPE (expr
), 0));
15241 if (c
== boolean_true_node
)
15243 warning_at (loc
, 0,
15244 "%qs value must be positive", str
);
15245 expr
= integer_one_node
;
15250 if (kind
== OMP_CLAUSE_GANG
15251 && c_parser_next_token_is (parser
, CPP_COMMA
))
15253 c_parser_consume_token (parser
);
15260 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
15261 goto cleanup_error
;
15264 check_no_duplicate_clause (list
, kind
, str
);
15266 c
= build_omp_clause (loc
, kind
);
15269 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
15271 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
15272 OMP_CLAUSE_CHAIN (c
) = list
;
15277 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
15289 c_parser_oacc_simple_clause (location_t loc
, enum omp_clause_code code
,
15292 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15294 tree c
= build_omp_clause (loc
, code
);
15295 OMP_CLAUSE_CHAIN (c
) = list
;
15301 async [( int-expr )] */
15304 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
15307 location_t loc
= c_parser_peek_token (parser
)->location
;
15309 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
15311 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
15313 c_parser_consume_token (parser
);
15315 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
15316 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15317 c_parser_error (parser
, "expected integer expression");
15318 else if (t
== error_mark_node
15319 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
15323 t
= c_fully_fold (t
, false, NULL
);
15325 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
15327 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
15328 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
15329 OMP_CLAUSE_CHAIN (c
) = list
;
15336 tile ( size-expr-list ) */
15339 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
15341 tree c
, expr
= error_mark_node
;
15343 tree tile
= NULL_TREE
;
15345 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
15346 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
15348 loc
= c_parser_peek_token (parser
)->location
;
15349 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
15354 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
15357 if (c_parser_next_token_is (parser
, CPP_MULT
)
15358 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
15359 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
15361 c_parser_consume_token (parser
);
15362 expr
= integer_zero_node
;
15366 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15367 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
15368 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
15369 expr
= cexpr
.value
;
15371 if (expr
== error_mark_node
)
15373 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15378 expr
= c_fully_fold (expr
, false, NULL
);
15380 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
15381 || !tree_fits_shwi_p (expr
)
15382 || tree_to_shwi (expr
) <= 0)
15384 error_at (expr_loc
, "%<tile%> argument needs positive"
15385 " integral constant");
15386 expr
= integer_zero_node
;
15390 tile
= tree_cons (NULL_TREE
, expr
, tile
);
15392 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
15394 /* Consume the trailing ')'. */
15395 c_parser_consume_token (parser
);
15397 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
15398 tile
= nreverse (tile
);
15399 OMP_CLAUSE_TILE_LIST (c
) = tile
;
15400 OMP_CLAUSE_CHAIN (c
) = list
;
15405 wait [( int-expr-list )] */
15408 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
15410 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15412 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
15413 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
15416 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
15418 OMP_CLAUSE_DECL (c
) = build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
15419 OMP_CLAUSE_CHAIN (c
) = list
;
15428 order ( concurrent )
15431 order ( order-modifier : concurrent )
15438 c_parser_omp_clause_order (c_parser
*parser
, tree list
)
15440 location_t loc
= c_parser_peek_token (parser
)->location
;
15443 bool unconstrained
= false;
15444 bool reproducible
= false;
15446 matching_parens parens
;
15447 if (!parens
.require_open (parser
))
15449 if (c_parser_next_token_is (parser
, CPP_NAME
)
15450 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
15452 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15453 if (strcmp (p
, "unconstrained") == 0)
15454 unconstrained
= true;
15455 else if (strcmp (p
, "reproducible") == 0)
15456 reproducible
= true;
15459 c_parser_error (parser
, "expected %<reproducible%> or "
15460 "%<unconstrained%>");
15463 c_parser_consume_token (parser
);
15464 c_parser_consume_token (parser
);
15466 if (!c_parser_next_token_is (parser
, CPP_NAME
))
15468 c_parser_error (parser
, "expected %<concurrent%>");
15471 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15472 if (strcmp (p
, "concurrent") != 0)
15474 c_parser_error (parser
, "expected %<concurrent%>");
15477 c_parser_consume_token (parser
);
15478 parens
.skip_until_found_close (parser
);
15479 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDER
, "order");
15480 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDER
);
15481 OMP_CLAUSE_ORDER_UNCONSTRAINED (c
) = unconstrained
;
15482 OMP_CLAUSE_ORDER_REPRODUCIBLE (c
) = reproducible
;
15483 OMP_CLAUSE_CHAIN (c
) = list
;
15487 parens
.skip_until_found_close (parser
);
15493 bind ( teams | parallel | thread ) */
15496 c_parser_omp_clause_bind (c_parser
*parser
, tree list
)
15498 location_t loc
= c_parser_peek_token (parser
)->location
;
15501 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
15503 matching_parens parens
;
15504 if (!parens
.require_open (parser
))
15506 if (!c_parser_next_token_is (parser
, CPP_NAME
))
15509 c_parser_error (parser
,
15510 "expected %<teams%>, %<parallel%> or %<thread%>");
15511 parens
.skip_until_found_close (parser
);
15514 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15515 if (strcmp (p
, "teams") == 0)
15516 kind
= OMP_CLAUSE_BIND_TEAMS
;
15517 else if (strcmp (p
, "parallel") == 0)
15518 kind
= OMP_CLAUSE_BIND_PARALLEL
;
15519 else if (strcmp (p
, "thread") != 0)
15521 c_parser_consume_token (parser
);
15522 parens
.skip_until_found_close (parser
);
15523 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
15524 c
= build_omp_clause (loc
, OMP_CLAUSE_BIND
);
15525 OMP_CLAUSE_BIND_KIND (c
) = kind
;
15526 OMP_CLAUSE_CHAIN (c
) = list
;
15535 ordered ( constant-expression ) */
15538 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
15540 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
15542 tree c
, num
= NULL_TREE
;
15544 location_t loc
= c_parser_peek_token (parser
)->location
;
15545 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
15547 matching_parens parens
;
15548 parens
.consume_open (parser
);
15549 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
15550 parens
.skip_until_found_close (parser
);
15552 if (num
== error_mark_node
)
15556 mark_exp_read (num
);
15557 num
= c_fully_fold (num
, false, NULL
);
15558 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
15559 || !tree_fits_shwi_p (num
)
15560 || (n
= tree_to_shwi (num
)) <= 0
15563 error_at (loc
, "ordered argument needs positive "
15564 "constant integer expression");
15568 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
15569 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
15570 OMP_CLAUSE_CHAIN (c
) = list
;
15575 private ( variable-list ) */
15578 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
15580 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
15584 reduction ( reduction-operator : variable-list )
15586 reduction-operator:
15587 One of: + * - & ^ | && ||
15591 reduction-operator:
15592 One of: + * - & ^ | && || max min
15596 reduction-operator:
15597 One of: + * - & ^ | && ||
15601 reduction ( reduction-modifier, reduction-operator : variable-list )
15602 in_reduction ( reduction-operator : variable-list )
15603 task_reduction ( reduction-operator : variable-list ) */
15606 c_parser_omp_clause_reduction (c_parser
*parser
, enum omp_clause_code kind
,
15607 bool is_omp
, tree list
)
15609 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15610 matching_parens parens
;
15611 if (parens
.require_open (parser
))
15614 bool inscan
= false;
15615 enum tree_code code
= ERROR_MARK
;
15616 tree reduc_id
= NULL_TREE
;
15618 if (kind
== OMP_CLAUSE_REDUCTION
&& is_omp
)
15620 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
15621 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
15623 c_parser_consume_token (parser
);
15624 c_parser_consume_token (parser
);
15626 else if (c_parser_next_token_is (parser
, CPP_NAME
)
15627 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
15630 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15631 if (strcmp (p
, "task") == 0)
15633 else if (strcmp (p
, "inscan") == 0)
15635 if (task
|| inscan
)
15637 c_parser_consume_token (parser
);
15638 c_parser_consume_token (parser
);
15643 switch (c_parser_peek_token (parser
)->type
)
15655 code
= BIT_AND_EXPR
;
15658 code
= BIT_XOR_EXPR
;
15661 code
= BIT_IOR_EXPR
;
15664 code
= TRUTH_ANDIF_EXPR
;
15667 code
= TRUTH_ORIF_EXPR
;
15672 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15673 if (strcmp (p
, "min") == 0)
15678 if (strcmp (p
, "max") == 0)
15683 reduc_id
= c_parser_peek_token (parser
)->value
;
15687 c_parser_error (parser
,
15688 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
15689 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
15690 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
15693 c_parser_consume_token (parser
);
15694 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
15695 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15699 nl
= c_parser_omp_variable_list (parser
, clause_loc
, kind
, list
);
15700 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15702 tree d
= OMP_CLAUSE_DECL (c
), type
;
15703 if (TREE_CODE (d
) != TREE_LIST
)
15704 type
= TREE_TYPE (d
);
15709 for (t
= d
; TREE_CODE (t
) == TREE_LIST
; t
= TREE_CHAIN (t
))
15711 type
= TREE_TYPE (t
);
15714 if (TREE_CODE (type
) != POINTER_TYPE
15715 && TREE_CODE (type
) != ARRAY_TYPE
)
15717 type
= TREE_TYPE (type
);
15721 while (TREE_CODE (type
) == ARRAY_TYPE
)
15722 type
= TREE_TYPE (type
);
15723 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
15725 OMP_CLAUSE_REDUCTION_TASK (c
) = 1;
15727 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 1;
15728 if (code
== ERROR_MARK
15729 || !(INTEGRAL_TYPE_P (type
)
15730 || TREE_CODE (type
) == REAL_TYPE
15731 || TREE_CODE (type
) == COMPLEX_TYPE
))
15732 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
15733 = c_omp_reduction_lookup (reduc_id
,
15734 TYPE_MAIN_VARIANT (type
));
15739 parens
.skip_until_found_close (parser
);
15745 schedule ( schedule-kind )
15746 schedule ( schedule-kind , expression )
15749 static | dynamic | guided | runtime | auto
15752 schedule ( schedule-modifier : schedule-kind )
15753 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15761 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
15764 location_t loc
= c_parser_peek_token (parser
)->location
;
15765 int modifiers
= 0, nmodifiers
= 0;
15767 matching_parens parens
;
15768 if (!parens
.require_open (parser
))
15771 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
15773 location_t comma
= UNKNOWN_LOCATION
;
15774 while (c_parser_next_token_is (parser
, CPP_NAME
))
15776 tree kind
= c_parser_peek_token (parser
)->value
;
15777 const char *p
= IDENTIFIER_POINTER (kind
);
15778 if (strcmp ("simd", p
) == 0)
15779 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
15780 else if (strcmp ("monotonic", p
) == 0)
15781 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
15782 else if (strcmp ("nonmonotonic", p
) == 0)
15783 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
15786 comma
= UNKNOWN_LOCATION
;
15787 c_parser_consume_token (parser
);
15788 if (nmodifiers
++ == 0
15789 && c_parser_next_token_is (parser
, CPP_COMMA
))
15791 comma
= c_parser_peek_token (parser
)->location
;
15792 c_parser_consume_token (parser
);
15796 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
15800 if (comma
!= UNKNOWN_LOCATION
)
15801 error_at (comma
, "expected %<:%>");
15803 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
15804 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
15805 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15806 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
15808 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15813 if (c_parser_next_token_is (parser
, CPP_NAME
))
15815 tree kind
= c_parser_peek_token (parser
)->value
;
15816 const char *p
= IDENTIFIER_POINTER (kind
);
15821 if (strcmp ("dynamic", p
) != 0)
15823 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
15827 if (strcmp ("guided", p
) != 0)
15829 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
15833 if (strcmp ("runtime", p
) != 0)
15835 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
15842 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
15843 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
15844 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
15845 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
15849 c_parser_consume_token (parser
);
15850 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15853 c_parser_consume_token (parser
);
15855 here
= c_parser_peek_token (parser
)->location
;
15856 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15857 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
15859 t
= c_fully_fold (t
, false, NULL
);
15861 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
15862 error_at (here
, "schedule %<runtime%> does not take "
15863 "a %<chunk_size%> parameter");
15864 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
15866 "schedule %<auto%> does not take "
15867 "a %<chunk_size%> parameter");
15868 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
)
15870 /* Attempt to statically determine when the number isn't
15872 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
15873 build_int_cst (TREE_TYPE (t
), 0));
15874 protected_set_expr_location (s
, loc
);
15875 if (s
== boolean_true_node
)
15877 warning_at (loc
, 0,
15878 "chunk size value must be positive");
15879 t
= integer_one_node
;
15881 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
15884 c_parser_error (parser
, "expected integer expression");
15886 parens
.skip_until_found_close (parser
);
15889 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15890 "expected %<,%> or %<)%>");
15892 OMP_CLAUSE_SCHEDULE_KIND (c
)
15893 = (enum omp_clause_schedule_kind
)
15894 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
15896 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
15897 OMP_CLAUSE_CHAIN (c
) = list
;
15901 c_parser_error (parser
, "invalid schedule kind");
15902 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
15907 shared ( variable-list ) */
15910 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
15912 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
15919 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
15923 /* FIXME: Should we allow duplicates? */
15924 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
15926 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
15927 OMP_CLAUSE_UNTIED
);
15928 OMP_CLAUSE_CHAIN (c
) = list
;
15938 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
15939 enum omp_clause_code code
, tree list
)
15941 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15943 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15944 OMP_CLAUSE_CHAIN (c
) = list
;
15956 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
15957 enum omp_clause_code code
, tree list
)
15959 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15960 OMP_CLAUSE_CHAIN (c
) = list
;
15969 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
15971 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
15972 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
15973 OMP_CLAUSE_NOGROUP
);
15974 OMP_CLAUSE_CHAIN (c
) = list
;
15983 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
15984 enum omp_clause_code code
, tree list
)
15986 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15987 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15988 OMP_CLAUSE_CHAIN (c
) = list
;
15993 num_teams ( expression )
15996 num_teams ( expression : expression ) */
15999 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
16001 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
16002 matching_parens parens
;
16003 if (parens
.require_open (parser
))
16005 location_t upper_loc
= c_parser_peek_token (parser
)->location
;
16006 location_t lower_loc
= UNKNOWN_LOCATION
;
16007 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16008 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
16009 tree c
, upper
= expr
.value
, lower
= NULL_TREE
;
16010 upper
= c_fully_fold (upper
, false, NULL
);
16012 if (c_parser_next_token_is (parser
, CPP_COLON
))
16014 c_parser_consume_token (parser
);
16015 lower_loc
= upper_loc
;
16017 upper_loc
= c_parser_peek_token (parser
)->location
;
16018 expr
= c_parser_expr_no_commas (parser
, NULL
);
16019 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
16020 upper
= expr
.value
;
16021 upper
= c_fully_fold (upper
, false, NULL
);
16024 parens
.skip_until_found_close (parser
);
16026 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper
))
16027 || (lower
&& !INTEGRAL_TYPE_P (TREE_TYPE (lower
))))
16029 c_parser_error (parser
, "expected integer expression");
16033 /* Attempt to statically determine when the number isn't positive. */
16034 c
= fold_build2_loc (upper_loc
, LE_EXPR
, boolean_type_node
, upper
,
16035 build_int_cst (TREE_TYPE (upper
), 0));
16036 protected_set_expr_location (c
, upper_loc
);
16037 if (c
== boolean_true_node
)
16039 warning_at (upper_loc
, 0, "%<num_teams%> value must be positive");
16040 upper
= integer_one_node
;
16044 c
= fold_build2_loc (lower_loc
, LE_EXPR
, boolean_type_node
, lower
,
16045 build_int_cst (TREE_TYPE (lower
), 0));
16046 protected_set_expr_location (c
, lower_loc
);
16047 if (c
== boolean_true_node
)
16049 warning_at (lower_loc
, 0, "%<num_teams%> value must be positive");
16052 else if (TREE_CODE (lower
) == INTEGER_CST
16053 && TREE_CODE (upper
) == INTEGER_CST
16054 && tree_int_cst_lt (upper
, lower
))
16056 warning_at (lower_loc
, 0, "%<num_teams%> lower bound %qE bigger "
16057 "than upper bound %qE", lower
, upper
);
16062 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
16064 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
16065 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c
) = upper
;
16066 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
) = lower
;
16067 OMP_CLAUSE_CHAIN (c
) = list
;
16075 thread_limit ( expression ) */
16078 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
16080 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
16081 matching_parens parens
;
16082 if (parens
.require_open (parser
))
16084 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16085 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16086 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16087 tree c
, t
= expr
.value
;
16088 t
= c_fully_fold (t
, false, NULL
);
16090 parens
.skip_until_found_close (parser
);
16092 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16094 c_parser_error (parser
, "expected integer expression");
16098 /* Attempt to statically determine when the number isn't positive. */
16099 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
16100 build_int_cst (TREE_TYPE (t
), 0));
16101 protected_set_expr_location (c
, expr_loc
);
16102 if (c
== boolean_true_node
)
16104 warning_at (expr_loc
, 0, "%<thread_limit%> value must be positive");
16105 t
= integer_one_node
;
16108 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
16111 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
16112 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
16113 OMP_CLAUSE_CHAIN (c
) = list
;
16121 aligned ( variable-list )
16122 aligned ( variable-list : constant-expression ) */
16125 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
16127 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16130 matching_parens parens
;
16131 if (!parens
.require_open (parser
))
16134 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
16135 OMP_CLAUSE_ALIGNED
, list
);
16137 if (c_parser_next_token_is (parser
, CPP_COLON
))
16139 c_parser_consume_token (parser
);
16140 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16141 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16142 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16143 tree alignment
= expr
.value
;
16144 alignment
= c_fully_fold (alignment
, false, NULL
);
16145 if (TREE_CODE (alignment
) != INTEGER_CST
16146 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
16147 || tree_int_cst_sgn (alignment
) != 1)
16149 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
16150 "be positive constant integer expression");
16151 alignment
= NULL_TREE
;
16154 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16155 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
16158 parens
.skip_until_found_close (parser
);
16163 allocate ( variable-list )
16164 allocate ( expression : variable-list )
16167 allocate ( allocator-modifier : variable-list )
16168 allocate ( allocator-modifier , allocator-modifier : variable-list )
16170 allocator-modifier:
16171 allocator ( expression )
16172 align ( expression ) */
16175 c_parser_omp_clause_allocate (c_parser
*parser
, tree list
)
16177 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16179 tree allocator
= NULL_TREE
;
16180 tree align
= NULL_TREE
;
16182 matching_parens parens
;
16183 if (!parens
.require_open (parser
))
16186 if ((c_parser_next_token_is_not (parser
, CPP_NAME
)
16187 && c_parser_next_token_is_not (parser
, CPP_KEYWORD
))
16188 || (c_parser_peek_2nd_token (parser
)->type
!= CPP_COMMA
16189 && c_parser_peek_2nd_token (parser
)->type
!= CPP_CLOSE_PAREN
))
16191 bool has_modifiers
= false;
16192 tree orig_type
= NULL_TREE
;
16193 if (c_parser_next_token_is (parser
, CPP_NAME
)
16194 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
16196 unsigned int n
= 3;
16198 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16199 if ((strcmp (p
, "allocator") == 0 || strcmp (p
, "align") == 0)
16200 && c_parser_check_balanced_raw_token_sequence (parser
, &n
)
16201 && (c_parser_peek_nth_token_raw (parser
, n
)->type
16202 == CPP_CLOSE_PAREN
))
16204 if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
16206 has_modifiers
= true;
16207 else if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
16209 && (c_parser_peek_nth_token_raw (parser
, n
+ 2)->type
16211 && (c_parser_peek_nth_token_raw (parser
, n
+ 3)->type
16212 == CPP_OPEN_PAREN
))
16214 c_token
*tok
= c_parser_peek_nth_token_raw (parser
, n
+ 2);
16215 const char *q
= IDENTIFIER_POINTER (tok
->value
);
16217 if ((strcmp (q
, "allocator") == 0
16218 || strcmp (q
, "align") == 0)
16219 && c_parser_check_balanced_raw_token_sequence (parser
,
16221 && (c_parser_peek_nth_token_raw (parser
, n
)->type
16222 == CPP_CLOSE_PAREN
)
16223 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
16225 has_modifiers
= true;
16230 c_parser_consume_token (parser
);
16231 matching_parens parens2
;;
16232 parens2
.require_open (parser
);
16233 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16234 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16235 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16236 if (strcmp (p
, "allocator") == 0)
16238 allocator
= expr
.value
;
16239 allocator
= c_fully_fold (allocator
, false, NULL
);
16240 orig_type
= expr
.original_type
16241 ? expr
.original_type
: TREE_TYPE (allocator
);
16242 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
16246 align
= expr
.value
;
16247 align
= c_fully_fold (align
, false, NULL
);
16249 parens2
.skip_until_found_close (parser
);
16250 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16252 c_parser_consume_token (parser
);
16253 c_token
*tok
= c_parser_peek_token (parser
);
16254 const char *q
= "";
16255 if (c_parser_next_token_is (parser
, CPP_NAME
))
16256 q
= IDENTIFIER_POINTER (tok
->value
);
16257 if (strcmp (q
, "allocator") != 0 && strcmp (q
, "align") != 0)
16259 c_parser_error (parser
, "expected %<allocator%> or "
16261 parens
.skip_until_found_close (parser
);
16264 else if (strcmp (p
, q
) == 0)
16266 error_at (tok
->location
, "duplicate %qs modifier", p
);
16267 parens
.skip_until_found_close (parser
);
16270 c_parser_consume_token (parser
);
16271 if (!parens2
.require_open (parser
))
16273 parens
.skip_until_found_close (parser
);
16276 expr_loc
= c_parser_peek_token (parser
)->location
;
16277 expr
= c_parser_expr_no_commas (parser
, NULL
);
16278 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
16280 if (strcmp (q
, "allocator") == 0)
16282 allocator
= expr
.value
;
16283 allocator
= c_fully_fold (allocator
, false, NULL
);
16284 orig_type
= expr
.original_type
16285 ? expr
.original_type
: TREE_TYPE (allocator
);
16286 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
16290 align
= expr
.value
;
16291 align
= c_fully_fold (align
, false, NULL
);
16293 parens2
.skip_until_found_close (parser
);
16297 if (!has_modifiers
)
16299 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16300 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16301 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16302 allocator
= expr
.value
;
16303 allocator
= c_fully_fold (allocator
, false, NULL
);
16304 orig_type
= expr
.original_type
16305 ? expr
.original_type
: TREE_TYPE (allocator
);
16306 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
16309 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
16310 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
16311 || (TYPE_NAME (orig_type
)
16312 != get_identifier ("omp_allocator_handle_t"))))
16314 error_at (clause_loc
, "%<allocate%> clause allocator expression "
16315 "has type %qT rather than "
16316 "%<omp_allocator_handle_t%>",
16317 TREE_TYPE (allocator
));
16318 allocator
= NULL_TREE
;
16321 && (!INTEGRAL_TYPE_P (TREE_TYPE (align
))
16322 || !tree_fits_uhwi_p (align
)
16323 || !integer_pow2p (align
)))
16325 error_at (clause_loc
, "%<allocate%> clause %<align%> modifier "
16326 "argument needs to be positive constant "
16327 "power of two integer expression");
16330 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16332 parens
.skip_until_found_close (parser
);
16337 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
16338 OMP_CLAUSE_ALLOCATE
, list
);
16340 if (allocator
|| align
)
16341 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16343 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
16344 OMP_CLAUSE_ALLOCATE_ALIGN (c
) = align
;
16347 parens
.skip_until_found_close (parser
);
16352 linear ( variable-list )
16353 linear ( variable-list : expression )
16356 linear ( modifier ( variable-list ) )
16357 linear ( modifier ( variable-list ) : expression )
16363 linear ( variable-list : modifiers-list )
16367 step ( expression ) */
16370 c_parser_omp_clause_linear (c_parser
*parser
, tree list
)
16372 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16374 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
16375 bool old_linear_modifier
= false;
16377 matching_parens parens
;
16378 if (!parens
.require_open (parser
))
16381 if (c_parser_next_token_is (parser
, CPP_NAME
))
16383 c_token
*tok
= c_parser_peek_token (parser
);
16384 const char *p
= IDENTIFIER_POINTER (tok
->value
);
16385 if (strcmp ("val", p
) == 0)
16386 kind
= OMP_CLAUSE_LINEAR_VAL
;
16387 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
16388 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
16389 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
16391 old_linear_modifier
= true;
16392 c_parser_consume_token (parser
);
16393 c_parser_consume_token (parser
);
16397 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
16398 OMP_CLAUSE_LINEAR
, list
);
16400 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
16401 parens
.skip_until_found_close (parser
);
16403 if (c_parser_next_token_is (parser
, CPP_COLON
))
16405 c_parser_consume_token (parser
);
16406 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16407 bool has_modifiers
= false;
16408 if (kind
== OMP_CLAUSE_LINEAR_DEFAULT
16409 && c_parser_next_token_is (parser
, CPP_NAME
))
16411 c_token
*tok
= c_parser_peek_token (parser
);
16412 const char *p
= IDENTIFIER_POINTER (tok
->value
);
16413 unsigned int pos
= 0;
16414 if (strcmp ("val", p
) == 0)
16416 else if (strcmp ("step", p
) == 0
16417 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
16420 if (c_parser_check_balanced_raw_token_sequence (parser
, &pos
)
16421 && (c_parser_peek_nth_token_raw (parser
, pos
)->type
16422 == CPP_CLOSE_PAREN
))
16429 tok
= c_parser_peek_nth_token_raw (parser
, pos
);
16430 if (tok
->type
== CPP_COMMA
|| tok
->type
== CPP_CLOSE_PAREN
)
16431 has_modifiers
= true;
16437 while (c_parser_next_token_is (parser
, CPP_NAME
))
16439 c_token
*tok
= c_parser_peek_token (parser
);
16440 const char *p
= IDENTIFIER_POINTER (tok
->value
);
16441 if (strcmp ("val", p
) == 0)
16443 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
16444 error_at (tok
->location
, "multiple linear modifiers");
16445 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
16446 c_parser_consume_token (parser
);
16448 else if (strcmp ("step", p
) == 0)
16450 c_parser_consume_token (parser
);
16451 matching_parens parens2
;
16452 if (parens2
.require_open (parser
))
16455 error_at (tok
->location
,
16456 "multiple %<step%> modifiers");
16457 expr_loc
= c_parser_peek_token (parser
)->location
;
16458 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16459 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
16461 step
= c_fully_fold (expr
.value
, false, NULL
);
16462 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
16464 error_at (clause_loc
, "%<linear%> clause step "
16465 "expression must be integral");
16466 step
= integer_one_node
;
16468 parens2
.skip_until_found_close (parser
);
16475 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16477 c_parser_consume_token (parser
);
16483 step
= integer_one_node
;
16487 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16488 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16489 step
= c_fully_fold (expr
.value
, false, NULL
);
16490 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
16492 error_at (clause_loc
, "%<linear%> clause step expression must "
16494 step
= integer_one_node
;
16500 step
= integer_one_node
;
16502 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16504 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
16505 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
16506 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c
) = old_linear_modifier
;
16509 parens
.skip_until_found_close (parser
);
16514 nontemporal ( variable-list ) */
16517 c_parser_omp_clause_nontemporal (c_parser
*parser
, tree list
)
16519 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_NONTEMPORAL
, list
);
16523 safelen ( constant-expression ) */
16526 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
16528 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16531 matching_parens parens
;
16532 if (!parens
.require_open (parser
))
16535 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16536 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16537 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16539 t
= c_fully_fold (t
, false, NULL
);
16540 if (TREE_CODE (t
) != INTEGER_CST
16541 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
16542 || tree_int_cst_sgn (t
) != 1)
16544 error_at (clause_loc
, "%<safelen%> clause expression must "
16545 "be positive constant integer expression");
16549 parens
.skip_until_found_close (parser
);
16550 if (t
== NULL_TREE
|| t
== error_mark_node
)
16553 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
16555 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
16556 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
16557 OMP_CLAUSE_CHAIN (c
) = list
;
16562 simdlen ( constant-expression ) */
16565 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
16567 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16570 matching_parens parens
;
16571 if (!parens
.require_open (parser
))
16574 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16575 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16576 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16578 t
= c_fully_fold (t
, false, NULL
);
16579 if (TREE_CODE (t
) != INTEGER_CST
16580 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
16581 || tree_int_cst_sgn (t
) != 1)
16583 error_at (clause_loc
, "%<simdlen%> clause expression must "
16584 "be positive constant integer expression");
16588 parens
.skip_until_found_close (parser
);
16589 if (t
== NULL_TREE
|| t
== error_mark_node
)
16592 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
16594 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
16595 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
16596 OMP_CLAUSE_CHAIN (c
) = list
;
16602 identifier [+/- integer]
16603 vec , identifier [+/- integer]
16607 c_parser_omp_clause_doacross_sink (c_parser
*parser
, location_t clause_loc
,
16608 tree list
, bool depend_p
)
16611 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
16612 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
16614 c_parser_error (parser
, "expected identifier");
16620 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16621 if (strcmp (p
, "omp_cur_iteration") == 0
16622 && c_parser_peek_2nd_token (parser
)->type
== CPP_MINUS
16623 && c_parser_peek_nth_token (parser
, 3)->type
== CPP_NUMBER
16624 && c_parser_peek_nth_token (parser
, 4)->type
== CPP_CLOSE_PAREN
)
16626 tree val
= c_parser_peek_nth_token (parser
, 3)->value
;
16627 if (integer_onep (val
))
16629 c_parser_consume_token (parser
);
16630 c_parser_consume_token (parser
);
16631 c_parser_consume_token (parser
);
16632 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
16633 OMP_CLAUSE_DOACROSS_KIND (u
) = OMP_CLAUSE_DOACROSS_SINK
;
16634 OMP_CLAUSE_CHAIN (u
) = list
;
16642 while (c_parser_next_token_is (parser
, CPP_NAME
)
16643 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
16645 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
16646 tree addend
= NULL
;
16648 if (t
== NULL_TREE
)
16650 undeclared_variable (c_parser_peek_token (parser
)->location
,
16651 c_parser_peek_token (parser
)->value
);
16652 t
= error_mark_node
;
16655 c_parser_consume_token (parser
);
16658 if (c_parser_next_token_is (parser
, CPP_MINUS
))
16660 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
16662 addend
= integer_zero_node
;
16664 goto add_to_vector
;
16666 c_parser_consume_token (parser
);
16668 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
16670 c_parser_error (parser
, "expected integer");
16674 addend
= c_parser_peek_token (parser
)->value
;
16675 if (TREE_CODE (addend
) != INTEGER_CST
)
16677 c_parser_error (parser
, "expected integer");
16680 c_parser_consume_token (parser
);
16683 if (t
!= error_mark_node
)
16685 vec
= tree_cons (addend
, t
, vec
);
16687 OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec
) = 1;
16690 if (c_parser_next_token_is_not (parser
, CPP_COMMA
)
16691 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
16692 || c_parser_peek_2nd_token (parser
)->id_kind
!= C_ID_ID
)
16695 c_parser_consume_token (parser
);
16698 if (vec
== NULL_TREE
)
16701 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
16702 OMP_CLAUSE_DOACROSS_KIND (u
) = OMP_CLAUSE_DOACROSS_SINK
;
16703 OMP_CLAUSE_DOACROSS_DEPEND (u
) = depend_p
;
16704 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
16705 OMP_CLAUSE_CHAIN (u
) = list
;
16710 iterators ( iterators-definition )
16712 iterators-definition:
16714 iterator-specifier , iterators-definition
16716 iterator-specifier:
16717 identifier = range-specification
16718 iterator-type identifier = range-specification
16720 range-specification:
16722 begin : end : step */
16725 c_parser_omp_iterators (c_parser
*parser
)
16727 tree ret
= NULL_TREE
, *last
= &ret
;
16728 c_parser_consume_token (parser
);
16732 matching_parens parens
;
16733 if (!parens
.require_open (parser
))
16734 return error_mark_node
;
16738 tree iter_type
= NULL_TREE
, type_expr
= NULL_TREE
;
16739 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
16741 struct c_type_name
*type
= c_parser_type_name (parser
);
16743 iter_type
= groktypename (type
, &type_expr
, NULL
);
16745 if (iter_type
== NULL_TREE
)
16746 iter_type
= integer_type_node
;
16748 location_t loc
= c_parser_peek_token (parser
)->location
;
16749 if (!c_parser_next_token_is (parser
, CPP_NAME
))
16751 c_parser_error (parser
, "expected identifier");
16755 tree id
= c_parser_peek_token (parser
)->value
;
16756 c_parser_consume_token (parser
);
16758 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
16761 location_t eloc
= c_parser_peek_token (parser
)->location
;
16762 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16763 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
16764 tree begin
= expr
.value
;
16766 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16769 eloc
= c_parser_peek_token (parser
)->location
;
16770 expr
= c_parser_expr_no_commas (parser
, NULL
);
16771 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
16772 tree end
= expr
.value
;
16774 tree step
= integer_one_node
;
16775 if (c_parser_next_token_is (parser
, CPP_COLON
))
16777 c_parser_consume_token (parser
);
16778 eloc
= c_parser_peek_token (parser
)->location
;
16779 expr
= c_parser_expr_no_commas (parser
, NULL
);
16780 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
16784 tree iter_var
= build_decl (loc
, VAR_DECL
, id
, iter_type
);
16785 DECL_ARTIFICIAL (iter_var
) = 1;
16786 DECL_CONTEXT (iter_var
) = current_function_decl
;
16787 pushdecl (iter_var
);
16789 *last
= make_tree_vec (6);
16790 TREE_VEC_ELT (*last
, 0) = iter_var
;
16791 TREE_VEC_ELT (*last
, 1) = begin
;
16792 TREE_VEC_ELT (*last
, 2) = end
;
16793 TREE_VEC_ELT (*last
, 3) = step
;
16794 last
= &TREE_CHAIN (*last
);
16796 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16798 c_parser_consume_token (parser
);
16805 parens
.skip_until_found_close (parser
);
16806 return ret
? ret
: error_mark_node
;
16810 affinity ( [aff-modifier :] variable-list )
16812 iterator ( iterators-definition ) */
16815 c_parser_omp_clause_affinity (c_parser
*parser
, tree list
)
16817 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16818 tree nl
, iterators
= NULL_TREE
;
16820 matching_parens parens
;
16821 if (!parens
.require_open (parser
))
16824 if (c_parser_next_token_is (parser
, CPP_NAME
))
16826 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16827 bool parse_iter
= ((strcmp ("iterator", p
) == 0)
16828 && (c_parser_peek_2nd_token (parser
)->type
16829 == CPP_OPEN_PAREN
));
16833 parse_iter
= (c_parser_check_balanced_raw_token_sequence (parser
, &n
)
16834 && (c_parser_peek_nth_token_raw (parser
, n
)->type
16835 == CPP_CLOSE_PAREN
)
16836 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
16841 iterators
= c_parser_omp_iterators (parser
);
16842 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16846 parens
.skip_until_found_close (parser
);
16851 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_AFFINITY
,
16855 tree block
= pop_scope ();
16856 if (iterators
!= error_mark_node
)
16858 TREE_VEC_ELT (iterators
, 5) = block
;
16859 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16860 OMP_CLAUSE_DECL (c
) = build_tree_list (iterators
,
16861 OMP_CLAUSE_DECL (c
));
16865 parens
.skip_until_found_close (parser
);
16871 depend ( depend-kind: variable-list )
16879 depend ( sink : vec )
16882 depend ( depend-modifier , depend-kind: variable-list )
16885 in | out | inout | mutexinoutset | depobj | inoutset
16888 iterator ( iterators-definition ) */
16891 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
16893 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16894 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_LAST
;
16895 enum omp_clause_doacross_kind dkind
= OMP_CLAUSE_DOACROSS_LAST
;
16896 tree nl
, c
, iterators
= NULL_TREE
;
16898 matching_parens parens
;
16899 if (!parens
.require_open (parser
))
16904 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
16907 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16908 if (strcmp ("iterator", p
) == 0 && iterators
== NULL_TREE
)
16910 iterators
= c_parser_omp_iterators (parser
);
16911 c_parser_require (parser
, CPP_COMMA
, "expected %<,%>");
16914 if (strcmp ("in", p
) == 0)
16915 kind
= OMP_CLAUSE_DEPEND_IN
;
16916 else if (strcmp ("inout", p
) == 0)
16917 kind
= OMP_CLAUSE_DEPEND_INOUT
;
16918 else if (strcmp ("inoutset", p
) == 0)
16919 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
16920 else if (strcmp ("mutexinoutset", p
) == 0)
16921 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
16922 else if (strcmp ("out", p
) == 0)
16923 kind
= OMP_CLAUSE_DEPEND_OUT
;
16924 else if (strcmp ("depobj", p
) == 0)
16925 kind
= OMP_CLAUSE_DEPEND_DEPOBJ
;
16926 else if (strcmp ("sink", p
) == 0)
16927 dkind
= OMP_CLAUSE_DOACROSS_SINK
;
16928 else if (strcmp ("source", p
) == 0)
16929 dkind
= OMP_CLAUSE_DOACROSS_SOURCE
;
16936 c_parser_consume_token (parser
);
16939 && (dkind
== OMP_CLAUSE_DOACROSS_SOURCE
16940 || dkind
== OMP_CLAUSE_DOACROSS_SINK
))
16943 error_at (clause_loc
, "%<iterator%> modifier incompatible with %qs",
16944 dkind
== OMP_CLAUSE_DOACROSS_SOURCE
? "source" : "sink");
16945 iterators
= NULL_TREE
;
16948 if (dkind
== OMP_CLAUSE_DOACROSS_SOURCE
)
16950 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
16951 OMP_CLAUSE_DOACROSS_KIND (c
) = dkind
;
16952 OMP_CLAUSE_DOACROSS_DEPEND (c
) = 1;
16953 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
16954 OMP_CLAUSE_CHAIN (c
) = list
;
16955 parens
.skip_until_found_close (parser
);
16959 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16962 if (dkind
== OMP_CLAUSE_DOACROSS_SINK
)
16963 nl
= c_parser_omp_clause_doacross_sink (parser
, clause_loc
, list
, true);
16966 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
16967 OMP_CLAUSE_DEPEND
, list
);
16971 tree block
= pop_scope ();
16972 if (iterators
== error_mark_node
)
16973 iterators
= NULL_TREE
;
16975 TREE_VEC_ELT (iterators
, 5) = block
;
16978 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16980 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
16982 OMP_CLAUSE_DECL (c
)
16983 = build_tree_list (iterators
, OMP_CLAUSE_DECL (c
));
16987 parens
.skip_until_found_close (parser
);
16991 c_parser_error (parser
, "invalid depend kind");
16993 parens
.skip_until_found_close (parser
);
17000 doacross ( source : )
17001 doacross ( source : omp_cur_iteration )
17003 doacross ( sink : vec )
17004 doacross ( sink : omp_cur_iteration - logical_iteration ) */
17007 c_parser_omp_clause_doacross (c_parser
*parser
, tree list
)
17009 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17010 enum omp_clause_doacross_kind kind
= OMP_CLAUSE_DOACROSS_LAST
;
17014 matching_parens parens
;
17015 if (!parens
.require_open (parser
))
17018 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
17021 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17022 if (strcmp ("sink", p
) == 0)
17023 kind
= OMP_CLAUSE_DOACROSS_SINK
;
17024 else if (strcmp ("source", p
) == 0)
17025 kind
= OMP_CLAUSE_DOACROSS_SOURCE
;
17029 c_parser_consume_token (parser
);
17031 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
17034 if (kind
== OMP_CLAUSE_DOACROSS_SOURCE
)
17036 if (c_parser_next_token_is (parser
, CPP_NAME
)
17037 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
17038 "omp_cur_iteration") == 0)
17039 c_parser_consume_token (parser
);
17040 nl
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
17041 OMP_CLAUSE_DOACROSS_KIND (nl
) = OMP_CLAUSE_DOACROSS_SOURCE
;
17042 OMP_CLAUSE_DECL (nl
) = NULL_TREE
;
17043 OMP_CLAUSE_CHAIN (nl
) = list
;
17046 nl
= c_parser_omp_clause_doacross_sink (parser
, clause_loc
, list
, false);
17048 parens
.skip_until_found_close (parser
);
17052 c_parser_error (parser
, "invalid doacross kind");
17054 parens
.skip_until_found_close (parser
);
17059 map ( map-kind: variable-list )
17060 map ( variable-list )
17063 alloc | to | from | tofrom
17067 alloc | to | from | tofrom | release | delete
17069 map ( always [,] map-kind: variable-list )
17072 map ( [map-type-modifier[,] ...] map-kind: variable-list )
17078 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
17080 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17081 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
17084 matching_parens parens
;
17085 if (!parens
.require_open (parser
))
17089 int map_kind_pos
= 0;
17090 while (c_parser_peek_nth_token_raw (parser
, pos
)->type
== CPP_NAME
)
17092 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COLON
)
17094 map_kind_pos
= pos
;
17098 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COMMA
)
17103 int always_modifier
= 0;
17104 int close_modifier
= 0;
17105 for (int pos
= 1; pos
< map_kind_pos
; ++pos
)
17107 c_token
*tok
= c_parser_peek_token (parser
);
17109 if (tok
->type
== CPP_COMMA
)
17111 c_parser_consume_token (parser
);
17115 const char *p
= IDENTIFIER_POINTER (tok
->value
);
17116 if (strcmp ("always", p
) == 0)
17118 if (always_modifier
)
17120 c_parser_error (parser
, "too many %<always%> modifiers");
17121 parens
.skip_until_found_close (parser
);
17126 else if (strcmp ("close", p
) == 0)
17128 if (close_modifier
)
17130 c_parser_error (parser
, "too many %<close%> modifiers");
17131 parens
.skip_until_found_close (parser
);
17138 c_parser_error (parser
, "%<#pragma omp target%> with "
17139 "modifier other than %<always%> or "
17140 "%<close%> on %<map%> clause");
17141 parens
.skip_until_found_close (parser
);
17145 c_parser_consume_token (parser
);
17148 if (c_parser_next_token_is (parser
, CPP_NAME
)
17149 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
17151 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17152 if (strcmp ("alloc", p
) == 0)
17153 kind
= GOMP_MAP_ALLOC
;
17154 else if (strcmp ("to", p
) == 0)
17155 kind
= always_modifier
? GOMP_MAP_ALWAYS_TO
: GOMP_MAP_TO
;
17156 else if (strcmp ("from", p
) == 0)
17157 kind
= always_modifier
? GOMP_MAP_ALWAYS_FROM
: GOMP_MAP_FROM
;
17158 else if (strcmp ("tofrom", p
) == 0)
17159 kind
= always_modifier
? GOMP_MAP_ALWAYS_TOFROM
: GOMP_MAP_TOFROM
;
17160 else if (strcmp ("release", p
) == 0)
17161 kind
= GOMP_MAP_RELEASE
;
17162 else if (strcmp ("delete", p
) == 0)
17163 kind
= GOMP_MAP_DELETE
;
17166 c_parser_error (parser
, "invalid map kind");
17167 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
17171 c_parser_consume_token (parser
);
17172 c_parser_consume_token (parser
);
17175 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
,
17178 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
17179 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
17181 parens
.skip_until_found_close (parser
);
17186 device ( expression )
17189 device ( [device-modifier :] integer-expression )
17192 ancestor | device_num */
17195 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
17197 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17198 location_t expr_loc
;
17201 bool ancestor
= false;
17203 matching_parens parens
;
17204 if (!parens
.require_open (parser
))
17207 if (c_parser_next_token_is (parser
, CPP_NAME
)
17208 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
17210 c_token
*tok
= c_parser_peek_token (parser
);
17211 const char *p
= IDENTIFIER_POINTER (tok
->value
);
17212 if (strcmp ("ancestor", p
) == 0)
17214 /* A requires directive with the reverse_offload clause must be
17216 if ((omp_requires_mask
& OMP_REQUIRES_REVERSE_OFFLOAD
) == 0)
17218 error_at (tok
->location
, "%<ancestor%> device modifier not "
17219 "preceded by %<requires%> directive "
17220 "with %<reverse_offload%> clause");
17221 parens
.skip_until_found_close (parser
);
17226 else if (strcmp ("device_num", p
) == 0)
17230 error_at (tok
->location
, "expected %<ancestor%> or %<device_num%>");
17231 parens
.skip_until_found_close (parser
);
17234 c_parser_consume_token (parser
);
17235 c_parser_consume_token (parser
);
17238 expr_loc
= c_parser_peek_token (parser
)->location
;
17239 expr
= c_parser_expr_no_commas (parser
, NULL
);
17240 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17242 t
= c_fully_fold (t
, false, NULL
);
17244 parens
.skip_until_found_close (parser
);
17246 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
17248 c_parser_error (parser
, "expected integer expression");
17251 if (ancestor
&& TREE_CODE (t
) == INTEGER_CST
&& !integer_onep (t
))
17253 error_at (expr_loc
, "the %<device%> clause expression must evaluate to "
17258 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
17260 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
17262 OMP_CLAUSE_DEVICE_ID (c
) = t
;
17263 OMP_CLAUSE_CHAIN (c
) = list
;
17264 OMP_CLAUSE_DEVICE_ANCESTOR (c
) = ancestor
;
17271 dist_schedule ( static )
17272 dist_schedule ( static , expression ) */
17275 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
17277 tree c
, t
= NULL_TREE
;
17278 location_t loc
= c_parser_peek_token (parser
)->location
;
17280 matching_parens parens
;
17281 if (!parens
.require_open (parser
))
17284 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
17286 c_parser_error (parser
, "invalid dist_schedule kind");
17287 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
17292 c_parser_consume_token (parser
);
17293 if (c_parser_next_token_is (parser
, CPP_COMMA
))
17295 c_parser_consume_token (parser
);
17297 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17298 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17299 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17301 t
= c_fully_fold (t
, false, NULL
);
17302 parens
.skip_until_found_close (parser
);
17305 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
17306 "expected %<,%> or %<)%>");
17308 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
17309 "dist_schedule"); */
17310 if (omp_find_clause (list
, OMP_CLAUSE_DIST_SCHEDULE
))
17311 warning_at (loc
, 0, "too many %qs clauses", "dist_schedule");
17312 if (t
== error_mark_node
)
17315 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
17316 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
17317 OMP_CLAUSE_CHAIN (c
) = list
;
17322 proc_bind ( proc-bind-kind )
17325 primary | master | close | spread
17326 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
17329 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
17331 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17332 enum omp_clause_proc_bind_kind kind
;
17335 matching_parens parens
;
17336 if (!parens
.require_open (parser
))
17339 if (c_parser_next_token_is (parser
, CPP_NAME
))
17341 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17342 if (strcmp ("primary", p
) == 0)
17343 kind
= OMP_CLAUSE_PROC_BIND_PRIMARY
;
17344 else if (strcmp ("master", p
) == 0)
17345 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
17346 else if (strcmp ("close", p
) == 0)
17347 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
17348 else if (strcmp ("spread", p
) == 0)
17349 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
17356 check_no_duplicate_clause (list
, OMP_CLAUSE_PROC_BIND
, "proc_bind");
17357 c_parser_consume_token (parser
);
17358 parens
.skip_until_found_close (parser
);
17359 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
17360 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
17361 OMP_CLAUSE_CHAIN (c
) = list
;
17365 c_parser_error (parser
, "invalid proc_bind kind");
17366 parens
.skip_until_found_close (parser
);
17371 device_type ( host | nohost | any ) */
17374 c_parser_omp_clause_device_type (c_parser
*parser
, tree list
)
17376 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17377 enum omp_clause_device_type_kind kind
;
17380 matching_parens parens
;
17381 if (!parens
.require_open (parser
))
17384 if (c_parser_next_token_is (parser
, CPP_NAME
))
17386 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17387 if (strcmp ("host", p
) == 0)
17388 kind
= OMP_CLAUSE_DEVICE_TYPE_HOST
;
17389 else if (strcmp ("nohost", p
) == 0)
17390 kind
= OMP_CLAUSE_DEVICE_TYPE_NOHOST
;
17391 else if (strcmp ("any", p
) == 0)
17392 kind
= OMP_CLAUSE_DEVICE_TYPE_ANY
;
17399 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE_TYPE
,
17401 c_parser_consume_token (parser
);
17402 parens
.skip_until_found_close (parser
);
17403 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE_TYPE
);
17404 OMP_CLAUSE_DEVICE_TYPE_KIND (c
) = kind
;
17405 OMP_CLAUSE_CHAIN (c
) = list
;
17409 c_parser_error (parser
, "expected %<host%>, %<nohost%> or %<any%>");
17410 parens
.skip_until_found_close (parser
);
17415 to ( variable-list ) */
17418 c_parser_omp_clause_to (c_parser
*parser
, tree list
)
17420 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO
, list
, true);
17424 from ( variable-list ) */
17427 c_parser_omp_clause_from (c_parser
*parser
, tree list
)
17429 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FROM
, list
, true);
17433 uniform ( variable-list ) */
17436 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
17438 /* The clauses location. */
17439 location_t loc
= c_parser_peek_token (parser
)->location
;
17441 matching_parens parens
;
17442 if (parens
.require_open (parser
))
17444 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
17446 parens
.skip_until_found_close (parser
);
17452 detach ( event-handle ) */
17455 c_parser_omp_clause_detach (c_parser
*parser
, tree list
)
17457 matching_parens parens
;
17458 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17460 if (!parens
.require_open (parser
))
17463 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
17464 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
17466 c_parser_error (parser
, "expected identifier");
17467 parens
.skip_until_found_close (parser
);
17471 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
17472 if (t
== NULL_TREE
)
17474 undeclared_variable (c_parser_peek_token (parser
)->location
,
17475 c_parser_peek_token (parser
)->value
);
17476 parens
.skip_until_found_close (parser
);
17479 c_parser_consume_token (parser
);
17481 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (t
));
17482 if (!INTEGRAL_TYPE_P (type
)
17483 || TREE_CODE (type
) != ENUMERAL_TYPE
17484 || TYPE_NAME (type
) != get_identifier ("omp_event_handle_t"))
17486 error_at (clause_loc
, "%<detach%> clause event handle "
17487 "has type %qT rather than "
17488 "%<omp_event_handle_t%>",
17490 parens
.skip_until_found_close (parser
);
17494 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DETACH
);
17495 OMP_CLAUSE_DECL (u
) = t
;
17496 OMP_CLAUSE_CHAIN (u
) = list
;
17497 parens
.skip_until_found_close (parser
);
17501 /* Parse all OpenACC clauses. The set clauses allowed by the directive
17502 is a bitmask in MASK. Return the list of clauses found. */
17505 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
17506 const char *where
, bool finish_p
= true)
17508 tree clauses
= NULL
;
17511 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17514 pragma_omp_clause c_kind
;
17515 const char *c_name
;
17516 tree prev
= clauses
;
17518 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
17519 c_parser_consume_token (parser
);
17521 here
= c_parser_peek_token (parser
)->location
;
17522 c_kind
= c_parser_omp_clause_name (parser
);
17526 case PRAGMA_OACC_CLAUSE_ASYNC
:
17527 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
17530 case PRAGMA_OACC_CLAUSE_AUTO
:
17531 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_AUTO
,
17535 case PRAGMA_OACC_CLAUSE_ATTACH
:
17536 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17539 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
17540 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
17541 c_name
= "collapse";
17543 case PRAGMA_OACC_CLAUSE_COPY
:
17544 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17547 case PRAGMA_OACC_CLAUSE_COPYIN
:
17548 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17551 case PRAGMA_OACC_CLAUSE_COPYOUT
:
17552 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17553 c_name
= "copyout";
17555 case PRAGMA_OACC_CLAUSE_CREATE
:
17556 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17559 case PRAGMA_OACC_CLAUSE_DELETE
:
17560 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17563 case PRAGMA_OMP_CLAUSE_DEFAULT
:
17564 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
17565 c_name
= "default";
17567 case PRAGMA_OACC_CLAUSE_DETACH
:
17568 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17571 case PRAGMA_OACC_CLAUSE_DEVICE
:
17572 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17575 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
17576 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
17577 c_name
= "deviceptr";
17579 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
17580 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17581 c_name
= "device_resident";
17583 case PRAGMA_OACC_CLAUSE_FINALIZE
:
17584 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_FINALIZE
,
17586 c_name
= "finalize";
17588 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
17589 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
17590 c_name
= "firstprivate";
17592 case PRAGMA_OACC_CLAUSE_GANG
:
17594 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_GANG
,
17597 case PRAGMA_OACC_CLAUSE_HOST
:
17598 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17601 case PRAGMA_OACC_CLAUSE_IF
:
17602 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
17605 case PRAGMA_OACC_CLAUSE_IF_PRESENT
:
17606 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_IF_PRESENT
,
17608 c_name
= "if_present";
17610 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
17611 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_INDEPENDENT
,
17613 c_name
= "independent";
17615 case PRAGMA_OACC_CLAUSE_LINK
:
17616 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17619 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
17620 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17621 c_name
= "no_create";
17623 case PRAGMA_OACC_CLAUSE_NOHOST
:
17624 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_NOHOST
,
17628 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
17629 clauses
= c_parser_oacc_single_int_clause (parser
,
17630 OMP_CLAUSE_NUM_GANGS
,
17632 c_name
= "num_gangs";
17634 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
17635 clauses
= c_parser_oacc_single_int_clause (parser
,
17636 OMP_CLAUSE_NUM_WORKERS
,
17638 c_name
= "num_workers";
17640 case PRAGMA_OACC_CLAUSE_PRESENT
:
17641 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17642 c_name
= "present";
17644 case PRAGMA_OACC_CLAUSE_PRIVATE
:
17645 clauses
= c_parser_omp_clause_private (parser
, clauses
);
17646 c_name
= "private";
17648 case PRAGMA_OACC_CLAUSE_REDUCTION
:
17650 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
17652 c_name
= "reduction";
17654 case PRAGMA_OACC_CLAUSE_SEQ
:
17655 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_SEQ
,
17659 case PRAGMA_OACC_CLAUSE_TILE
:
17660 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
17663 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
17664 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
17665 c_name
= "use_device";
17667 case PRAGMA_OACC_CLAUSE_VECTOR
:
17669 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_VECTOR
,
17672 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
17673 clauses
= c_parser_oacc_single_int_clause (parser
,
17674 OMP_CLAUSE_VECTOR_LENGTH
,
17676 c_name
= "vector_length";
17678 case PRAGMA_OACC_CLAUSE_WAIT
:
17679 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
17682 case PRAGMA_OACC_CLAUSE_WORKER
:
17684 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_WORKER
,
17688 c_parser_error (parser
, "expected %<#pragma acc%> clause");
17694 if (((mask
>> c_kind
) & 1) == 0)
17696 /* Remove the invalid clause(s) from the list to avoid
17697 confusing the rest of the compiler. */
17699 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
17704 c_parser_skip_to_pragma_eol (parser
);
17707 return c_finish_omp_clauses (clauses
, C_ORT_ACC
);
17712 /* Parse all OpenMP clauses. The set clauses allowed by the directive
17713 is a bitmask in MASK. Return the list of clauses found.
17714 FINISH_P set if c_finish_omp_clauses should be called.
17715 NESTED non-zero if clauses should be terminated by closing paren instead
17716 of end of pragma. If it is 2, additionally commas are required in between
17720 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
17721 const char *where
, bool finish_p
= true,
17724 tree clauses
= NULL
;
17727 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17730 pragma_omp_clause c_kind
;
17731 const char *c_name
;
17732 tree prev
= clauses
;
17734 if (nested
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
17737 if (!first
|| nested
!= 2)
17739 if (c_parser_next_token_is (parser
, CPP_COMMA
))
17740 c_parser_consume_token (parser
);
17741 else if (nested
== 2)
17742 error_at (c_parser_peek_token (parser
)->location
,
17743 "clauses in %<simd%> trait should be separated "
17747 here
= c_parser_peek_token (parser
)->location
;
17748 c_kind
= c_parser_omp_clause_name (parser
);
17752 case PRAGMA_OMP_CLAUSE_BIND
:
17753 clauses
= c_parser_omp_clause_bind (parser
, clauses
);
17756 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
17757 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
17758 c_name
= "collapse";
17760 case PRAGMA_OMP_CLAUSE_COPYIN
:
17761 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
17764 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
17765 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
17766 c_name
= "copyprivate";
17768 case PRAGMA_OMP_CLAUSE_DEFAULT
:
17769 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
17770 c_name
= "default";
17772 case PRAGMA_OMP_CLAUSE_DETACH
:
17773 clauses
= c_parser_omp_clause_detach (parser
, clauses
);
17776 case PRAGMA_OMP_CLAUSE_FILTER
:
17777 clauses
= c_parser_omp_clause_filter (parser
, clauses
);
17780 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
17781 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
17782 c_name
= "firstprivate";
17784 case PRAGMA_OMP_CLAUSE_FINAL
:
17785 clauses
= c_parser_omp_clause_final (parser
, clauses
);
17788 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
17789 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
17790 c_name
= "grainsize";
17792 case PRAGMA_OMP_CLAUSE_HINT
:
17793 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
17796 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
17797 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
17798 c_name
= "defaultmap";
17800 case PRAGMA_OMP_CLAUSE_IF
:
17801 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
17804 case PRAGMA_OMP_CLAUSE_IN_REDUCTION
:
17806 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_IN_REDUCTION
,
17808 c_name
= "in_reduction";
17810 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
17811 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
17812 c_name
= "lastprivate";
17814 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
17815 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
17816 c_name
= "mergeable";
17818 case PRAGMA_OMP_CLAUSE_NOWAIT
:
17819 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
17822 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
17823 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
17824 c_name
= "num_tasks";
17826 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
17827 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
17828 c_name
= "num_threads";
17830 case PRAGMA_OMP_CLAUSE_ORDER
:
17831 clauses
= c_parser_omp_clause_order (parser
, clauses
);
17834 case PRAGMA_OMP_CLAUSE_ORDERED
:
17835 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
17836 c_name
= "ordered";
17838 case PRAGMA_OMP_CLAUSE_PRIORITY
:
17839 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
17840 c_name
= "priority";
17842 case PRAGMA_OMP_CLAUSE_PRIVATE
:
17843 clauses
= c_parser_omp_clause_private (parser
, clauses
);
17844 c_name
= "private";
17846 case PRAGMA_OMP_CLAUSE_REDUCTION
:
17848 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
17850 c_name
= "reduction";
17852 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
17853 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
17854 c_name
= "schedule";
17856 case PRAGMA_OMP_CLAUSE_SHARED
:
17857 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
17860 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION
:
17862 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_TASK_REDUCTION
,
17864 c_name
= "task_reduction";
17866 case PRAGMA_OMP_CLAUSE_UNTIED
:
17867 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
17870 case PRAGMA_OMP_CLAUSE_INBRANCH
:
17871 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
17873 c_name
= "inbranch";
17875 case PRAGMA_OMP_CLAUSE_NONTEMPORAL
:
17876 clauses
= c_parser_omp_clause_nontemporal (parser
, clauses
);
17877 c_name
= "nontemporal";
17879 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
17880 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
17882 c_name
= "notinbranch";
17884 case PRAGMA_OMP_CLAUSE_PARALLEL
:
17886 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
17888 c_name
= "parallel";
17892 error_at (here
, "%qs must be the first clause of %qs",
17897 case PRAGMA_OMP_CLAUSE_FOR
:
17899 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
17903 goto clause_not_first
;
17905 case PRAGMA_OMP_CLAUSE_SECTIONS
:
17907 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
17909 c_name
= "sections";
17911 goto clause_not_first
;
17913 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
17915 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
17917 c_name
= "taskgroup";
17919 goto clause_not_first
;
17921 case PRAGMA_OMP_CLAUSE_LINK
:
17923 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
17926 case PRAGMA_OMP_CLAUSE_TO
:
17927 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
17929 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
17931 for (tree c
= nl
; c
!= clauses
; c
= OMP_CLAUSE_CHAIN (c
))
17932 OMP_CLAUSE_ENTER_TO (c
) = 1;
17936 clauses
= c_parser_omp_clause_to (parser
, clauses
);
17939 case PRAGMA_OMP_CLAUSE_FROM
:
17940 clauses
= c_parser_omp_clause_from (parser
, clauses
);
17943 case PRAGMA_OMP_CLAUSE_UNIFORM
:
17944 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
17945 c_name
= "uniform";
17947 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
17948 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
17949 c_name
= "num_teams";
17951 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
17952 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
17953 c_name
= "thread_limit";
17955 case PRAGMA_OMP_CLAUSE_ALIGNED
:
17956 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
17957 c_name
= "aligned";
17959 case PRAGMA_OMP_CLAUSE_ALLOCATE
:
17960 clauses
= c_parser_omp_clause_allocate (parser
, clauses
);
17961 c_name
= "allocate";
17963 case PRAGMA_OMP_CLAUSE_LINEAR
:
17964 clauses
= c_parser_omp_clause_linear (parser
, clauses
);
17967 case PRAGMA_OMP_CLAUSE_AFFINITY
:
17968 clauses
= c_parser_omp_clause_affinity (parser
, clauses
);
17969 c_name
= "affinity";
17971 case PRAGMA_OMP_CLAUSE_DEPEND
:
17972 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
17975 case PRAGMA_OMP_CLAUSE_DOACROSS
:
17976 clauses
= c_parser_omp_clause_doacross (parser
, clauses
);
17977 c_name
= "doacross";
17979 case PRAGMA_OMP_CLAUSE_MAP
:
17980 clauses
= c_parser_omp_clause_map (parser
, clauses
);
17983 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
17984 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
17985 c_name
= "use_device_ptr";
17987 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
:
17988 clauses
= c_parser_omp_clause_use_device_addr (parser
, clauses
);
17989 c_name
= "use_device_addr";
17991 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
:
17992 clauses
= c_parser_omp_clause_has_device_addr (parser
, clauses
);
17993 c_name
= "has_device_addr";
17995 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
17996 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
17997 c_name
= "is_device_ptr";
17999 case PRAGMA_OMP_CLAUSE_DEVICE
:
18000 clauses
= c_parser_omp_clause_device (parser
, clauses
);
18003 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
18004 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
18005 c_name
= "dist_schedule";
18007 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
18008 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
18009 c_name
= "proc_bind";
18011 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE
:
18012 clauses
= c_parser_omp_clause_device_type (parser
, clauses
);
18013 c_name
= "device_type";
18015 case PRAGMA_OMP_CLAUSE_SAFELEN
:
18016 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
18017 c_name
= "safelen";
18019 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
18020 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
18021 c_name
= "simdlen";
18023 case PRAGMA_OMP_CLAUSE_NOGROUP
:
18024 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
18025 c_name
= "nogroup";
18027 case PRAGMA_OMP_CLAUSE_THREADS
:
18029 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
18031 c_name
= "threads";
18033 case PRAGMA_OMP_CLAUSE_SIMD
:
18035 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
18039 case PRAGMA_OMP_CLAUSE_ENTER
:
18041 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
18046 c_parser_error (parser
, "expected %<#pragma omp%> clause");
18052 if (((mask
>> c_kind
) & 1) == 0)
18054 /* Remove the invalid clause(s) from the list to avoid
18055 confusing the rest of the compiler. */
18057 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
18063 c_parser_skip_to_pragma_eol (parser
);
18067 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
18068 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
18069 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
18075 /* OpenACC 2.0, OpenMP 2.5:
18079 In practice, we're also interested in adding the statement to an
18080 outer node. So it is convenient if we work around the fact that
18081 c_parser_statement calls add_stmt. */
18084 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
18086 tree stmt
= push_stmt_list ();
18087 c_parser_statement (parser
, if_p
);
18088 return pop_stmt_list (stmt
);
18092 # pragma acc cache (variable-list) new-line
18094 LOC is the location of the #pragma token.
18098 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
18100 tree stmt
, clauses
;
18102 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE__CACHE_
, NULL
);
18103 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
18105 c_parser_skip_to_pragma_eol (parser
);
18107 stmt
= make_node (OACC_CACHE
);
18108 TREE_TYPE (stmt
) = void_type_node
;
18109 OACC_CACHE_CLAUSES (stmt
) = clauses
;
18110 SET_EXPR_LOCATION (stmt
, loc
);
18117 # pragma acc data oacc-data-clause[optseq] new-line
18120 LOC is the location of the #pragma token.
18123 #define OACC_DATA_CLAUSE_MASK \
18124 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18125 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18126 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18127 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18128 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18129 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18130 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18131 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
18132 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
18135 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
18137 tree stmt
, clauses
, block
;
18139 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
18140 "#pragma acc data");
18142 block
= c_begin_omp_parallel ();
18143 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
18145 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
18151 # pragma acc declare oacc-data-clause[optseq] new-line
18154 #define OACC_DECLARE_CLAUSE_MASK \
18155 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18156 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18157 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18158 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18159 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18160 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
18161 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
18162 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
18165 c_parser_oacc_declare (c_parser
*parser
)
18167 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
18168 tree clauses
, stmt
, t
, decl
;
18170 bool error
= false;
18172 c_parser_consume_pragma (parser
);
18174 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
18175 "#pragma acc declare");
18178 error_at (pragma_loc
,
18179 "no valid clauses specified in %<#pragma acc declare%>");
18183 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
18185 location_t loc
= OMP_CLAUSE_LOCATION (t
);
18186 decl
= OMP_CLAUSE_DECL (t
);
18187 if (!DECL_P (decl
))
18189 error_at (loc
, "array section in %<#pragma acc declare%>");
18194 switch (OMP_CLAUSE_MAP_KIND (t
))
18196 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
18197 case GOMP_MAP_ALLOC
:
18199 case GOMP_MAP_FORCE_DEVICEPTR
:
18200 case GOMP_MAP_DEVICE_RESIDENT
:
18203 case GOMP_MAP_LINK
:
18204 if (!global_bindings_p ()
18205 && (TREE_STATIC (decl
)
18206 || !DECL_EXTERNAL (decl
)))
18209 "%qD must be a global variable in "
18210 "%<#pragma acc declare link%>",
18218 if (global_bindings_p ())
18220 error_at (loc
, "invalid OpenACC clause at file scope");
18224 if (DECL_EXTERNAL (decl
))
18227 "invalid use of %<extern%> variable %qD "
18228 "in %<#pragma acc declare%>", decl
);
18232 else if (TREE_PUBLIC (decl
))
18235 "invalid use of %<global%> variable %qD "
18236 "in %<#pragma acc declare%>", decl
);
18243 if (!c_check_in_current_scope (decl
))
18246 "%qD must be a variable declared in the same scope as "
18247 "%<#pragma acc declare%>", decl
);
18252 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
18253 || lookup_attribute ("omp declare target link",
18254 DECL_ATTRIBUTES (decl
)))
18256 error_at (loc
, "variable %qD used more than once with "
18257 "%<#pragma acc declare%>", decl
);
18266 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
18267 id
= get_identifier ("omp declare target link");
18269 id
= get_identifier ("omp declare target");
18271 DECL_ATTRIBUTES (decl
)
18272 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
18274 if (global_bindings_p ())
18276 symtab_node
*node
= symtab_node::get (decl
);
18279 node
->offloadable
= 1;
18280 if (ENABLE_OFFLOADING
)
18282 g
->have_offload
= true;
18283 if (is_a
<varpool_node
*> (node
))
18284 vec_safe_push (offload_vars
, decl
);
18291 if (error
|| global_bindings_p ())
18294 stmt
= make_node (OACC_DECLARE
);
18295 TREE_TYPE (stmt
) = void_type_node
;
18296 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
18297 SET_EXPR_LOCATION (stmt
, pragma_loc
);
18305 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
18309 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
18312 LOC is the location of the #pragma token.
18315 #define OACC_ENTER_DATA_CLAUSE_MASK \
18316 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18317 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18318 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18319 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18320 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18321 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18323 #define OACC_EXIT_DATA_CLAUSE_MASK \
18324 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18325 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18326 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18327 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
18328 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
18329 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
18330 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18333 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
18335 location_t loc
= c_parser_peek_token (parser
)->location
;
18336 tree clauses
, stmt
;
18337 const char *p
= "";
18339 c_parser_consume_pragma (parser
);
18341 if (c_parser_next_token_is (parser
, CPP_NAME
))
18343 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18344 c_parser_consume_token (parser
);
18347 if (strcmp (p
, "data") != 0)
18349 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
18350 enter
? "enter" : "exit");
18351 parser
->error
= true;
18352 c_parser_skip_to_pragma_eol (parser
);
18357 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
18358 "#pragma acc enter data");
18360 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
18361 "#pragma acc exit data");
18363 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
18365 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
18366 enter
? "enter" : "exit");
18370 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
18371 TREE_TYPE (stmt
) = void_type_node
;
18372 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
18373 SET_EXPR_LOCATION (stmt
, loc
);
18379 # pragma acc host_data oacc-data-clause[optseq] new-line
18383 #define OACC_HOST_DATA_CLAUSE_MASK \
18384 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
18385 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18386 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
18389 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
18391 tree stmt
, clauses
, block
;
18393 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
18394 "#pragma acc host_data");
18396 block
= c_begin_omp_parallel ();
18397 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
18398 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
18405 # pragma acc loop oacc-loop-clause[optseq] new-line
18408 LOC is the location of the #pragma token.
18411 #define OACC_LOOP_CLAUSE_MASK \
18412 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
18413 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
18414 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
18415 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
18416 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
18417 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
18418 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
18419 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
18420 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
18421 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
18423 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
18424 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
18426 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
18428 strcat (p_name
, " loop");
18429 mask
|= OACC_LOOP_CLAUSE_MASK
;
18431 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
18435 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
18437 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC
);
18439 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
18442 tree block
= c_begin_compound_stmt (true);
18443 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
18445 block
= c_end_compound_stmt (loc
, block
, true);
18452 # pragma acc kernels oacc-kernels-clause[optseq] new-line
18457 # pragma acc parallel oacc-parallel-clause[optseq] new-line
18462 # pragma acc serial oacc-serial-clause[optseq] new-line
18465 LOC is the location of the #pragma token.
18468 #define OACC_KERNELS_CLAUSE_MASK \
18469 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18470 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18471 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18473 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18474 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18475 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
18476 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18477 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18478 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
18479 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
18480 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
18481 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
18482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
18483 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18485 #define OACC_PARALLEL_CLAUSE_MASK \
18486 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18487 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18488 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18489 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18490 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18491 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18492 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
18493 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18494 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18495 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
18496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
18497 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
18498 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
18499 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
18500 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
18501 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
18502 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
18503 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18505 #define OACC_SERIAL_CLAUSE_MASK \
18506 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18507 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18508 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18509 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
18513 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18514 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18515 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
18516 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
18517 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
18518 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
18519 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
18520 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18523 c_parser_oacc_compute (location_t loc
, c_parser
*parser
,
18524 enum pragma_kind p_kind
, char *p_name
, bool *if_p
)
18526 omp_clause_mask mask
;
18527 enum tree_code code
;
18530 case PRAGMA_OACC_KERNELS
:
18531 strcat (p_name
, " kernels");
18532 mask
= OACC_KERNELS_CLAUSE_MASK
;
18533 code
= OACC_KERNELS
;
18535 case PRAGMA_OACC_PARALLEL
:
18536 strcat (p_name
, " parallel");
18537 mask
= OACC_PARALLEL_CLAUSE_MASK
;
18538 code
= OACC_PARALLEL
;
18540 case PRAGMA_OACC_SERIAL
:
18541 strcat (p_name
, " serial");
18542 mask
= OACC_SERIAL_CLAUSE_MASK
;
18543 code
= OACC_SERIAL
;
18546 gcc_unreachable ();
18549 if (c_parser_next_token_is (parser
, CPP_NAME
))
18551 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18552 if (strcmp (p
, "loop") == 0)
18554 c_parser_consume_token (parser
);
18555 tree block
= c_begin_omp_parallel ();
18557 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
18558 return c_finish_omp_construct (loc
, code
, block
, clauses
);
18562 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
);
18564 tree block
= c_begin_omp_parallel ();
18565 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
18567 return c_finish_omp_construct (loc
, code
, block
, clauses
);
18571 # pragma acc routine oacc-routine-clause[optseq] new-line
18572 function-definition
18574 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
18577 #define OACC_ROUTINE_CLAUSE_MASK \
18578 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
18579 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
18580 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
18581 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
18582 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
18584 /* Parse an OpenACC routine directive. For named directives, we apply
18585 immediately to the named function. For unnamed ones we then parse
18586 a declaration or definition, which must be for a function. */
18589 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
18591 gcc_checking_assert (context
== pragma_external
);
18593 oacc_routine_data data
;
18594 data
.error_seen
= false;
18595 data
.fndecl_seen
= false;
18596 data
.loc
= c_parser_peek_token (parser
)->location
;
18598 c_parser_consume_pragma (parser
);
18600 /* Look for optional '( name )'. */
18601 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
18603 c_parser_consume_token (parser
); /* '(' */
18605 tree decl
= NULL_TREE
;
18606 c_token
*name_token
= c_parser_peek_token (parser
);
18607 location_t name_loc
= name_token
->location
;
18608 if (name_token
->type
== CPP_NAME
18609 && (name_token
->id_kind
== C_ID_ID
18610 || name_token
->id_kind
== C_ID_TYPENAME
))
18612 decl
= lookup_name (name_token
->value
);
18614 error_at (name_loc
,
18615 "%qE has not been declared", name_token
->value
);
18616 c_parser_consume_token (parser
);
18619 c_parser_error (parser
, "expected function name");
18622 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
18624 c_parser_skip_to_pragma_eol (parser
, false);
18629 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
18630 "#pragma acc routine");
18631 /* The clauses are in reverse order; fix that to make later diagnostic
18632 emission easier. */
18633 data
.clauses
= nreverse (data
.clauses
);
18635 if (TREE_CODE (decl
) != FUNCTION_DECL
)
18637 error_at (name_loc
, "%qD does not refer to a function", decl
);
18641 c_finish_oacc_routine (&data
, decl
, false);
18643 else /* No optional '( name )'. */
18646 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
18647 "#pragma acc routine");
18648 /* The clauses are in reverse order; fix that to make later diagnostic
18649 emission easier. */
18650 data
.clauses
= nreverse (data
.clauses
);
18652 /* Emit a helpful diagnostic if there's another pragma following this
18653 one. Also don't allow a static assertion declaration, as in the
18654 following we'll just parse a *single* "declaration or function
18655 definition", and the static assertion counts an one. */
18656 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
18657 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
18659 error_at (data
.loc
,
18660 "%<#pragma acc routine%> not immediately followed by"
18661 " function declaration or definition");
18662 /* ..., and then just keep going. */
18666 /* We only have to consider the pragma_external case here. */
18667 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
18668 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
18670 int ext
= disable_extension_diagnostics ();
18672 c_parser_consume_token (parser
);
18673 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
18674 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
18675 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
18676 NULL
, NULL
, false, NULL
, &data
);
18677 restore_extension_diagnostics (ext
);
18680 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
18681 NULL
, NULL
, false, NULL
, &data
);
18685 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
18686 IS_DEFN is true if we're applying it to the definition. */
18689 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
18692 /* Keep going if we're in error reporting mode. */
18693 if (data
->error_seen
18694 || fndecl
== error_mark_node
)
18697 if (data
->fndecl_seen
)
18699 error_at (data
->loc
,
18700 "%<#pragma acc routine%> not immediately followed by"
18701 " a single function declaration or definition");
18702 data
->error_seen
= true;
18705 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
18707 error_at (data
->loc
,
18708 "%<#pragma acc routine%> not immediately followed by"
18709 " function declaration or definition");
18710 data
->error_seen
= true;
18715 = oacc_verify_routine_clauses (fndecl
, &data
->clauses
, data
->loc
,
18716 "#pragma acc routine");
18717 if (compatible
< 0)
18719 data
->error_seen
= true;
18722 if (compatible
> 0)
18727 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
18729 error_at (data
->loc
,
18731 ? G_("%<#pragma acc routine%> must be applied before use")
18732 : G_("%<#pragma acc routine%> must be applied before"
18734 data
->error_seen
= true;
18738 /* Set the routine's level of parallelism. */
18739 tree dims
= oacc_build_routine_dims (data
->clauses
);
18740 oacc_replace_fn_attrib (fndecl
, dims
);
18742 /* Add an "omp declare target" attribute. */
18743 DECL_ATTRIBUTES (fndecl
)
18744 = tree_cons (get_identifier ("omp declare target"),
18745 data
->clauses
, DECL_ATTRIBUTES (fndecl
));
18748 /* Remember that we've used this "#pragma acc routine". */
18749 data
->fndecl_seen
= true;
18753 # pragma acc update oacc-update-clause[optseq] new-line
18756 #define OACC_UPDATE_CLAUSE_MASK \
18757 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18758 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
18759 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
18760 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18761 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
18762 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18765 c_parser_oacc_update (c_parser
*parser
)
18767 location_t loc
= c_parser_peek_token (parser
)->location
;
18769 c_parser_consume_pragma (parser
);
18771 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
18772 "#pragma acc update");
18773 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
18776 "%<#pragma acc update%> must contain at least one "
18777 "%<device%> or %<host%> or %<self%> clause");
18784 tree stmt
= make_node (OACC_UPDATE
);
18785 TREE_TYPE (stmt
) = void_type_node
;
18786 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
18787 SET_EXPR_LOCATION (stmt
, loc
);
18792 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
18794 LOC is the location of the #pragma token.
18797 #define OACC_WAIT_CLAUSE_MASK \
18798 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
18801 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
18803 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
18805 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
18806 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
18808 strcpy (p_name
, " wait");
18809 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
18810 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
18817 # pragma omp allocate (list) clauses
18820 allocator (omp_allocator_handle_t expression)
18822 OpenMP 5.1 additional clause:
18823 align (constant-expression)] */
18826 c_parser_omp_allocate (location_t loc
, c_parser
*parser
)
18828 tree alignment
= NULL_TREE
;
18829 tree allocator
= NULL_TREE
;
18830 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ALLOCATE
, NULL_TREE
);
18833 if (c_parser_next_token_is (parser
, CPP_COMMA
)
18834 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
18835 c_parser_consume_token (parser
);
18836 if (!c_parser_next_token_is (parser
, CPP_NAME
))
18838 matching_parens parens
;
18839 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18840 c_parser_consume_token (parser
);
18841 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18842 if (strcmp ("align", p
) != 0 && strcmp ("allocator", p
) != 0)
18844 error_at (c_parser_peek_token (parser
)->location
,
18845 "expected %<allocator%> or %<align%>");
18848 if (!parens
.require_open (parser
))
18851 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18852 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18853 expr_loc
= c_parser_peek_token (parser
)->location
;
18854 if (p
[2] == 'i' && alignment
)
18856 error_at (expr_loc
, "too many %qs clauses", "align");
18859 else if (p
[2] == 'i')
18861 alignment
= c_fully_fold (expr
.value
, false, NULL
);
18862 if (TREE_CODE (alignment
) != INTEGER_CST
18863 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
18864 || tree_int_cst_sgn (alignment
) != 1
18865 || !integer_pow2p (alignment
))
18867 error_at (expr_loc
, "%<align%> clause argument needs to be "
18868 "positive constant power of two integer "
18870 alignment
= NULL_TREE
;
18873 else if (allocator
)
18875 error_at (expr_loc
, "too many %qs clauses", "allocator");
18880 allocator
= c_fully_fold (expr
.value
, false, NULL
);
18882 = expr
.original_type
? expr
.original_type
: TREE_TYPE (allocator
);
18883 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
18884 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
18885 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
18886 || TYPE_NAME (orig_type
)
18887 != get_identifier ("omp_allocator_handle_t"))
18889 error_at (expr_loc
,
18890 "%<allocator%> clause allocator expression has type "
18891 "%qT rather than %<omp_allocator_handle_t%>",
18892 TREE_TYPE (allocator
));
18893 allocator
= NULL_TREE
;
18896 parens
.skip_until_found_close (parser
);
18898 c_parser_skip_to_pragma_eol (parser
);
18900 if (allocator
|| alignment
)
18901 for (tree c
= nl
; c
!= NULL_TREE
; c
= OMP_CLAUSE_CHAIN (c
))
18903 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
18904 OMP_CLAUSE_ALLOCATE_ALIGN (c
) = alignment
;
18907 sorry_at (loc
, "%<#pragma omp allocate%> not yet supported");
18911 # pragma omp atomic new-line
18915 x binop= expr | x++ | ++x | x-- | --x
18917 +, *, -, /, &, ^, |, <<, >>
18919 where x is an lvalue expression with scalar type.
18922 # pragma omp atomic new-line
18925 # pragma omp atomic read new-line
18928 # pragma omp atomic write new-line
18931 # pragma omp atomic update new-line
18934 # pragma omp atomic capture new-line
18937 # pragma omp atomic capture new-line
18945 expression-stmt | x = x binop expr
18947 v = expression-stmt
18949 { v = x; update-stmt; } | { update-stmt; v = x; }
18953 expression-stmt | x = x binop expr | x = expr binop x
18957 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
18960 # pragma omp atomic compare new-line
18961 conditional-update-atomic
18963 # pragma omp atomic compare capture new-line
18964 conditional-update-capture-atomic
18966 conditional-update-atomic:
18967 cond-expr-stmt | cond-update-stmt
18969 x = expr ordop x ? expr : x;
18970 x = x ordop expr ? expr : x;
18971 x = x == e ? d : x;
18973 if (expr ordop x) { x = expr; }
18974 if (x ordop expr) { x = expr; }
18975 if (x == e) { x = d; }
18978 conditional-update-capture-atomic:
18980 { v = x; cond-expr-stmt }
18981 { cond-expr-stmt v = x; }
18982 { v = x; cond-update-stmt }
18983 { cond-update-stmt v = x; }
18984 if (x == e) { x = d; } else { v = x; }
18985 { r = x == e; if (r) { x = d; } }
18986 { r = x == e; if (r) { x = d; } else { v = x; } }
18988 where x, r and v are lvalue expressions with scalar type,
18989 expr, e and d are expressions with scalar type and e might be
18992 LOC is the location of the #pragma token. */
18995 c_parser_omp_atomic (location_t loc
, c_parser
*parser
, bool openacc
)
18997 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
, r
= NULL_TREE
;
18998 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
18999 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
19000 enum tree_code code
= ERROR_MARK
, opcode
= NOP_EXPR
;
19001 enum omp_memory_order memory_order
= OMP_MEMORY_ORDER_UNSPECIFIED
;
19002 struct c_expr expr
;
19004 bool structured_block
= false;
19005 bool swapped
= false;
19007 tree clauses
= NULL_TREE
;
19008 bool capture
= false;
19009 bool compare
= false;
19011 enum omp_memory_order fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
19012 bool no_semicolon
= false;
19013 bool extra_scope
= false;
19015 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19017 if (c_parser_next_token_is (parser
, CPP_COMMA
)
19018 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
19019 c_parser_consume_token (parser
);
19021 if (c_parser_next_token_is (parser
, CPP_NAME
))
19024 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19025 location_t cloc
= c_parser_peek_token (parser
)->location
;
19026 enum tree_code new_code
= ERROR_MARK
;
19027 enum omp_memory_order new_memory_order
19028 = OMP_MEMORY_ORDER_UNSPECIFIED
;
19029 bool new_capture
= false;
19030 bool new_compare
= false;
19031 bool new_weak
= false;
19032 enum omp_memory_order new_fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
19034 if (!strcmp (p
, "read"))
19035 new_code
= OMP_ATOMIC_READ
;
19036 else if (!strcmp (p
, "write"))
19037 new_code
= NOP_EXPR
;
19038 else if (!strcmp (p
, "update"))
19039 new_code
= OMP_ATOMIC
;
19040 else if (openacc
&& !strcmp (p
, "capture"))
19041 new_code
= OMP_ATOMIC_CAPTURE_NEW
;
19045 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
19046 "or %<capture%> clause");
19048 else if (!strcmp (p
, "capture"))
19049 new_capture
= true;
19050 else if (!strcmp (p
, "compare"))
19051 new_compare
= true;
19052 else if (!strcmp (p
, "weak"))
19054 else if (!strcmp (p
, "fail"))
19056 matching_parens parens
;
19058 c_parser_consume_token (parser
);
19059 if (!parens
.require_open (parser
))
19062 if (c_parser_next_token_is (parser
, CPP_NAME
))
19065 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19067 if (!strcmp (q
, "seq_cst"))
19068 new_fail
= OMP_MEMORY_ORDER_SEQ_CST
;
19069 else if (!strcmp (q
, "acquire"))
19070 new_fail
= OMP_MEMORY_ORDER_ACQUIRE
;
19071 else if (!strcmp (q
, "relaxed"))
19072 new_fail
= OMP_MEMORY_ORDER_RELAXED
;
19075 if (new_fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
19077 c_parser_consume_token (parser
);
19078 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
19079 error_at (cloc
, "too many %qs clauses", "fail");
19084 c_parser_error (parser
, "expected %<seq_cst%>, %<acquire%> "
19086 parens
.skip_until_found_close (parser
);
19089 else if (!strcmp (p
, "seq_cst"))
19090 new_memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
19091 else if (!strcmp (p
, "acq_rel"))
19092 new_memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
19093 else if (!strcmp (p
, "release"))
19094 new_memory_order
= OMP_MEMORY_ORDER_RELEASE
;
19095 else if (!strcmp (p
, "acquire"))
19096 new_memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
19097 else if (!strcmp (p
, "relaxed"))
19098 new_memory_order
= OMP_MEMORY_ORDER_RELAXED
;
19099 else if (!strcmp (p
, "hint"))
19101 c_parser_consume_token (parser
);
19102 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
19108 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
19109 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
19110 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
19111 "%<relaxed%> or %<hint%> clause");
19115 if (new_code
!= ERROR_MARK
)
19117 /* OpenACC permits 'update capture'. */
19119 && code
== OMP_ATOMIC
19120 && new_code
== OMP_ATOMIC_CAPTURE_NEW
)
19122 else if (code
!= ERROR_MARK
)
19123 error_at (cloc
, "too many atomic clauses");
19127 else if (new_memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
19129 if (memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
19130 error_at (cloc
, "too many memory order clauses");
19132 memory_order
= new_memory_order
;
19134 else if (new_capture
)
19137 error_at (cloc
, "too many %qs clauses", "capture");
19141 else if (new_compare
)
19144 error_at (cloc
, "too many %qs clauses", "compare");
19151 error_at (cloc
, "too many %qs clauses", "weak");
19155 c_parser_consume_token (parser
);
19161 c_parser_skip_to_pragma_eol (parser
);
19163 if (code
== ERROR_MARK
)
19167 if (code
!= OMP_ATOMIC
)
19168 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
19169 "clauses", "capture");
19171 code
= OMP_ATOMIC_CAPTURE_NEW
;
19173 if (compare
&& code
!= OMP_ATOMIC
&& code
!= OMP_ATOMIC_CAPTURE_NEW
)
19175 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
19176 "clauses", "compare");
19179 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
&& !compare
)
19181 error_at (loc
, "%qs clause requires %qs clause", "fail", "compare");
19182 fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
19184 if (weak
&& !compare
)
19186 error_at (loc
, "%qs clause requires %qs clause", "weak", "compare");
19190 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
19191 else if (memory_order
== OMP_MEMORY_ORDER_UNSPECIFIED
)
19194 = (enum omp_requires
) (omp_requires_mask
19195 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
);
19196 switch ((enum omp_memory_order
)
19197 (omp_requires_mask
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
))
19199 case OMP_MEMORY_ORDER_UNSPECIFIED
:
19200 case OMP_MEMORY_ORDER_RELAXED
:
19201 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
19203 case OMP_MEMORY_ORDER_SEQ_CST
:
19204 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
19206 case OMP_MEMORY_ORDER_ACQ_REL
:
19209 case OMP_ATOMIC_READ
:
19210 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
19212 case NOP_EXPR
: /* atomic write */
19213 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
19216 memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
19221 gcc_unreachable ();
19227 case OMP_ATOMIC_READ
:
19228 if (memory_order
== OMP_MEMORY_ORDER_RELEASE
)
19230 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
19231 "%<release%> clause");
19232 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
19234 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
19235 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
19237 case NOP_EXPR
: /* atomic write */
19238 if (memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
19240 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
19241 "%<acquire%> clause");
19242 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
19244 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
19245 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
19250 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
19252 = (enum omp_memory_order
) (memory_order
19253 | (fail
<< OMP_FAIL_MEMORY_ORDER_SHIFT
));
19257 case OMP_ATOMIC_READ
:
19258 case NOP_EXPR
: /* atomic write */
19259 v
= c_parser_cast_expression (parser
, NULL
).value
;
19260 non_lvalue_p
= !lvalue_p (v
);
19261 v
= c_fully_fold (v
, false, NULL
, true);
19262 if (v
== error_mark_node
)
19265 v
= non_lvalue (v
);
19266 loc
= c_parser_peek_token (parser
)->location
;
19267 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
19269 if (code
== NOP_EXPR
)
19271 lhs
= c_parser_expression (parser
).value
;
19272 lhs
= c_fully_fold (lhs
, false, NULL
);
19273 if (lhs
== error_mark_node
)
19278 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
19279 non_lvalue_p
= !lvalue_p (lhs
);
19280 lhs
= c_fully_fold (lhs
, false, NULL
, true);
19281 if (lhs
== error_mark_node
)
19284 lhs
= non_lvalue (lhs
);
19286 if (code
== NOP_EXPR
)
19288 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
19296 case OMP_ATOMIC_CAPTURE_NEW
:
19297 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
19299 c_parser_consume_token (parser
);
19300 structured_block
= true;
19303 && c_parser_next_token_is_keyword (parser
, RID_IF
))
19307 v
= c_parser_cast_expression (parser
, NULL
).value
;
19308 non_lvalue_p
= !lvalue_p (v
);
19309 v
= c_fully_fold (v
, false, NULL
, true);
19310 if (v
== error_mark_node
)
19313 v
= non_lvalue (v
);
19314 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
19316 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
19318 eloc
= c_parser_peek_token (parser
)->location
;
19319 error_at (eloc
, "expected expression");
19328 /* For structured_block case we don't know yet whether
19329 old or new x should be captured. */
19331 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
19333 c_parser_consume_token (parser
);
19335 matching_parens parens
;
19336 if (!parens
.require_open (parser
))
19338 eloc
= c_parser_peek_token (parser
)->location
;
19342 cmp_expr
= c_parser_cast_expression (parser
, NULL
);
19343 cmp_expr
= default_function_array_conversion (eloc
, cmp_expr
);
19346 cmp_expr
= c_parser_binary_expression (parser
, NULL
, void_list_node
);
19347 parens
.skip_until_found_close (parser
);
19348 if (cmp_expr
.value
== error_mark_node
)
19352 if (!c_tree_equal (cmp_expr
.value
, unfolded_lhs
))
19354 cmp_expr
.value
= rhs1
;
19356 gcc_assert (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
);
19358 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
19360 else if (!structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
19362 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
19363 "expected %<==%> comparison in %<if%> condition");
19366 else if (TREE_CODE (cmp_expr
.value
) != GT_EXPR
19367 && TREE_CODE (cmp_expr
.value
) != LT_EXPR
)
19369 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
19370 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
19374 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
19377 extra_scope
= true;
19378 eloc
= c_parser_peek_token (parser
)->location
;
19379 expr
= c_parser_cast_expression (parser
, NULL
);
19381 expr
= default_function_array_conversion (eloc
, expr
);
19382 unfolded_lhs
= expr
.value
;
19383 lhs
= c_fully_fold (lhs
, false, NULL
, true);
19385 if (lhs
== error_mark_node
)
19387 if (!lvalue_p (unfolded_lhs
))
19388 lhs
= non_lvalue (lhs
);
19389 if (!c_parser_next_token_is (parser
, CPP_EQ
))
19391 c_parser_error (parser
, "expected %<=%>");
19394 c_parser_consume_token (parser
);
19395 eloc
= c_parser_peek_token (parser
)->location
;
19396 expr
= c_parser_expr_no_commas (parser
, NULL
);
19399 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
19402 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
19405 extra_scope
= false;
19406 no_semicolon
= true;
19408 if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), unfolded_lhs
))
19410 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
19412 opcode
= COND_EXPR
;
19413 rhs
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
19414 false, NULL
, true);
19415 rhs1
= c_fully_fold (rhs1
, false, NULL
, true);
19417 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), rhs1
))
19419 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
19420 ? MIN_EXPR
: MAX_EXPR
);
19421 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
19422 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 0),
19423 false, NULL
, true);
19428 else if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
19430 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), unfolded_lhs
)
19431 && c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), rhs1
))
19433 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
19434 ? MAX_EXPR
: MIN_EXPR
);
19435 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
19436 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
19437 false, NULL
, true);
19442 c_parser_error (parser
,
19443 "invalid form of %<#pragma omp atomic compare%>");
19447 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
19449 if (code
!= OMP_ATOMIC_CAPTURE_NEW
19450 || (structured_block
&& r
== NULL_TREE
)
19451 || TREE_CODE (cmp_expr
.value
) != EQ_EXPR
)
19453 eloc
= c_parser_peek_token (parser
)->location
;
19454 error_at (eloc
, "unexpected %<else%>");
19458 c_parser_consume_token (parser
);
19460 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
19463 extra_scope
= true;
19464 v
= c_parser_cast_expression (parser
, NULL
).value
;
19465 non_lvalue_p
= !lvalue_p (v
);
19466 v
= c_fully_fold (v
, false, NULL
, true);
19467 if (v
== error_mark_node
)
19470 v
= non_lvalue (v
);
19471 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
19474 expr
= c_parser_expr_no_commas (parser
, NULL
);
19476 if (!c_tree_equal (expr
.value
, unfolded_lhs
))
19479 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
19482 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
19485 extra_scope
= false;
19486 code
= OMP_ATOMIC_CAPTURE_OLD
;
19487 if (r
== NULL_TREE
)
19488 /* Signal to c_finish_omp_atomic that in
19489 if (x == e) { x = d; } else { v = x; }
19490 case the store to v should be conditional. */
19491 r
= void_list_node
;
19493 else if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
19495 c_parser_require_keyword (parser
, RID_ELSE
, "expected %<else%>");
19498 else if (code
== OMP_ATOMIC_CAPTURE_NEW
19504 eloc
= c_parser_peek_token (parser
)->location
;
19505 expr
= c_parser_cast_expression (parser
, NULL
);
19507 expr
= default_function_array_conversion (eloc
, expr
);
19508 unfolded_lhs
= expr
.value
;
19509 lhs
= c_fully_fold (lhs
, false, NULL
, true);
19511 switch (TREE_CODE (lhs
))
19514 error_at (eloc
, "invalid form of %<pragma omp atomic compare%>");
19518 c_parser_skip_to_end_of_block_or_statement (parser
);
19519 if (extra_scope
&& c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
19520 c_parser_consume_token (parser
);
19521 if (structured_block
)
19523 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
19524 c_parser_consume_token (parser
);
19525 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
19527 c_parser_skip_to_end_of_block_or_statement (parser
);
19528 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
19529 c_parser_consume_token (parser
);
19534 case POSTINCREMENT_EXPR
:
19535 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
19536 code
= OMP_ATOMIC_CAPTURE_OLD
;
19538 case PREINCREMENT_EXPR
:
19539 lhs
= TREE_OPERAND (lhs
, 0);
19540 unfolded_lhs
= NULL_TREE
;
19541 opcode
= PLUS_EXPR
;
19542 rhs
= integer_one_node
;
19544 goto invalid_compare
;
19547 case POSTDECREMENT_EXPR
:
19548 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
19549 code
= OMP_ATOMIC_CAPTURE_OLD
;
19551 case PREDECREMENT_EXPR
:
19552 lhs
= TREE_OPERAND (lhs
, 0);
19553 unfolded_lhs
= NULL_TREE
;
19554 opcode
= MINUS_EXPR
;
19555 rhs
= integer_one_node
;
19557 goto invalid_compare
;
19560 case COMPOUND_EXPR
:
19561 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
19562 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
19563 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
19564 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
19565 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
19566 (TREE_OPERAND (lhs
, 1), 0), 0))))
19567 /* Undo effects of boolean_increment for post {in,de}crement. */
19568 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
19571 if (TREE_CODE (lhs
) == MODIFY_EXPR
19572 && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs
, 0))))
19574 /* Undo effects of boolean_increment. */
19575 if (integer_onep (TREE_OPERAND (lhs
, 1)))
19577 /* This is pre or post increment. */
19578 rhs
= TREE_OPERAND (lhs
, 1);
19579 lhs
= TREE_OPERAND (lhs
, 0);
19580 unfolded_lhs
= NULL_TREE
;
19582 if (code
== OMP_ATOMIC_CAPTURE_NEW
19583 && !structured_block
19584 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
19585 code
= OMP_ATOMIC_CAPTURE_OLD
;
19587 goto invalid_compare
;
19590 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
19591 && TREE_OPERAND (lhs
, 0)
19592 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
19594 /* This is pre or post decrement. */
19595 rhs
= TREE_OPERAND (lhs
, 1);
19596 lhs
= TREE_OPERAND (lhs
, 0);
19597 unfolded_lhs
= NULL_TREE
;
19599 if (code
== OMP_ATOMIC_CAPTURE_NEW
19600 && !structured_block
19601 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
19602 code
= OMP_ATOMIC_CAPTURE_OLD
;
19604 goto invalid_compare
;
19610 if (!lvalue_p (unfolded_lhs
))
19611 lhs
= non_lvalue (lhs
);
19612 if (compare
&& !c_parser_next_token_is (parser
, CPP_EQ
))
19614 c_parser_error (parser
, "expected %<=%>");
19617 switch (c_parser_peek_token (parser
)->type
)
19620 opcode
= MULT_EXPR
;
19623 opcode
= TRUNC_DIV_EXPR
;
19626 opcode
= PLUS_EXPR
;
19629 opcode
= MINUS_EXPR
;
19631 case CPP_LSHIFT_EQ
:
19632 opcode
= LSHIFT_EXPR
;
19634 case CPP_RSHIFT_EQ
:
19635 opcode
= RSHIFT_EXPR
;
19638 opcode
= BIT_AND_EXPR
;
19641 opcode
= BIT_IOR_EXPR
;
19644 opcode
= BIT_XOR_EXPR
;
19647 c_parser_consume_token (parser
);
19648 eloc
= c_parser_peek_token (parser
)->location
;
19649 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
19651 switch (TREE_CODE (rhs1
))
19654 case TRUNC_DIV_EXPR
:
19665 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
19667 opcode
= TREE_CODE (rhs1
);
19668 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
19670 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
19674 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
19676 opcode
= TREE_CODE (rhs1
);
19677 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
19679 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
19681 swapped
= !commutative_tree_code (opcode
);
19688 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) != GT_EXPR
19689 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != LT_EXPR
19690 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != EQ_EXPR
)
19692 if (!TREE_OPERAND (rhs1
, 1))
19694 if (!c_tree_equal (TREE_OPERAND (rhs1
, 2), unfolded_lhs
))
19696 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
19699 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
19701 opcode
= COND_EXPR
;
19702 rhs
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
19704 false, NULL
, true);
19705 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false,
19709 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
19710 TREE_OPERAND (rhs1
, 1)))
19712 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
19713 ? MIN_EXPR
: MAX_EXPR
);
19714 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
19716 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
19718 false, NULL
, true);
19722 else if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
19724 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
19727 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
19728 TREE_OPERAND (rhs1
, 1)))
19730 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
19731 ? MAX_EXPR
: MIN_EXPR
);
19732 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
19734 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
19736 false, NULL
, true);
19743 || code
!= OMP_ATOMIC_CAPTURE_NEW
19744 || !structured_block
19748 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
19749 && c_parser_peek_2nd_token (parser
)->keyword
== RID_IF
)
19753 c_parser_consume_token (parser
);
19762 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
19764 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
19766 code
= OMP_ATOMIC_CAPTURE_OLD
;
19769 expr
= default_function_array_read_conversion (eloc
, expr
);
19770 unfolded_lhs1
= expr
.value
;
19771 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
19773 c_parser_consume_token (parser
);
19776 if (structured_block
&& !compare
)
19779 expr
= default_function_array_read_conversion (eloc
, expr
);
19780 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
19785 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
19788 c_parser_error (parser
,
19789 "invalid operator for %<#pragma omp atomic%>");
19793 /* Arrange to pass the location of the assignment operator to
19794 c_finish_omp_atomic. */
19795 loc
= c_parser_peek_token (parser
)->location
;
19796 c_parser_consume_token (parser
);
19797 eloc
= c_parser_peek_token (parser
)->location
;
19798 expr
= c_parser_expression (parser
);
19799 expr
= default_function_array_read_conversion (eloc
, expr
);
19801 rhs
= c_fully_fold (rhs
, false, NULL
, true);
19805 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
&& r
== NULL_TREE
)
19808 && !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
19810 no_semicolon
= false;
19811 v
= c_parser_cast_expression (parser
, NULL
).value
;
19812 non_lvalue_p
= !lvalue_p (v
);
19813 v
= c_fully_fold (v
, false, NULL
, true);
19814 if (v
== error_mark_node
)
19817 v
= non_lvalue (v
);
19818 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
19820 eloc
= c_parser_peek_token (parser
)->location
;
19821 expr
= c_parser_cast_expression (parser
, NULL
);
19823 expr
= default_function_array_read_conversion (eloc
, expr
);
19824 unfolded_lhs1
= expr
.value
;
19825 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
19826 if (lhs1
== error_mark_node
)
19828 if (!lvalue_p (unfolded_lhs1
))
19829 lhs1
= non_lvalue (lhs1
);
19831 if (structured_block
)
19834 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19835 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
19838 if (weak
&& opcode
!= COND_EXPR
)
19840 error_at (loc
, "%<weak%> clause requires atomic equality comparison");
19843 if (unfolded_lhs
&& unfolded_lhs1
19844 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
19846 error ("%<#pragma omp atomic capture%> uses two different "
19847 "expressions for memory");
19848 stmt
= error_mark_node
;
19851 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
, r
,
19852 swapped
, memory_order
, weak
);
19853 if (stmt
!= error_mark_node
)
19856 if (!structured_block
&& !no_semicolon
)
19857 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19862 # pragma omp barrier new-line
19866 c_parser_omp_barrier (c_parser
*parser
)
19868 location_t loc
= c_parser_peek_token (parser
)->location
;
19869 c_parser_consume_pragma (parser
);
19870 c_parser_skip_to_pragma_eol (parser
);
19872 c_finish_omp_barrier (loc
);
19876 # pragma omp critical [(name)] new-line
19880 # pragma omp critical [(name) [hint(expression)]] new-line
19882 LOC is the location of the #pragma itself. */
19884 #define OMP_CRITICAL_CLAUSE_MASK \
19885 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
19888 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
19890 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
19892 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
19894 c_parser_consume_token (parser
);
19895 if (c_parser_next_token_is (parser
, CPP_NAME
))
19897 name
= c_parser_peek_token (parser
)->value
;
19898 c_parser_consume_token (parser
);
19899 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
19902 c_parser_error (parser
, "expected identifier");
19904 if (c_parser_next_token_is (parser
, CPP_COMMA
)
19905 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
19906 c_parser_consume_token (parser
);
19908 clauses
= c_parser_omp_all_clauses (parser
, OMP_CRITICAL_CLAUSE_MASK
,
19909 "#pragma omp critical");
19910 stmt
= c_parser_omp_structured_block (parser
, if_p
);
19911 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
19915 # pragma omp depobj ( depobj ) depobj-clause new-line
19918 depend (dependence-type : locator)
19920 update (dependence-type)
19929 c_parser_omp_depobj (c_parser
*parser
)
19931 location_t loc
= c_parser_peek_token (parser
)->location
;
19932 c_parser_consume_pragma (parser
);
19933 matching_parens parens
;
19934 if (!parens
.require_open (parser
))
19936 c_parser_skip_to_pragma_eol (parser
);
19940 tree depobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
19941 if (depobj
!= error_mark_node
)
19943 if (!lvalue_p (depobj
))
19945 error_at (EXPR_LOC_OR_LOC (depobj
, loc
),
19946 "%<depobj%> expression is not lvalue expression");
19947 depobj
= error_mark_node
;
19951 tree addr
= build_unary_op (EXPR_LOC_OR_LOC (depobj
, loc
), ADDR_EXPR
,
19953 if (addr
== error_mark_node
)
19954 depobj
= error_mark_node
;
19956 depobj
= build_indirect_ref (EXPR_LOC_OR_LOC (depobj
, loc
),
19957 addr
, RO_UNARY_STAR
);
19961 parens
.skip_until_found_close (parser
);
19962 tree clause
= NULL_TREE
;
19963 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_INVALID
;
19964 if (c_parser_next_token_is (parser
, CPP_COMMA
))
19965 c_parser_consume_token (parser
);
19966 location_t c_loc
= c_parser_peek_token (parser
)->location
;
19967 if (c_parser_next_token_is (parser
, CPP_NAME
))
19969 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19971 c_parser_consume_token (parser
);
19972 if (!strcmp ("depend", p
))
19974 clause
= c_parser_omp_clause_depend (parser
, NULL_TREE
);
19975 clause
= c_finish_omp_clauses (clause
, C_ORT_OMP
);
19977 clause
= error_mark_node
;
19979 else if (!strcmp ("destroy", p
))
19980 kind
= OMP_CLAUSE_DEPEND_LAST
;
19981 else if (!strcmp ("update", p
))
19983 matching_parens c_parens
;
19984 if (c_parens
.require_open (parser
))
19986 location_t c2_loc
= c_parser_peek_token (parser
)->location
;
19987 if (c_parser_next_token_is (parser
, CPP_NAME
))
19990 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19992 c_parser_consume_token (parser
);
19993 if (!strcmp ("in", p2
))
19994 kind
= OMP_CLAUSE_DEPEND_IN
;
19995 else if (!strcmp ("out", p2
))
19996 kind
= OMP_CLAUSE_DEPEND_OUT
;
19997 else if (!strcmp ("inout", p2
))
19998 kind
= OMP_CLAUSE_DEPEND_INOUT
;
19999 else if (!strcmp ("mutexinoutset", p2
))
20000 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
20001 else if (!strcmp ("inoutset", p2
))
20002 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
20004 if (kind
== OMP_CLAUSE_DEPEND_INVALID
)
20006 clause
= error_mark_node
;
20007 error_at (c2_loc
, "expected %<in%>, %<out%>, %<inout%>, "
20008 "%<mutexinoutset%> or %<inoutset%>");
20010 c_parens
.skip_until_found_close (parser
);
20013 clause
= error_mark_node
;
20016 if (!clause
&& kind
== OMP_CLAUSE_DEPEND_INVALID
)
20018 clause
= error_mark_node
;
20019 error_at (c_loc
, "expected %<depend%>, %<destroy%> or %<update%> clause");
20021 c_parser_skip_to_pragma_eol (parser
);
20023 c_finish_omp_depobj (loc
, depobj
, kind
, clause
);
20028 # pragma omp flush flush-vars[opt] new-line
20034 # pragma omp flush memory-order-clause new-line */
20037 c_parser_omp_flush (c_parser
*parser
)
20039 location_t loc
= c_parser_peek_token (parser
)->location
;
20040 c_parser_consume_pragma (parser
);
20041 enum memmodel mo
= MEMMODEL_LAST
;
20042 if (c_parser_next_token_is (parser
, CPP_COMMA
)
20043 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
20044 c_parser_consume_token (parser
);
20045 if (c_parser_next_token_is (parser
, CPP_NAME
))
20048 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20050 if (!strcmp (p
, "seq_cst"))
20051 mo
= MEMMODEL_SEQ_CST
;
20052 else if (!strcmp (p
, "acq_rel"))
20053 mo
= MEMMODEL_ACQ_REL
;
20054 else if (!strcmp (p
, "release"))
20055 mo
= MEMMODEL_RELEASE
;
20056 else if (!strcmp (p
, "acquire"))
20057 mo
= MEMMODEL_ACQUIRE
;
20059 error_at (c_parser_peek_token (parser
)->location
,
20060 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
20062 c_parser_consume_token (parser
);
20064 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
20066 if (mo
!= MEMMODEL_LAST
)
20067 error_at (c_parser_peek_token (parser
)->location
,
20068 "%<flush%> list specified together with memory order "
20070 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
20072 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
20073 c_parser_error (parser
, "expected %<(%> or end of line");
20074 c_parser_skip_to_pragma_eol (parser
);
20076 c_finish_omp_flush (loc
, mo
);
20079 /* Parse an OpenMP structured block sequence. KIND is the corresponding
20080 separating directive. */
20083 c_parser_omp_structured_block_sequence (c_parser
*parser
,
20084 enum pragma_kind kind
)
20086 tree stmt
= push_stmt_list ();
20087 c_parser_statement (parser
, NULL
);
20090 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
20092 if (c_parser_next_token_is (parser
, CPP_EOF
))
20095 if (kind
!= PRAGMA_NONE
20096 && c_parser_peek_token (parser
)->pragma_kind
== kind
)
20098 c_parser_statement (parser
, NULL
);
20101 return pop_stmt_list (stmt
);
20107 { structured-block scan-directive structured-block } */
20110 c_parser_omp_scan_loop_body (c_parser
*parser
, bool open_brace_parsed
)
20114 tree clauses
= NULL_TREE
;
20116 loc
= c_parser_peek_token (parser
)->location
;
20117 if (!open_brace_parsed
20118 && !c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
20120 /* Avoid skipping until the end of the block. */
20121 parser
->error
= false;
20125 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_OMP_SCAN
);
20126 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, NULL_TREE
);
20127 SET_EXPR_LOCATION (substmt
, loc
);
20128 add_stmt (substmt
);
20130 loc
= c_parser_peek_token (parser
)->location
;
20131 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SCAN
)
20133 enum omp_clause_code clause
= OMP_CLAUSE_ERROR
;
20135 c_parser_consume_pragma (parser
);
20137 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20138 c_parser_consume_token (parser
);
20140 if (c_parser_next_token_is (parser
, CPP_NAME
))
20143 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20144 if (strcmp (p
, "inclusive") == 0)
20145 clause
= OMP_CLAUSE_INCLUSIVE
;
20146 else if (strcmp (p
, "exclusive") == 0)
20147 clause
= OMP_CLAUSE_EXCLUSIVE
;
20149 if (clause
!= OMP_CLAUSE_ERROR
)
20151 c_parser_consume_token (parser
);
20152 clauses
= c_parser_omp_var_list_parens (parser
, clause
, NULL_TREE
);
20155 c_parser_error (parser
, "expected %<inclusive%> or "
20156 "%<exclusive%> clause");
20157 c_parser_skip_to_pragma_eol (parser
);
20160 error ("expected %<#pragma omp scan%>");
20162 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
20163 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_NONE
);
20164 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, clauses
);
20165 SET_EXPR_LOCATION (substmt
, loc
);
20166 add_stmt (substmt
);
20168 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
20172 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
20173 The real trick here is to determine the loop control variable early
20174 so that we can push a new decl if necessary to make it private.
20175 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
20179 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
20180 tree clauses
, tree
*cclauses
, bool *if_p
)
20182 tree decl
, cond
, incr
, body
, init
, stmt
, cl
;
20183 unsigned char save_in_statement
;
20184 tree declv
, condv
, incrv
, initv
, ret
= NULL_TREE
;
20185 tree pre_body
= NULL_TREE
, this_pre_body
;
20186 tree ordered_cl
= NULL_TREE
;
20187 bool fail
= false, open_brace_parsed
= false;
20188 int i
, collapse
= 1, ordered
= 0, count
, nbraces
= 0;
20189 location_t for_loc
;
20190 bool tiling
= false;
20191 bool inscan
= false;
20192 vec
<tree
, va_gc
> *for_block
= make_tree_vector ();
20194 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
20195 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
20196 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
20197 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
20200 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
20202 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
20203 && OMP_CLAUSE_ORDERED_EXPR (cl
))
20206 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
20208 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_REDUCTION
20209 && OMP_CLAUSE_REDUCTION_INSCAN (cl
)
20210 && (code
== OMP_SIMD
|| code
== OMP_FOR
))
20213 if (ordered
&& ordered
< collapse
)
20215 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
20216 "%<ordered%> clause parameter is less than %<collapse%>");
20217 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
20218 = build_int_cst (NULL_TREE
, collapse
);
20219 ordered
= collapse
;
20222 gcc_assert (tiling
|| (collapse
>= 1 && ordered
>= 0));
20223 count
= ordered
? ordered
: collapse
;
20225 declv
= make_tree_vec (count
);
20226 initv
= make_tree_vec (count
);
20227 condv
= make_tree_vec (count
);
20228 incrv
= make_tree_vec (count
);
20230 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
))
20232 c_parser_error (parser
, "for statement expected");
20235 for_loc
= c_parser_peek_token (parser
)->location
;
20236 c_parser_consume_token (parser
);
20238 /* Forbid break/continue in the loop initializer, condition, and
20239 increment expressions. */
20240 save_in_statement
= in_statement
;
20241 in_statement
= IN_OMP_BLOCK
;
20243 for (i
= 0; i
< count
; i
++)
20245 int bracecount
= 0;
20247 matching_parens parens
;
20248 if (!parens
.require_open (parser
))
20251 /* Parse the initialization declaration or expression. */
20252 if (c_parser_next_tokens_start_declaration (parser
))
20255 vec_safe_push (for_block
, c_begin_compound_stmt (true));
20256 this_pre_body
= push_stmt_list ();
20257 c_in_omp_for
= true;
20258 c_parser_declaration_or_fndef (parser
, true, true, true, true, true);
20259 c_in_omp_for
= false;
20262 this_pre_body
= pop_stmt_list (this_pre_body
);
20266 pre_body
= push_stmt_list ();
20268 add_stmt (this_pre_body
);
20269 pre_body
= pop_stmt_list (pre_body
);
20272 pre_body
= this_pre_body
;
20274 decl
= check_for_loop_decls (for_loc
, flag_isoc99
);
20277 if (DECL_INITIAL (decl
) == error_mark_node
)
20278 decl
= error_mark_node
;
20281 else if (c_parser_next_token_is (parser
, CPP_NAME
)
20282 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
20284 struct c_expr decl_exp
;
20285 struct c_expr init_exp
;
20286 location_t init_loc
;
20288 decl_exp
= c_parser_postfix_expression (parser
);
20289 decl
= decl_exp
.value
;
20291 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
20293 init_loc
= c_parser_peek_token (parser
)->location
;
20294 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
20295 init_exp
= default_function_array_read_conversion (init_loc
,
20297 c_in_omp_for
= true;
20298 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
20299 NOP_EXPR
, init_loc
, init_exp
.value
,
20300 init_exp
.original_type
);
20301 c_in_omp_for
= false;
20302 init
= c_process_expr_stmt (init_loc
, init
);
20304 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
20309 c_parser_error (parser
,
20310 "expected iteration declaration or initialization");
20311 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
20317 /* Parse the loop condition. */
20319 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
20321 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
20322 c_in_omp_for
= true;
20323 struct c_expr cond_expr
20324 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
20325 c_in_omp_for
= false;
20327 cond
= cond_expr
.value
;
20328 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
20329 switch (cond_expr
.original_code
)
20337 if (code
!= OACC_LOOP
)
20341 /* Can't be cond = error_mark_node, because we want to preserve
20342 the location until c_finish_omp_for. */
20343 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
20346 protected_set_expr_location (cond
, cond_loc
);
20348 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
20350 /* Parse the increment expression. */
20352 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
20354 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
20356 incr
= c_process_expr_stmt (incr_loc
,
20357 c_parser_expression (parser
).value
);
20359 parens
.skip_until_found_close (parser
);
20361 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
20365 TREE_VEC_ELT (declv
, i
) = decl
;
20366 TREE_VEC_ELT (initv
, i
) = init
;
20367 TREE_VEC_ELT (condv
, i
) = cond
;
20368 TREE_VEC_ELT (incrv
, i
) = incr
;
20372 if (i
== count
- 1)
20375 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
20376 in between the collapsed for loops to be still considered perfectly
20377 nested. Hopefully the final version clarifies this.
20378 For now handle (multiple) {'s and empty statements. */
20381 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
20383 c_parser_consume_token (parser
);
20386 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
20388 c_parser_consume_token (parser
);
20391 else if (bracecount
20392 && c_parser_next_token_is (parser
, CPP_SEMICOLON
))
20393 c_parser_consume_token (parser
);
20396 c_parser_error (parser
, "not enough perfectly nested loops");
20399 open_brace_parsed
= true;
20409 nbraces
+= bracecount
;
20415 in_statement
= IN_OMP_FOR
;
20416 body
= push_stmt_list ();
20419 c_parser_omp_scan_loop_body (parser
, open_brace_parsed
);
20420 else if (open_brace_parsed
)
20422 location_t here
= c_parser_peek_token (parser
)->location
;
20423 stmt
= c_begin_compound_stmt (true);
20424 c_parser_compound_statement_nostart (parser
);
20425 add_stmt (c_end_compound_stmt (here
, stmt
, true));
20428 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
20430 body
= pop_stmt_list (body
);
20431 in_statement
= save_in_statement
;
20435 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
20437 c_parser_consume_token (parser
);
20440 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
20441 c_parser_consume_token (parser
);
20444 c_parser_error (parser
, "collapsed loops not perfectly nested");
20447 location_t here
= c_parser_peek_token (parser
)->location
;
20448 stmt
= c_begin_compound_stmt (true);
20450 c_parser_compound_statement_nostart (parser
);
20451 body
= c_end_compound_stmt (here
, stmt
, true);
20458 /* Only bother calling c_finish_omp_for if we haven't already generated
20459 an error from the initialization parsing. */
20462 c_in_omp_for
= true;
20463 stmt
= c_finish_omp_for (loc
, code
, declv
, NULL
, initv
, condv
,
20464 incrv
, body
, pre_body
, true);
20465 c_in_omp_for
= false;
20467 /* Check for iterators appearing in lb, b or incr expressions. */
20468 if (stmt
&& !c_omp_check_loop_iv (stmt
, declv
, NULL
))
20475 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (stmt
)); i
++)
20477 tree init
= TREE_VEC_ELT (OMP_FOR_INIT (stmt
), i
);
20478 gcc_assert (TREE_CODE (init
) == MODIFY_EXPR
);
20479 tree decl
= TREE_OPERAND (init
, 0);
20480 tree cond
= TREE_VEC_ELT (OMP_FOR_COND (stmt
), i
);
20481 gcc_assert (COMPARISON_CLASS_P (cond
));
20482 gcc_assert (TREE_OPERAND (cond
, 0) == decl
);
20484 tree op0
= TREE_OPERAND (init
, 1);
20485 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
20486 || TREE_CODE (op0
) != TREE_VEC
)
20487 TREE_OPERAND (init
, 1) = c_fully_fold (op0
, false, NULL
);
20490 TREE_VEC_ELT (op0
, 1)
20491 = c_fully_fold (TREE_VEC_ELT (op0
, 1), false, NULL
);
20492 TREE_VEC_ELT (op0
, 2)
20493 = c_fully_fold (TREE_VEC_ELT (op0
, 2), false, NULL
);
20496 tree op1
= TREE_OPERAND (cond
, 1);
20497 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
20498 || TREE_CODE (op1
) != TREE_VEC
)
20499 TREE_OPERAND (cond
, 1) = c_fully_fold (op1
, false, NULL
);
20502 TREE_VEC_ELT (op1
, 1)
20503 = c_fully_fold (TREE_VEC_ELT (op1
, 1), false, NULL
);
20504 TREE_VEC_ELT (op1
, 2)
20505 = c_fully_fold (TREE_VEC_ELT (op1
, 2), false, NULL
);
20509 if (cclauses
!= NULL
20510 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
20513 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
20514 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
20515 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
20516 c
= &OMP_CLAUSE_CHAIN (*c
);
20519 for (i
= 0; i
< count
; i
++)
20520 if (TREE_VEC_ELT (declv
, i
) == OMP_CLAUSE_DECL (*c
))
20523 c
= &OMP_CLAUSE_CHAIN (*c
);
20524 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
20527 "iteration variable %qD should not be firstprivate",
20528 OMP_CLAUSE_DECL (*c
));
20529 *c
= OMP_CLAUSE_CHAIN (*c
);
20533 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
20535 *c
= OMP_CLAUSE_CHAIN (*c
);
20536 if (code
== OMP_SIMD
)
20538 OMP_CLAUSE_CHAIN (l
)
20539 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
20540 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
20544 OMP_CLAUSE_CHAIN (l
) = clauses
;
20550 OMP_FOR_CLAUSES (stmt
) = clauses
;
20555 while (!for_block
->is_empty ())
20557 /* FIXME diagnostics: LOC below should be the actual location of
20558 this particular for block. We need to build a list of
20559 locations to go along with FOR_BLOCK. */
20560 stmt
= c_end_compound_stmt (loc
, for_block
->pop (), true);
20563 release_tree_vector (for_block
);
20567 /* Helper function for OpenMP parsing, split clauses and call
20568 finish_omp_clauses on each of the set of clauses afterwards. */
20571 omp_split_clauses (location_t loc
, enum tree_code code
,
20572 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
20575 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
20576 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
20578 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
],
20579 i
== C_OMP_CLAUSE_SPLIT_TARGET
20580 ? C_ORT_OMP_TARGET
: C_ORT_OMP
);
20584 #pragma omp loop loop-clause[optseq] new-line
20587 LOC is the location of the #pragma token.
20590 #define OMP_LOOP_CLAUSE_MASK \
20591 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20592 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20593 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20594 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20595 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
20596 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20599 c_parser_omp_loop (location_t loc
, c_parser
*parser
,
20600 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20603 tree block
, clauses
, ret
;
20605 strcat (p_name
, " loop");
20606 mask
|= OMP_LOOP_CLAUSE_MASK
;
20608 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20611 omp_split_clauses (loc
, OMP_LOOP
, mask
, clauses
, cclauses
);
20612 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_LOOP
];
20615 block
= c_begin_compound_stmt (true);
20616 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_LOOP
, clauses
, cclauses
, if_p
);
20617 block
= c_end_compound_stmt (loc
, block
, true);
20624 #pragma omp simd simd-clause[optseq] new-line
20627 LOC is the location of the #pragma token.
20630 #define OMP_SIMD_CLAUSE_MASK \
20631 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
20632 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
20633 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
20634 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
20635 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20636 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
20641 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20644 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
20645 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20648 tree block
, clauses
, ret
;
20650 strcat (p_name
, " simd");
20651 mask
|= OMP_SIMD_CLAUSE_MASK
;
20653 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20656 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
20657 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
20660 block
= c_begin_compound_stmt (true);
20661 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
20662 block
= c_end_compound_stmt (loc
, block
, true);
20669 #pragma omp for for-clause[optseq] new-line
20673 #pragma omp for simd for-simd-clause[optseq] new-line
20676 LOC is the location of the #pragma token.
20679 #define OMP_FOR_CLAUSE_MASK \
20680 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20681 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20682 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20683 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
20684 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20685 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
20686 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
20687 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20688 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
20689 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20690 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20693 c_parser_omp_for (location_t loc
, c_parser
*parser
,
20694 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20697 tree block
, clauses
, ret
;
20699 strcat (p_name
, " for");
20700 mask
|= OMP_FOR_CLAUSE_MASK
;
20701 /* parallel for{, simd} disallows nowait clause, but for
20702 target {teams distribute ,}parallel for{, simd} it should be accepted. */
20703 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
20704 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
20705 /* Composite distribute parallel for{, simd} disallows ordered clause. */
20706 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
20707 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
20709 if (c_parser_next_token_is (parser
, CPP_NAME
))
20711 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20713 if (strcmp (p
, "simd") == 0)
20715 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20716 if (cclauses
== NULL
)
20717 cclauses
= cclauses_buf
;
20719 c_parser_consume_token (parser
);
20720 if (!flag_openmp
) /* flag_openmp_simd */
20721 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
20723 block
= c_begin_compound_stmt (true);
20724 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
20725 block
= c_end_compound_stmt (loc
, block
, true);
20726 if (ret
== NULL_TREE
)
20728 ret
= make_node (OMP_FOR
);
20729 TREE_TYPE (ret
) = void_type_node
;
20730 OMP_FOR_BODY (ret
) = block
;
20731 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
20732 SET_EXPR_LOCATION (ret
, loc
);
20737 if (!flag_openmp
) /* flag_openmp_simd */
20739 c_parser_skip_to_pragma_eol (parser
, false);
20743 /* Composite distribute parallel for disallows linear clause. */
20744 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
20745 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
20747 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20750 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
20751 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
20754 block
= c_begin_compound_stmt (true);
20755 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
20756 block
= c_end_compound_stmt (loc
, block
, true);
20762 static tree
c_parser_omp_taskloop (location_t
, c_parser
*, char *,
20763 omp_clause_mask
, tree
*, bool *);
20766 # pragma omp master new-line
20769 LOC is the location of the #pragma token.
20773 c_parser_omp_master (location_t loc
, c_parser
*parser
,
20774 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20777 tree block
, clauses
, ret
;
20779 strcat (p_name
, " master");
20781 if (c_parser_next_token_is (parser
, CPP_NAME
))
20783 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20785 if (strcmp (p
, "taskloop") == 0)
20787 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20788 if (cclauses
== NULL
)
20789 cclauses
= cclauses_buf
;
20791 c_parser_consume_token (parser
);
20792 if (!flag_openmp
) /* flag_openmp_simd */
20793 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
20795 block
= c_begin_compound_stmt (true);
20796 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
20798 block
= c_end_compound_stmt (loc
, block
, true);
20799 if (ret
== NULL_TREE
)
20801 ret
= c_finish_omp_master (loc
, block
);
20802 OMP_MASTER_COMBINED (ret
) = 1;
20806 if (!flag_openmp
) /* flag_openmp_simd */
20808 c_parser_skip_to_pragma_eol (parser
, false);
20814 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, false);
20815 omp_split_clauses (loc
, OMP_MASTER
, mask
, clauses
, cclauses
);
20818 c_parser_skip_to_pragma_eol (parser
);
20820 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
20825 # pragma omp masked masked-clauses new-line
20828 LOC is the location of the #pragma token.
20831 #define OMP_MASKED_CLAUSE_MASK \
20832 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
20835 c_parser_omp_masked (location_t loc
, c_parser
*parser
,
20836 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20839 tree block
, clauses
, ret
;
20841 strcat (p_name
, " masked");
20842 mask
|= OMP_MASKED_CLAUSE_MASK
;
20844 if (c_parser_next_token_is (parser
, CPP_NAME
))
20846 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20848 if (strcmp (p
, "taskloop") == 0)
20850 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20851 if (cclauses
== NULL
)
20852 cclauses
= cclauses_buf
;
20854 c_parser_consume_token (parser
);
20855 if (!flag_openmp
) /* flag_openmp_simd */
20856 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
20858 block
= c_begin_compound_stmt (true);
20859 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
20861 block
= c_end_compound_stmt (loc
, block
, true);
20862 if (ret
== NULL_TREE
)
20864 ret
= c_finish_omp_masked (loc
, block
,
20865 cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
]);
20866 OMP_MASKED_COMBINED (ret
) = 1;
20870 if (!flag_openmp
) /* flag_openmp_simd */
20872 c_parser_skip_to_pragma_eol (parser
, false);
20876 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20879 omp_split_clauses (loc
, OMP_MASKED
, mask
, clauses
, cclauses
);
20880 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
];
20883 return c_finish_omp_masked (loc
, c_parser_omp_structured_block (parser
,
20889 # pragma omp ordered new-line
20893 # pragma omp ordered ordered-clauses new-line
20896 # pragma omp ordered depend-clauses new-line
20899 # pragma omp ordered doacross-clauses new-line */
20901 #define OMP_ORDERED_CLAUSE_MASK \
20902 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
20903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
20905 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
20906 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20907 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
20910 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
20913 location_t loc
= c_parser_peek_token (parser
)->location
;
20914 c_parser_consume_pragma (parser
);
20916 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
20918 c_parser_error (parser
, "expected declaration specifiers");
20919 c_parser_skip_to_pragma_eol (parser
, false);
20924 if (c_parser_next_token_is (parser
, CPP_COMMA
))
20927 if (c_parser_peek_nth_token (parser
, n
)->type
== CPP_NAME
)
20930 = IDENTIFIER_POINTER (c_parser_peek_nth_token (parser
, n
)->value
);
20932 if (!strcmp ("depend", p
) || !strcmp ("doacross", p
))
20934 if (!flag_openmp
) /* flag_openmp_simd */
20936 c_parser_skip_to_pragma_eol (parser
, false);
20939 if (context
== pragma_stmt
)
20942 "%<#pragma omp ordered%> with %qs clause may "
20943 "only be used in compound statements", p
);
20944 c_parser_skip_to_pragma_eol (parser
, false);
20949 = c_parser_omp_all_clauses (parser
,
20950 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
20951 "#pragma omp ordered");
20952 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
20957 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
20958 "#pragma omp ordered");
20960 if (!flag_openmp
/* flag_openmp_simd */
20961 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
20964 c_finish_omp_ordered (loc
, clauses
,
20965 c_parser_omp_structured_block (parser
, if_p
));
20972 { section-sequence }
20975 section-directive[opt] structured-block
20976 section-sequence section-directive structured-block
20978 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20980 SECTIONS_LOC is the location of the #pragma omp sections. */
20983 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
20985 tree stmt
, substmt
;
20986 bool error_suppress
= false;
20989 loc
= c_parser_peek_token (parser
)->location
;
20990 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
20992 /* Avoid skipping until the end of the block. */
20993 parser
->error
= false;
20997 stmt
= push_stmt_list ();
20999 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
)
21001 substmt
= c_parser_omp_structured_block_sequence (parser
,
21002 PRAGMA_OMP_SECTION
);
21003 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
21004 SET_EXPR_LOCATION (substmt
, loc
);
21005 add_stmt (substmt
);
21010 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
21012 if (c_parser_next_token_is (parser
, CPP_EOF
))
21015 loc
= c_parser_peek_token (parser
)->location
;
21016 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
21018 c_parser_consume_pragma (parser
);
21019 c_parser_skip_to_pragma_eol (parser
);
21020 error_suppress
= false;
21022 else if (!error_suppress
)
21024 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
21025 error_suppress
= true;
21028 substmt
= c_parser_omp_structured_block_sequence (parser
,
21029 PRAGMA_OMP_SECTION
);
21030 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
21031 SET_EXPR_LOCATION (substmt
, loc
);
21032 add_stmt (substmt
);
21034 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
21035 "expected %<#pragma omp section%> or %<}%>");
21037 substmt
= pop_stmt_list (stmt
);
21039 stmt
= make_node (OMP_SECTIONS
);
21040 SET_EXPR_LOCATION (stmt
, sections_loc
);
21041 TREE_TYPE (stmt
) = void_type_node
;
21042 OMP_SECTIONS_BODY (stmt
) = substmt
;
21044 return add_stmt (stmt
);
21048 # pragma omp sections sections-clause[optseq] newline
21051 LOC is the location of the #pragma token.
21054 #define OMP_SECTIONS_CLAUSE_MASK \
21055 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21056 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21057 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
21058 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21059 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21060 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21063 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
21064 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
21066 tree block
, clauses
, ret
;
21068 strcat (p_name
, " sections");
21069 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
21071 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
21073 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
21076 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
21077 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
21080 block
= c_begin_compound_stmt (true);
21081 ret
= c_parser_omp_sections_scope (loc
, parser
);
21083 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
21084 block
= c_end_compound_stmt (loc
, block
, true);
21091 # pragma omp parallel parallel-clause[optseq] new-line
21093 # pragma omp parallel for parallel-for-clause[optseq] new-line
21095 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
21099 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
21102 LOC is the location of the #pragma token.
21105 #define OMP_PARALLEL_CLAUSE_MASK \
21106 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21107 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21108 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21109 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
21110 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21111 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
21112 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21113 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
21114 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21115 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
21118 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
21119 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
21122 tree stmt
, clauses
, block
;
21124 strcat (p_name
, " parallel");
21125 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
21126 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
21127 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
21128 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
21129 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
21131 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
21133 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
21134 if (cclauses
== NULL
)
21135 cclauses
= cclauses_buf
;
21137 c_parser_consume_token (parser
);
21138 if (!flag_openmp
) /* flag_openmp_simd */
21139 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
21140 block
= c_begin_omp_parallel ();
21141 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
21143 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
21145 if (ret
== NULL_TREE
)
21147 OMP_PARALLEL_COMBINED (stmt
) = 1;
21150 /* When combined with distribute, parallel has to be followed by for.
21151 #pragma omp target parallel is allowed though. */
21153 && (mask
& (OMP_CLAUSE_MASK_1
21154 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
21156 error_at (loc
, "expected %<for%> after %qs", p_name
);
21157 c_parser_skip_to_pragma_eol (parser
);
21160 else if (c_parser_next_token_is (parser
, CPP_NAME
))
21162 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21163 if (cclauses
== NULL
&& strcmp (p
, "masked") == 0)
21165 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
21166 cclauses
= cclauses_buf
;
21168 c_parser_consume_token (parser
);
21169 if (!flag_openmp
) /* flag_openmp_simd */
21170 return c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
21172 block
= c_begin_omp_parallel ();
21173 tree ret
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
21175 stmt
= c_finish_omp_parallel (loc
,
21176 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
21180 /* masked does have just filter clause, but during gimplification
21181 isn't represented by a gimplification omp context, so for
21182 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
21184 #pragma omp parallel masked
21185 #pragma omp taskloop simd lastprivate (x)
21186 isn't confused with
21187 #pragma omp parallel masked taskloop simd lastprivate (x) */
21188 if (OMP_MASKED_COMBINED (ret
))
21189 OMP_PARALLEL_COMBINED (stmt
) = 1;
21192 else if (cclauses
== NULL
&& strcmp (p
, "master") == 0)
21194 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
21195 cclauses
= cclauses_buf
;
21197 c_parser_consume_token (parser
);
21198 if (!flag_openmp
) /* flag_openmp_simd */
21199 return c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
21201 block
= c_begin_omp_parallel ();
21202 tree ret
= c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
21204 stmt
= c_finish_omp_parallel (loc
,
21205 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
21209 /* master doesn't have any clauses and during gimplification
21210 isn't represented by a gimplification omp context, so for
21211 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
21213 #pragma omp parallel master
21214 #pragma omp taskloop simd lastprivate (x)
21215 isn't confused with
21216 #pragma omp parallel master taskloop simd lastprivate (x) */
21217 if (OMP_MASTER_COMBINED (ret
))
21218 OMP_PARALLEL_COMBINED (stmt
) = 1;
21221 else if (strcmp (p
, "loop") == 0)
21223 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
21224 if (cclauses
== NULL
)
21225 cclauses
= cclauses_buf
;
21227 c_parser_consume_token (parser
);
21228 if (!flag_openmp
) /* flag_openmp_simd */
21229 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
21231 block
= c_begin_omp_parallel ();
21232 tree ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
21235 = c_finish_omp_parallel (loc
,
21236 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
21238 if (ret
== NULL_TREE
)
21240 OMP_PARALLEL_COMBINED (stmt
) = 1;
21243 else if (!flag_openmp
) /* flag_openmp_simd */
21245 c_parser_skip_to_pragma_eol (parser
, false);
21248 else if (cclauses
== NULL
&& strcmp (p
, "sections") == 0)
21250 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
21251 cclauses
= cclauses_buf
;
21253 c_parser_consume_token (parser
);
21254 block
= c_begin_omp_parallel ();
21255 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
21256 stmt
= c_finish_omp_parallel (loc
,
21257 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
21259 OMP_PARALLEL_COMBINED (stmt
) = 1;
21263 else if (!flag_openmp
) /* flag_openmp_simd */
21265 c_parser_skip_to_pragma_eol (parser
, false);
21269 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
21272 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
21273 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
21276 block
= c_begin_omp_parallel ();
21277 c_parser_statement (parser
, if_p
);
21278 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
21284 # pragma omp single single-clause[optseq] new-line
21287 LOC is the location of the #pragma.
21290 #define OMP_SINGLE_CLAUSE_MASK \
21291 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21292 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21293 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
21294 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21295 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21298 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
21300 tree stmt
= make_node (OMP_SINGLE
);
21301 SET_EXPR_LOCATION (stmt
, loc
);
21302 TREE_TYPE (stmt
) = void_type_node
;
21304 OMP_SINGLE_CLAUSES (stmt
)
21305 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
21306 "#pragma omp single");
21307 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
21309 return add_stmt (stmt
);
21313 # pragma omp scope scope-clause[optseq] new-line
21316 LOC is the location of the #pragma.
21319 #define OMP_SCOPE_CLAUSE_MASK \
21320 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21321 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21322 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21323 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21324 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21327 c_parser_omp_scope (location_t loc
, c_parser
*parser
, bool *if_p
)
21329 tree stmt
= make_node (OMP_SCOPE
);
21330 SET_EXPR_LOCATION (stmt
, loc
);
21331 TREE_TYPE (stmt
) = void_type_node
;
21333 OMP_SCOPE_CLAUSES (stmt
)
21334 = c_parser_omp_all_clauses (parser
, OMP_SCOPE_CLAUSE_MASK
,
21335 "#pragma omp scope");
21336 OMP_SCOPE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
21338 return add_stmt (stmt
);
21342 # pragma omp task task-clause[optseq] new-line
21344 LOC is the location of the #pragma.
21347 #define OMP_TASK_CLAUSE_MASK \
21348 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21349 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
21350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
21351 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21354 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
21355 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
21356 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21357 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
21358 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21359 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
21360 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
21361 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
21364 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
21366 tree clauses
, block
;
21368 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
21369 "#pragma omp task");
21371 block
= c_begin_omp_task ();
21372 c_parser_statement (parser
, if_p
);
21373 return c_finish_omp_task (loc
, clauses
, block
);
21377 # pragma omp taskwait new-line
21380 # pragma omp taskwait taskwait-clause[optseq] new-line
21383 #define OMP_TASKWAIT_CLAUSE_MASK \
21384 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21385 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21388 c_parser_omp_taskwait (c_parser
*parser
)
21390 location_t loc
= c_parser_peek_token (parser
)->location
;
21391 c_parser_consume_pragma (parser
);
21394 = c_parser_omp_all_clauses (parser
, OMP_TASKWAIT_CLAUSE_MASK
,
21395 "#pragma omp taskwait");
21399 tree stmt
= make_node (OMP_TASK
);
21400 TREE_TYPE (stmt
) = void_node
;
21401 OMP_TASK_CLAUSES (stmt
) = clauses
;
21402 OMP_TASK_BODY (stmt
) = NULL_TREE
;
21403 SET_EXPR_LOCATION (stmt
, loc
);
21407 c_finish_omp_taskwait (loc
);
21411 # pragma omp taskyield new-line
21415 c_parser_omp_taskyield (c_parser
*parser
)
21417 location_t loc
= c_parser_peek_token (parser
)->location
;
21418 c_parser_consume_pragma (parser
);
21419 c_parser_skip_to_pragma_eol (parser
);
21421 c_finish_omp_taskyield (loc
);
21425 # pragma omp taskgroup new-line
21428 # pragma omp taskgroup taskgroup-clause[optseq] new-line
21431 #define OMP_TASKGROUP_CLAUSE_MASK \
21432 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21433 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
21436 c_parser_omp_taskgroup (location_t loc
, c_parser
*parser
, bool *if_p
)
21438 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_TASKGROUP_CLAUSE_MASK
,
21439 "#pragma omp taskgroup");
21441 tree body
= c_parser_omp_structured_block (parser
, if_p
);
21442 return c_finish_omp_taskgroup (loc
, body
, clauses
);
21446 # pragma omp cancel cancel-clause[optseq] new-line
21448 LOC is the location of the #pragma.
21451 #define OMP_CANCEL_CLAUSE_MASK \
21452 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
21453 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
21454 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
21455 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
21456 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
21459 c_parser_omp_cancel (c_parser
*parser
)
21461 location_t loc
= c_parser_peek_token (parser
)->location
;
21463 c_parser_consume_pragma (parser
);
21464 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
21465 "#pragma omp cancel");
21467 c_finish_omp_cancel (loc
, clauses
);
21471 # pragma omp cancellation point cancelpt-clause[optseq] new-line
21473 LOC is the location of the #pragma.
21476 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
21477 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
21478 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
21479 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
21480 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
21483 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
21485 location_t loc
= c_parser_peek_token (parser
)->location
;
21487 bool point_seen
= false;
21489 c_parser_consume_pragma (parser
);
21490 if (c_parser_next_token_is (parser
, CPP_NAME
))
21492 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21493 if (strcmp (p
, "point") == 0)
21495 c_parser_consume_token (parser
);
21501 c_parser_error (parser
, "expected %<point%>");
21502 c_parser_skip_to_pragma_eol (parser
);
21506 if (context
!= pragma_compound
)
21508 if (context
== pragma_stmt
)
21510 "%<#pragma %s%> may only be used in compound statements",
21511 "omp cancellation point");
21513 c_parser_error (parser
, "expected declaration specifiers");
21514 c_parser_skip_to_pragma_eol (parser
, false);
21519 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
21520 "#pragma omp cancellation point");
21522 c_finish_omp_cancellation_point (loc
, clauses
);
21527 #pragma omp distribute distribute-clause[optseq] new-line
21530 #define OMP_DISTRIBUTE_CLAUSE_MASK \
21531 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21532 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21533 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
21534 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
21535 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21536 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
21537 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
21540 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
21541 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
21544 tree clauses
, block
, ret
;
21546 strcat (p_name
, " distribute");
21547 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
21549 if (c_parser_next_token_is (parser
, CPP_NAME
))
21551 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21553 bool parallel
= false;
21555 if (strcmp (p
, "simd") == 0)
21558 parallel
= strcmp (p
, "parallel") == 0;
21559 if (parallel
|| simd
)
21561 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
21562 if (cclauses
== NULL
)
21563 cclauses
= cclauses_buf
;
21564 c_parser_consume_token (parser
);
21565 if (!flag_openmp
) /* flag_openmp_simd */
21568 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
21571 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
21574 block
= c_begin_compound_stmt (true);
21576 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
21579 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
21581 block
= c_end_compound_stmt (loc
, block
, true);
21584 ret
= make_node (OMP_DISTRIBUTE
);
21585 TREE_TYPE (ret
) = void_type_node
;
21586 OMP_FOR_BODY (ret
) = block
;
21587 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
21588 SET_EXPR_LOCATION (ret
, loc
);
21593 if (!flag_openmp
) /* flag_openmp_simd */
21595 c_parser_skip_to_pragma_eol (parser
, false);
21599 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
21602 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
21603 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
21606 block
= c_begin_compound_stmt (true);
21607 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
21609 block
= c_end_compound_stmt (loc
, block
, true);
21616 # pragma omp teams teams-clause[optseq] new-line
21617 structured-block */
21619 #define OMP_TEAMS_CLAUSE_MASK \
21620 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21621 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21622 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21623 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21624 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
21625 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21626 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21627 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
21630 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
21631 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
21634 tree clauses
, block
, ret
;
21636 strcat (p_name
, " teams");
21637 mask
|= OMP_TEAMS_CLAUSE_MASK
;
21639 if (c_parser_next_token_is (parser
, CPP_NAME
))
21641 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21642 if (strcmp (p
, "distribute") == 0)
21644 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
21645 if (cclauses
== NULL
)
21646 cclauses
= cclauses_buf
;
21648 c_parser_consume_token (parser
);
21649 if (!flag_openmp
) /* flag_openmp_simd */
21650 return c_parser_omp_distribute (loc
, parser
, p_name
, mask
,
21652 block
= c_begin_omp_parallel ();
21653 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
21655 block
= c_end_compound_stmt (loc
, block
, true);
21658 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
21659 ret
= make_node (OMP_TEAMS
);
21660 TREE_TYPE (ret
) = void_type_node
;
21661 OMP_TEAMS_CLAUSES (ret
) = clauses
;
21662 OMP_TEAMS_BODY (ret
) = block
;
21663 OMP_TEAMS_COMBINED (ret
) = 1;
21664 SET_EXPR_LOCATION (ret
, loc
);
21665 return add_stmt (ret
);
21667 else if (strcmp (p
, "loop") == 0)
21669 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
21670 if (cclauses
== NULL
)
21671 cclauses
= cclauses_buf
;
21673 c_parser_consume_token (parser
);
21674 if (!flag_openmp
) /* flag_openmp_simd */
21675 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
21677 block
= c_begin_omp_parallel ();
21678 ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
21679 block
= c_end_compound_stmt (loc
, block
, true);
21682 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
21683 ret
= make_node (OMP_TEAMS
);
21684 TREE_TYPE (ret
) = void_type_node
;
21685 OMP_TEAMS_CLAUSES (ret
) = clauses
;
21686 OMP_TEAMS_BODY (ret
) = block
;
21687 OMP_TEAMS_COMBINED (ret
) = 1;
21688 SET_EXPR_LOCATION (ret
, loc
);
21689 return add_stmt (ret
);
21692 if (!flag_openmp
) /* flag_openmp_simd */
21694 c_parser_skip_to_pragma_eol (parser
, false);
21698 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
21701 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
21702 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
21705 tree stmt
= make_node (OMP_TEAMS
);
21706 TREE_TYPE (stmt
) = void_type_node
;
21707 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
21708 block
= c_begin_omp_parallel ();
21709 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
21710 OMP_TEAMS_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
21711 SET_EXPR_LOCATION (stmt
, loc
);
21713 return add_stmt (stmt
);
21717 # pragma omp target data target-data-clause[optseq] new-line
21718 structured-block */
21720 #define OMP_TARGET_DATA_CLAUSE_MASK \
21721 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
21725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
21728 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
21732 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21735 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
21736 "#pragma omp target data");
21737 c_omp_adjust_map_clauses (clauses
, false);
21739 for (tree
*pc
= &clauses
; *pc
;)
21741 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21742 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21745 case GOMP_MAP_ALWAYS_TO
:
21746 case GOMP_MAP_FROM
:
21747 case GOMP_MAP_ALWAYS_FROM
:
21748 case GOMP_MAP_TOFROM
:
21749 case GOMP_MAP_ALWAYS_TOFROM
:
21750 case GOMP_MAP_ALLOC
:
21753 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
21754 case GOMP_MAP_ALWAYS_POINTER
:
21755 case GOMP_MAP_ATTACH_DETACH
:
21759 error_at (OMP_CLAUSE_LOCATION (*pc
),
21760 "%<#pragma omp target data%> with map-type other "
21761 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21762 "on %<map%> clause");
21763 *pc
= OMP_CLAUSE_CHAIN (*pc
);
21766 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
21767 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
21769 pc
= &OMP_CLAUSE_CHAIN (*pc
);
21776 "%<#pragma omp target data%> must contain at least "
21777 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
21782 tree stmt
= make_node (OMP_TARGET_DATA
);
21783 TREE_TYPE (stmt
) = void_type_node
;
21784 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
21785 keep_next_level ();
21786 tree block
= c_begin_compound_stmt (true);
21787 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
21788 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
21790 SET_EXPR_LOCATION (stmt
, loc
);
21791 return add_stmt (stmt
);
21795 # pragma omp target update target-update-clause[optseq] new-line */
21797 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
21798 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
21799 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
21800 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21801 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21802 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21806 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
21807 enum pragma_context context
)
21809 if (context
== pragma_stmt
)
21811 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
21812 "omp target update");
21813 c_parser_skip_to_pragma_eol (parser
, false);
21818 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
21819 "#pragma omp target update");
21820 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
21821 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
21824 "%<#pragma omp target update%> must contain at least one "
21825 "%<from%> or %<to%> clauses");
21831 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21833 tree stmt
= make_node (OMP_TARGET_UPDATE
);
21834 TREE_TYPE (stmt
) = void_type_node
;
21835 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
21836 SET_EXPR_LOCATION (stmt
, loc
);
21842 # pragma omp target enter data target-data-clause[optseq] new-line */
21844 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
21845 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21846 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21847 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21848 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21849 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21852 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
21853 enum pragma_context context
)
21855 bool data_seen
= false;
21856 if (c_parser_next_token_is (parser
, CPP_NAME
))
21858 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21859 if (strcmp (p
, "data") == 0)
21861 c_parser_consume_token (parser
);
21867 c_parser_error (parser
, "expected %<data%>");
21868 c_parser_skip_to_pragma_eol (parser
);
21872 if (context
== pragma_stmt
)
21874 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
21875 "omp target enter data");
21876 c_parser_skip_to_pragma_eol (parser
, false);
21882 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21885 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
21886 "#pragma omp target enter data");
21887 c_omp_adjust_map_clauses (clauses
, false);
21889 for (tree
*pc
= &clauses
; *pc
;)
21891 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21892 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21895 case GOMP_MAP_ALWAYS_TO
:
21896 case GOMP_MAP_ALLOC
:
21899 case GOMP_MAP_TOFROM
:
21900 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_TO
);
21903 case GOMP_MAP_ALWAYS_TOFROM
:
21904 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_TO
);
21907 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
21908 case GOMP_MAP_ALWAYS_POINTER
:
21909 case GOMP_MAP_ATTACH_DETACH
:
21913 error_at (OMP_CLAUSE_LOCATION (*pc
),
21914 "%<#pragma omp target enter data%> with map-type other "
21915 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
21916 *pc
= OMP_CLAUSE_CHAIN (*pc
);
21919 pc
= &OMP_CLAUSE_CHAIN (*pc
);
21926 "%<#pragma omp target enter data%> must contain at least "
21927 "one %<map%> clause");
21931 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
21932 TREE_TYPE (stmt
) = void_type_node
;
21933 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
21934 SET_EXPR_LOCATION (stmt
, loc
);
21940 # pragma omp target exit data target-data-clause[optseq] new-line */
21942 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
21943 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21944 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21945 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21946 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21947 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21950 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
21951 enum pragma_context context
)
21953 bool data_seen
= false;
21954 if (c_parser_next_token_is (parser
, CPP_NAME
))
21956 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21957 if (strcmp (p
, "data") == 0)
21959 c_parser_consume_token (parser
);
21965 c_parser_error (parser
, "expected %<data%>");
21966 c_parser_skip_to_pragma_eol (parser
);
21970 if (context
== pragma_stmt
)
21972 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
21973 "omp target exit data");
21974 c_parser_skip_to_pragma_eol (parser
, false);
21980 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21983 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
21984 "#pragma omp target exit data");
21985 c_omp_adjust_map_clauses (clauses
, false);
21987 for (tree
*pc
= &clauses
; *pc
;)
21989 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21990 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21992 case GOMP_MAP_FROM
:
21993 case GOMP_MAP_ALWAYS_FROM
:
21994 case GOMP_MAP_RELEASE
:
21995 case GOMP_MAP_DELETE
:
21998 case GOMP_MAP_TOFROM
:
21999 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_FROM
);
22002 case GOMP_MAP_ALWAYS_TOFROM
:
22003 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_FROM
);
22006 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
22007 case GOMP_MAP_ALWAYS_POINTER
:
22008 case GOMP_MAP_ATTACH_DETACH
:
22012 error_at (OMP_CLAUSE_LOCATION (*pc
),
22013 "%<#pragma omp target exit data%> with map-type other "
22014 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
22015 "on %<map%> clause");
22016 *pc
= OMP_CLAUSE_CHAIN (*pc
);
22019 pc
= &OMP_CLAUSE_CHAIN (*pc
);
22026 "%<#pragma omp target exit data%> must contain at least one "
22031 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
22032 TREE_TYPE (stmt
) = void_type_node
;
22033 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
22034 SET_EXPR_LOCATION (stmt
, loc
);
22040 # pragma omp target target-clause[optseq] new-line
22041 structured-block */
22043 #define OMP_TARGET_CLAUSE_MASK \
22044 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
22045 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
22046 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22047 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
22048 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
22049 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22050 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22051 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22052 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
22053 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
22054 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
22055 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
22056 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
22059 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
22061 location_t loc
= c_parser_peek_token (parser
)->location
;
22062 c_parser_consume_pragma (parser
);
22063 tree
*pc
= NULL
, stmt
, block
;
22065 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
22067 c_parser_error (parser
, "expected declaration specifiers");
22068 c_parser_skip_to_pragma_eol (parser
);
22074 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
22076 if (c_parser_next_token_is (parser
, CPP_NAME
))
22078 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22079 enum tree_code ccode
= ERROR_MARK
;
22081 if (strcmp (p
, "teams") == 0)
22083 else if (strcmp (p
, "parallel") == 0)
22084 ccode
= OMP_PARALLEL
;
22085 else if (strcmp (p
, "simd") == 0)
22087 if (ccode
!= ERROR_MARK
)
22089 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
22090 char p_name
[sizeof ("#pragma omp target teams distribute "
22091 "parallel for simd")];
22093 c_parser_consume_token (parser
);
22094 strcpy (p_name
, "#pragma omp target");
22095 if (!flag_openmp
) /* flag_openmp_simd */
22101 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
22102 OMP_TARGET_CLAUSE_MASK
,
22106 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
22107 OMP_TARGET_CLAUSE_MASK
,
22111 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
22112 OMP_TARGET_CLAUSE_MASK
,
22116 gcc_unreachable ();
22118 return stmt
!= NULL_TREE
;
22120 keep_next_level ();
22121 tree block
= c_begin_compound_stmt (true), ret
;
22125 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
22126 OMP_TARGET_CLAUSE_MASK
, cclauses
,
22130 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
22131 OMP_TARGET_CLAUSE_MASK
, cclauses
,
22135 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
22136 OMP_TARGET_CLAUSE_MASK
, cclauses
,
22140 gcc_unreachable ();
22142 block
= c_end_compound_stmt (loc
, block
, true);
22143 if (ret
== NULL_TREE
)
22145 if (ccode
== OMP_TEAMS
)
22146 /* For combined target teams, ensure the num_teams and
22147 thread_limit clause expressions are evaluated on the host,
22148 before entering the target construct. */
22149 for (tree c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
22150 c
; c
= OMP_CLAUSE_CHAIN (c
))
22151 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
22152 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
22154 i
<= (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
); ++i
)
22155 if (OMP_CLAUSE_OPERAND (c
, i
)
22156 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, i
)) != INTEGER_CST
)
22158 tree expr
= OMP_CLAUSE_OPERAND (c
, i
);
22159 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
22160 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
22161 expr
, NULL_TREE
, NULL_TREE
);
22163 OMP_CLAUSE_OPERAND (c
, i
) = expr
;
22164 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
22165 OMP_CLAUSE_FIRSTPRIVATE
);
22166 OMP_CLAUSE_DECL (tc
) = tmp
;
22167 OMP_CLAUSE_CHAIN (tc
)
22168 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
22169 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
22171 tree stmt
= make_node (OMP_TARGET
);
22172 TREE_TYPE (stmt
) = void_type_node
;
22173 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
22174 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
22175 OMP_TARGET_BODY (stmt
) = block
;
22176 OMP_TARGET_COMBINED (stmt
) = 1;
22177 SET_EXPR_LOCATION (stmt
, loc
);
22179 pc
= &OMP_TARGET_CLAUSES (stmt
);
22180 goto check_clauses
;
22182 else if (!flag_openmp
) /* flag_openmp_simd */
22184 c_parser_skip_to_pragma_eol (parser
, false);
22187 else if (strcmp (p
, "data") == 0)
22189 c_parser_consume_token (parser
);
22190 c_parser_omp_target_data (loc
, parser
, if_p
);
22193 else if (strcmp (p
, "enter") == 0)
22195 c_parser_consume_token (parser
);
22196 return c_parser_omp_target_enter_data (loc
, parser
, context
);
22198 else if (strcmp (p
, "exit") == 0)
22200 c_parser_consume_token (parser
);
22201 return c_parser_omp_target_exit_data (loc
, parser
, context
);
22203 else if (strcmp (p
, "update") == 0)
22205 c_parser_consume_token (parser
);
22206 return c_parser_omp_target_update (loc
, parser
, context
);
22209 if (!flag_openmp
) /* flag_openmp_simd */
22211 c_parser_skip_to_pragma_eol (parser
, false);
22215 stmt
= make_node (OMP_TARGET
);
22216 TREE_TYPE (stmt
) = void_type_node
;
22218 OMP_TARGET_CLAUSES (stmt
)
22219 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
22220 "#pragma omp target", false);
22221 for (tree c
= OMP_TARGET_CLAUSES (stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
22222 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
)
22224 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
22225 OMP_CLAUSE_DECL (nc
) = OMP_CLAUSE_DECL (c
);
22226 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_ALWAYS_TOFROM
);
22227 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
22228 OMP_CLAUSE_CHAIN (c
) = nc
;
22230 OMP_TARGET_CLAUSES (stmt
)
22231 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt
), C_ORT_OMP_TARGET
);
22232 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
22234 pc
= &OMP_TARGET_CLAUSES (stmt
);
22235 keep_next_level ();
22236 block
= c_begin_compound_stmt (true);
22237 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
22238 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
22240 SET_EXPR_LOCATION (stmt
, loc
);
22246 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
22247 switch (OMP_CLAUSE_MAP_KIND (*pc
))
22250 case GOMP_MAP_ALWAYS_TO
:
22251 case GOMP_MAP_FROM
:
22252 case GOMP_MAP_ALWAYS_FROM
:
22253 case GOMP_MAP_TOFROM
:
22254 case GOMP_MAP_ALWAYS_TOFROM
:
22255 case GOMP_MAP_ALLOC
:
22256 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
22257 case GOMP_MAP_ALWAYS_POINTER
:
22258 case GOMP_MAP_ATTACH_DETACH
:
22261 error_at (OMP_CLAUSE_LOCATION (*pc
),
22262 "%<#pragma omp target%> with map-type other "
22263 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
22264 "on %<map%> clause");
22265 *pc
= OMP_CLAUSE_CHAIN (*pc
);
22268 pc
= &OMP_CLAUSE_CHAIN (*pc
);
22270 cfun
->has_omp_target
= true;
22275 # pragma omp declare simd declare-simd-clauses[optseq] new-line
22278 # pragma omp declare variant (identifier) match(context-selector) new-line
22281 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
22282 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
22283 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
22284 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
22285 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
22286 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
22287 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
22290 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
22292 c_token
*token
= c_parser_peek_token (parser
);
22293 gcc_assert (token
->type
== CPP_NAME
);
22294 tree kind
= token
->value
;
22295 gcc_assert (strcmp (IDENTIFIER_POINTER (kind
), "simd") == 0
22296 || strcmp (IDENTIFIER_POINTER (kind
), "variant") == 0);
22298 auto_vec
<c_token
> clauses
;
22299 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
22301 c_token
*token
= c_parser_peek_token (parser
);
22302 if (token
->type
== CPP_EOF
)
22304 c_parser_skip_to_pragma_eol (parser
);
22307 clauses
.safe_push (*token
);
22308 c_parser_consume_token (parser
);
22310 clauses
.safe_push (*c_parser_peek_token (parser
));
22311 c_parser_skip_to_pragma_eol (parser
);
22313 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
22315 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_DECLARE
22316 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
22317 || c_parser_peek_2nd_token (parser
)->value
!= kind
)
22319 error ("%<#pragma omp declare %s%> must be followed by "
22320 "function declaration or definition or another "
22321 "%<#pragma omp declare %s%>",
22322 IDENTIFIER_POINTER (kind
), IDENTIFIER_POINTER (kind
));
22325 c_parser_consume_pragma (parser
);
22326 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
22328 c_token
*token
= c_parser_peek_token (parser
);
22329 if (token
->type
== CPP_EOF
)
22331 c_parser_skip_to_pragma_eol (parser
);
22334 clauses
.safe_push (*token
);
22335 c_parser_consume_token (parser
);
22337 clauses
.safe_push (*c_parser_peek_token (parser
));
22338 c_parser_skip_to_pragma_eol (parser
);
22341 /* Make sure nothing tries to read past the end of the tokens. */
22343 memset (&eof_token
, 0, sizeof (eof_token
));
22344 eof_token
.type
= CPP_EOF
;
22345 clauses
.safe_push (eof_token
);
22346 clauses
.safe_push (eof_token
);
22350 case pragma_external
:
22351 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
22352 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
22354 int ext
= disable_extension_diagnostics ();
22356 c_parser_consume_token (parser
);
22357 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
22358 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
22359 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
22361 restore_extension_diagnostics (ext
);
22364 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
22367 case pragma_struct
:
22370 error ("%<#pragma omp declare %s%> must be followed by "
22371 "function declaration or definition",
22372 IDENTIFIER_POINTER (kind
));
22374 case pragma_compound
:
22375 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
22376 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
22378 int ext
= disable_extension_diagnostics ();
22380 c_parser_consume_token (parser
);
22381 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
22382 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
22383 if (c_parser_next_tokens_start_declaration (parser
))
22385 c_parser_declaration_or_fndef (parser
, true, true, true, true,
22386 true, NULL
, &clauses
);
22387 restore_extension_diagnostics (ext
);
22390 restore_extension_diagnostics (ext
);
22392 else if (c_parser_next_tokens_start_declaration (parser
))
22394 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
22398 error ("%<#pragma omp declare %s%> must be followed by "
22399 "function declaration or definition",
22400 IDENTIFIER_POINTER (kind
));
22403 gcc_unreachable ();
22407 static const char *const omp_construct_selectors
[] = {
22408 "simd", "target", "teams", "parallel", "for", NULL
};
22409 static const char *const omp_device_selectors
[] = {
22410 "kind", "isa", "arch", NULL
};
22411 static const char *const omp_implementation_selectors
[] = {
22412 "vendor", "extension", "atomic_default_mem_order", "unified_address",
22413 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL
};
22414 static const char *const omp_user_selectors
[] = {
22415 "condition", NULL
};
22420 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
22423 score(score-expression) */
22426 c_parser_omp_context_selector (c_parser
*parser
, tree set
, tree parms
)
22428 tree ret
= NULL_TREE
;
22432 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
22433 || c_parser_next_token_is (parser
, CPP_NAME
))
22434 selector
= c_parser_peek_token (parser
)->value
;
22437 c_parser_error (parser
, "expected trait selector name");
22438 return error_mark_node
;
22441 tree properties
= NULL_TREE
;
22442 const char *const *selectors
= NULL
;
22443 bool allow_score
= true;
22444 bool allow_user
= false;
22445 int property_limit
= 0;
22446 enum { CTX_PROPERTY_NONE
, CTX_PROPERTY_USER
, CTX_PROPERTY_NAME_LIST
,
22447 CTX_PROPERTY_ID
, CTX_PROPERTY_EXPR
,
22448 CTX_PROPERTY_SIMD
} property_kind
= CTX_PROPERTY_NONE
;
22449 switch (IDENTIFIER_POINTER (set
)[0])
22451 case 'c': /* construct */
22452 selectors
= omp_construct_selectors
;
22453 allow_score
= false;
22454 property_limit
= 1;
22455 property_kind
= CTX_PROPERTY_SIMD
;
22457 case 'd': /* device */
22458 selectors
= omp_device_selectors
;
22459 allow_score
= false;
22461 property_limit
= 3;
22462 property_kind
= CTX_PROPERTY_NAME_LIST
;
22464 case 'i': /* implementation */
22465 selectors
= omp_implementation_selectors
;
22467 property_limit
= 3;
22468 property_kind
= CTX_PROPERTY_NAME_LIST
;
22470 case 'u': /* user */
22471 selectors
= omp_user_selectors
;
22472 property_limit
= 1;
22473 property_kind
= CTX_PROPERTY_EXPR
;
22476 gcc_unreachable ();
22478 for (int i
= 0; ; i
++)
22480 if (selectors
[i
] == NULL
)
22484 property_kind
= CTX_PROPERTY_USER
;
22489 error_at (c_parser_peek_token (parser
)->location
,
22490 "selector %qs not allowed for context selector "
22491 "set %qs", IDENTIFIER_POINTER (selector
),
22492 IDENTIFIER_POINTER (set
));
22493 c_parser_consume_token (parser
);
22494 return error_mark_node
;
22497 if (i
== property_limit
)
22498 property_kind
= CTX_PROPERTY_NONE
;
22499 if (strcmp (selectors
[i
], IDENTIFIER_POINTER (selector
)) == 0)
22502 if (property_kind
== CTX_PROPERTY_NAME_LIST
22503 && IDENTIFIER_POINTER (set
)[0] == 'i'
22504 && strcmp (IDENTIFIER_POINTER (selector
),
22505 "atomic_default_mem_order") == 0)
22506 property_kind
= CTX_PROPERTY_ID
;
22508 c_parser_consume_token (parser
);
22510 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
22512 if (property_kind
== CTX_PROPERTY_NONE
)
22514 error_at (c_parser_peek_token (parser
)->location
,
22515 "selector %qs does not accept any properties",
22516 IDENTIFIER_POINTER (selector
));
22517 return error_mark_node
;
22520 matching_parens parens
;
22521 parens
.require_open (parser
);
22523 c_token
*token
= c_parser_peek_token (parser
);
22525 && c_parser_next_token_is (parser
, CPP_NAME
)
22526 && strcmp (IDENTIFIER_POINTER (token
->value
), "score") == 0
22527 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
22529 c_parser_consume_token (parser
);
22531 matching_parens parens2
;
22532 parens2
.require_open (parser
);
22533 tree score
= c_parser_expr_no_commas (parser
, NULL
).value
;
22534 parens2
.skip_until_found_close (parser
);
22535 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
22536 if (score
!= error_mark_node
)
22538 mark_exp_read (score
);
22539 score
= c_fully_fold (score
, false, NULL
);
22540 if (!INTEGRAL_TYPE_P (TREE_TYPE (score
))
22541 || TREE_CODE (score
) != INTEGER_CST
)
22542 error_at (token
->location
, "score argument must be "
22543 "constant integer expression");
22544 else if (tree_int_cst_sgn (score
) < 0)
22545 error_at (token
->location
, "score argument must be "
22548 properties
= tree_cons (get_identifier (" score"),
22549 score
, properties
);
22551 token
= c_parser_peek_token (parser
);
22554 switch (property_kind
)
22557 case CTX_PROPERTY_USER
:
22560 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
22561 if (TREE_CODE (t
) == STRING_CST
)
22562 properties
= tree_cons (NULL_TREE
, t
, properties
);
22563 else if (t
!= error_mark_node
)
22566 t
= c_fully_fold (t
, false, NULL
);
22567 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
22568 || !tree_fits_shwi_p (t
))
22569 error_at (token
->location
, "property must be "
22570 "constant integer expression or string "
22573 properties
= tree_cons (NULL_TREE
, t
, properties
);
22576 return error_mark_node
;
22578 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22579 c_parser_consume_token (parser
);
22585 case CTX_PROPERTY_ID
:
22586 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
22587 || c_parser_next_token_is (parser
, CPP_NAME
))
22589 tree prop
= c_parser_peek_token (parser
)->value
;
22590 c_parser_consume_token (parser
);
22591 properties
= tree_cons (prop
, NULL_TREE
, properties
);
22595 c_parser_error (parser
, "expected identifier");
22596 return error_mark_node
;
22599 case CTX_PROPERTY_NAME_LIST
:
22602 tree prop
= NULL_TREE
, value
= NULL_TREE
;
22603 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
22604 || c_parser_next_token_is (parser
, CPP_NAME
))
22606 prop
= c_parser_peek_token (parser
)->value
;
22607 c_parser_consume_token (parser
);
22609 else if (c_parser_next_token_is (parser
, CPP_STRING
))
22610 value
= c_parser_string_literal (parser
, false,
22614 c_parser_error (parser
, "expected identifier or "
22616 return error_mark_node
;
22619 properties
= tree_cons (prop
, value
, properties
);
22621 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22622 c_parser_consume_token (parser
);
22628 case CTX_PROPERTY_EXPR
:
22629 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
22630 if (t
!= error_mark_node
)
22633 t
= c_fully_fold (t
, false, NULL
);
22634 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
22635 || !tree_fits_shwi_p (t
))
22636 error_at (token
->location
, "property must be "
22637 "constant integer expression");
22639 properties
= tree_cons (NULL_TREE
, t
, properties
);
22642 return error_mark_node
;
22644 case CTX_PROPERTY_SIMD
:
22645 if (parms
== NULL_TREE
)
22647 error_at (token
->location
, "properties for %<simd%> "
22648 "selector may not be specified in "
22649 "%<metadirective%>");
22650 return error_mark_node
;
22653 c
= c_parser_omp_all_clauses (parser
,
22654 OMP_DECLARE_SIMD_CLAUSE_MASK
,
22656 c
= c_omp_declare_simd_clauses_to_numbers (parms
22658 ? NULL_TREE
: parms
,
22663 gcc_unreachable ();
22666 parens
.skip_until_found_close (parser
);
22667 properties
= nreverse (properties
);
22669 else if (property_kind
== CTX_PROPERTY_NAME_LIST
22670 || property_kind
== CTX_PROPERTY_ID
22671 || property_kind
== CTX_PROPERTY_EXPR
)
22673 c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>");
22674 return error_mark_node
;
22677 ret
= tree_cons (selector
, properties
, ret
);
22679 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22680 c_parser_consume_token (parser
);
22686 return nreverse (ret
);
22691 trait-set-selector[,trait-set-selector[,...]]
22693 trait-set-selector:
22694 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
22696 trait-set-selector-name:
22703 c_parser_omp_context_selector_specification (c_parser
*parser
, tree parms
)
22705 tree ret
= NULL_TREE
;
22708 const char *setp
= "";
22709 if (c_parser_next_token_is (parser
, CPP_NAME
))
22710 setp
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22714 if (strcmp (setp
, "construct") == 0)
22718 if (strcmp (setp
, "device") == 0)
22722 if (strcmp (setp
, "implementation") == 0)
22726 if (strcmp (setp
, "user") == 0)
22734 c_parser_error (parser
, "expected %<construct%>, %<device%>, "
22735 "%<implementation%> or %<user%>");
22736 return error_mark_node
;
22739 tree set
= c_parser_peek_token (parser
)->value
;
22740 c_parser_consume_token (parser
);
22742 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
22743 return error_mark_node
;
22745 matching_braces braces
;
22746 if (!braces
.require_open (parser
))
22747 return error_mark_node
;
22749 tree selectors
= c_parser_omp_context_selector (parser
, set
, parms
);
22750 if (selectors
== error_mark_node
)
22751 ret
= error_mark_node
;
22752 else if (ret
!= error_mark_node
)
22753 ret
= tree_cons (set
, selectors
, ret
);
22755 braces
.skip_until_found_close (parser
);
22757 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22758 c_parser_consume_token (parser
);
22764 if (ret
== error_mark_node
)
22766 return nreverse (ret
);
22769 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
22770 that into "omp declare variant base" attribute. */
22773 c_finish_omp_declare_variant (c_parser
*parser
, tree fndecl
, tree parms
)
22775 matching_parens parens
;
22776 if (!parens
.require_open (parser
))
22779 c_parser_skip_to_pragma_eol (parser
, false);
22783 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
22784 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
22786 c_parser_error (parser
, "expected identifier");
22790 c_token
*token
= c_parser_peek_token (parser
);
22791 tree variant
= lookup_name (token
->value
);
22793 if (variant
== NULL_TREE
)
22795 undeclared_variable (token
->location
, token
->value
);
22796 variant
= error_mark_node
;
22799 c_parser_consume_token (parser
);
22801 parens
.require_close (parser
);
22803 if (c_parser_next_token_is (parser
, CPP_COMMA
)
22804 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
22805 c_parser_consume_token (parser
);
22807 const char *clause
= "";
22808 location_t match_loc
= c_parser_peek_token (parser
)->location
;
22809 if (c_parser_next_token_is (parser
, CPP_NAME
))
22810 clause
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22811 if (strcmp (clause
, "match"))
22813 c_parser_error (parser
, "expected %<match%>");
22817 c_parser_consume_token (parser
);
22819 if (!parens
.require_open (parser
))
22822 if (parms
== NULL_TREE
)
22823 parms
= error_mark_node
;
22825 tree ctx
= c_parser_omp_context_selector_specification (parser
, parms
);
22826 if (ctx
== error_mark_node
)
22828 ctx
= omp_check_context_selector (match_loc
, ctx
);
22829 if (ctx
!= error_mark_node
&& variant
!= error_mark_node
)
22831 if (TREE_CODE (variant
) != FUNCTION_DECL
)
22833 error_at (token
->location
, "variant %qD is not a function", variant
);
22834 variant
= error_mark_node
;
22836 else if (omp_get_context_selector (ctx
, "construct", "simd") == NULL_TREE
22837 && !comptypes (TREE_TYPE (fndecl
), TREE_TYPE (variant
)))
22839 error_at (token
->location
, "variant %qD and base %qD have "
22840 "incompatible types", variant
, fndecl
);
22841 variant
= error_mark_node
;
22843 else if (fndecl_built_in_p (variant
)
22844 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
22845 "__builtin_", strlen ("__builtin_")) == 0
22846 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
22847 "__sync_", strlen ("__sync_")) == 0
22848 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
22849 "__atomic_", strlen ("__atomic_")) == 0))
22851 error_at (token
->location
, "variant %qD is a built-in", variant
);
22852 variant
= error_mark_node
;
22854 if (variant
!= error_mark_node
)
22856 C_DECL_USED (variant
) = 1;
22857 tree construct
= omp_get_context_selector (ctx
, "construct", NULL
);
22858 omp_mark_declare_variant (match_loc
, variant
, construct
);
22859 if (omp_context_selector_matches (ctx
))
22862 = tree_cons (get_identifier ("omp declare variant base"),
22863 build_tree_list (variant
, ctx
),
22864 DECL_ATTRIBUTES (fndecl
));
22865 DECL_ATTRIBUTES (fndecl
) = attr
;
22870 parens
.require_close (parser
);
22871 c_parser_skip_to_pragma_eol (parser
);
22874 /* Finalize #pragma omp declare simd or #pragma omp declare variant
22875 clauses after FNDECL has been parsed, and put that into "omp declare simd"
22876 or "omp declare variant base" attribute. */
22879 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
22880 vec
<c_token
> *pclauses
)
22882 vec
<c_token
> &clauses
= *pclauses
;
22884 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
22885 indicates error has been reported and CPP_PRAGMA that
22886 c_finish_omp_declare_simd has already processed the tokens. */
22887 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
22889 const char *kind
= "simd";
22890 if (clauses
.exists ()
22891 && (clauses
[0].type
== CPP_NAME
|| clauses
[0].type
== CPP_PRAGMA
))
22892 kind
= IDENTIFIER_POINTER (clauses
[0].value
);
22893 gcc_assert (strcmp (kind
, "simd") == 0 || strcmp (kind
, "variant") == 0);
22894 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
22896 error ("%<#pragma omp declare %s%> not immediately followed by "
22897 "a function declaration or definition", kind
);
22898 clauses
[0].type
= CPP_EOF
;
22901 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
22903 error_at (DECL_SOURCE_LOCATION (fndecl
),
22904 "%<#pragma omp declare %s%> not immediately followed by "
22905 "a single function declaration or definition", kind
);
22906 clauses
[0].type
= CPP_EOF
;
22910 if (parms
== NULL_TREE
)
22911 parms
= DECL_ARGUMENTS (fndecl
);
22913 unsigned int tokens_avail
= parser
->tokens_avail
;
22914 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
22916 parser
->tokens
= clauses
.address ();
22917 parser
->tokens_avail
= clauses
.length ();
22919 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
22920 while (parser
->tokens_avail
> 3)
22922 c_token
*token
= c_parser_peek_token (parser
);
22923 gcc_assert (token
->type
== CPP_NAME
22924 && strcmp (IDENTIFIER_POINTER (token
->value
), kind
) == 0);
22925 c_parser_consume_token (parser
);
22926 parser
->in_pragma
= true;
22928 if (strcmp (kind
, "simd") == 0)
22931 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
22932 "#pragma omp declare simd");
22933 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
22934 if (c
!= NULL_TREE
)
22935 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
22936 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
22937 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
22938 DECL_ATTRIBUTES (fndecl
) = c
;
22942 gcc_assert (strcmp (kind
, "variant") == 0);
22943 c_finish_omp_declare_variant (parser
, fndecl
, parms
);
22947 parser
->tokens
= &parser
->tokens_buf
[0];
22948 parser
->tokens_avail
= tokens_avail
;
22949 if (clauses
.exists ())
22950 clauses
[0].type
= CPP_PRAGMA
;
22955 # pragma omp declare target new-line
22956 declarations and definitions
22957 # pragma omp end declare target new-line
22960 # pragma omp declare target ( extended-list ) new-line
22962 # pragma omp declare target declare-target-clauses[seq] new-line */
22964 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
22965 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
22966 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
22967 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
22968 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
22971 c_parser_omp_declare_target (c_parser
*parser
)
22973 tree clauses
= NULL_TREE
;
22974 int device_type
= 0;
22975 bool only_device_type
= true;
22976 if (c_parser_next_token_is (parser
, CPP_NAME
)
22977 || (c_parser_next_token_is (parser
, CPP_COMMA
)
22978 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
))
22979 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
22980 "#pragma omp declare target");
22981 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
22983 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
22985 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
22986 c_parser_skip_to_pragma_eol (parser
);
22990 c_parser_skip_to_pragma_eol (parser
);
22991 c_omp_declare_target_attr attr
= { -1 };
22992 vec_safe_push (current_omp_declare_target_attribute
, attr
);
22995 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
22996 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
22997 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
22998 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
23000 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
23002 tree t
= OMP_CLAUSE_DECL (c
), id
;
23003 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
23004 tree at2
= lookup_attribute ("omp declare target link",
23005 DECL_ATTRIBUTES (t
));
23006 only_device_type
= false;
23007 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
23009 id
= get_identifier ("omp declare target link");
23010 std::swap (at1
, at2
);
23013 id
= get_identifier ("omp declare target");
23016 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_ENTER
)
23017 error_at (OMP_CLAUSE_LOCATION (c
),
23018 "%qD specified both in declare target %<link%> and %qs"
23019 " clauses", t
, OMP_CLAUSE_ENTER_TO (c
) ? "to" : "enter");
23021 error_at (OMP_CLAUSE_LOCATION (c
),
23022 "%qD specified both in declare target %<link%> and "
23023 "%<to%> or %<enter%> clauses", t
);
23028 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
23029 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
23032 symtab_node
*node
= symtab_node::get (t
);
23035 node
->offloadable
= 1;
23036 if (ENABLE_OFFLOADING
)
23038 g
->have_offload
= true;
23039 if (is_a
<varpool_node
*> (node
))
23040 vec_safe_push (offload_vars
, t
);
23044 if (TREE_CODE (t
) != FUNCTION_DECL
)
23046 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_HOST
) != 0)
23048 tree at3
= lookup_attribute ("omp declare target host",
23049 DECL_ATTRIBUTES (t
));
23050 if (at3
== NULL_TREE
)
23052 id
= get_identifier ("omp declare target host");
23053 DECL_ATTRIBUTES (t
)
23054 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
23057 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_NOHOST
) != 0)
23059 tree at3
= lookup_attribute ("omp declare target nohost",
23060 DECL_ATTRIBUTES (t
));
23061 if (at3
== NULL_TREE
)
23063 id
= get_identifier ("omp declare target nohost");
23064 DECL_ATTRIBUTES (t
)
23065 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
23069 if (device_type
&& only_device_type
)
23070 error_at (OMP_CLAUSE_LOCATION (clauses
),
23071 "directive with only %<device_type%> clause");
23075 #pragma omp begin assumes clauses[optseq] new-line
23077 #pragma omp begin declare target clauses[optseq] new-line */
23079 #define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \
23080 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE)
23083 c_parser_omp_begin (c_parser
*parser
)
23085 const char *p
= "";
23086 c_parser_consume_pragma (parser
);
23087 if (c_parser_next_token_is (parser
, CPP_NAME
))
23088 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23089 if (strcmp (p
, "declare") == 0)
23091 c_parser_consume_token (parser
);
23093 if (c_parser_next_token_is (parser
, CPP_NAME
))
23094 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23095 if (strcmp (p
, "target") == 0)
23097 c_parser_consume_token (parser
);
23099 = c_parser_omp_all_clauses (parser
,
23100 OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK
,
23101 "#pragma omp begin declare target");
23102 int device_type
= 0;
23103 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
23104 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
23105 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
23106 c_omp_declare_target_attr attr
= { device_type
};
23107 vec_safe_push (current_omp_declare_target_attribute
, attr
);
23111 c_parser_error (parser
, "expected %<target%>");
23112 c_parser_skip_to_pragma_eol (parser
);
23115 else if (strcmp (p
, "assumes") == 0)
23117 c_parser_consume_token (parser
);
23118 c_parser_omp_assumption_clauses (parser
, false);
23119 current_omp_begin_assumes
++;
23123 c_parser_error (parser
, "expected %<declare target%> or %<assumes%>");
23124 c_parser_skip_to_pragma_eol (parser
);
23129 #pragma omp end declare target
23132 #pragma omp end assumes */
23135 c_parser_omp_end (c_parser
*parser
)
23137 location_t loc
= c_parser_peek_token (parser
)->location
;
23138 const char *p
= "";
23139 c_parser_consume_pragma (parser
);
23140 if (c_parser_next_token_is (parser
, CPP_NAME
))
23141 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23142 if (strcmp (p
, "declare") == 0)
23144 c_parser_consume_token (parser
);
23145 if (c_parser_next_token_is (parser
, CPP_NAME
)
23146 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
23148 c_parser_consume_token (parser
);
23151 c_parser_error (parser
, "expected %<target%>");
23152 c_parser_skip_to_pragma_eol (parser
);
23155 c_parser_skip_to_pragma_eol (parser
);
23156 if (!vec_safe_length (current_omp_declare_target_attribute
))
23157 error_at (loc
, "%<#pragma omp end declare target%> without "
23158 "corresponding %<#pragma omp declare target%> or "
23159 "%<#pragma omp begin declare target%>");
23161 current_omp_declare_target_attribute
->pop ();
23163 else if (strcmp (p
, "assumes") == 0)
23165 c_parser_consume_token (parser
);
23166 c_parser_skip_to_pragma_eol (parser
);
23167 if (!current_omp_begin_assumes
)
23168 error_at (loc
, "%qs without corresponding %qs",
23169 "#pragma omp end assumes", "#pragma omp begin assumes");
23171 current_omp_begin_assumes
--;
23175 c_parser_error (parser
, "expected %<declare%> or %<assumes%>");
23176 c_parser_skip_to_pragma_eol (parser
);
23181 #pragma omp declare reduction (reduction-id : typename-list : expression) \
23182 initializer-clause[opt] new-line
23184 initializer-clause:
23185 initializer (omp_priv = initializer)
23186 initializer (function-name (argument-list)) */
23189 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
23191 unsigned int tokens_avail
= 0, i
;
23192 vec
<tree
> types
= vNULL
;
23193 vec
<c_token
> clauses
= vNULL
;
23194 enum tree_code reduc_code
= ERROR_MARK
;
23195 tree reduc_id
= NULL_TREE
;
23197 location_t rloc
= c_parser_peek_token (parser
)->location
;
23199 if (context
== pragma_struct
|| context
== pragma_param
)
23201 error ("%<#pragma omp declare reduction%> not at file or block scope");
23205 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
23208 switch (c_parser_peek_token (parser
)->type
)
23211 reduc_code
= PLUS_EXPR
;
23214 reduc_code
= MULT_EXPR
;
23217 reduc_code
= MINUS_EXPR
;
23220 reduc_code
= BIT_AND_EXPR
;
23223 reduc_code
= BIT_XOR_EXPR
;
23226 reduc_code
= BIT_IOR_EXPR
;
23229 reduc_code
= TRUTH_ANDIF_EXPR
;
23232 reduc_code
= TRUTH_ORIF_EXPR
;
23236 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23237 if (strcmp (p
, "min") == 0)
23239 reduc_code
= MIN_EXPR
;
23242 if (strcmp (p
, "max") == 0)
23244 reduc_code
= MAX_EXPR
;
23247 reduc_id
= c_parser_peek_token (parser
)->value
;
23250 c_parser_error (parser
,
23251 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
23252 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
23256 tree orig_reduc_id
, reduc_decl
;
23257 orig_reduc_id
= reduc_id
;
23258 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
23259 reduc_decl
= c_omp_reduction_decl (reduc_id
);
23260 c_parser_consume_token (parser
);
23262 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
23267 location_t loc
= c_parser_peek_token (parser
)->location
;
23268 struct c_type_name
*ctype
= c_parser_type_name (parser
);
23271 type
= groktypename (ctype
, NULL
, NULL
);
23272 if (type
== error_mark_node
)
23274 else if ((INTEGRAL_TYPE_P (type
)
23275 || TREE_CODE (type
) == REAL_TYPE
23276 || TREE_CODE (type
) == COMPLEX_TYPE
)
23277 && orig_reduc_id
== NULL_TREE
)
23278 error_at (loc
, "predeclared arithmetic type in "
23279 "%<#pragma omp declare reduction%>");
23280 else if (TREE_CODE (type
) == FUNCTION_TYPE
23281 || TREE_CODE (type
) == ARRAY_TYPE
)
23282 error_at (loc
, "function or array type in "
23283 "%<#pragma omp declare reduction%>");
23284 else if (TYPE_ATOMIC (type
))
23285 error_at (loc
, "%<_Atomic%> qualified type in "
23286 "%<#pragma omp declare reduction%>");
23287 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
23288 error_at (loc
, "const, volatile or restrict qualified type in "
23289 "%<#pragma omp declare reduction%>");
23293 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
23294 if (comptypes (TREE_PURPOSE (t
), type
))
23296 error_at (loc
, "redeclaration of %qs "
23297 "%<#pragma omp declare reduction%> for "
23299 IDENTIFIER_POINTER (reduc_id
)
23300 + sizeof ("omp declare reduction ") - 1,
23303 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
23305 error_at (ploc
, "previous %<#pragma omp declare "
23309 if (t
== NULL_TREE
)
23310 types
.safe_push (type
);
23312 if (c_parser_next_token_is (parser
, CPP_COMMA
))
23313 c_parser_consume_token (parser
);
23321 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
23322 || types
.is_empty ())
23325 clauses
.release ();
23329 c_token
*token
= c_parser_peek_token (parser
);
23330 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
23332 c_parser_consume_token (parser
);
23334 c_parser_skip_to_pragma_eol (parser
);
23338 if (types
.length () > 1)
23340 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
23342 c_token
*token
= c_parser_peek_token (parser
);
23343 if (token
->type
== CPP_EOF
)
23345 clauses
.safe_push (*token
);
23346 c_parser_consume_token (parser
);
23348 clauses
.safe_push (*c_parser_peek_token (parser
));
23349 c_parser_skip_to_pragma_eol (parser
);
23351 /* Make sure nothing tries to read past the end of the tokens. */
23353 memset (&eof_token
, 0, sizeof (eof_token
));
23354 eof_token
.type
= CPP_EOF
;
23355 clauses
.safe_push (eof_token
);
23356 clauses
.safe_push (eof_token
);
23359 int errs
= errorcount
;
23360 FOR_EACH_VEC_ELT (types
, i
, type
)
23362 tokens_avail
= parser
->tokens_avail
;
23363 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
23364 if (!clauses
.is_empty ())
23366 parser
->tokens
= clauses
.address ();
23367 parser
->tokens_avail
= clauses
.length ();
23368 parser
->in_pragma
= true;
23371 bool nested
= current_function_decl
!= NULL_TREE
;
23373 c_push_function_context ();
23374 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
23375 reduc_id
, default_function_type
);
23376 current_function_decl
= fndecl
;
23377 allocate_struct_function (fndecl
, true);
23379 tree stmt
= push_stmt_list ();
23380 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
23381 warn about these. */
23382 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
23383 get_identifier ("omp_out"), type
);
23384 DECL_ARTIFICIAL (omp_out
) = 1;
23385 DECL_CONTEXT (omp_out
) = fndecl
;
23386 pushdecl (omp_out
);
23387 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
23388 get_identifier ("omp_in"), type
);
23389 DECL_ARTIFICIAL (omp_in
) = 1;
23390 DECL_CONTEXT (omp_in
) = fndecl
;
23392 struct c_expr combiner
= c_parser_expression (parser
);
23393 struct c_expr initializer
;
23394 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
23396 initializer
.set_error ();
23397 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
23399 else if (c_parser_next_token_is (parser
, CPP_COMMA
)
23400 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
23401 c_parser_consume_token (parser
);
23403 && (c_parser_next_token_is (parser
, CPP_NAME
)
23404 && strcmp (IDENTIFIER_POINTER
23405 (c_parser_peek_token (parser
)->value
),
23406 "initializer") == 0))
23408 c_parser_consume_token (parser
);
23411 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
23412 get_identifier ("omp_priv"), type
);
23413 DECL_ARTIFICIAL (omp_priv
) = 1;
23414 DECL_INITIAL (omp_priv
) = error_mark_node
;
23415 DECL_CONTEXT (omp_priv
) = fndecl
;
23416 pushdecl (omp_priv
);
23417 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
23418 get_identifier ("omp_orig"), type
);
23419 DECL_ARTIFICIAL (omp_orig
) = 1;
23420 DECL_CONTEXT (omp_orig
) = fndecl
;
23421 pushdecl (omp_orig
);
23422 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
23424 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
23426 c_parser_error (parser
, "expected %<omp_priv%> or "
23430 else if (strcmp (IDENTIFIER_POINTER
23431 (c_parser_peek_token (parser
)->value
),
23434 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
23435 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
23437 c_parser_error (parser
, "expected function-name %<(%>");
23441 initializer
= c_parser_postfix_expression (parser
);
23442 if (initializer
.value
23443 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
23446 tree c
= initializer
.value
;
23447 for (j
= 0; j
< call_expr_nargs (c
); j
++)
23449 tree a
= CALL_EXPR_ARG (c
, j
);
23451 if (TREE_CODE (a
) == ADDR_EXPR
23452 && TREE_OPERAND (a
, 0) == omp_priv
)
23455 if (j
== call_expr_nargs (c
))
23456 error ("one of the initializer call arguments should be "
23462 c_parser_consume_token (parser
);
23463 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
23467 tree st
= push_stmt_list ();
23468 location_t loc
= c_parser_peek_token (parser
)->location
;
23469 rich_location
richloc (line_table
, loc
);
23470 start_init (omp_priv
, NULL_TREE
, false, false, &richloc
);
23471 struct c_expr init
= c_parser_initializer (parser
, omp_priv
);
23473 finish_decl (omp_priv
, loc
, init
.value
,
23474 init
.original_type
, NULL_TREE
);
23475 pop_stmt_list (st
);
23479 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
23485 c_parser_skip_to_pragma_eol (parser
);
23487 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
23488 DECL_INITIAL (reduc_decl
));
23489 DECL_INITIAL (reduc_decl
) = t
;
23490 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
23491 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
23492 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
23493 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
23494 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
23495 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
23498 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
23499 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
23500 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
23501 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
23502 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
23503 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
23504 walk_tree (&DECL_INITIAL (omp_priv
),
23505 c_check_omp_declare_reduction_r
,
23506 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
23510 pop_stmt_list (stmt
);
23512 if (cfun
->language
!= NULL
)
23514 ggc_free (cfun
->language
);
23515 cfun
->language
= NULL
;
23518 current_function_decl
= NULL_TREE
;
23520 c_pop_function_context ();
23522 if (!clauses
.is_empty ())
23524 parser
->tokens
= &parser
->tokens_buf
[0];
23525 parser
->tokens_avail
= tokens_avail
;
23529 if (errs
!= errorcount
)
23533 clauses
.release ();
23539 #pragma omp declare simd declare-simd-clauses[optseq] new-line
23540 #pragma omp declare reduction (reduction-id : typename-list : expression) \
23541 initializer-clause[opt] new-line
23542 #pragma omp declare target new-line
23545 #pragma omp declare variant (identifier) match (context-selector) */
23548 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
23550 c_parser_consume_pragma (parser
);
23551 if (c_parser_next_token_is (parser
, CPP_NAME
))
23553 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23554 if (strcmp (p
, "simd") == 0)
23556 /* c_parser_consume_token (parser); done in
23557 c_parser_omp_declare_simd. */
23558 c_parser_omp_declare_simd (parser
, context
);
23561 if (strcmp (p
, "reduction") == 0)
23563 c_parser_consume_token (parser
);
23564 c_parser_omp_declare_reduction (parser
, context
);
23567 if (!flag_openmp
) /* flag_openmp_simd */
23569 c_parser_skip_to_pragma_eol (parser
, false);
23572 if (strcmp (p
, "target") == 0)
23574 c_parser_consume_token (parser
);
23575 c_parser_omp_declare_target (parser
);
23578 if (strcmp (p
, "variant") == 0)
23580 /* c_parser_consume_token (parser); done in
23581 c_parser_omp_declare_simd. */
23582 c_parser_omp_declare_simd (parser
, context
);
23587 c_parser_error (parser
, "expected %<simd%>, %<reduction%>, "
23588 "%<target%> or %<variant%>");
23589 c_parser_skip_to_pragma_eol (parser
);
23594 #pragma omp requires clauses[optseq] new-line */
23597 c_parser_omp_requires (c_parser
*parser
)
23599 enum omp_requires new_req
= (enum omp_requires
) 0;
23601 c_parser_consume_pragma (parser
);
23603 location_t loc
= c_parser_peek_token (parser
)->location
;
23604 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
23606 if (c_parser_next_token_is (parser
, CPP_COMMA
)
23607 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
23608 c_parser_consume_token (parser
);
23610 if (c_parser_next_token_is (parser
, CPP_NAME
))
23613 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23614 location_t cloc
= c_parser_peek_token (parser
)->location
;
23615 enum omp_requires this_req
= (enum omp_requires
) 0;
23617 if (!strcmp (p
, "unified_address"))
23618 this_req
= OMP_REQUIRES_UNIFIED_ADDRESS
;
23619 else if (!strcmp (p
, "unified_shared_memory"))
23620 this_req
= OMP_REQUIRES_UNIFIED_SHARED_MEMORY
;
23621 else if (!strcmp (p
, "dynamic_allocators"))
23622 this_req
= OMP_REQUIRES_DYNAMIC_ALLOCATORS
;
23623 else if (!strcmp (p
, "reverse_offload"))
23624 this_req
= OMP_REQUIRES_REVERSE_OFFLOAD
;
23625 else if (!strcmp (p
, "atomic_default_mem_order"))
23627 c_parser_consume_token (parser
);
23629 matching_parens parens
;
23630 if (parens
.require_open (parser
))
23632 if (c_parser_next_token_is (parser
, CPP_NAME
))
23634 tree v
= c_parser_peek_token (parser
)->value
;
23635 p
= IDENTIFIER_POINTER (v
);
23637 if (!strcmp (p
, "seq_cst"))
23639 = (enum omp_requires
) OMP_MEMORY_ORDER_SEQ_CST
;
23640 else if (!strcmp (p
, "relaxed"))
23642 = (enum omp_requires
) OMP_MEMORY_ORDER_RELAXED
;
23643 else if (!strcmp (p
, "acq_rel"))
23645 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQ_REL
;
23649 error_at (c_parser_peek_token (parser
)->location
,
23650 "expected %<seq_cst%>, %<relaxed%> or "
23652 switch (c_parser_peek_token (parser
)->type
)
23655 case CPP_PRAGMA_EOL
:
23656 case CPP_CLOSE_PAREN
:
23659 if (c_parser_peek_2nd_token (parser
)->type
23660 == CPP_CLOSE_PAREN
)
23661 c_parser_consume_token (parser
);
23666 c_parser_consume_token (parser
);
23668 parens
.skip_until_found_close (parser
);
23671 c_parser_skip_to_pragma_eol (parser
, false);
23679 error_at (cloc
, "expected %<unified_address%>, "
23680 "%<unified_shared_memory%>, "
23681 "%<dynamic_allocators%>, "
23682 "%<reverse_offload%> "
23683 "or %<atomic_default_mem_order%> clause");
23684 c_parser_skip_to_pragma_eol (parser
, false);
23688 c_parser_consume_token (parser
);
23691 if ((this_req
& ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
23693 if ((this_req
& new_req
) != 0)
23694 error_at (cloc
, "too many %qs clauses", p
);
23695 if (this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
23696 && (omp_requires_mask
& OMP_REQUIRES_TARGET_USED
) != 0)
23697 error_at (cloc
, "%qs clause used lexically after first "
23698 "target construct or offloading API", p
);
23700 else if ((new_req
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
23702 error_at (cloc
, "too many %qs clauses",
23703 "atomic_default_mem_order");
23704 this_req
= (enum omp_requires
) 0;
23706 else if ((omp_requires_mask
23707 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
23709 error_at (cloc
, "more than one %<atomic_default_mem_order%>"
23710 " clause in a single compilation unit");
23712 = (enum omp_requires
)
23714 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
);
23716 else if ((omp_requires_mask
23717 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
) != 0)
23718 error_at (cloc
, "%<atomic_default_mem_order%> clause used "
23719 "lexically after first %<atomic%> construct "
23720 "without memory order clause");
23721 new_req
= (enum omp_requires
) (new_req
| this_req
);
23723 = (enum omp_requires
) (omp_requires_mask
| this_req
);
23729 c_parser_skip_to_pragma_eol (parser
);
23732 error_at (loc
, "%<pragma omp requires%> requires at least one clause");
23735 /* Helper function for c_parser_omp_taskloop.
23736 Disallow zero sized or potentially zero sized task reductions. */
23739 c_finish_taskloop_clauses (tree clauses
)
23741 tree
*pc
= &clauses
;
23742 for (tree c
= clauses
; c
; c
= *pc
)
23744 bool remove
= false;
23745 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
23747 tree type
= strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
23748 if (integer_zerop (TYPE_SIZE_UNIT (type
)))
23750 error_at (OMP_CLAUSE_LOCATION (c
),
23751 "zero sized type %qT in %<reduction%> clause", type
);
23754 else if (TREE_CODE (TYPE_SIZE_UNIT (type
)) != INTEGER_CST
)
23756 error_at (OMP_CLAUSE_LOCATION (c
),
23757 "variable sized type %qT in %<reduction%> clause",
23763 *pc
= OMP_CLAUSE_CHAIN (c
);
23765 pc
= &OMP_CLAUSE_CHAIN (c
);
23771 #pragma omp taskloop taskloop-clause[optseq] new-line
23774 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
23777 #define OMP_TASKLOOP_CLAUSE_MASK \
23778 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23779 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23780 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23781 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23782 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23783 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
23784 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
23785 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23786 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
23787 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23788 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
23789 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
23790 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
23791 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
23792 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23793 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23794 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
23797 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
23798 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23801 tree clauses
, block
, ret
;
23803 strcat (p_name
, " taskloop");
23804 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
23805 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
23807 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
)) != 0)
23808 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_IN_REDUCTION
);
23810 if (c_parser_next_token_is (parser
, CPP_NAME
))
23812 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23814 if (strcmp (p
, "simd") == 0)
23816 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23817 if (cclauses
== NULL
)
23818 cclauses
= cclauses_buf
;
23819 c_parser_consume_token (parser
);
23820 if (!flag_openmp
) /* flag_openmp_simd */
23821 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
23823 block
= c_begin_compound_stmt (true);
23824 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
23825 block
= c_end_compound_stmt (loc
, block
, true);
23828 ret
= make_node (OMP_TASKLOOP
);
23829 TREE_TYPE (ret
) = void_type_node
;
23830 OMP_FOR_BODY (ret
) = block
;
23831 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
23832 OMP_FOR_CLAUSES (ret
)
23833 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret
));
23834 SET_EXPR_LOCATION (ret
, loc
);
23839 if (!flag_openmp
) /* flag_openmp_simd */
23841 c_parser_skip_to_pragma_eol (parser
, false);
23845 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23848 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
23849 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
23852 clauses
= c_finish_taskloop_clauses (clauses
);
23853 block
= c_begin_compound_stmt (true);
23854 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
23855 block
= c_end_compound_stmt (loc
, block
, true);
23862 #pragma omp nothing new-line */
23865 c_parser_omp_nothing (c_parser
*parser
)
23867 c_parser_consume_pragma (parser
);
23868 c_parser_skip_to_pragma_eol (parser
);
23872 #pragma omp error clauses[optseq] new-line */
23875 c_parser_omp_error (c_parser
*parser
, enum pragma_context context
)
23877 int at_compilation
= -1;
23878 int severity_fatal
= -1;
23879 tree message
= NULL_TREE
;
23881 location_t loc
= c_parser_peek_token (parser
)->location
;
23883 c_parser_consume_pragma (parser
);
23885 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
23887 if (c_parser_next_token_is (parser
, CPP_COMMA
)
23888 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
23889 c_parser_consume_token (parser
);
23891 if (!c_parser_next_token_is (parser
, CPP_NAME
))
23895 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23896 location_t cloc
= c_parser_peek_token (parser
)->location
;
23897 static const char *args
[] = {
23898 "execution", "compilation", "warning", "fatal"
23901 int idx
= 0, n
= -1;
23902 tree m
= NULL_TREE
;
23904 if (!strcmp (p
, "at"))
23905 v
= &at_compilation
;
23906 else if (!strcmp (p
, "severity"))
23908 v
= &severity_fatal
;
23911 else if (strcmp (p
, "message"))
23914 "expected %<at%>, %<severity%> or %<message%> clause");
23915 c_parser_skip_to_pragma_eol (parser
, false);
23919 c_parser_consume_token (parser
);
23921 matching_parens parens
;
23922 if (parens
.require_open (parser
))
23926 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
23927 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
23928 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
23929 m
= convert (const_string_type_node
, expr
.value
);
23930 m
= c_fully_fold (m
, false, NULL
);
23934 if (c_parser_next_token_is (parser
, CPP_NAME
))
23936 tree val
= c_parser_peek_token (parser
)->value
;
23937 const char *q
= IDENTIFIER_POINTER (val
);
23939 if (!strcmp (q
, args
[idx
]))
23941 else if (!strcmp (q
, args
[idx
+ 1]))
23946 error_at (c_parser_peek_token (parser
)->location
,
23947 "expected %qs or %qs", args
[idx
], args
[idx
+ 1]);
23949 switch (c_parser_peek_token (parser
)->type
)
23952 case CPP_PRAGMA_EOL
:
23953 case CPP_CLOSE_PAREN
:
23956 if (c_parser_peek_2nd_token (parser
)->type
23957 == CPP_CLOSE_PAREN
)
23958 c_parser_consume_token (parser
);
23963 c_parser_consume_token (parser
);
23966 parens
.skip_until_found_close (parser
);
23972 error_at (cloc
, "too many %qs clauses", p
);
23982 error_at (cloc
, "too many %qs clauses", p
);
23992 c_parser_skip_to_pragma_eol (parser
);
23996 if (at_compilation
== -1)
23997 at_compilation
= 1;
23998 if (severity_fatal
== -1)
23999 severity_fatal
= 1;
24000 if (!at_compilation
)
24002 if (context
!= pragma_compound
)
24004 error_at (loc
, "%<#pragma omp error%> with %<at(execution)%> clause "
24005 "may only be used in compound statements");
24009 = builtin_decl_explicit (severity_fatal
? BUILT_IN_GOMP_ERROR
24010 : BUILT_IN_GOMP_WARNING
);
24012 message
= build_zero_cst (const_string_type_node
);
24013 tree stmt
= build_call_expr_loc (loc
, fndecl
, 2, message
,
24014 build_all_ones_cst (size_type_node
));
24018 const char *msg
= NULL
;
24021 msg
= c_getstr (message
);
24023 msg
= _("<message unknown at compile time>");
24026 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
24027 "%<pragma omp error%> encountered: %s", msg
);
24029 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
24030 "%<pragma omp error%> encountered");
24034 /* Assumption clauses:
24036 absent (directive-name-list)
24037 contains (directive-name-list)
24044 c_parser_omp_assumption_clauses (c_parser
*parser
, bool is_assume
)
24046 bool no_openmp
= false;
24047 bool no_openmp_routines
= false;
24048 bool no_parallelism
= false;
24049 bitmap_head absent_head
, contains_head
;
24051 bitmap_obstack_initialize (NULL
);
24052 bitmap_initialize (&absent_head
, &bitmap_default_obstack
);
24053 bitmap_initialize (&contains_head
, &bitmap_default_obstack
);
24055 if (c_parser_next_token_is (parser
, CPP_PRAGMA_EOL
))
24056 error_at (c_parser_peek_token (parser
)->location
,
24057 "expected at least one assumption clause");
24059 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
24061 if (c_parser_next_token_is (parser
, CPP_COMMA
)
24062 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
24063 c_parser_consume_token (parser
);
24065 if (!c_parser_next_token_is (parser
, CPP_NAME
))
24069 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
24070 location_t cloc
= c_parser_peek_token (parser
)->location
;
24072 if (!strcmp (p
, "no_openmp"))
24074 c_parser_consume_token (parser
);
24076 error_at (cloc
, "too many %qs clauses", "no_openmp");
24079 else if (!strcmp (p
, "no_openmp_routines"))
24081 c_parser_consume_token (parser
);
24082 if (no_openmp_routines
)
24083 error_at (cloc
, "too many %qs clauses", "no_openmp_routines");
24084 no_openmp_routines
= true;
24086 else if (!strcmp (p
, "no_parallelism"))
24088 c_parser_consume_token (parser
);
24089 if (no_parallelism
)
24090 error_at (cloc
, "too many %qs clauses", "no_parallelism");
24091 no_parallelism
= true;
24093 else if (!strcmp (p
, "holds"))
24095 c_parser_consume_token (parser
);
24096 matching_parens parens
;
24097 if (parens
.require_open (parser
))
24099 location_t eloc
= c_parser_peek_token (parser
)->location
;
24100 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
24101 tree t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
24102 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
24103 t
= c_fully_fold (t
, false, NULL
);
24104 if (is_assume
&& t
!= error_mark_node
)
24106 tree fn
= build_call_expr_internal_loc (eloc
, IFN_ASSUME
,
24111 parens
.skip_until_found_close (parser
);
24114 else if (!strcmp (p
, "absent") || !strcmp (p
, "contains"))
24116 c_parser_consume_token (parser
);
24117 matching_parens parens
;
24118 if (parens
.require_open (parser
))
24122 const char *directive
[3] = {};
24124 location_t dloc
= c_parser_peek_token (parser
)->location
;
24125 for (i
= 0; i
< 3; i
++)
24128 if (c_parser_peek_nth_token (parser
, i
+ 1)->type
24130 id
= c_parser_peek_nth_token (parser
, i
+ 1)->value
;
24131 else if (c_parser_peek_nth_token (parser
, i
+ 1)->keyword
24135 = c_parser_peek_nth_token (parser
, i
+ 1)->keyword
;
24136 id
= ridpointers
[rid
];
24140 directive
[i
] = IDENTIFIER_POINTER (id
);
24143 error_at (dloc
, "expected directive name");
24146 const struct c_omp_directive
*dir
24147 = c_omp_categorize_directive (directive
[0],
24151 || dir
->kind
== C_OMP_DIR_DECLARATIVE
24152 || dir
->kind
== C_OMP_DIR_INFORMATIONAL
24153 || dir
->id
== PRAGMA_OMP_END
24154 || (!dir
->second
&& directive
[1])
24155 || (!dir
->third
&& directive
[2]))
24156 error_at (dloc
, "unknown OpenMP directive name in "
24157 "%qs clause argument", p
);
24160 int id
= dir
- c_omp_directives
;
24161 if (bitmap_bit_p (p
[0] == 'a' ? &contains_head
24162 : &absent_head
, id
))
24163 error_at (dloc
, "%<%s%s%s%s%s%> directive "
24164 "mentioned in both %<absent%> and "
24165 "%<contains%> clauses",
24167 directive
[1] ? " " : "",
24168 directive
[1] ? directive
[1] : "",
24169 directive
[2] ? " " : "",
24170 directive
[2] ? directive
[2] : "");
24171 else if (!bitmap_set_bit (p
[0] == 'a'
24173 : &contains_head
, id
))
24174 error_at (dloc
, "%<%s%s%s%s%s%> directive "
24175 "mentioned multiple times in %qs "
24178 directive
[1] ? " " : "",
24179 directive
[1] ? directive
[1] : "",
24180 directive
[2] ? " " : "",
24181 directive
[2] ? directive
[2] : "", p
);
24184 c_parser_consume_token (parser
);
24186 if (c_parser_next_token_is (parser
, CPP_COMMA
))
24187 c_parser_consume_token (parser
);
24192 parens
.skip_until_found_close (parser
);
24195 else if (startswith (p
, "ext_"))
24197 warning_at (cloc
, 0, "unknown assumption clause %qs", p
);
24198 c_parser_consume_token (parser
);
24199 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
24201 matching_parens parens
;
24202 parens
.consume_open (parser
);
24203 c_parser_balanced_token_sequence (parser
);
24204 parens
.require_close (parser
);
24209 c_parser_consume_token (parser
);
24210 error_at (cloc
, "expected assumption clause");
24214 c_parser_skip_to_pragma_eol (parser
);
24218 #pragma omp assume clauses[optseq] new-line */
24221 c_parser_omp_assume (c_parser
*parser
, bool *if_p
)
24223 c_parser_omp_assumption_clauses (parser
, true);
24224 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
24228 #pragma omp assumes clauses[optseq] new-line */
24231 c_parser_omp_assumes (c_parser
*parser
)
24233 c_parser_consume_pragma (parser
);
24234 c_parser_omp_assumption_clauses (parser
, false);
24237 /* Main entry point to parsing most OpenMP pragmas. */
24240 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
24242 enum pragma_kind p_kind
;
24245 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
24246 omp_clause_mask
mask (0);
24248 loc
= c_parser_peek_token (parser
)->location
;
24249 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
24250 c_parser_consume_pragma (parser
);
24254 case PRAGMA_OACC_ATOMIC
:
24255 c_parser_omp_atomic (loc
, parser
, true);
24257 case PRAGMA_OACC_CACHE
:
24258 strcpy (p_name
, "#pragma acc");
24259 stmt
= c_parser_oacc_cache (loc
, parser
);
24261 case PRAGMA_OACC_DATA
:
24262 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
24264 case PRAGMA_OACC_HOST_DATA
:
24265 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
24267 case PRAGMA_OACC_KERNELS
:
24268 case PRAGMA_OACC_PARALLEL
:
24269 case PRAGMA_OACC_SERIAL
:
24270 strcpy (p_name
, "#pragma acc");
24271 stmt
= c_parser_oacc_compute (loc
, parser
, p_kind
, p_name
, if_p
);
24273 case PRAGMA_OACC_LOOP
:
24274 strcpy (p_name
, "#pragma acc");
24275 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
24277 case PRAGMA_OACC_WAIT
:
24278 strcpy (p_name
, "#pragma wait");
24279 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
24281 case PRAGMA_OMP_ALLOCATE
:
24282 c_parser_omp_allocate (loc
, parser
);
24284 case PRAGMA_OMP_ATOMIC
:
24285 c_parser_omp_atomic (loc
, parser
, false);
24287 case PRAGMA_OMP_CRITICAL
:
24288 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
24290 case PRAGMA_OMP_DISTRIBUTE
:
24291 strcpy (p_name
, "#pragma omp");
24292 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
24294 case PRAGMA_OMP_FOR
:
24295 strcpy (p_name
, "#pragma omp");
24296 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
24298 case PRAGMA_OMP_LOOP
:
24299 strcpy (p_name
, "#pragma omp");
24300 stmt
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
24302 case PRAGMA_OMP_MASKED
:
24303 strcpy (p_name
, "#pragma omp");
24304 stmt
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, NULL
, if_p
);
24306 case PRAGMA_OMP_MASTER
:
24307 strcpy (p_name
, "#pragma omp");
24308 stmt
= c_parser_omp_master (loc
, parser
, p_name
, mask
, NULL
, if_p
);
24310 case PRAGMA_OMP_PARALLEL
:
24311 strcpy (p_name
, "#pragma omp");
24312 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
24314 case PRAGMA_OMP_SCOPE
:
24315 stmt
= c_parser_omp_scope (loc
, parser
, if_p
);
24317 case PRAGMA_OMP_SECTIONS
:
24318 strcpy (p_name
, "#pragma omp");
24319 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
24321 case PRAGMA_OMP_SIMD
:
24322 strcpy (p_name
, "#pragma omp");
24323 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
24325 case PRAGMA_OMP_SINGLE
:
24326 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
24328 case PRAGMA_OMP_TASK
:
24329 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
24331 case PRAGMA_OMP_TASKGROUP
:
24332 stmt
= c_parser_omp_taskgroup (loc
, parser
, if_p
);
24334 case PRAGMA_OMP_TASKLOOP
:
24335 strcpy (p_name
, "#pragma omp");
24336 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
24338 case PRAGMA_OMP_TEAMS
:
24339 strcpy (p_name
, "#pragma omp");
24340 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
24342 case PRAGMA_OMP_ASSUME
:
24343 c_parser_omp_assume (parser
, if_p
);
24346 gcc_unreachable ();
24349 if (stmt
&& stmt
!= error_mark_node
)
24350 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
24355 # pragma omp threadprivate (variable-list) */
24358 c_parser_omp_threadprivate (c_parser
*parser
)
24363 c_parser_consume_pragma (parser
);
24364 loc
= c_parser_peek_token (parser
)->location
;
24365 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
24367 /* Mark every variable in VARS to be assigned thread local storage. */
24368 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
24370 tree v
= TREE_PURPOSE (t
);
24372 /* FIXME diagnostics: Ideally we should keep individual
24373 locations for all the variables in the var list to make the
24374 following errors more precise. Perhaps
24375 c_parser_omp_var_list_parens() should construct a list of
24376 locations to go along with the var list. */
24378 /* If V had already been marked threadprivate, it doesn't matter
24379 whether it had been used prior to this point. */
24381 error_at (loc
, "%qD is not a variable", v
);
24382 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
24383 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
24384 else if (! is_global_var (v
))
24385 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
24386 else if (TREE_TYPE (v
) == error_mark_node
)
24388 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
24389 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
24392 if (! DECL_THREAD_LOCAL_P (v
))
24394 set_decl_tls_model (v
, decl_default_tls_model (v
));
24395 /* If rtl has been already set for this var, call
24396 make_decl_rtl once again, so that encode_section_info
24397 has a chance to look at the new decl flags. */
24398 if (DECL_RTL_SET_P (v
))
24401 C_DECL_THREADPRIVATE_P (v
) = 1;
24405 c_parser_skip_to_pragma_eol (parser
);
24408 /* Parse a transaction attribute (GCC Extension).
24410 transaction-attribute:
24412 attribute-specifier
24416 c_parser_transaction_attributes (c_parser
*parser
)
24418 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
24419 return c_parser_gnu_attributes (parser
);
24421 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
24423 return c_parser_std_attribute_specifier (parser
, true);
24426 /* Parse a __transaction_atomic or __transaction_relaxed statement
24429 transaction-statement:
24430 __transaction_atomic transaction-attribute[opt] compound-statement
24431 __transaction_relaxed compound-statement
24433 Note that the only valid attribute is: "outer".
24437 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
24439 unsigned int old_in
= parser
->in_transaction
;
24440 unsigned int this_in
= 1, new_in
;
24441 location_t loc
= c_parser_peek_token (parser
)->location
;
24444 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
24445 || keyword
== RID_TRANSACTION_RELAXED
)
24446 && c_parser_next_token_is_keyword (parser
, keyword
));
24447 c_parser_consume_token (parser
);
24449 if (keyword
== RID_TRANSACTION_RELAXED
)
24450 this_in
|= TM_STMT_ATTR_RELAXED
;
24453 attrs
= c_parser_transaction_attributes (parser
);
24455 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
24458 /* Keep track if we're in the lexical scope of an outer transaction. */
24459 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
24461 parser
->in_transaction
= new_in
;
24462 stmt
= c_parser_compound_statement (parser
);
24463 parser
->in_transaction
= old_in
;
24466 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
24468 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
24469 "%<__transaction_atomic%> without transactional memory support enabled"
24470 : "%<__transaction_relaxed %> "
24471 "without transactional memory support enabled"));
24476 /* Parse a __transaction_atomic or __transaction_relaxed expression
24479 transaction-expression:
24480 __transaction_atomic ( expression )
24481 __transaction_relaxed ( expression )
24484 static struct c_expr
24485 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
24488 unsigned int old_in
= parser
->in_transaction
;
24489 unsigned int this_in
= 1;
24490 location_t loc
= c_parser_peek_token (parser
)->location
;
24493 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
24494 || keyword
== RID_TRANSACTION_RELAXED
)
24495 && c_parser_next_token_is_keyword (parser
, keyword
));
24496 c_parser_consume_token (parser
);
24498 if (keyword
== RID_TRANSACTION_RELAXED
)
24499 this_in
|= TM_STMT_ATTR_RELAXED
;
24502 attrs
= c_parser_transaction_attributes (parser
);
24504 this_in
|= parse_tm_stmt_attr (attrs
, 0);
24507 parser
->in_transaction
= this_in
;
24508 matching_parens parens
;
24509 if (parens
.require_open (parser
))
24511 tree expr
= c_parser_expression (parser
).value
;
24512 ret
.original_type
= TREE_TYPE (expr
);
24513 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
24514 if (this_in
& TM_STMT_ATTR_RELAXED
)
24515 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
24516 SET_EXPR_LOCATION (ret
.value
, loc
);
24517 ret
.original_code
= TRANSACTION_EXPR
;
24519 if (!parens
.require_close (parser
))
24521 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
24529 ret
.original_code
= ERROR_MARK
;
24530 ret
.original_type
= NULL
;
24532 parser
->in_transaction
= old_in
;
24535 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
24536 "%<__transaction_atomic%> without transactional memory support enabled"
24537 : "%<__transaction_relaxed %> "
24538 "without transactional memory support enabled"));
24540 set_c_expr_source_range (&ret
, loc
, loc
);
24545 /* Parse a __transaction_cancel statement (GCC Extension).
24547 transaction-cancel-statement:
24548 __transaction_cancel transaction-attribute[opt] ;
24550 Note that the only valid attribute is "outer".
24554 c_parser_transaction_cancel (c_parser
*parser
)
24556 location_t loc
= c_parser_peek_token (parser
)->location
;
24558 bool is_outer
= false;
24560 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
24561 c_parser_consume_token (parser
);
24563 attrs
= c_parser_transaction_attributes (parser
);
24565 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
24569 error_at (loc
, "%<__transaction_cancel%> without "
24570 "transactional memory support enabled");
24573 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
24575 error_at (loc
, "%<__transaction_cancel%> within a "
24576 "%<__transaction_relaxed%>");
24581 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
24582 && !is_tm_may_cancel_outer (current_function_decl
))
24584 error_at (loc
, "outer %<__transaction_cancel%> not "
24585 "within outer %<__transaction_atomic%> or "
24586 "a %<transaction_may_cancel_outer%> function");
24590 else if (parser
->in_transaction
== 0)
24592 error_at (loc
, "%<__transaction_cancel%> not within "
24593 "%<__transaction_atomic%>");
24597 return add_stmt (build_tm_abort_call (loc
, is_outer
));
24600 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
24603 /* Parse a single source file. */
24606 c_parse_file (void)
24608 /* Use local storage to begin. If the first token is a pragma, parse it.
24609 If it is #pragma GCC pch_preprocess, then this will load a PCH file
24610 which will cause garbage collection. */
24613 memset (&tparser
, 0, sizeof tparser
);
24614 tparser
.translate_strings_p
= true;
24615 tparser
.tokens
= &tparser
.tokens_buf
[0];
24616 the_parser
= &tparser
;
24618 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
24619 c_parser_pragma_pch_preprocess (&tparser
);
24621 c_common_no_more_pch ();
24623 the_parser
= ggc_alloc
<c_parser
> ();
24624 *the_parser
= tparser
;
24625 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
24626 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
24628 /* Initialize EH, if we've been told to do so. */
24629 if (flag_exceptions
)
24630 using_eh_for_cleanups ();
24632 c_parser_translation_unit (the_parser
);
24636 /* Parse the body of a function declaration marked with "__RTL".
24638 The RTL parser works on the level of characters read from a
24639 FILE *, whereas c_parser works at the level of tokens.
24640 Square this circle by consuming all of the tokens up to and
24641 including the closing brace, recording the start/end of the RTL
24642 fragment, and reopening the file and re-reading the relevant
24643 lines within the RTL parser.
24645 This requires the opening and closing braces of the C function
24646 to be on separate lines from the RTL they wrap.
24648 Take ownership of START_WITH_PASS, if non-NULL. */
24651 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
24653 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
24655 free (start_with_pass
);
24656 return c_parser_peek_token (parser
)->location
;
24659 location_t start_loc
= c_parser_peek_token (parser
)->location
;
24661 /* Consume all tokens, up to the closing brace, handling
24662 matching pairs of braces in the rtl dump. */
24663 int num_open_braces
= 1;
24666 switch (c_parser_peek_token (parser
)->type
)
24668 case CPP_OPEN_BRACE
:
24671 case CPP_CLOSE_BRACE
:
24672 if (--num_open_braces
== 0)
24673 goto found_closing_brace
;
24676 error_at (start_loc
, "no closing brace");
24677 free (start_with_pass
);
24678 return c_parser_peek_token (parser
)->location
;
24682 c_parser_consume_token (parser
);
24685 found_closing_brace
:
24686 /* At the closing brace; record its location. */
24687 location_t end_loc
= c_parser_peek_token (parser
)->location
;
24689 /* Consume the closing brace. */
24690 c_parser_consume_token (parser
);
24692 /* Invoke the RTL parser. */
24693 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
24695 free (start_with_pass
);
24699 /* Run the backend on the cfun created above, transferring ownership of
24700 START_WITH_PASS. */
24701 run_rtl_passes (start_with_pass
);
24705 #include "gt-c-c-parser.h"