1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2022 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"
76 /* We need to walk over decls with incomplete struct/union/enum types
77 after parsing the whole translation unit.
78 In finish_decl(), if the decl is static, has incomplete
79 struct/union/enum type, it is appended to incomplete_record_decls.
80 In c_parser_translation_unit(), we iterate over incomplete_record_decls
81 and report error if any of the decls are still incomplete. */
83 vec
<tree
> incomplete_record_decls
;
86 set_c_expr_source_range (c_expr
*expr
,
87 location_t start
, location_t finish
)
89 expr
->src_range
.m_start
= start
;
90 expr
->src_range
.m_finish
= finish
;
92 set_source_range (expr
->value
, start
, finish
);
96 set_c_expr_source_range (c_expr
*expr
,
97 source_range src_range
)
99 expr
->src_range
= src_range
;
101 set_source_range (expr
->value
, src_range
);
105 /* Initialization routine for this file. */
110 /* The only initialization required is of the reserved word
116 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
117 the c_token structure. */
118 gcc_assert (RID_MAX
<= 255);
127 mask
|= D_ASM
| D_EXT
;
133 if (!c_dialect_objc ())
134 mask
|= D_OBJC
| D_CXX_OBJC
;
136 ridpointers
= ggc_cleared_vec_alloc
<tree
> ((int) RID_MAX
);
137 for (i
= 0; i
< num_c_common_reswords
; i
++)
139 /* If a keyword is disabled, do not enter it into the table
140 and so create a canonical spelling that isn't a keyword. */
141 if (c_common_reswords
[i
].disable
& mask
)
144 && (c_common_reswords
[i
].disable
& D_CXXWARN
))
146 id
= get_identifier (c_common_reswords
[i
].word
);
147 C_SET_RID_CODE (id
, RID_CXX_COMPAT_WARN
);
148 C_IS_RESERVED_WORD (id
) = 1;
153 id
= get_identifier (c_common_reswords
[i
].word
);
154 C_SET_RID_CODE (id
, c_common_reswords
[i
].rid
);
155 C_IS_RESERVED_WORD (id
) = 1;
156 ridpointers
[(int) c_common_reswords
[i
].rid
] = id
;
159 for (i
= 0; i
< NUM_INT_N_ENTS
; i
++)
161 /* We always create the symbols but they aren't always supported. */
163 sprintf (name
, "__int%d", int_n_data
[i
].bitsize
);
164 id
= get_identifier (name
);
165 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
166 C_IS_RESERVED_WORD (id
) = 1;
168 sprintf (name
, "__int%d__", int_n_data
[i
].bitsize
);
169 id
= get_identifier (name
);
170 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
171 C_IS_RESERVED_WORD (id
) = 1;
176 id
= get_identifier ("omp_all_memory");
177 C_SET_RID_CODE (id
, RID_OMP_ALL_MEMORY
);
178 C_IS_RESERVED_WORD (id
) = 1;
179 ridpointers
[RID_OMP_ALL_MEMORY
] = id
;
183 /* A parser structure recording information about the state and
184 context of parsing. Includes lexer information with up to two
185 tokens of look-ahead; more are not needed for C. */
186 struct GTY(()) c_parser
{
187 /* The look-ahead tokens. */
188 c_token
* GTY((skip
)) tokens
;
189 /* Buffer for look-ahead tokens. */
190 c_token tokens_buf
[4];
191 /* How many look-ahead tokens are available (0 - 4, or
192 more if parsing from pre-lexed tokens). */
193 unsigned int tokens_avail
;
194 /* Raw look-ahead tokens, used only for checking in Objective-C
195 whether '[[' starts attributes. */
196 vec
<c_token
, va_gc
> *raw_tokens
;
197 /* The number of raw look-ahead tokens that have since been fully
199 unsigned int raw_tokens_used
;
200 /* True if a syntax error is being recovered from; false otherwise.
201 c_parser_error sets this flag. It should clear this flag when
202 enough tokens have been consumed to recover from the error. */
203 BOOL_BITFIELD error
: 1;
204 /* True if we're processing a pragma, and shouldn't automatically
205 consume CPP_PRAGMA_EOL. */
206 BOOL_BITFIELD in_pragma
: 1;
207 /* True if we're parsing the outermost block of an if statement. */
208 BOOL_BITFIELD in_if_block
: 1;
209 /* True if we want to lex a translated, joined string (for an
210 initial #pragma pch_preprocess). Otherwise the parser is
211 responsible for concatenating strings and translating to the
212 execution character set as needed. */
213 BOOL_BITFIELD lex_joined_string
: 1;
214 /* True if, when the parser is concatenating string literals, it
215 should translate them to the execution character set (false
216 inside attributes). */
217 BOOL_BITFIELD translate_strings_p
: 1;
219 /* Objective-C specific parser/lexer information. */
221 /* True if we are in a context where the Objective-C "PQ" keywords
222 are considered keywords. */
223 BOOL_BITFIELD objc_pq_context
: 1;
224 /* True if we are parsing a (potential) Objective-C foreach
225 statement. This is set to true after we parsed 'for (' and while
226 we wait for 'in' or ';' to decide if it's a standard C for loop or an
227 Objective-C foreach loop. */
228 BOOL_BITFIELD objc_could_be_foreach_context
: 1;
229 /* The following flag is needed to contextualize Objective-C lexical
230 analysis. In some cases (e.g., 'int NSObject;'), it is
231 undesirable to bind an identifier to an Objective-C class, even
232 if a class with that name exists. */
233 BOOL_BITFIELD objc_need_raw_identifier
: 1;
234 /* Nonzero if we're processing a __transaction statement. The value
235 is 1 | TM_STMT_ATTR_*. */
236 unsigned int in_transaction
: 4;
237 /* True if we are in a context where the Objective-C "Property attribute"
238 keywords are valid. */
239 BOOL_BITFIELD objc_property_attr_context
: 1;
241 /* Whether we have just seen/constructed a string-literal. Set when
242 returning a string-literal from c_parser_string_literal. Reset
243 in consume_token. Useful when we get a parse error and see an
244 unknown token, which could have been a string-literal constant
246 BOOL_BITFIELD seen_string_literal
: 1;
248 /* Location of the last consumed token. */
249 location_t last_token_location
;
252 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
255 c_parser_tokens_buf (c_parser
*parser
, unsigned n
)
257 return &parser
->tokens_buf
[n
];
260 /* Return the error state of PARSER. */
263 c_parser_error (c_parser
*parser
)
265 return parser
->error
;
268 /* Set the error state of PARSER to ERR. */
271 c_parser_set_error (c_parser
*parser
, bool err
)
277 /* The actual parser and external interface. ??? Does this need to be
278 garbage-collected? */
280 static GTY (()) c_parser
*the_parser
;
282 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
283 context-sensitive postprocessing of the token is not done. */
286 c_lex_one_token (c_parser
*parser
, c_token
*token
, bool raw
= false)
288 timevar_push (TV_LEX
);
290 if (raw
|| vec_safe_length (parser
->raw_tokens
) == 0)
292 token
->type
= c_lex_with_flags (&token
->value
, &token
->location
,
294 (parser
->lex_joined_string
295 ? 0 : C_LEX_STRING_NO_JOIN
));
296 token
->id_kind
= C_ID_NONE
;
297 token
->keyword
= RID_MAX
;
298 token
->pragma_kind
= PRAGMA_NONE
;
302 /* Use a token previously lexed as a raw look-ahead token, and
303 complete the processing on it. */
304 *token
= (*parser
->raw_tokens
)[parser
->raw_tokens_used
];
305 ++parser
->raw_tokens_used
;
306 if (parser
->raw_tokens_used
== vec_safe_length (parser
->raw_tokens
))
308 vec_free (parser
->raw_tokens
);
309 parser
->raw_tokens_used
= 0;
322 bool objc_force_identifier
= parser
->objc_need_raw_identifier
;
323 if (c_dialect_objc ())
324 parser
->objc_need_raw_identifier
= false;
326 if (C_IS_RESERVED_WORD (token
->value
))
328 enum rid rid_code
= C_RID_CODE (token
->value
);
330 if (rid_code
== RID_CXX_COMPAT_WARN
)
332 warning_at (token
->location
,
334 "identifier %qE conflicts with C++ keyword",
337 else if (rid_code
>= RID_FIRST_ADDR_SPACE
338 && rid_code
<= RID_LAST_ADDR_SPACE
)
341 as
= (addr_space_t
) (rid_code
- RID_FIRST_ADDR_SPACE
);
342 targetm
.addr_space
.diagnose_usage (as
, token
->location
);
343 token
->id_kind
= C_ID_ADDRSPACE
;
344 token
->keyword
= rid_code
;
347 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code
))
349 /* We found an Objective-C "pq" keyword (in, out,
350 inout, bycopy, byref, oneway). They need special
351 care because the interpretation depends on the
353 if (parser
->objc_pq_context
)
355 token
->type
= CPP_KEYWORD
;
356 token
->keyword
= rid_code
;
359 else if (parser
->objc_could_be_foreach_context
360 && rid_code
== RID_IN
)
362 /* We are in Objective-C, inside a (potential)
363 foreach context (which means after having
364 parsed 'for (', but before having parsed ';'),
365 and we found 'in'. We consider it the keyword
366 which terminates the declaration at the
367 beginning of a foreach-statement. Note that
368 this means you can't use 'in' for anything else
369 in that context; in particular, in Objective-C
370 you can't use 'in' as the name of the running
371 variable in a C for loop. We could potentially
372 try to add code here to disambiguate, but it
373 seems a reasonable limitation. */
374 token
->type
= CPP_KEYWORD
;
375 token
->keyword
= rid_code
;
378 /* Else, "pq" keywords outside of the "pq" context are
379 not keywords, and we fall through to the code for
382 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code
))
384 /* We found an Objective-C "property attribute"
385 keyword (getter, setter, readonly, etc). These are
386 only valid in the property context. */
387 if (parser
->objc_property_attr_context
)
389 token
->type
= CPP_KEYWORD
;
390 token
->keyword
= rid_code
;
393 /* Else they are not special keywords.
396 else if (c_dialect_objc ()
397 && (OBJC_IS_AT_KEYWORD (rid_code
)
398 || OBJC_IS_CXX_KEYWORD (rid_code
)))
400 /* We found one of the Objective-C "@" keywords (defs,
401 selector, synchronized, etc) or one of the
402 Objective-C "cxx" keywords (class, private,
403 protected, public, try, catch, throw) without a
404 preceding '@' sign. Do nothing and fall through to
405 the code for normal tokens (in C++ we would still
406 consider the CXX ones keywords, but not in C). */
411 token
->type
= CPP_KEYWORD
;
412 token
->keyword
= rid_code
;
417 decl
= lookup_name (token
->value
);
420 if (TREE_CODE (decl
) == TYPE_DECL
)
422 token
->id_kind
= C_ID_TYPENAME
;
426 else if (c_dialect_objc ())
428 tree objc_interface_decl
= objc_is_class_name (token
->value
);
429 /* Objective-C class names are in the same namespace as
430 variables and typedefs, and hence are shadowed by local
432 if (objc_interface_decl
433 && (!objc_force_identifier
|| global_bindings_p ()))
435 token
->value
= objc_interface_decl
;
436 token
->id_kind
= C_ID_CLASSNAME
;
440 token
->id_kind
= C_ID_ID
;
444 /* This only happens in Objective-C; it must be a keyword. */
445 token
->type
= CPP_KEYWORD
;
446 switch (C_RID_CODE (token
->value
))
448 /* Replace 'class' with '@class', 'private' with '@private',
449 etc. This prevents confusion with the C++ keyword
450 'class', and makes the tokens consistent with other
451 Objective-C 'AT' keywords. For example '@class' is
452 reported as RID_AT_CLASS which is consistent with
453 '@synchronized', which is reported as
456 case RID_CLASS
: token
->keyword
= RID_AT_CLASS
; break;
457 case RID_PRIVATE
: token
->keyword
= RID_AT_PRIVATE
; break;
458 case RID_PROTECTED
: token
->keyword
= RID_AT_PROTECTED
; break;
459 case RID_PUBLIC
: token
->keyword
= RID_AT_PUBLIC
; break;
460 case RID_THROW
: token
->keyword
= RID_AT_THROW
; break;
461 case RID_TRY
: token
->keyword
= RID_AT_TRY
; break;
462 case RID_CATCH
: token
->keyword
= RID_AT_CATCH
; break;
463 case RID_SYNCHRONIZED
: token
->keyword
= RID_AT_SYNCHRONIZED
; break;
464 default: token
->keyword
= C_RID_CODE (token
->value
);
469 case CPP_CLOSE_PAREN
:
471 /* These tokens may affect the interpretation of any identifiers
472 following, if doing Objective-C. */
473 if (c_dialect_objc ())
474 parser
->objc_need_raw_identifier
= false;
477 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
478 token
->pragma_kind
= (enum pragma_kind
) TREE_INT_CST_LOW (token
->value
);
485 timevar_pop (TV_LEX
);
488 /* Return a pointer to the next token from PARSER, reading it in if
492 c_parser_peek_token (c_parser
*parser
)
494 if (parser
->tokens_avail
== 0)
496 c_lex_one_token (parser
, &parser
->tokens
[0]);
497 parser
->tokens_avail
= 1;
499 return &parser
->tokens
[0];
502 /* Return a pointer to the next-but-one token from PARSER, reading it
503 in if necessary. The next token is already read in. */
506 c_parser_peek_2nd_token (c_parser
*parser
)
508 if (parser
->tokens_avail
>= 2)
509 return &parser
->tokens
[1];
510 gcc_assert (parser
->tokens_avail
== 1);
511 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
512 gcc_assert (parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
513 c_lex_one_token (parser
, &parser
->tokens
[1]);
514 parser
->tokens_avail
= 2;
515 return &parser
->tokens
[1];
518 /* Return a pointer to the Nth token from PARSER, reading it
519 in if necessary. The N-1th token is already read in. */
522 c_parser_peek_nth_token (c_parser
*parser
, unsigned int n
)
524 /* N is 1-based, not zero-based. */
527 if (parser
->tokens_avail
>= n
)
528 return &parser
->tokens
[n
- 1];
529 gcc_assert (parser
->tokens_avail
== n
- 1);
530 c_lex_one_token (parser
, &parser
->tokens
[n
- 1]);
531 parser
->tokens_avail
= n
;
532 return &parser
->tokens
[n
- 1];
535 /* Return a pointer to the Nth token from PARSER, reading it in as a
536 raw look-ahead token if necessary. The N-1th token is already read
537 in. Raw look-ahead tokens remain available for when the non-raw
538 functions above are called. */
541 c_parser_peek_nth_token_raw (c_parser
*parser
, unsigned int n
)
543 /* N is 1-based, not zero-based. */
546 if (parser
->tokens_avail
>= n
)
547 return &parser
->tokens
[n
- 1];
548 unsigned int raw_len
= vec_safe_length (parser
->raw_tokens
);
549 unsigned int raw_avail
550 = parser
->tokens_avail
+ raw_len
- parser
->raw_tokens_used
;
551 gcc_assert (raw_avail
>= n
- 1);
553 return &(*parser
->raw_tokens
)[parser
->raw_tokens_used
554 + n
- 1 - parser
->tokens_avail
];
555 vec_safe_reserve (parser
->raw_tokens
, 1);
556 parser
->raw_tokens
->quick_grow (raw_len
+ 1);
557 c_lex_one_token (parser
, &(*parser
->raw_tokens
)[raw_len
], true);
558 return &(*parser
->raw_tokens
)[raw_len
];
562 c_keyword_starts_typename (enum rid keyword
)
585 case RID_TYPEOF_UNQUAL
:
598 if (keyword
>= RID_FIRST_INT_N
599 && keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
600 && int_n_enabled_p
[keyword
- RID_FIRST_INT_N
])
606 /* Return true if TOKEN can start a type name,
609 c_token_starts_typename (c_token
*token
)
614 switch (token
->id_kind
)
623 gcc_assert (c_dialect_objc ());
629 return c_keyword_starts_typename (token
->keyword
);
631 if (c_dialect_objc ())
639 /* Return true if the next token from PARSER can start a type name,
640 false otherwise. LA specifies how to do lookahead in order to
641 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
644 c_parser_next_tokens_start_typename (c_parser
*parser
, enum c_lookahead_kind la
)
646 c_token
*token
= c_parser_peek_token (parser
);
647 if (c_token_starts_typename (token
))
650 /* Try a bit harder to detect an unknown typename. */
651 if (la
!= cla_prefer_id
652 && token
->type
== CPP_NAME
653 && token
->id_kind
== C_ID_ID
655 /* Do not try too hard when we could have "object in array". */
656 && !parser
->objc_could_be_foreach_context
658 && (la
== cla_prefer_type
659 || c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
660 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
662 /* Only unknown identifiers. */
663 && !lookup_name (token
->value
))
669 /* Return true if TOKEN, after an open parenthesis, can start a
670 compound literal (either a storage class specifier allowed in that
671 context, or a type name), false otherwise. */
673 c_token_starts_compound_literal (c_token
*token
)
678 switch (token
->keyword
)
689 return c_token_starts_typename (token
);
693 /* Return true if TOKEN is a type qualifier, false otherwise. */
695 c_token_is_qualifier (c_token
*token
)
700 switch (token
->id_kind
)
708 switch (token
->keyword
)
726 /* Return true if the next token from PARSER is a type qualifier,
729 c_parser_next_token_is_qualifier (c_parser
*parser
)
731 c_token
*token
= c_parser_peek_token (parser
);
732 return c_token_is_qualifier (token
);
735 /* Return true if TOKEN can start declaration specifiers (not
736 including standard attributes), false otherwise. */
738 c_token_starts_declspecs (c_token
*token
)
743 switch (token
->id_kind
)
752 gcc_assert (c_dialect_objc ());
758 switch (token
->keyword
)
787 case RID_TYPEOF_UNQUAL
:
800 if (token
->keyword
>= RID_FIRST_INT_N
801 && token
->keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
802 && int_n_enabled_p
[token
->keyword
- RID_FIRST_INT_N
])
807 if (c_dialect_objc ())
816 /* Return true if TOKEN can start declaration specifiers (not
817 including standard attributes) or a static assertion, false
820 c_token_starts_declaration (c_token
*token
)
822 if (c_token_starts_declspecs (token
)
823 || token
->keyword
== RID_STATIC_ASSERT
)
829 /* Return true if the next token from PARSER can start declaration
830 specifiers (not including standard attributes), false
833 c_parser_next_token_starts_declspecs (c_parser
*parser
)
835 c_token
*token
= c_parser_peek_token (parser
);
837 /* In Objective-C, a classname normally starts a declspecs unless it
838 is immediately followed by a dot. In that case, it is the
839 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
840 setter/getter on the class. c_token_starts_declspecs() can't
841 differentiate between the two cases because it only checks the
842 current token, so we have a special check here. */
843 if (c_dialect_objc ()
844 && token
->type
== CPP_NAME
845 && token
->id_kind
== C_ID_CLASSNAME
846 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
849 return c_token_starts_declspecs (token
);
852 /* Return true if the next tokens from PARSER can start declaration
853 specifiers (not including standard attributes) or a static
854 assertion, false otherwise. */
856 c_parser_next_tokens_start_declaration (c_parser
*parser
)
858 c_token
*token
= c_parser_peek_token (parser
);
861 if (c_dialect_objc ()
862 && token
->type
== CPP_NAME
863 && token
->id_kind
== C_ID_CLASSNAME
864 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
867 /* Labels do not start declarations. */
868 if (token
->type
== CPP_NAME
869 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
872 if (c_token_starts_declaration (token
))
875 if (c_parser_next_tokens_start_typename (parser
, cla_nonabstract_decl
))
881 /* Consume the next token from PARSER. */
884 c_parser_consume_token (c_parser
*parser
)
886 gcc_assert (parser
->tokens_avail
>= 1);
887 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
888 gcc_assert (!parser
->in_pragma
|| parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
889 gcc_assert (parser
->error
|| parser
->tokens
[0].type
!= CPP_PRAGMA
);
890 parser
->last_token_location
= parser
->tokens
[0].location
;
891 if (parser
->tokens
!= &parser
->tokens_buf
[0])
893 else if (parser
->tokens_avail
>= 2)
895 parser
->tokens
[0] = parser
->tokens
[1];
896 if (parser
->tokens_avail
>= 3)
898 parser
->tokens
[1] = parser
->tokens
[2];
899 if (parser
->tokens_avail
>= 4)
900 parser
->tokens
[2] = parser
->tokens
[3];
903 parser
->tokens_avail
--;
904 parser
->seen_string_literal
= false;
907 /* Expect the current token to be a #pragma. Consume it and remember
908 that we've begun parsing a pragma. */
911 c_parser_consume_pragma (c_parser
*parser
)
913 gcc_assert (!parser
->in_pragma
);
914 gcc_assert (parser
->tokens_avail
>= 1);
915 gcc_assert (parser
->tokens
[0].type
== CPP_PRAGMA
);
916 if (parser
->tokens
!= &parser
->tokens_buf
[0])
918 else if (parser
->tokens_avail
>= 2)
920 parser
->tokens
[0] = parser
->tokens
[1];
921 if (parser
->tokens_avail
>= 3)
922 parser
->tokens
[1] = parser
->tokens
[2];
924 parser
->tokens_avail
--;
925 parser
->in_pragma
= true;
928 /* Update the global input_location from TOKEN. */
930 c_parser_set_source_position_from_token (c_token
*token
)
932 if (token
->type
!= CPP_EOF
)
934 input_location
= token
->location
;
938 /* Helper function for c_parser_error.
939 Having peeked a token of kind TOK1_KIND that might signify
940 a conflict marker, peek successor tokens to determine
941 if we actually do have a conflict marker.
942 Specifically, we consider a run of 7 '<', '=' or '>' characters
943 at the start of a line as a conflict marker.
944 These come through the lexer as three pairs and a single,
945 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
946 If it returns true, *OUT_LOC is written to with the location/range
950 c_parser_peek_conflict_marker (c_parser
*parser
, enum cpp_ttype tok1_kind
,
953 c_token
*token2
= c_parser_peek_2nd_token (parser
);
954 if (token2
->type
!= tok1_kind
)
956 c_token
*token3
= c_parser_peek_nth_token (parser
, 3);
957 if (token3
->type
!= tok1_kind
)
959 c_token
*token4
= c_parser_peek_nth_token (parser
, 4);
960 if (token4
->type
!= conflict_marker_get_final_tok_kind (tok1_kind
))
963 /* It must be at the start of the line. */
964 location_t start_loc
= c_parser_peek_token (parser
)->location
;
965 if (LOCATION_COLUMN (start_loc
) != 1)
968 /* We have a conflict marker. Construct a location of the form:
971 with start == caret, finishing at the end of the marker. */
972 location_t finish_loc
= get_finish (token4
->location
);
973 *out_loc
= make_location (start_loc
, start_loc
, finish_loc
);
978 /* Issue a diagnostic of the form
979 FILE:LINE: MESSAGE before TOKEN
980 where TOKEN is the next token in the input stream of PARSER.
981 MESSAGE (specified by the caller) is usually of the form "expected
984 Use RICHLOC as the location of the diagnostic.
986 Do not issue a diagnostic if still recovering from an error.
988 Return true iff an error was actually emitted.
990 ??? This is taken from the C++ parser, but building up messages in
991 this way is not i18n-friendly and some other approach should be
995 c_parser_error_richloc (c_parser
*parser
, const char *gmsgid
,
996 rich_location
*richloc
)
998 c_token
*token
= c_parser_peek_token (parser
);
1001 parser
->error
= true;
1005 /* If this is actually a conflict marker, report it as such. */
1006 if (token
->type
== CPP_LSHIFT
1007 || token
->type
== CPP_RSHIFT
1008 || token
->type
== CPP_EQ_EQ
)
1011 if (c_parser_peek_conflict_marker (parser
, token
->type
, &loc
))
1013 error_at (loc
, "version control conflict marker in file");
1018 /* If we were parsing a string-literal and there is an unknown name
1019 token right after, then check to see if that could also have been
1020 a literal string by checking the name against a list of known
1021 standard string literal constants defined in header files. If
1022 there is one, then add that as an hint to the error message. */
1023 auto_diagnostic_group d
;
1025 if (parser
->seen_string_literal
&& token
->type
== CPP_NAME
)
1027 tree name
= token
->value
;
1028 const char *token_name
= IDENTIFIER_POINTER (name
);
1029 const char *header_hint
1030 = get_c_stdlib_header_for_string_macro_name (token_name
);
1031 if (header_hint
!= NULL
)
1032 h
= name_hint (NULL
, new suggest_missing_header (token
->location
,
1037 c_parse_error (gmsgid
,
1038 /* Because c_parse_error does not understand
1039 CPP_KEYWORD, keywords are treated like
1041 (token
->type
== CPP_KEYWORD
? CPP_NAME
: token
->type
),
1042 /* ??? The C parser does not save the cpp flags of a
1043 token, we need to pass 0 here and we will not get
1044 the source spelling of some tokens but rather the
1045 canonical spelling. */
1046 token
->value
, /*flags=*/0, richloc
);
1050 /* As c_parser_error_richloc, but issue the message at the
1051 location of PARSER's next token, or at input_location
1052 if the next token is EOF. */
1055 c_parser_error (c_parser
*parser
, const char *gmsgid
)
1057 c_token
*token
= c_parser_peek_token (parser
);
1058 c_parser_set_source_position_from_token (token
);
1059 rich_location
richloc (line_table
, input_location
);
1060 return c_parser_error_richloc (parser
, gmsgid
, &richloc
);
1063 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1064 This class is for tracking such a matching pair of symbols.
1065 In particular, it tracks the location of the first token,
1066 so that if the second token is missing, we can highlight the
1067 location of the first token when notifying the user about the
1070 template <typename traits_t
>
1074 /* token_pair's ctor. */
1075 token_pair () : m_open_loc (UNKNOWN_LOCATION
) {}
1077 /* If the next token is the opening symbol for this pair, consume it and
1079 Otherwise, issue an error and return false.
1080 In either case, record the location of the opening token. */
1082 bool require_open (c_parser
*parser
)
1084 c_token
*token
= c_parser_peek_token (parser
);
1086 m_open_loc
= token
->location
;
1088 return c_parser_require (parser
, traits_t::open_token_type
,
1089 traits_t::open_gmsgid
);
1092 /* Consume the next token from PARSER, recording its location as
1093 that of the opening token within the pair. */
1095 void consume_open (c_parser
*parser
)
1097 c_token
*token
= c_parser_peek_token (parser
);
1098 gcc_assert (token
->type
== traits_t::open_token_type
);
1099 m_open_loc
= token
->location
;
1100 c_parser_consume_token (parser
);
1103 /* If the next token is the closing symbol for this pair, consume it
1105 Otherwise, issue an error, highlighting the location of the
1106 corresponding opening token, and return false. */
1108 bool require_close (c_parser
*parser
) const
1110 return c_parser_require (parser
, traits_t::close_token_type
,
1111 traits_t::close_gmsgid
, m_open_loc
);
1114 /* Like token_pair::require_close, except that tokens will be skipped
1115 until the desired token is found. An error message is still produced
1116 if the next token is not as expected. */
1118 void skip_until_found_close (c_parser
*parser
) const
1120 c_parser_skip_until_found (parser
, traits_t::close_token_type
,
1121 traits_t::close_gmsgid
, m_open_loc
);
1125 location_t m_open_loc
;
1128 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1130 struct matching_paren_traits
1132 static const enum cpp_ttype open_token_type
= CPP_OPEN_PAREN
;
1133 static const char * const open_gmsgid
;
1134 static const enum cpp_ttype close_token_type
= CPP_CLOSE_PAREN
;
1135 static const char * const close_gmsgid
;
1138 const char * const matching_paren_traits::open_gmsgid
= "expected %<(%>";
1139 const char * const matching_paren_traits::close_gmsgid
= "expected %<)%>";
1141 /* "matching_parens" is a token_pair<T> class for tracking matching
1142 pairs of parentheses. */
1144 typedef token_pair
<matching_paren_traits
> matching_parens
;
1146 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1148 struct matching_brace_traits
1150 static const enum cpp_ttype open_token_type
= CPP_OPEN_BRACE
;
1151 static const char * const open_gmsgid
;
1152 static const enum cpp_ttype close_token_type
= CPP_CLOSE_BRACE
;
1153 static const char * const close_gmsgid
;
1156 const char * const matching_brace_traits::open_gmsgid
= "expected %<{%>";
1157 const char * const matching_brace_traits::close_gmsgid
= "expected %<}%>";
1159 /* "matching_braces" is a token_pair<T> class for tracking matching
1162 typedef token_pair
<matching_brace_traits
> matching_braces
;
1164 /* Get a description of the matching symbol to TYPE e.g. "(" for
1168 get_matching_symbol (enum cpp_ttype type
)
1174 case CPP_CLOSE_PAREN
:
1176 case CPP_CLOSE_BRACE
:
1181 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1182 issue the error MSGID. If MSGID is NULL then a message has already
1183 been produced and no message will be produced this time. Returns
1184 true if found, false otherwise.
1186 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1187 within any error as the location of an "opening" token matching
1188 the close token TYPE (e.g. the location of the '(' when TYPE is
1191 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1192 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1193 attempt to generate a fix-it hint for the problem.
1194 Otherwise msgid describes multiple token types (e.g.
1195 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1196 generate a fix-it hint. */
1199 c_parser_require (c_parser
*parser
,
1200 enum cpp_ttype type
,
1202 location_t matching_location
,
1203 bool type_is_unique
)
1205 if (c_parser_next_token_is (parser
, type
))
1207 c_parser_consume_token (parser
);
1212 location_t next_token_loc
= c_parser_peek_token (parser
)->location
;
1213 gcc_rich_location
richloc (next_token_loc
);
1215 /* Potentially supply a fix-it hint, suggesting to add the
1216 missing token immediately after the *previous* token.
1217 This may move the primary location within richloc. */
1218 if (!parser
->error
&& type_is_unique
)
1219 maybe_suggest_missing_token_insertion (&richloc
, type
,
1220 parser
->last_token_location
);
1222 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1223 Attempt to consolidate diagnostics by printing it as a
1224 secondary range within the main diagnostic. */
1225 bool added_matching_location
= false;
1226 if (matching_location
!= UNKNOWN_LOCATION
)
1227 added_matching_location
1228 = richloc
.add_location_if_nearby (matching_location
);
1230 if (c_parser_error_richloc (parser
, msgid
, &richloc
))
1231 /* If we weren't able to consolidate matching_location, then
1232 print it as a secondary diagnostic. */
1233 if (matching_location
!= UNKNOWN_LOCATION
&& !added_matching_location
)
1234 inform (matching_location
, "to match this %qs",
1235 get_matching_symbol (type
));
1241 /* If the next token is the indicated keyword, consume it. Otherwise,
1242 issue the error MSGID. Returns true if found, false otherwise. */
1245 c_parser_require_keyword (c_parser
*parser
,
1249 if (c_parser_next_token_is_keyword (parser
, keyword
))
1251 c_parser_consume_token (parser
);
1256 c_parser_error (parser
, msgid
);
1261 /* Like c_parser_require, except that tokens will be skipped until the
1262 desired token is found. An error message is still produced if the
1263 next token is not as expected. If MSGID is NULL then a message has
1264 already been produced and no message will be produced this
1267 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1268 within any error as the location of an "opening" token matching
1269 the close token TYPE (e.g. the location of the '(' when TYPE is
1270 CPP_CLOSE_PAREN). */
1273 c_parser_skip_until_found (c_parser
*parser
,
1274 enum cpp_ttype type
,
1276 location_t matching_location
)
1278 unsigned nesting_depth
= 0;
1280 if (c_parser_require (parser
, type
, msgid
, matching_location
))
1283 /* Skip tokens until the desired token is found. */
1286 /* Peek at the next token. */
1287 c_token
*token
= c_parser_peek_token (parser
);
1288 /* If we've reached the token we want, consume it and stop. */
1289 if (token
->type
== type
&& !nesting_depth
)
1291 c_parser_consume_token (parser
);
1295 /* If we've run out of tokens, stop. */
1296 if (token
->type
== CPP_EOF
)
1298 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1300 if (token
->type
== CPP_OPEN_BRACE
1301 || token
->type
== CPP_OPEN_PAREN
1302 || token
->type
== CPP_OPEN_SQUARE
)
1304 else if (token
->type
== CPP_CLOSE_BRACE
1305 || token
->type
== CPP_CLOSE_PAREN
1306 || token
->type
== CPP_CLOSE_SQUARE
)
1308 if (nesting_depth
-- == 0)
1311 /* Consume this token. */
1312 c_parser_consume_token (parser
);
1314 parser
->error
= false;
1317 /* Skip tokens until the end of a parameter is found, but do not
1318 consume the comma, semicolon or closing delimiter. */
1321 c_parser_skip_to_end_of_parameter (c_parser
*parser
)
1323 unsigned nesting_depth
= 0;
1327 c_token
*token
= c_parser_peek_token (parser
);
1328 if ((token
->type
== CPP_COMMA
|| token
->type
== CPP_SEMICOLON
)
1331 /* If we've run out of tokens, stop. */
1332 if (token
->type
== CPP_EOF
)
1334 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1336 if (token
->type
== CPP_OPEN_BRACE
1337 || token
->type
== CPP_OPEN_PAREN
1338 || token
->type
== CPP_OPEN_SQUARE
)
1340 else if (token
->type
== CPP_CLOSE_BRACE
1341 || token
->type
== CPP_CLOSE_PAREN
1342 || token
->type
== CPP_CLOSE_SQUARE
)
1344 if (nesting_depth
-- == 0)
1347 /* Consume this token. */
1348 c_parser_consume_token (parser
);
1350 parser
->error
= false;
1353 /* Expect to be at the end of the pragma directive and consume an
1354 end of line marker. */
1357 c_parser_skip_to_pragma_eol (c_parser
*parser
, bool error_if_not_eol
= true)
1359 gcc_assert (parser
->in_pragma
);
1360 parser
->in_pragma
= false;
1362 if (error_if_not_eol
&& c_parser_peek_token (parser
)->type
!= CPP_PRAGMA_EOL
)
1363 c_parser_error (parser
, "expected end of line");
1365 cpp_ttype token_type
;
1368 c_token
*token
= c_parser_peek_token (parser
);
1369 token_type
= token
->type
;
1370 if (token_type
== CPP_EOF
)
1372 c_parser_consume_token (parser
);
1374 while (token_type
!= CPP_PRAGMA_EOL
);
1376 parser
->error
= false;
1379 /* Skip tokens until we have consumed an entire block, or until we
1380 have consumed a non-nested ';'. */
1383 c_parser_skip_to_end_of_block_or_statement (c_parser
*parser
)
1385 unsigned nesting_depth
= 0;
1386 bool save_error
= parser
->error
;
1392 /* Peek at the next token. */
1393 token
= c_parser_peek_token (parser
);
1395 switch (token
->type
)
1400 case CPP_PRAGMA_EOL
:
1401 if (parser
->in_pragma
)
1406 /* If the next token is a ';', we have reached the
1407 end of the statement. */
1410 /* Consume the ';'. */
1411 c_parser_consume_token (parser
);
1416 case CPP_CLOSE_BRACE
:
1417 /* If the next token is a non-nested '}', then we have
1418 reached the end of the current block. */
1419 if (nesting_depth
== 0 || --nesting_depth
== 0)
1421 c_parser_consume_token (parser
);
1426 case CPP_OPEN_BRACE
:
1427 /* If it the next token is a '{', then we are entering a new
1428 block. Consume the entire block. */
1433 /* If we see a pragma, consume the whole thing at once. We
1434 have some safeguards against consuming pragmas willy-nilly.
1435 Normally, we'd expect to be here with parser->error set,
1436 which disables these safeguards. But it's possible to get
1437 here for secondary error recovery, after parser->error has
1439 c_parser_consume_pragma (parser
);
1440 c_parser_skip_to_pragma_eol (parser
);
1441 parser
->error
= save_error
;
1448 c_parser_consume_token (parser
);
1452 parser
->error
= false;
1455 /* CPP's options (initialized by c-opts.cc). */
1456 extern cpp_options
*cpp_opts
;
1458 /* Save the warning flags which are controlled by __extension__. */
1461 disable_extension_diagnostics (void)
1464 | (warn_pointer_arith
<< 1)
1465 | (warn_traditional
<< 2)
1467 | (warn_long_long
<< 4)
1468 | (warn_cxx_compat
<< 5)
1469 | (warn_overlength_strings
<< 6)
1470 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1471 play tricks to properly restore it. */
1472 | ((warn_c90_c99_compat
== 1) << 7)
1473 | ((warn_c90_c99_compat
== -1) << 8)
1474 /* Similarly for warn_c99_c11_compat. */
1475 | ((warn_c99_c11_compat
== 1) << 9)
1476 | ((warn_c99_c11_compat
== -1) << 10)
1477 /* Similarly for warn_c11_c2x_compat. */
1478 | ((warn_c11_c2x_compat
== 1) << 11)
1479 | ((warn_c11_c2x_compat
== -1) << 12)
1481 cpp_opts
->cpp_pedantic
= pedantic
= 0;
1482 warn_pointer_arith
= 0;
1483 cpp_opts
->cpp_warn_traditional
= warn_traditional
= 0;
1485 cpp_opts
->cpp_warn_long_long
= warn_long_long
= 0;
1486 warn_cxx_compat
= 0;
1487 warn_overlength_strings
= 0;
1488 warn_c90_c99_compat
= 0;
1489 warn_c99_c11_compat
= 0;
1490 warn_c11_c2x_compat
= 0;
1494 /* Restore the warning flags which are controlled by __extension__.
1495 FLAGS is the return value from disable_extension_diagnostics. */
1498 restore_extension_diagnostics (int flags
)
1500 cpp_opts
->cpp_pedantic
= pedantic
= flags
& 1;
1501 warn_pointer_arith
= (flags
>> 1) & 1;
1502 cpp_opts
->cpp_warn_traditional
= warn_traditional
= (flags
>> 2) & 1;
1503 flag_iso
= (flags
>> 3) & 1;
1504 cpp_opts
->cpp_warn_long_long
= warn_long_long
= (flags
>> 4) & 1;
1505 warn_cxx_compat
= (flags
>> 5) & 1;
1506 warn_overlength_strings
= (flags
>> 6) & 1;
1507 /* See above for why is this needed. */
1508 warn_c90_c99_compat
= (flags
>> 7) & 1 ? 1 : ((flags
>> 8) & 1 ? -1 : 0);
1509 warn_c99_c11_compat
= (flags
>> 9) & 1 ? 1 : ((flags
>> 10) & 1 ? -1 : 0);
1510 warn_c11_c2x_compat
= (flags
>> 11) & 1 ? 1 : ((flags
>> 12) & 1 ? -1 : 0);
1513 /* Helper data structure for parsing #pragma acc routine. */
1514 struct oacc_routine_data
{
1515 bool error_seen
; /* Set if error has been reported. */
1516 bool fndecl_seen
; /* Set if one fn decl/definition has been seen already. */
1521 /* Used for parsing objc foreach statements. */
1522 static tree objc_foreach_break_label
, objc_foreach_continue_label
;
1524 static bool c_parser_nth_token_starts_std_attributes (c_parser
*,
1526 static tree
c_parser_std_attribute_specifier_sequence (c_parser
*);
1527 static void c_parser_external_declaration (c_parser
*);
1528 static void c_parser_asm_definition (c_parser
*);
1529 static void c_parser_declaration_or_fndef (c_parser
*, bool, bool, bool,
1530 bool, bool, tree
* = NULL
,
1531 vec
<c_token
> * = NULL
,
1532 bool have_attrs
= false,
1534 struct oacc_routine_data
* = NULL
,
1536 static void c_parser_static_assert_declaration_no_semi (c_parser
*);
1537 static void c_parser_static_assert_declaration (c_parser
*);
1538 static struct c_typespec
c_parser_enum_specifier (c_parser
*);
1539 static struct c_typespec
c_parser_struct_or_union_specifier (c_parser
*);
1540 static tree
c_parser_struct_declaration (c_parser
*);
1541 static struct c_typespec
c_parser_typeof_specifier (c_parser
*);
1542 static tree
c_parser_alignas_specifier (c_parser
*);
1543 static struct c_declarator
*c_parser_direct_declarator (c_parser
*, bool,
1545 static struct c_declarator
*c_parser_direct_declarator_inner (c_parser
*,
1547 struct c_declarator
*);
1548 static struct c_arg_info
*c_parser_parms_declarator (c_parser
*, bool, tree
,
1550 static struct c_arg_info
*c_parser_parms_list_declarator (c_parser
*, tree
,
1552 static struct c_parm
*c_parser_parameter_declaration (c_parser
*, tree
, bool);
1553 static tree
c_parser_simple_asm_expr (c_parser
*);
1554 static tree
c_parser_gnu_attributes (c_parser
*);
1555 static struct c_expr
c_parser_initializer (c_parser
*, tree
);
1556 static struct c_expr
c_parser_braced_init (c_parser
*, tree
, bool,
1557 struct obstack
*, tree
);
1558 static void c_parser_initelt (c_parser
*, struct obstack
*);
1559 static void c_parser_initval (c_parser
*, struct c_expr
*,
1561 static tree
c_parser_compound_statement (c_parser
*, location_t
* = NULL
);
1562 static location_t
c_parser_compound_statement_nostart (c_parser
*);
1563 static void c_parser_label (c_parser
*, tree
);
1564 static void c_parser_statement (c_parser
*, bool *, location_t
* = NULL
);
1565 static void c_parser_statement_after_labels (c_parser
*, bool *,
1566 vec
<tree
> * = NULL
);
1567 static tree
c_parser_c99_block_statement (c_parser
*, bool *,
1568 location_t
* = NULL
);
1569 static void c_parser_if_statement (c_parser
*, bool *, vec
<tree
> *);
1570 static void c_parser_switch_statement (c_parser
*, bool *);
1571 static void c_parser_while_statement (c_parser
*, bool, unsigned short, bool *);
1572 static void c_parser_do_statement (c_parser
*, bool, unsigned short);
1573 static void c_parser_for_statement (c_parser
*, bool, unsigned short, bool *);
1574 static tree
c_parser_asm_statement (c_parser
*);
1575 static tree
c_parser_asm_operands (c_parser
*);
1576 static tree
c_parser_asm_goto_operands (c_parser
*);
1577 static tree
c_parser_asm_clobbers (c_parser
*);
1578 static struct c_expr
c_parser_expr_no_commas (c_parser
*, struct c_expr
*,
1580 static struct c_expr
c_parser_conditional_expression (c_parser
*,
1581 struct c_expr
*, tree
);
1582 static struct c_expr
c_parser_binary_expression (c_parser
*, struct c_expr
*,
1584 static struct c_expr
c_parser_cast_expression (c_parser
*, struct c_expr
*);
1585 static struct c_expr
c_parser_unary_expression (c_parser
*);
1586 static struct c_expr
c_parser_sizeof_expression (c_parser
*);
1587 static struct c_expr
c_parser_alignof_expression (c_parser
*);
1588 static struct c_expr
c_parser_postfix_expression (c_parser
*);
1589 static struct c_expr
c_parser_postfix_expression_after_paren_type (c_parser
*,
1590 struct c_declspecs
*,
1591 struct c_type_name
*,
1593 static struct c_expr
c_parser_postfix_expression_after_primary (c_parser
*,
1596 static tree
c_parser_transaction (c_parser
*, enum rid
);
1597 static struct c_expr
c_parser_transaction_expression (c_parser
*, enum rid
);
1598 static tree
c_parser_transaction_cancel (c_parser
*);
1599 static struct c_expr
c_parser_expression (c_parser
*);
1600 static struct c_expr
c_parser_expression_conv (c_parser
*);
1601 static vec
<tree
, va_gc
> *c_parser_expr_list (c_parser
*, bool, bool,
1602 vec
<tree
, va_gc
> **, location_t
*,
1603 tree
*, vec
<location_t
> *,
1604 unsigned int * = NULL
);
1605 static struct c_expr
c_parser_has_attribute_expression (c_parser
*);
1607 static void c_parser_oacc_declare (c_parser
*);
1608 static void c_parser_oacc_enter_exit_data (c_parser
*, bool);
1609 static void c_parser_oacc_update (c_parser
*);
1610 static void c_parser_omp_construct (c_parser
*, bool *);
1611 static void c_parser_omp_threadprivate (c_parser
*);
1612 static void c_parser_omp_barrier (c_parser
*);
1613 static void c_parser_omp_depobj (c_parser
*);
1614 static void c_parser_omp_flush (c_parser
*);
1615 static tree
c_parser_omp_for_loop (location_t
, c_parser
*, enum tree_code
,
1616 tree
, tree
*, bool *);
1617 static void c_parser_omp_taskwait (c_parser
*);
1618 static void c_parser_omp_taskyield (c_parser
*);
1619 static void c_parser_omp_cancel (c_parser
*);
1620 static void c_parser_omp_nothing (c_parser
*);
1622 enum pragma_context
{ pragma_external
, pragma_struct
, pragma_param
,
1623 pragma_stmt
, pragma_compound
};
1624 static bool c_parser_pragma (c_parser
*, enum pragma_context
, bool *);
1625 static bool c_parser_omp_cancellation_point (c_parser
*, enum pragma_context
);
1626 static bool c_parser_omp_target (c_parser
*, enum pragma_context
, bool *);
1627 static void c_parser_omp_begin (c_parser
*);
1628 static void c_parser_omp_end (c_parser
*);
1629 static bool c_parser_omp_declare (c_parser
*, enum pragma_context
);
1630 static void c_parser_omp_requires (c_parser
*);
1631 static bool c_parser_omp_error (c_parser
*, enum pragma_context
);
1632 static void c_parser_omp_assumption_clauses (c_parser
*, bool);
1633 static void c_parser_omp_assumes (c_parser
*);
1634 static bool c_parser_omp_ordered (c_parser
*, enum pragma_context
, bool *);
1635 static void c_parser_oacc_routine (c_parser
*, enum pragma_context
);
1637 /* These Objective-C parser functions are only ever called when
1638 compiling Objective-C. */
1639 static void c_parser_objc_class_definition (c_parser
*, tree
);
1640 static void c_parser_objc_class_instance_variables (c_parser
*);
1641 static void c_parser_objc_class_declaration (c_parser
*);
1642 static void c_parser_objc_alias_declaration (c_parser
*);
1643 static void c_parser_objc_protocol_definition (c_parser
*, tree
);
1644 static bool c_parser_objc_method_type (c_parser
*);
1645 static void c_parser_objc_method_definition (c_parser
*);
1646 static void c_parser_objc_methodprotolist (c_parser
*);
1647 static void c_parser_objc_methodproto (c_parser
*);
1648 static tree
c_parser_objc_method_decl (c_parser
*, bool, tree
*, tree
*);
1649 static tree
c_parser_objc_type_name (c_parser
*);
1650 static tree
c_parser_objc_protocol_refs (c_parser
*);
1651 static void c_parser_objc_try_catch_finally_statement (c_parser
*);
1652 static void c_parser_objc_synchronized_statement (c_parser
*);
1653 static tree
c_parser_objc_selector (c_parser
*);
1654 static tree
c_parser_objc_selector_arg (c_parser
*);
1655 static tree
c_parser_objc_receiver (c_parser
*);
1656 static tree
c_parser_objc_message_args (c_parser
*);
1657 static tree
c_parser_objc_keywordexpr (c_parser
*);
1658 static void c_parser_objc_at_property_declaration (c_parser
*);
1659 static void c_parser_objc_at_synthesize_declaration (c_parser
*);
1660 static void c_parser_objc_at_dynamic_declaration (c_parser
*);
1661 static bool c_parser_objc_diagnose_bad_element_prefix
1662 (c_parser
*, struct c_declspecs
*);
1663 static location_t
c_parser_parse_rtl_body (c_parser
*, char *);
1665 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1668 external-declarations
1670 external-declarations:
1671 external-declaration
1672 external-declarations external-declaration
1681 c_parser_translation_unit (c_parser
*parser
)
1683 if (c_parser_next_token_is (parser
, CPP_EOF
))
1685 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1686 "ISO C forbids an empty translation unit");
1690 void *obstack_position
= obstack_alloc (&parser_obstack
, 0);
1691 mark_valid_location_for_stdc_pragma (false);
1695 c_parser_external_declaration (parser
);
1696 obstack_free (&parser_obstack
, obstack_position
);
1698 while (c_parser_next_token_is_not (parser
, CPP_EOF
));
1703 FOR_EACH_VEC_ELT (incomplete_record_decls
, i
, decl
)
1704 if (DECL_SIZE (decl
) == NULL_TREE
&& TREE_TYPE (decl
) != error_mark_node
)
1705 error ("storage size of %q+D isn%'t known", decl
);
1707 if (vec_safe_length (current_omp_declare_target_attribute
))
1709 c_omp_declare_target_attr
1710 a
= current_omp_declare_target_attribute
->pop ();
1712 error ("%qs without corresponding %qs",
1713 a
.device_type
>= 0 ? "#pragma omp begin declare target"
1714 : "#pragma omp declare target",
1715 "#pragma omp end declare target");
1716 vec_safe_truncate (current_omp_declare_target_attribute
, 0);
1718 if (current_omp_begin_assumes
)
1721 error ("%qs without corresponding %qs",
1722 "#pragma omp begin assumes", "#pragma omp end assumes");
1723 current_omp_begin_assumes
= 0;
1727 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1729 external-declaration:
1735 external-declaration:
1738 __extension__ external-declaration
1742 external-declaration:
1743 objc-class-definition
1744 objc-class-declaration
1745 objc-alias-declaration
1746 objc-protocol-definition
1747 objc-method-definition
1752 c_parser_external_declaration (c_parser
*parser
)
1755 switch (c_parser_peek_token (parser
)->type
)
1758 switch (c_parser_peek_token (parser
)->keyword
)
1761 ext
= disable_extension_diagnostics ();
1762 c_parser_consume_token (parser
);
1763 c_parser_external_declaration (parser
);
1764 restore_extension_diagnostics (ext
);
1767 c_parser_asm_definition (parser
);
1769 case RID_AT_INTERFACE
:
1770 case RID_AT_IMPLEMENTATION
:
1771 gcc_assert (c_dialect_objc ());
1772 c_parser_objc_class_definition (parser
, NULL_TREE
);
1775 gcc_assert (c_dialect_objc ());
1776 c_parser_objc_class_declaration (parser
);
1779 gcc_assert (c_dialect_objc ());
1780 c_parser_objc_alias_declaration (parser
);
1782 case RID_AT_PROTOCOL
:
1783 gcc_assert (c_dialect_objc ());
1784 c_parser_objc_protocol_definition (parser
, NULL_TREE
);
1786 case RID_AT_PROPERTY
:
1787 gcc_assert (c_dialect_objc ());
1788 c_parser_objc_at_property_declaration (parser
);
1790 case RID_AT_SYNTHESIZE
:
1791 gcc_assert (c_dialect_objc ());
1792 c_parser_objc_at_synthesize_declaration (parser
);
1794 case RID_AT_DYNAMIC
:
1795 gcc_assert (c_dialect_objc ());
1796 c_parser_objc_at_dynamic_declaration (parser
);
1799 gcc_assert (c_dialect_objc ());
1800 c_parser_consume_token (parser
);
1801 objc_finish_implementation ();
1808 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1809 "ISO C does not allow extra %<;%> outside of a function");
1810 c_parser_consume_token (parser
);
1813 mark_valid_location_for_stdc_pragma (true);
1814 c_parser_pragma (parser
, pragma_external
, NULL
);
1815 mark_valid_location_for_stdc_pragma (false);
1819 if (c_dialect_objc ())
1821 c_parser_objc_method_definition (parser
);
1824 /* Else fall through, and yield a syntax error trying to parse
1825 as a declaration or function definition. */
1829 /* A declaration or a function definition (or, in Objective-C,
1830 an @interface or @protocol with prefix attributes). We can
1831 only tell which after parsing the declaration specifiers, if
1832 any, and the first declarator. */
1833 c_parser_declaration_or_fndef (parser
, true, true, true, false, true);
1838 static void c_finish_omp_declare_simd (c_parser
*, tree
, tree
, vec
<c_token
> *);
1839 static void c_finish_oacc_routine (struct oacc_routine_data
*, tree
, bool);
1841 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1844 add_debug_begin_stmt (location_t loc
)
1846 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1847 if (!MAY_HAVE_DEBUG_MARKER_STMTS
|| !building_stmt_list_p ())
1850 tree stmt
= build0 (DEBUG_BEGIN_STMT
, void_type_node
);
1851 SET_EXPR_LOCATION (stmt
, loc
);
1855 /* Helper function for c_parser_declaration_or_fndef and
1856 Handle assume attribute(s). */
1859 handle_assume_attribute (location_t here
, tree attrs
, bool nested
)
1862 for (tree attr
= lookup_attribute ("gnu", "assume", attrs
); attr
;
1863 attr
= lookup_attribute ("gnu", "assume", TREE_CHAIN (attr
)))
1865 tree args
= TREE_VALUE (attr
);
1866 int nargs
= list_length (args
);
1869 error_at (here
, "wrong number of arguments specified "
1870 "for %qE attribute",
1871 get_attribute_name (attr
));
1872 inform (here
, "expected %i, found %i", 1, nargs
);
1876 tree arg
= TREE_VALUE (args
);
1877 arg
= c_objc_common_truthvalue_conversion (here
, arg
);
1878 arg
= c_fully_fold (arg
, false, NULL
);
1879 if (arg
!= error_mark_node
)
1881 tree fn
= build_call_expr_internal_loc (here
, IFN_ASSUME
,
1889 pedwarn (here
, OPT_Wattributes
,
1890 "%<assume%> attribute at top level");
1892 return remove_attribute ("gnu", "assume", attrs
);
1895 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1896 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1897 is accepted; otherwise (old-style parameter declarations) only other
1898 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1899 assertion is accepted; otherwise (old-style parameter declarations)
1900 it is not. If NESTED is true, we are inside a function or parsing
1901 old-style parameter declarations; any functions encountered are
1902 nested functions and declaration specifiers are required; otherwise
1903 we are at top level and functions are normal functions and
1904 declaration specifiers may be optional. If EMPTY_OK is true, empty
1905 declarations are OK (subject to all other constraints); otherwise
1906 (old-style parameter declarations) they are diagnosed. If
1907 START_ATTR_OK is true, the declaration specifiers may start with
1908 attributes (GNU or standard); otherwise they may not.
1909 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1910 declaration when parsing an Objective-C foreach statement.
1911 FALLTHRU_ATTR_P is used to signal whether this function parsed
1912 "__attribute__((fallthrough));". ATTRS are any standard attributes
1913 parsed in the caller (in contexts where such attributes had to be
1914 parsed to determine whether what follows is a declaration or a
1915 statement); HAVE_ATTRS says whether there were any such attributes
1919 declaration-specifiers init-declarator-list[opt] ;
1920 static_assert-declaration
1922 function-definition:
1923 declaration-specifiers[opt] declarator declaration-list[opt]
1928 declaration-list declaration
1930 init-declarator-list:
1932 init-declarator-list , init-declarator
1935 declarator simple-asm-expr[opt] gnu-attributes[opt]
1936 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1940 nested-function-definition:
1941 declaration-specifiers declarator declaration-list[opt]
1947 gnu-attributes objc-class-definition
1948 gnu-attributes objc-category-definition
1949 gnu-attributes objc-protocol-definition
1951 The simple-asm-expr and gnu-attributes are GNU extensions.
1953 This function does not handle __extension__; that is handled in its
1954 callers. ??? Following the old parser, __extension__ may start
1955 external declarations, declarations in functions and declarations
1956 at the start of "for" loops, but not old-style parameter
1959 C99 requires declaration specifiers in a function definition; the
1960 absence is diagnosed through the diagnosis of implicit int. In GNU
1961 C we also allow but diagnose declarations without declaration
1962 specifiers, but only at top level (elsewhere they conflict with
1965 In Objective-C, declarations of the looping variable in a foreach
1966 statement are exceptionally terminated by 'in' (for example, 'for
1967 (NSObject *object in array) { ... }').
1972 threadprivate-directive
1976 gimple-function-definition:
1977 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1978 declaration-list[opt] compound-statement
1980 rtl-function-definition:
1981 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1982 declaration-list[opt] compound-statement */
1985 c_parser_declaration_or_fndef (c_parser
*parser
, bool fndef_ok
,
1986 bool static_assert_ok
, bool empty_ok
,
1987 bool nested
, bool start_attr_ok
,
1988 tree
*objc_foreach_object_declaration
1990 vec
<c_token
> *omp_declare_simd_clauses
1992 bool have_attrs
/* = false */,
1993 tree attrs
/* = NULL_TREE */,
1994 struct oacc_routine_data
*oacc_routine_data
1996 bool *fallthru_attr_p
/* = NULL */)
1998 struct c_declspecs
*specs
;
2000 tree all_prefix_attrs
;
2001 bool diagnosed_no_specs
= false;
2002 location_t here
= c_parser_peek_token (parser
)->location
;
2004 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
2006 if (static_assert_ok
2007 && c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
2009 c_parser_static_assert_declaration (parser
);
2012 specs
= build_null_declspecs ();
2014 /* Handle any standard attributes parsed in the caller. */
2017 declspecs_add_attrs (here
, specs
, attrs
);
2018 specs
->non_std_attrs_seen_p
= false;
2021 /* Try to detect an unknown type name when we have "A B" or "A *B". */
2022 if (c_parser_peek_token (parser
)->type
== CPP_NAME
2023 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
2024 && (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
2025 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
2026 && (!nested
|| !lookup_name (c_parser_peek_token (parser
)->value
)))
2028 tree name
= c_parser_peek_token (parser
)->value
;
2030 /* Issue a warning about NAME being an unknown type name, perhaps
2031 with some kind of hint.
2032 If the user forgot a "struct" etc, suggest inserting
2033 it. Otherwise, attempt to look for misspellings. */
2034 gcc_rich_location
richloc (here
);
2035 if (tag_exists_p (RECORD_TYPE
, name
))
2037 /* This is not C++ with its implicit typedef. */
2038 richloc
.add_fixit_insert_before ("struct ");
2040 "unknown type name %qE;"
2041 " use %<struct%> keyword to refer to the type",
2044 else if (tag_exists_p (UNION_TYPE
, name
))
2046 richloc
.add_fixit_insert_before ("union ");
2048 "unknown type name %qE;"
2049 " use %<union%> keyword to refer to the type",
2052 else if (tag_exists_p (ENUMERAL_TYPE
, name
))
2054 richloc
.add_fixit_insert_before ("enum ");
2056 "unknown type name %qE;"
2057 " use %<enum%> keyword to refer to the type",
2062 auto_diagnostic_group d
;
2063 name_hint hint
= lookup_name_fuzzy (name
, FUZZY_LOOKUP_TYPENAME
,
2065 if (const char *suggestion
= hint
.suggestion ())
2067 richloc
.add_fixit_replace (suggestion
);
2069 "unknown type name %qE; did you mean %qs?",
2073 error_at (here
, "unknown type name %qE", name
);
2076 /* Parse declspecs normally to get a correct pointer type, but avoid
2077 a further "fails to be a type name" error. Refuse nested functions
2078 since it is not how the user likely wants us to recover. */
2079 c_parser_peek_token (parser
)->type
= CPP_KEYWORD
;
2080 c_parser_peek_token (parser
)->keyword
= RID_VOID
;
2081 c_parser_peek_token (parser
)->value
= error_mark_node
;
2085 /* When there are standard attributes at the start of the
2086 declaration (to apply to the entity being declared), an
2087 init-declarator-list or function definition must be present. */
2088 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
2091 c_parser_declspecs (parser
, specs
, true, true, start_attr_ok
,
2092 true, true, start_attr_ok
, true, cla_nonabstract_decl
);
2095 c_parser_skip_to_end_of_block_or_statement (parser
);
2098 if (nested
&& !specs
->declspecs_seen_p
)
2100 c_parser_error (parser
, "expected declaration specifiers");
2101 c_parser_skip_to_end_of_block_or_statement (parser
);
2105 finish_declspecs (specs
);
2106 bool auto_type_p
= specs
->typespec_word
== cts_auto_type
;
2107 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2109 bool handled_assume
= false;
2110 if (specs
->typespec_kind
== ctsk_none
2111 && lookup_attribute ("gnu", "assume", specs
->attrs
))
2113 handled_assume
= true;
2115 = handle_assume_attribute (here
, specs
->attrs
, nested
);
2118 error_at (here
, "%<__auto_type%> in empty declaration");
2119 else if (specs
->typespec_kind
== ctsk_none
2120 && attribute_fallthrough_p (specs
->attrs
))
2122 if (fallthru_attr_p
!= NULL
)
2123 *fallthru_attr_p
= true;
2126 tree fn
= build_call_expr_internal_loc (here
, IFN_FALLTHROUGH
,
2131 pedwarn (here
, OPT_Wattributes
,
2132 "%<fallthrough%> attribute at top level");
2135 && !(have_attrs
&& specs
->non_std_attrs_seen_p
)
2140 shadow_tag_warned (specs
, 1);
2141 if (!handled_assume
)
2142 pedwarn (here
, 0, "empty declaration");
2144 c_parser_consume_token (parser
);
2145 if (oacc_routine_data
)
2146 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2150 /* Provide better error recovery. Note that a type name here is usually
2151 better diagnosed as a redeclaration. */
2153 && specs
->typespec_kind
== ctsk_tagdef
2154 && c_parser_next_token_starts_declspecs (parser
)
2155 && !c_parser_next_token_is (parser
, CPP_NAME
))
2157 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
2158 parser
->error
= false;
2159 shadow_tag_warned (specs
, 1);
2162 else if (c_dialect_objc () && !auto_type_p
)
2164 /* Prefix attributes are an error on method decls. */
2165 switch (c_parser_peek_token (parser
)->type
)
2169 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2173 warning_at (c_parser_peek_token (parser
)->location
,
2175 "prefix attributes are ignored for methods");
2176 specs
->attrs
= NULL_TREE
;
2179 c_parser_objc_method_definition (parser
);
2181 c_parser_objc_methodproto (parser
);
2187 /* This is where we parse 'attributes @interface ...',
2188 'attributes @implementation ...', 'attributes @protocol ...'
2189 (where attributes could be, for example, __attribute__
2192 switch (c_parser_peek_token (parser
)->keyword
)
2194 case RID_AT_INTERFACE
:
2196 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2198 c_parser_objc_class_definition (parser
, specs
->attrs
);
2202 case RID_AT_IMPLEMENTATION
:
2204 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2208 warning_at (c_parser_peek_token (parser
)->location
,
2210 "prefix attributes are ignored for implementations");
2211 specs
->attrs
= NULL_TREE
;
2213 c_parser_objc_class_definition (parser
, NULL_TREE
);
2217 case RID_AT_PROTOCOL
:
2219 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2221 c_parser_objc_protocol_definition (parser
, specs
->attrs
);
2228 case RID_AT_PROPERTY
:
2231 c_parser_error (parser
, "unexpected attribute");
2232 specs
->attrs
= NULL
;
2239 else if (attribute_fallthrough_p (specs
->attrs
))
2240 warning_at (here
, OPT_Wattributes
,
2241 "%<fallthrough%> attribute not followed by %<;%>");
2242 else if (lookup_attribute ("gnu", "assume", specs
->attrs
))
2243 warning_at (here
, OPT_Wattributes
,
2244 "%<assume%> attribute not followed by %<;%>");
2246 pending_xref_error ();
2247 prefix_attrs
= specs
->attrs
;
2248 all_prefix_attrs
= prefix_attrs
;
2249 specs
->attrs
= NULL_TREE
;
2252 struct c_declarator
*declarator
;
2255 tree fnbody
= NULL_TREE
;
2256 /* Declaring either one or more declarators (in which case we
2257 should diagnose if there were no declaration specifiers) or a
2258 function definition (in which case the diagnostic for
2259 implicit int suffices). */
2260 declarator
= c_parser_declarator (parser
,
2261 specs
->typespec_kind
!= ctsk_none
,
2262 C_DTR_NORMAL
, &dummy
);
2263 if (declarator
== NULL
)
2265 if (omp_declare_simd_clauses
)
2266 c_finish_omp_declare_simd (parser
, NULL_TREE
, NULL_TREE
,
2267 omp_declare_simd_clauses
);
2268 if (oacc_routine_data
)
2269 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2270 c_parser_skip_to_end_of_block_or_statement (parser
);
2273 if (auto_type_p
&& declarator
->kind
!= cdk_id
)
2276 "%<__auto_type%> requires a plain identifier"
2278 c_parser_skip_to_end_of_block_or_statement (parser
);
2281 if (c_parser_next_token_is (parser
, CPP_EQ
)
2282 || c_parser_next_token_is (parser
, CPP_COMMA
)
2283 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
2284 || c_parser_next_token_is_keyword (parser
, RID_ASM
)
2285 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
)
2286 || c_parser_next_token_is_keyword (parser
, RID_IN
))
2288 tree asm_name
= NULL_TREE
;
2289 tree postfix_attrs
= NULL_TREE
;
2290 if (!diagnosed_no_specs
&& !specs
->declspecs_seen_p
)
2292 diagnosed_no_specs
= true;
2293 pedwarn (here
, 0, "data definition has no type or storage class");
2295 /* Having seen a data definition, there cannot now be a
2296 function definition. */
2298 if (c_parser_next_token_is_keyword (parser
, RID_ASM
))
2299 asm_name
= c_parser_simple_asm_expr (parser
);
2300 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2302 postfix_attrs
= c_parser_gnu_attributes (parser
);
2303 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2305 /* This means there is an attribute specifier after
2306 the declarator in a function definition. Provide
2307 some more information for the user. */
2308 error_at (here
, "attributes should be specified before the "
2309 "declarator in a function definition");
2310 c_parser_skip_to_end_of_block_or_statement (parser
);
2314 if (c_parser_next_token_is (parser
, CPP_EQ
))
2318 location_t init_loc
;
2319 c_parser_consume_token (parser
);
2322 init_loc
= c_parser_peek_token (parser
)->location
;
2323 rich_location
richloc (line_table
, init_loc
);
2324 start_init (NULL_TREE
, asm_name
, global_bindings_p (), &richloc
);
2325 /* A parameter is initialized, which is invalid. Don't
2326 attempt to instrument the initializer. */
2327 int flag_sanitize_save
= flag_sanitize
;
2328 if (nested
&& !empty_ok
)
2330 init
= c_parser_expr_no_commas (parser
, NULL
);
2331 flag_sanitize
= flag_sanitize_save
;
2332 if (TREE_CODE (init
.value
) == COMPONENT_REF
2333 && DECL_C_BIT_FIELD (TREE_OPERAND (init
.value
, 1)))
2335 "%<__auto_type%> used with a bit-field"
2337 init
= convert_lvalue_to_rvalue (init_loc
, init
, true, true);
2338 tree init_type
= TREE_TYPE (init
.value
);
2339 bool vm_type
= variably_modified_type_p (init_type
,
2342 init
.value
= save_expr (init
.value
);
2344 specs
->typespec_kind
= ctsk_typeof
;
2345 specs
->locations
[cdw_typedef
] = init_loc
;
2346 specs
->typedef_p
= true;
2347 specs
->type
= init_type
;
2350 bool maybe_const
= true;
2351 tree type_expr
= c_fully_fold (init
.value
, false,
2353 specs
->expr_const_operands
&= maybe_const
;
2355 specs
->expr
= build2 (COMPOUND_EXPR
,
2356 TREE_TYPE (type_expr
),
2357 specs
->expr
, type_expr
);
2359 specs
->expr
= type_expr
;
2361 d
= start_decl (declarator
, specs
, true,
2362 chainon (postfix_attrs
, all_prefix_attrs
));
2364 d
= error_mark_node
;
2365 if (omp_declare_simd_clauses
)
2366 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2367 omp_declare_simd_clauses
);
2371 /* The declaration of the variable is in effect while
2372 its initializer is parsed. */
2373 d
= start_decl (declarator
, specs
, true,
2374 chainon (postfix_attrs
, all_prefix_attrs
));
2376 d
= error_mark_node
;
2377 if (omp_declare_simd_clauses
)
2378 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2379 omp_declare_simd_clauses
);
2380 init_loc
= c_parser_peek_token (parser
)->location
;
2381 rich_location
richloc (line_table
, init_loc
);
2382 start_init (d
, asm_name
, global_bindings_p (), &richloc
);
2383 /* A parameter is initialized, which is invalid. Don't
2384 attempt to instrument the initializer. */
2385 int flag_sanitize_save
= flag_sanitize
;
2386 if (TREE_CODE (d
) == PARM_DECL
)
2388 init
= c_parser_initializer (parser
, d
);
2389 flag_sanitize
= flag_sanitize_save
;
2392 if (oacc_routine_data
)
2393 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2394 if (d
!= error_mark_node
)
2396 maybe_warn_string_init (init_loc
, TREE_TYPE (d
), init
);
2397 finish_decl (d
, init_loc
, init
.value
,
2398 init
.original_type
, asm_name
);
2406 "%<__auto_type%> requires an initialized "
2407 "data declaration");
2408 c_parser_skip_to_end_of_block_or_statement (parser
);
2412 location_t lastloc
= UNKNOWN_LOCATION
;
2413 tree attrs
= chainon (postfix_attrs
, all_prefix_attrs
);
2414 tree d
= start_decl (declarator
, specs
, false, attrs
, &lastloc
);
2415 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2417 /* Find the innermost declarator that is neither cdk_id
2419 const struct c_declarator
*decl
= declarator
;
2420 const struct c_declarator
*last_non_id_attrs
= NULL
;
2428 last_non_id_attrs
= decl
;
2429 decl
= decl
->declarator
;
2433 decl
= decl
->declarator
;
2444 /* If it exists and is cdk_function declaration whose
2445 arguments have not been set yet, use its arguments. */
2446 if (last_non_id_attrs
2447 && last_non_id_attrs
->kind
== cdk_function
)
2449 tree parms
= last_non_id_attrs
->u
.arg_info
->parms
;
2450 if (DECL_ARGUMENTS (d
) == NULL_TREE
2451 && DECL_INITIAL (d
) == NULL_TREE
)
2452 DECL_ARGUMENTS (d
) = parms
;
2454 warn_parm_array_mismatch (lastloc
, d
, parms
);
2457 if (omp_declare_simd_clauses
)
2459 tree parms
= NULL_TREE
;
2460 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2462 struct c_declarator
*ce
= declarator
;
2464 if (ce
->kind
== cdk_function
)
2466 parms
= ce
->u
.arg_info
->parms
;
2470 ce
= ce
->declarator
;
2473 temp_store_parm_decls (d
, parms
);
2474 c_finish_omp_declare_simd (parser
, d
, parms
,
2475 omp_declare_simd_clauses
);
2477 temp_pop_parm_decls ();
2479 if (oacc_routine_data
)
2480 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2482 finish_decl (d
, UNKNOWN_LOCATION
, NULL_TREE
,
2483 NULL_TREE
, asm_name
);
2485 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2488 *objc_foreach_object_declaration
= d
;
2490 *objc_foreach_object_declaration
= error_mark_node
;
2493 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2498 "%<__auto_type%> may only be used with"
2499 " a single declarator");
2500 c_parser_skip_to_end_of_block_or_statement (parser
);
2503 c_parser_consume_token (parser
);
2504 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2505 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
2508 all_prefix_attrs
= prefix_attrs
;
2511 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2513 c_parser_consume_token (parser
);
2516 else if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2518 /* This can only happen in Objective-C: we found the
2519 'in' that terminates the declaration inside an
2520 Objective-C foreach statement. Do not consume the
2521 token, so that the caller can use it to determine
2522 that this indeed is a foreach context. */
2527 c_parser_error (parser
, "expected %<,%> or %<;%>");
2528 c_parser_skip_to_end_of_block_or_statement (parser
);
2532 else if (auto_type_p
)
2535 "%<__auto_type%> requires an initialized data declaration");
2536 c_parser_skip_to_end_of_block_or_statement (parser
);
2541 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, "
2542 "%<asm%> or %<__attribute__%>");
2543 c_parser_skip_to_end_of_block_or_statement (parser
);
2546 /* Function definition (nested or otherwise). */
2549 pedwarn (here
, OPT_Wpedantic
, "ISO C forbids nested functions");
2550 c_push_function_context ();
2552 if (!start_function (specs
, declarator
, all_prefix_attrs
))
2554 /* At this point we've consumed:
2555 declaration-specifiers declarator
2556 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2557 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2559 declaration-specifiers declarator
2560 aren't grokkable as a function definition, so we have
2562 gcc_assert (!c_parser_next_token_is (parser
, CPP_SEMICOLON
));
2563 if (c_parser_next_token_starts_declspecs (parser
))
2566 declaration-specifiers declarator decl-specs
2567 then assume we have a missing semicolon, which would
2569 declaration-specifiers declarator decl-specs
2572 <~~~~~~~~~ declaration ~~~~~~~~~~>
2573 Use c_parser_require to get an error with a fix-it hint. */
2574 c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>");
2575 parser
->error
= false;
2579 /* This can appear in many cases looking nothing like a
2580 function definition, so we don't give a more specific
2581 error suggesting there was one. */
2582 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2583 "or %<__attribute__%>");
2586 c_pop_function_context ();
2590 if (DECL_DECLARED_INLINE_P (current_function_decl
))
2591 tv
= TV_PARSE_INLINE
;
2594 auto_timevar
at (g_timer
, tv
);
2596 /* Parse old-style parameter declarations. ??? Attributes are
2597 not allowed to start declaration specifiers here because of a
2598 syntax conflict between a function declaration with attribute
2599 suffix and a function definition with an attribute prefix on
2600 first old-style parameter declaration. Following the old
2601 parser, they are not accepted on subsequent old-style
2602 parameter declarations either. However, there is no
2603 ambiguity after the first declaration, nor indeed on the
2604 first as long as we don't allow postfix attributes after a
2605 declarator with a nonempty identifier list in a definition;
2606 and postfix attributes have never been accepted here in
2607 function definitions either. */
2608 while (c_parser_next_token_is_not (parser
, CPP_EOF
)
2609 && c_parser_next_token_is_not (parser
, CPP_OPEN_BRACE
))
2610 c_parser_declaration_or_fndef (parser
, false, false, false,
2612 store_parm_decls ();
2613 if (omp_declare_simd_clauses
)
2614 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2615 omp_declare_simd_clauses
);
2616 if (oacc_routine_data
)
2617 c_finish_oacc_routine (oacc_routine_data
, current_function_decl
, true);
2618 location_t startloc
= c_parser_peek_token (parser
)->location
;
2619 DECL_STRUCT_FUNCTION (current_function_decl
)->function_start_locus
2621 location_t endloc
= startloc
;
2623 /* If the definition was marked with __RTL, use the RTL parser now,
2624 consuming the function body. */
2625 if (specs
->declspec_il
== cdil_rtl
)
2627 endloc
= c_parser_parse_rtl_body (parser
, specs
->gimple_or_rtl_pass
);
2629 /* Normally, store_parm_decls sets next_is_function_body,
2630 anticipating a function body. We need a push_scope/pop_scope
2631 pair to flush out this state, or subsequent function parsing
2636 finish_function (endloc
);
2639 /* If the definition was marked with __GIMPLE then parse the
2640 function body as GIMPLE. */
2641 else if (specs
->declspec_il
!= cdil_none
)
2643 bool saved
= in_late_binary_op
;
2644 in_late_binary_op
= true;
2645 c_parser_parse_gimple_body (parser
, specs
->gimple_or_rtl_pass
,
2647 specs
->entry_bb_count
);
2648 in_late_binary_op
= saved
;
2651 fnbody
= c_parser_compound_statement (parser
, &endloc
);
2652 tree fndecl
= current_function_decl
;
2655 tree decl
= current_function_decl
;
2656 /* Mark nested functions as needing static-chain initially.
2657 lower_nested_functions will recompute it but the
2658 DECL_STATIC_CHAIN flag is also used before that happens,
2659 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2660 DECL_STATIC_CHAIN (decl
) = 1;
2662 finish_function (endloc
);
2663 c_pop_function_context ();
2664 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl
), DECL_EXPR
, decl
));
2670 finish_function (endloc
);
2672 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2673 if (specs
->declspec_il
!= cdil_none
)
2674 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
2680 /* Parse an asm-definition (asm() outside a function body). This is a
2688 c_parser_asm_definition (c_parser
*parser
)
2690 tree asm_str
= c_parser_simple_asm_expr (parser
);
2692 symtab
->finalize_toplevel_asm (asm_str
);
2693 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
2696 /* Parse a static assertion (C11 6.7.10).
2698 static_assert-declaration:
2699 static_assert-declaration-no-semi ;
2703 c_parser_static_assert_declaration (c_parser
*parser
)
2705 c_parser_static_assert_declaration_no_semi (parser
);
2707 || !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
2708 c_parser_skip_to_end_of_block_or_statement (parser
);
2711 /* Parse a static assertion (C11 6.7.10), without the trailing
2714 static_assert-declaration-no-semi:
2715 _Static_assert ( constant-expression , string-literal )
2718 static_assert-declaration-no-semi:
2719 _Static_assert ( constant-expression )
2723 c_parser_static_assert_declaration_no_semi (c_parser
*parser
)
2725 location_t assert_loc
, value_loc
;
2727 tree string
= NULL_TREE
;
2729 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
));
2730 tree spelling
= c_parser_peek_token (parser
)->value
;
2731 assert_loc
= c_parser_peek_token (parser
)->location
;
2733 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2734 "ISO C99 does not support %qE", spelling
);
2736 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2737 "ISO C90 does not support %qE", spelling
);
2738 c_parser_consume_token (parser
);
2739 matching_parens parens
;
2740 if (!parens
.require_open (parser
))
2742 location_t value_tok_loc
= c_parser_peek_token (parser
)->location
;
2743 value
= c_parser_expr_no_commas (parser
, NULL
).value
;
2744 value_loc
= EXPR_LOC_OR_LOC (value
, value_tok_loc
);
2745 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2747 c_parser_consume_token (parser
);
2748 switch (c_parser_peek_token (parser
)->type
)
2754 case CPP_UTF8STRING
:
2755 string
= c_parser_string_literal (parser
, false, true).value
;
2758 c_parser_error (parser
, "expected string literal");
2762 else if (flag_isoc11
)
2763 /* If pedantic for pre-C11, the use of _Static_assert itself will
2764 have been diagnosed, so do not also diagnose the use of this
2765 new C2X feature of _Static_assert. */
2766 pedwarn_c11 (assert_loc
, OPT_Wpedantic
,
2767 "ISO C11 does not support omitting the string in "
2769 parens
.require_close (parser
);
2771 if (!INTEGRAL_TYPE_P (TREE_TYPE (value
)))
2773 error_at (value_loc
, "expression in static assertion is not an integer");
2776 if (TREE_CODE (value
) != INTEGER_CST
)
2778 value
= c_fully_fold (value
, false, NULL
);
2779 /* Strip no-op conversions. */
2780 STRIP_TYPE_NOPS (value
);
2781 if (TREE_CODE (value
) == INTEGER_CST
)
2782 pedwarn (value_loc
, OPT_Wpedantic
, "expression in static assertion "
2783 "is not an integer constant expression");
2785 if (TREE_CODE (value
) != INTEGER_CST
)
2787 error_at (value_loc
, "expression in static assertion is not constant");
2790 constant_expression_warning (value
);
2791 if (integer_zerop (value
))
2794 error_at (assert_loc
, "static assertion failed: %E", string
);
2796 error_at (assert_loc
, "static assertion failed");
2800 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2801 6.7, C11 6.7), adding them to SPECS (which may already include some).
2802 Storage class specifiers are accepted iff SCSPEC_OK; type
2803 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2804 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2805 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2806 addition to the syntax shown, standard attributes are accepted at
2807 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2808 unlike gnu-attributes, they are not accepted in the middle of the
2809 list. (This combines various different syntax productions in the C
2810 standard, and in some cases gnu-attributes and standard attributes
2811 at the start may already have been parsed before this function is
2814 declaration-specifiers:
2815 storage-class-specifier declaration-specifiers[opt]
2816 type-specifier declaration-specifiers[opt]
2817 type-qualifier declaration-specifiers[opt]
2818 function-specifier declaration-specifiers[opt]
2819 alignment-specifier declaration-specifiers[opt]
2821 Function specifiers (inline) are from C99, and are currently
2822 handled as storage class specifiers, as is __thread. Alignment
2823 specifiers are from C11.
2825 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2826 storage-class-specifier:
2834 (_Thread_local is new in C11.)
2836 C99 6.7.4, C11 6.7.4:
2841 (_Noreturn is new in C11.)
2843 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2856 [_Imaginary removed in C99 TC2]
2857 struct-or-union-specifier
2860 atomic-type-specifier
2862 (_Bool and _Complex are new in C99.)
2863 (atomic-type-specifier is new in C11.)
2865 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2871 address-space-qualifier
2874 (restrict is new in C99.)
2875 (_Atomic is new in C11.)
2879 declaration-specifiers:
2880 gnu-attributes declaration-specifiers[opt]
2886 identifier recognized by the target
2888 storage-class-specifier:
2902 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2903 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2905 atomic-type-specifier
2906 _Atomic ( type-name )
2911 class-name objc-protocol-refs[opt]
2912 typedef-name objc-protocol-refs
2917 c_parser_declspecs (c_parser
*parser
, struct c_declspecs
*specs
,
2918 bool scspec_ok
, bool typespec_ok
, bool start_attr_ok
,
2919 bool alignspec_ok
, bool auto_type_ok
,
2920 bool start_std_attr_ok
, bool end_std_attr_ok
,
2921 enum c_lookahead_kind la
)
2923 bool attrs_ok
= start_attr_ok
;
2924 bool seen_type
= specs
->typespec_kind
!= ctsk_none
;
2927 gcc_assert (la
== cla_prefer_id
);
2929 if (start_std_attr_ok
2930 && c_parser_nth_token_starts_std_attributes (parser
, 1))
2932 gcc_assert (!specs
->non_std_attrs_seen_p
);
2933 location_t loc
= c_parser_peek_token (parser
)->location
;
2934 tree attrs
= c_parser_std_attribute_specifier_sequence (parser
);
2935 declspecs_add_attrs (loc
, specs
, attrs
);
2936 specs
->non_std_attrs_seen_p
= false;
2939 while (c_parser_next_token_is (parser
, CPP_NAME
)
2940 || c_parser_next_token_is (parser
, CPP_KEYWORD
)
2941 || (c_dialect_objc () && c_parser_next_token_is (parser
, CPP_LESS
)))
2943 struct c_typespec t
;
2946 location_t loc
= c_parser_peek_token (parser
)->location
;
2948 /* If we cannot accept a type, exit if the next token must start
2949 one. Also, if we already have seen a tagged definition,
2950 a typename would be an error anyway and likely the user
2951 has simply forgotten a semicolon, so we exit. */
2952 if ((!typespec_ok
|| specs
->typespec_kind
== ctsk_tagdef
)
2953 && c_parser_next_tokens_start_typename (parser
, la
)
2954 && !c_parser_next_token_is_qualifier (parser
)
2955 && !c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
))
2958 if (c_parser_next_token_is (parser
, CPP_NAME
))
2960 c_token
*name_token
= c_parser_peek_token (parser
);
2961 tree value
= name_token
->value
;
2962 c_id_kind kind
= name_token
->id_kind
;
2964 if (kind
== C_ID_ADDRSPACE
)
2967 = name_token
->keyword
- RID_FIRST_ADDR_SPACE
;
2968 declspecs_add_addrspace (name_token
->location
, specs
, as
);
2969 c_parser_consume_token (parser
);
2974 gcc_assert (!c_parser_next_token_is_qualifier (parser
));
2976 /* If we cannot accept a type, and the next token must start one,
2977 exit. Do the same if we already have seen a tagged definition,
2978 since it would be an error anyway and likely the user has simply
2979 forgotten a semicolon. */
2980 if (seen_type
|| !c_parser_next_tokens_start_typename (parser
, la
))
2983 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2984 a C_ID_CLASSNAME. */
2985 c_parser_consume_token (parser
);
2988 if (kind
== C_ID_ID
)
2990 error_at (loc
, "unknown type name %qE", value
);
2991 t
.kind
= ctsk_typedef
;
2992 t
.spec
= error_mark_node
;
2994 else if (kind
== C_ID_TYPENAME
2995 && (!c_dialect_objc ()
2996 || c_parser_next_token_is_not (parser
, CPP_LESS
)))
2998 t
.kind
= ctsk_typedef
;
2999 /* For a typedef name, record the meaning, not the name.
3000 In case of 'foo foo, bar;'. */
3001 t
.spec
= lookup_name (value
);
3005 tree proto
= NULL_TREE
;
3006 gcc_assert (c_dialect_objc ());
3008 if (c_parser_next_token_is (parser
, CPP_LESS
))
3009 proto
= c_parser_objc_protocol_refs (parser
);
3010 t
.spec
= objc_get_protocol_qualified_type (value
, proto
);
3013 t
.expr_const_operands
= true;
3014 declspecs_add_type (name_token
->location
, specs
, t
);
3017 if (c_parser_next_token_is (parser
, CPP_LESS
))
3019 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
3020 nisse@lysator.liu.se. */
3022 gcc_assert (c_dialect_objc ());
3023 if (!typespec_ok
|| seen_type
)
3025 proto
= c_parser_objc_protocol_refs (parser
);
3027 t
.spec
= objc_get_protocol_qualified_type (NULL_TREE
, proto
);
3029 t
.expr_const_operands
= true;
3030 declspecs_add_type (loc
, specs
, t
);
3033 gcc_assert (c_parser_next_token_is (parser
, CPP_KEYWORD
));
3034 switch (c_parser_peek_token (parser
)->keyword
)
3047 /* TODO: Distinguish between function specifiers (inline, noreturn)
3048 and storage class specifiers, either here or in
3049 declspecs_add_scspec. */
3050 declspecs_add_scspec (loc
, specs
,
3051 c_parser_peek_token (parser
)->value
);
3052 c_parser_consume_token (parser
);
3084 if (c_dialect_objc ())
3085 parser
->objc_need_raw_identifier
= true;
3086 t
.kind
= ctsk_resword
;
3087 t
.spec
= c_parser_peek_token (parser
)->value
;
3089 t
.expr_const_operands
= true;
3090 declspecs_add_type (loc
, specs
, t
);
3091 c_parser_consume_token (parser
);
3098 t
= c_parser_enum_specifier (parser
);
3099 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
3100 declspecs_add_type (loc
, specs
, t
);
3108 t
= c_parser_struct_or_union_specifier (parser
);
3109 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
3110 declspecs_add_type (loc
, specs
, t
);
3113 case RID_TYPEOF_UNQUAL
:
3114 /* ??? The old parser rejected typeof after other type
3115 specifiers, but is a syntax error the best way of
3117 if (!typespec_ok
|| seen_type
)
3121 t
= c_parser_typeof_specifier (parser
);
3122 declspecs_add_type (loc
, specs
, t
);
3125 /* C parser handling of Objective-C constructs needs
3126 checking for correct lvalue-to-rvalue conversions, and
3127 the code in build_modify_expr handling various
3128 Objective-C cases, and that in build_unary_op handling
3129 Objective-C cases for increment / decrement, also needs
3130 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3131 and objc_types_are_equivalent may also need updates. */
3132 if (c_dialect_objc ())
3133 sorry ("%<_Atomic%> in Objective-C");
3135 pedwarn_c99 (loc
, OPT_Wpedantic
,
3136 "ISO C99 does not support the %<_Atomic%> qualifier");
3138 pedwarn_c99 (loc
, OPT_Wpedantic
,
3139 "ISO C90 does not support the %<_Atomic%> qualifier");
3142 value
= c_parser_peek_token (parser
)->value
;
3143 c_parser_consume_token (parser
);
3144 if (typespec_ok
&& c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3146 /* _Atomic ( type-name ). */
3148 c_parser_consume_token (parser
);
3149 struct c_type_name
*type
= c_parser_type_name (parser
);
3150 t
.kind
= ctsk_typeof
;
3151 t
.spec
= error_mark_node
;
3153 t
.expr_const_operands
= true;
3155 t
.spec
= groktypename (type
, &t
.expr
,
3156 &t
.expr_const_operands
);
3157 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3159 if (t
.spec
!= error_mark_node
)
3161 if (TREE_CODE (t
.spec
) == ARRAY_TYPE
)
3162 error_at (loc
, "%<_Atomic%>-qualified array type");
3163 else if (TREE_CODE (t
.spec
) == FUNCTION_TYPE
)
3164 error_at (loc
, "%<_Atomic%>-qualified function type");
3165 else if (TYPE_QUALS (t
.spec
) != TYPE_UNQUALIFIED
)
3166 error_at (loc
, "%<_Atomic%> applied to a qualified type");
3168 t
.spec
= c_build_qualified_type (t
.spec
, TYPE_QUAL_ATOMIC
);
3170 declspecs_add_type (loc
, specs
, t
);
3173 declspecs_add_qual (loc
, specs
, value
);
3179 declspecs_add_qual (loc
, specs
, c_parser_peek_token (parser
)->value
);
3180 c_parser_consume_token (parser
);
3185 attrs
= c_parser_gnu_attributes (parser
);
3186 declspecs_add_attrs (loc
, specs
, attrs
);
3191 align
= c_parser_alignas_specifier (parser
);
3192 declspecs_add_alignas (loc
, specs
, align
);
3196 error_at (loc
, "%<__GIMPLE%> only valid with %<-fgimple%>");
3197 c_parser_consume_token (parser
);
3198 specs
->declspec_il
= cdil_gimple
;
3199 specs
->locations
[cdw_gimple
] = loc
;
3200 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3203 c_parser_consume_token (parser
);
3204 specs
->declspec_il
= cdil_rtl
;
3205 specs
->locations
[cdw_rtl
] = loc
;
3206 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3214 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3215 specs
->postfix_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3218 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3221 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3223 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3225 enum gnu-attributes[opt] identifier
3227 The form with trailing comma is new in C99. The forms with
3228 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3229 without commas in the syntax (assignment expressions, not just
3230 conditional expressions); assignment expressions will be diagnosed
3235 enumerator-list , enumerator
3238 enumeration-constant attribute-specifier-sequence[opt]
3239 enumeration-constant attribute-specifier-sequence[opt]
3240 = constant-expression
3245 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3246 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3247 = constant-expression
3251 static struct c_typespec
3252 c_parser_enum_specifier (c_parser
*parser
)
3254 struct c_typespec ret
;
3255 bool have_std_attrs
;
3256 tree std_attrs
= NULL_TREE
;
3258 tree ident
= NULL_TREE
;
3259 location_t enum_loc
;
3260 location_t ident_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3261 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ENUM
));
3262 c_parser_consume_token (parser
);
3263 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3265 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3266 attrs
= c_parser_gnu_attributes (parser
);
3267 enum_loc
= c_parser_peek_token (parser
)->location
;
3268 /* Set the location in case we create a decl now. */
3269 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3270 if (c_parser_next_token_is (parser
, CPP_NAME
))
3272 ident
= c_parser_peek_token (parser
)->value
;
3273 ident_loc
= c_parser_peek_token (parser
)->location
;
3274 enum_loc
= ident_loc
;
3275 c_parser_consume_token (parser
);
3277 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3279 /* Parse an enum definition. */
3280 struct c_enum_contents the_enum
;
3283 /* We chain the enumerators in reverse order, then put them in
3284 forward order at the end. */
3286 timevar_push (TV_PARSE_ENUM
);
3287 type
= start_enum (enum_loc
, &the_enum
, ident
);
3289 c_parser_consume_token (parser
);
3297 location_t comma_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3298 location_t decl_loc
, value_loc
;
3299 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
3301 /* Give a nicer error for "enum {}". */
3302 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3305 error_at (c_parser_peek_token (parser
)->location
,
3306 "empty enum is invalid");
3307 parser
->error
= true;
3310 c_parser_error (parser
, "expected identifier");
3311 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3312 values
= error_mark_node
;
3315 token
= c_parser_peek_token (parser
);
3316 enum_id
= token
->value
;
3317 /* Set the location in case we create a decl now. */
3318 c_parser_set_source_position_from_token (token
);
3319 decl_loc
= value_loc
= token
->location
;
3320 c_parser_consume_token (parser
);
3321 /* Parse any specified attributes. */
3322 tree std_attrs
= NULL_TREE
;
3323 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3324 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3325 tree enum_attrs
= chainon (std_attrs
,
3326 c_parser_gnu_attributes (parser
));
3327 if (c_parser_next_token_is (parser
, CPP_EQ
))
3329 c_parser_consume_token (parser
);
3330 value_loc
= c_parser_peek_token (parser
)->location
;
3331 enum_value
= c_parser_expr_no_commas (parser
, NULL
).value
;
3334 enum_value
= NULL_TREE
;
3335 enum_decl
= build_enumerator (decl_loc
, value_loc
,
3336 &the_enum
, enum_id
, enum_value
);
3338 decl_attributes (&TREE_PURPOSE (enum_decl
), enum_attrs
, 0);
3339 TREE_CHAIN (enum_decl
) = values
;
3342 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3344 comma_loc
= c_parser_peek_token (parser
)->location
;
3346 c_parser_consume_token (parser
);
3348 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3351 pedwarn_c90 (comma_loc
, OPT_Wpedantic
,
3352 "comma at end of enumerator list");
3353 c_parser_consume_token (parser
);
3358 c_parser_error (parser
, "expected %<,%> or %<}%>");
3359 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3360 values
= error_mark_node
;
3364 postfix_attrs
= c_parser_gnu_attributes (parser
);
3365 ret
.spec
= finish_enum (type
, nreverse (values
),
3367 chainon (attrs
, postfix_attrs
)));
3368 ret
.kind
= ctsk_tagdef
;
3369 ret
.expr
= NULL_TREE
;
3370 ret
.expr_const_operands
= true;
3371 timevar_pop (TV_PARSE_ENUM
);
3376 c_parser_error (parser
, "expected %<{%>");
3377 ret
.spec
= error_mark_node
;
3378 ret
.kind
= ctsk_tagref
;
3379 ret
.expr
= NULL_TREE
;
3380 ret
.expr_const_operands
= true;
3383 /* Attributes may only appear when the members are defined or in
3384 certain forward declarations (treat enum forward declarations in
3385 GNU C analogously to struct and union forward declarations in
3387 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3388 c_parser_error (parser
, "expected %<;%>");
3389 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
, have_std_attrs
,
3391 /* In ISO C, enumerated types can be referred to only if already
3393 if (pedantic
&& !COMPLETE_TYPE_P (ret
.spec
))
3396 pedwarn (enum_loc
, OPT_Wpedantic
,
3397 "ISO C forbids forward references to %<enum%> types");
3402 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3404 struct-or-union-specifier:
3405 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3406 identifier[opt] { struct-contents } gnu-attributes[opt]
3407 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3411 struct-declaration-list
3413 struct-declaration-list:
3414 struct-declaration ;
3415 struct-declaration-list struct-declaration ;
3422 struct-declaration-list struct-declaration
3424 struct-declaration-list:
3425 struct-declaration-list ;
3428 (Note that in the syntax here, unlike that in ISO C, the semicolons
3429 are included here rather than in struct-declaration, in order to
3430 describe the syntax with extra semicolons and missing semicolon at
3435 struct-declaration-list:
3436 @defs ( class-name )
3438 (Note this does not include a trailing semicolon, but can be
3439 followed by further declarations, and gets a pedwarn-if-pedantic
3440 when followed by a semicolon.) */
3442 static struct c_typespec
3443 c_parser_struct_or_union_specifier (c_parser
*parser
)
3445 struct c_typespec ret
;
3446 bool have_std_attrs
;
3447 tree std_attrs
= NULL_TREE
;
3449 tree ident
= NULL_TREE
;
3450 location_t struct_loc
;
3451 location_t ident_loc
= UNKNOWN_LOCATION
;
3452 enum tree_code code
;
3453 switch (c_parser_peek_token (parser
)->keyword
)
3464 struct_loc
= c_parser_peek_token (parser
)->location
;
3465 c_parser_consume_token (parser
);
3466 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3468 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3469 attrs
= c_parser_gnu_attributes (parser
);
3471 /* Set the location in case we create a decl now. */
3472 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3474 if (c_parser_next_token_is (parser
, CPP_NAME
))
3476 ident
= c_parser_peek_token (parser
)->value
;
3477 ident_loc
= c_parser_peek_token (parser
)->location
;
3478 struct_loc
= ident_loc
;
3479 c_parser_consume_token (parser
);
3481 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3483 /* Parse a struct or union definition. Start the scope of the
3484 tag before parsing components. */
3485 class c_struct_parse_info
*struct_info
;
3486 tree type
= start_struct (struct_loc
, code
, ident
, &struct_info
);
3488 /* We chain the components in reverse order, then put them in
3489 forward order at the end. Each struct-declaration may
3490 declare multiple components (comma-separated), so we must use
3491 chainon to join them, although when parsing each
3492 struct-declaration we can use TREE_CHAIN directly.
3494 The theory behind all this is that there will be more
3495 semicolon separated fields than comma separated fields, and
3496 so we'll be minimizing the number of node traversals required
3499 timevar_push (TV_PARSE_STRUCT
);
3500 contents
= NULL_TREE
;
3501 c_parser_consume_token (parser
);
3502 /* Handle the Objective-C @defs construct,
3503 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3504 if (c_parser_next_token_is_keyword (parser
, RID_AT_DEFS
))
3507 gcc_assert (c_dialect_objc ());
3508 c_parser_consume_token (parser
);
3509 matching_parens parens
;
3510 if (!parens
.require_open (parser
))
3512 if (c_parser_next_token_is (parser
, CPP_NAME
)
3513 && c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
)
3515 name
= c_parser_peek_token (parser
)->value
;
3516 c_parser_consume_token (parser
);
3520 c_parser_error (parser
, "expected class name");
3521 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
3524 parens
.skip_until_found_close (parser
);
3525 contents
= nreverse (objc_get_class_ivars (name
));
3528 /* Parse the struct-declarations and semicolons. Problems with
3529 semicolons are diagnosed here; empty structures are diagnosed
3534 /* Parse any stray semicolon. */
3535 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3537 location_t semicolon_loc
3538 = c_parser_peek_token (parser
)->location
;
3539 gcc_rich_location
richloc (semicolon_loc
);
3540 richloc
.add_fixit_remove ();
3541 pedwarn (&richloc
, OPT_Wpedantic
,
3542 "extra semicolon in struct or union specified");
3543 c_parser_consume_token (parser
);
3546 /* Stop if at the end of the struct or union contents. */
3547 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3549 c_parser_consume_token (parser
);
3552 /* Accept #pragmas at struct scope. */
3553 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
3555 c_parser_pragma (parser
, pragma_struct
, NULL
);
3558 /* Parse some comma-separated declarations, but not the
3559 trailing semicolon if any. */
3560 decls
= c_parser_struct_declaration (parser
);
3561 contents
= chainon (decls
, contents
);
3562 /* If no semicolon follows, either we have a parse error or
3563 are at the end of the struct or union and should
3565 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3566 c_parser_consume_token (parser
);
3569 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3570 pedwarn (c_parser_peek_token (parser
)->location
, 0,
3571 "no semicolon at end of struct or union");
3572 else if (parser
->error
3573 || !c_parser_next_token_starts_declspecs (parser
))
3575 c_parser_error (parser
, "expected %<;%>");
3576 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3580 /* If we come here, we have already emitted an error
3581 for an expected `;', identifier or `(', and we also
3582 recovered already. Go on with the next field. */
3585 postfix_attrs
= c_parser_gnu_attributes (parser
);
3586 ret
.spec
= finish_struct (struct_loc
, type
, nreverse (contents
),
3588 chainon (attrs
, postfix_attrs
)),
3590 ret
.kind
= ctsk_tagdef
;
3591 ret
.expr
= NULL_TREE
;
3592 ret
.expr_const_operands
= true;
3593 timevar_pop (TV_PARSE_STRUCT
);
3598 c_parser_error (parser
, "expected %<{%>");
3599 ret
.spec
= error_mark_node
;
3600 ret
.kind
= ctsk_tagref
;
3601 ret
.expr
= NULL_TREE
;
3602 ret
.expr_const_operands
= true;
3605 /* Attributes may only appear when the members are defined or in
3606 certain forward declarations. */
3607 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3608 c_parser_error (parser
, "expected %<;%>");
3609 /* ??? Existing practice is that GNU attributes are ignored after
3610 the struct or union keyword when not defining the members. */
3611 ret
= parser_xref_tag (ident_loc
, code
, ident
, have_std_attrs
, std_attrs
);
3615 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3616 *without* the trailing semicolon.
3619 attribute-specifier-sequence[opt] specifier-qualifier-list
3620 attribute-specifier-sequence[opt] struct-declarator-list
3621 static_assert-declaration-no-semi
3623 specifier-qualifier-list:
3624 type-specifier specifier-qualifier-list[opt]
3625 type-qualifier specifier-qualifier-list[opt]
3626 alignment-specifier specifier-qualifier-list[opt]
3627 gnu-attributes specifier-qualifier-list[opt]
3629 struct-declarator-list:
3631 struct-declarator-list , gnu-attributes[opt] struct-declarator
3634 declarator gnu-attributes[opt]
3635 declarator[opt] : constant-expression gnu-attributes[opt]
3640 __extension__ struct-declaration
3641 specifier-qualifier-list
3643 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3644 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3645 any expression without commas in the syntax (assignment
3646 expressions, not just conditional expressions); assignment
3647 expressions will be diagnosed as non-constant. */
3650 c_parser_struct_declaration (c_parser
*parser
)
3652 struct c_declspecs
*specs
;
3654 tree all_prefix_attrs
;
3656 location_t decl_loc
;
3657 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
3661 ext
= disable_extension_diagnostics ();
3662 c_parser_consume_token (parser
);
3663 decl
= c_parser_struct_declaration (parser
);
3664 restore_extension_diagnostics (ext
);
3667 if (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
3669 c_parser_static_assert_declaration_no_semi (parser
);
3672 specs
= build_null_declspecs ();
3673 decl_loc
= c_parser_peek_token (parser
)->location
;
3674 /* Strictly by the standard, we shouldn't allow _Alignas here,
3675 but it appears to have been intended to allow it there, so
3676 we're keeping it as it is until WG14 reaches a conclusion
3678 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3679 c_parser_declspecs (parser
, specs
, false, true, true,
3680 true, false, true, true, cla_nonabstract_decl
);
3683 if (!specs
->declspecs_seen_p
)
3685 c_parser_error (parser
, "expected specifier-qualifier-list");
3688 finish_declspecs (specs
);
3689 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3690 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3693 if (specs
->typespec_kind
== ctsk_none
)
3695 pedwarn (decl_loc
, OPT_Wpedantic
,
3696 "ISO C forbids member declarations with no members");
3697 shadow_tag_warned (specs
, pedantic
);
3702 /* Support for unnamed structs or unions as members of
3703 structs or unions (which is [a] useful and [b] supports
3707 ret
= grokfield (c_parser_peek_token (parser
)->location
,
3708 build_id_declarator (NULL_TREE
), specs
,
3711 decl_attributes (&ret
, attrs
, 0);
3716 /* Provide better error recovery. Note that a type name here is valid,
3717 and will be treated as a field name. */
3718 if (specs
->typespec_kind
== ctsk_tagdef
3719 && TREE_CODE (specs
->type
) != ENUMERAL_TYPE
3720 && c_parser_next_token_starts_declspecs (parser
)
3721 && !c_parser_next_token_is (parser
, CPP_NAME
))
3723 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
3724 parser
->error
= false;
3728 pending_xref_error ();
3729 prefix_attrs
= specs
->attrs
;
3730 all_prefix_attrs
= prefix_attrs
;
3731 specs
->attrs
= NULL_TREE
;
3735 /* Declaring one or more declarators or un-named bit-fields. */
3736 struct c_declarator
*declarator
;
3738 if (c_parser_next_token_is (parser
, CPP_COLON
))
3739 declarator
= build_id_declarator (NULL_TREE
);
3741 declarator
= c_parser_declarator (parser
,
3742 specs
->typespec_kind
!= ctsk_none
,
3743 C_DTR_NORMAL
, &dummy
);
3744 if (declarator
== NULL
)
3746 c_parser_skip_to_end_of_block_or_statement (parser
);
3749 if (c_parser_next_token_is (parser
, CPP_COLON
)
3750 || c_parser_next_token_is (parser
, CPP_COMMA
)
3751 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3752 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3753 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3755 tree postfix_attrs
= NULL_TREE
;
3756 tree width
= NULL_TREE
;
3758 if (c_parser_next_token_is (parser
, CPP_COLON
))
3760 c_parser_consume_token (parser
);
3761 width
= c_parser_expr_no_commas (parser
, NULL
).value
;
3763 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3764 postfix_attrs
= c_parser_gnu_attributes (parser
);
3765 d
= grokfield (c_parser_peek_token (parser
)->location
,
3766 declarator
, specs
, width
, &all_prefix_attrs
);
3767 decl_attributes (&d
, chainon (postfix_attrs
,
3768 all_prefix_attrs
), 0);
3769 DECL_CHAIN (d
) = decls
;
3771 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3772 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
3775 all_prefix_attrs
= prefix_attrs
;
3776 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3777 c_parser_consume_token (parser
);
3778 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3779 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3781 /* Semicolon consumed in caller. */
3786 c_parser_error (parser
, "expected %<,%>, %<;%> or %<}%>");
3792 c_parser_error (parser
,
3793 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3794 "%<__attribute__%>");
3801 /* Parse a typeof specifier (a GNU extension adopted in C2X).
3804 typeof ( expression )
3805 typeof ( type-name )
3806 typeof_unqual ( expression )
3807 typeof_unqual ( type-name )
3810 static struct c_typespec
3811 c_parser_typeof_specifier (c_parser
*parser
)
3815 struct c_typespec ret
;
3816 ret
.kind
= ctsk_typeof
;
3817 ret
.spec
= error_mark_node
;
3818 ret
.expr
= NULL_TREE
;
3819 ret
.expr_const_operands
= true;
3820 if (c_parser_next_token_is_keyword (parser
, RID_TYPEOF
))
3823 tree spelling
= c_parser_peek_token (parser
)->value
;
3824 is_std
= (flag_isoc2x
3825 && strcmp (IDENTIFIER_POINTER (spelling
), "typeof") == 0);
3829 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TYPEOF_UNQUAL
));
3833 c_parser_consume_token (parser
);
3834 c_inhibit_evaluation_warnings
++;
3836 matching_parens parens
;
3837 if (!parens
.require_open (parser
))
3839 c_inhibit_evaluation_warnings
--;
3843 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3845 struct c_type_name
*type
= c_parser_type_name (parser
);
3846 c_inhibit_evaluation_warnings
--;
3850 ret
.spec
= groktypename (type
, &ret
.expr
, &ret
.expr_const_operands
);
3851 pop_maybe_used (variably_modified_type_p (ret
.spec
, NULL_TREE
));
3857 location_t here
= c_parser_peek_token (parser
)->location
;
3858 struct c_expr expr
= c_parser_expression (parser
);
3859 c_inhibit_evaluation_warnings
--;
3861 if (TREE_CODE (expr
.value
) == COMPONENT_REF
3862 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
3863 error_at (here
, "%<typeof%> applied to a bit-field");
3864 mark_exp_read (expr
.value
);
3865 ret
.spec
= TREE_TYPE (expr
.value
);
3866 was_vm
= variably_modified_type_p (ret
.spec
, NULL_TREE
);
3867 /* This is returned with the type so that when the type is
3868 evaluated, this can be evaluated. */
3870 ret
.expr
= c_fully_fold (expr
.value
, false, &ret
.expr_const_operands
);
3871 pop_maybe_used (was_vm
);
3873 parens
.skip_until_found_close (parser
);
3874 if (ret
.spec
!= error_mark_node
)
3876 if (is_unqual
&& TYPE_QUALS (ret
.spec
) != TYPE_UNQUALIFIED
)
3877 ret
.spec
= TYPE_MAIN_VARIANT (ret
.spec
);
3880 /* In ISO C terms, _Noreturn is not part of the type of
3881 expressions such as &abort, but in GCC it is represented
3882 internally as a type qualifier. */
3883 if (TREE_CODE (ret
.spec
) == FUNCTION_TYPE
3884 && TYPE_QUALS (ret
.spec
) != TYPE_UNQUALIFIED
)
3885 ret
.spec
= TYPE_MAIN_VARIANT (ret
.spec
);
3886 else if (FUNCTION_POINTER_TYPE_P (ret
.spec
)
3887 && TYPE_QUALS (TREE_TYPE (ret
.spec
)) != TYPE_UNQUALIFIED
)
3889 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (ret
.spec
)));
3895 /* Parse an alignment-specifier.
3899 alignment-specifier:
3900 _Alignas ( type-name )
3901 _Alignas ( constant-expression )
3905 c_parser_alignas_specifier (c_parser
* parser
)
3907 tree ret
= error_mark_node
;
3908 location_t loc
= c_parser_peek_token (parser
)->location
;
3909 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
));
3910 tree spelling
= c_parser_peek_token (parser
)->value
;
3911 c_parser_consume_token (parser
);
3913 pedwarn_c99 (loc
, OPT_Wpedantic
,
3914 "ISO C99 does not support %qE", spelling
);
3916 pedwarn_c99 (loc
, OPT_Wpedantic
,
3917 "ISO C90 does not support %qE", spelling
);
3918 matching_parens parens
;
3919 if (!parens
.require_open (parser
))
3921 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3923 struct c_type_name
*type
= c_parser_type_name (parser
);
3925 ret
= c_sizeof_or_alignof_type (loc
, groktypename (type
, NULL
, NULL
),
3929 ret
= c_parser_expr_no_commas (parser
, NULL
).value
;
3930 parens
.skip_until_found_close (parser
);
3934 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3935 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3936 a typedef name may be redeclared; otherwise it may not. KIND
3937 indicates which kind of declarator is wanted. Returns a valid
3938 declarator except in the case of a syntax error in which case NULL is
3939 returned. *SEEN_ID is set to true if an identifier being declared is
3940 seen; this is used to diagnose bad forms of abstract array declarators
3941 and to determine whether an identifier list is syntactically permitted.
3944 pointer[opt] direct-declarator
3948 ( gnu-attributes[opt] declarator )
3949 direct-declarator array-declarator
3950 direct-declarator ( parameter-type-list )
3951 direct-declarator ( identifier-list[opt] )
3954 * type-qualifier-list[opt]
3955 * type-qualifier-list[opt] pointer
3957 type-qualifier-list:
3960 type-qualifier-list type-qualifier
3961 type-qualifier-list gnu-attributes
3964 [ type-qualifier-list[opt] assignment-expression[opt] ]
3965 [ static type-qualifier-list[opt] assignment-expression ]
3966 [ type-qualifier-list static assignment-expression ]
3967 [ type-qualifier-list[opt] * ]
3969 parameter-type-list:
3971 parameter-list , ...
3974 parameter-declaration
3975 parameter-list , parameter-declaration
3977 parameter-declaration:
3978 declaration-specifiers declarator gnu-attributes[opt]
3979 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3983 identifier-list , identifier
3985 abstract-declarator:
3987 pointer[opt] direct-abstract-declarator
3989 direct-abstract-declarator:
3990 ( gnu-attributes[opt] abstract-declarator )
3991 direct-abstract-declarator[opt] array-declarator
3992 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3997 direct-declarator ( parameter-forward-declarations
3998 parameter-type-list[opt] )
4000 direct-abstract-declarator:
4001 direct-abstract-declarator[opt] ( parameter-forward-declarations
4002 parameter-type-list[opt] )
4004 parameter-forward-declarations:
4006 parameter-forward-declarations parameter-list ;
4008 The uses of gnu-attributes shown above are GNU extensions.
4010 Some forms of array declarator are not included in C99 in the
4011 syntax for abstract declarators; these are disallowed elsewhere.
4012 This may be a defect (DR#289).
4014 This function also accepts an omitted abstract declarator as being
4015 an abstract declarator, although not part of the formal syntax. */
4017 struct c_declarator
*
4018 c_parser_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
4021 /* Parse any initial pointer part. */
4022 if (c_parser_next_token_is (parser
, CPP_MULT
))
4024 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4025 struct c_declarator
*inner
;
4026 c_parser_consume_token (parser
);
4027 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4028 false, false, true, false, cla_prefer_id
);
4029 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4033 return make_pointer_declarator (quals_attrs
, inner
);
4035 /* Now we have a direct declarator, direct abstract declarator or
4036 nothing (which counts as a direct abstract declarator here). */
4037 return c_parser_direct_declarator (parser
, type_seen_p
, kind
, seen_id
);
4040 /* Parse a direct declarator or direct abstract declarator; arguments
4041 as c_parser_declarator. */
4043 static struct c_declarator
*
4044 c_parser_direct_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
4047 /* The direct declarator must start with an identifier (possibly
4048 omitted) or a parenthesized declarator (possibly abstract). In
4049 an ordinary declarator, initial parentheses must start a
4050 parenthesized declarator. In an abstract declarator or parameter
4051 declarator, they could start a parenthesized declarator or a
4052 parameter list. To tell which, the open parenthesis and any
4053 following gnu-attributes must be read. If a declaration
4054 specifier or standard attributes follow, then it is a parameter
4055 list; if the specifier is a typedef name, there might be an
4056 ambiguity about redeclaring it, which is resolved in the
4057 direction of treating it as a typedef name. If a close
4058 parenthesis follows, it is also an empty parameter list, as the
4059 syntax does not permit empty abstract declarators. Otherwise, it
4060 is a parenthesized declarator (in which case the analysis may be
4061 repeated inside it, recursively).
4063 ??? There is an ambiguity in a parameter declaration "int
4064 (__attribute__((foo)) x)", where x is not a typedef name: it
4065 could be an abstract declarator for a function, or declare x with
4066 parentheses. The proper resolution of this ambiguity needs
4067 documenting. At present we follow an accident of the old
4068 parser's implementation, whereby the first parameter must have
4069 some declaration specifiers other than just gnu-attributes. Thus as
4070 a parameter declaration it is treated as a parenthesized
4071 parameter named x, and as an abstract declarator it is
4074 ??? Also following the old parser, gnu-attributes inside an empty
4075 parameter list are ignored, making it a list not yielding a
4076 prototype, rather than giving an error or making it have one
4077 parameter with implicit type int.
4079 ??? Also following the old parser, typedef names may be
4080 redeclared in declarators, but not Objective-C class names. */
4082 if (kind
!= C_DTR_ABSTRACT
4083 && c_parser_next_token_is (parser
, CPP_NAME
)
4085 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
4086 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
4087 || c_parser_peek_token (parser
)->id_kind
== C_ID_ID
))
4089 struct c_declarator
*inner
4090 = build_id_declarator (c_parser_peek_token (parser
)->value
);
4092 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
4093 c_parser_consume_token (parser
);
4094 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4095 inner
->u
.id
.attrs
= c_parser_std_attribute_specifier_sequence (parser
);
4096 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4099 if (kind
!= C_DTR_NORMAL
4100 && c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4101 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4103 struct c_declarator
*inner
= build_id_declarator (NULL_TREE
);
4104 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
4105 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4108 /* Either we are at the end of an abstract declarator, or we have
4111 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4114 struct c_declarator
*inner
;
4115 c_parser_consume_token (parser
);
4116 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4118 attrs
= c_parser_gnu_attributes (parser
);
4119 if (kind
!= C_DTR_NORMAL
4120 && (c_parser_next_token_starts_declspecs (parser
)
4122 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4123 || c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
)))
4125 struct c_arg_info
*args
4126 = c_parser_parms_declarator (parser
, kind
== C_DTR_NORMAL
,
4127 attrs
, have_gnu_attrs
);
4132 inner
= build_id_declarator (NULL_TREE
);
4134 && args
->types
!= error_mark_node
4135 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4136 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4139 = c_parser_std_attribute_specifier_sequence (parser
);
4141 inner
= build_attrs_declarator (std_attrs
, inner
);
4143 inner
= build_function_declarator (args
, inner
);
4144 return c_parser_direct_declarator_inner (parser
, *seen_id
,
4148 /* A parenthesized declarator. */
4149 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4150 if (inner
!= NULL
&& attrs
!= NULL
)
4151 inner
= build_attrs_declarator (attrs
, inner
);
4152 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4154 c_parser_consume_token (parser
);
4158 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4162 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4169 if (kind
== C_DTR_NORMAL
)
4171 c_parser_error (parser
, "expected identifier or %<(%>");
4175 return build_id_declarator (NULL_TREE
);
4179 /* Parse part of a direct declarator or direct abstract declarator,
4180 given that some (in INNER) has already been parsed; ID_PRESENT is
4181 true if an identifier is present, false for an abstract
4184 static struct c_declarator
*
4185 c_parser_direct_declarator_inner (c_parser
*parser
, bool id_present
,
4186 struct c_declarator
*inner
)
4188 /* Parse a sequence of array declarators and parameter lists. */
4189 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4190 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4192 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
4193 struct c_declarator
*declarator
;
4194 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4197 struct c_expr dimen
;
4198 dimen
.value
= NULL_TREE
;
4199 dimen
.original_code
= ERROR_MARK
;
4200 dimen
.original_type
= NULL_TREE
;
4201 c_parser_consume_token (parser
);
4202 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4203 false, false, false, false, cla_prefer_id
);
4204 static_seen
= c_parser_next_token_is_keyword (parser
, RID_STATIC
);
4206 c_parser_consume_token (parser
);
4207 if (static_seen
&& !quals_attrs
->declspecs_seen_p
)
4208 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4209 false, false, false, false, cla_prefer_id
);
4210 if (!quals_attrs
->declspecs_seen_p
)
4212 /* If "static" is present, there must be an array dimension.
4213 Otherwise, there may be a dimension, "*", or no
4218 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4222 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4224 dimen
.value
= NULL_TREE
;
4227 else if (c_parser_next_token_is (parser
, CPP_MULT
))
4229 if (c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_SQUARE
)
4231 dimen
.value
= NULL_TREE
;
4233 c_parser_consume_token (parser
);
4238 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4244 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4247 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4248 c_parser_consume_token (parser
);
4251 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4256 dimen
= convert_lvalue_to_rvalue (brace_loc
, dimen
, true, true);
4257 declarator
= build_array_declarator (brace_loc
, dimen
.value
, quals_attrs
,
4258 static_seen
, star_seen
);
4259 if (declarator
== NULL
)
4261 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4264 = c_parser_std_attribute_specifier_sequence (parser
);
4266 inner
= build_attrs_declarator (std_attrs
, inner
);
4268 inner
= set_array_declarator_inner (declarator
, inner
);
4269 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4271 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4274 struct c_arg_info
*args
;
4275 c_parser_consume_token (parser
);
4276 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4278 attrs
= c_parser_gnu_attributes (parser
);
4279 args
= c_parser_parms_declarator (parser
, id_present
, attrs
,
4286 && args
->types
!= error_mark_node
4287 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4288 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4291 = c_parser_std_attribute_specifier_sequence (parser
);
4293 inner
= build_attrs_declarator (std_attrs
, inner
);
4295 inner
= build_function_declarator (args
, inner
);
4296 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4302 /* Parse a parameter list or identifier list, including the closing
4303 parenthesis but not the opening one. ATTRS are the gnu-attributes
4304 at the start of the list. ID_LIST_OK is true if an identifier list
4305 is acceptable; such a list must not have attributes at the start.
4306 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4307 attributes) were present (in which case standard attributes cannot
4310 static struct c_arg_info
*
4311 c_parser_parms_declarator (c_parser
*parser
, bool id_list_ok
, tree attrs
,
4312 bool have_gnu_attrs
)
4315 declare_parm_level ();
4316 /* If the list starts with an identifier, it is an identifier list.
4317 Otherwise, it is either a prototype list or an empty list. */
4320 && c_parser_next_token_is (parser
, CPP_NAME
)
4321 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4323 /* Look ahead to detect typos in type names. */
4324 && c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
4325 && c_parser_peek_2nd_token (parser
)->type
!= CPP_MULT
4326 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
4327 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_SQUARE
4328 && c_parser_peek_2nd_token (parser
)->type
!= CPP_KEYWORD
)
4330 tree list
= NULL_TREE
, *nextp
= &list
;
4331 while (c_parser_next_token_is (parser
, CPP_NAME
)
4332 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
4334 *nextp
= build_tree_list (NULL_TREE
,
4335 c_parser_peek_token (parser
)->value
);
4336 nextp
= & TREE_CHAIN (*nextp
);
4337 c_parser_consume_token (parser
);
4338 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
4340 c_parser_consume_token (parser
);
4341 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4343 c_parser_error (parser
, "expected identifier");
4347 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4349 struct c_arg_info
*ret
= build_arg_info ();
4351 c_parser_consume_token (parser
);
4357 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4365 struct c_arg_info
*ret
4366 = c_parser_parms_list_declarator (parser
, attrs
, NULL
, have_gnu_attrs
);
4372 /* Parse a parameter list (possibly empty), including the closing
4373 parenthesis but not the opening one. ATTRS are the gnu-attributes
4374 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4375 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4376 which means standard attributes cannot start the list. EXPR is
4377 NULL or an expression that needs to be evaluated for the side
4378 effects of array size expressions in the parameters. */
4380 static struct c_arg_info
*
4381 c_parser_parms_list_declarator (c_parser
*parser
, tree attrs
, tree expr
,
4382 bool have_gnu_attrs
)
4384 bool bad_parm
= false;
4386 /* ??? Following the old parser, forward parameter declarations may
4387 use abstract declarators, and if no real parameter declarations
4388 follow the forward declarations then this is not diagnosed. Also
4389 note as above that gnu-attributes are ignored as the only contents of
4390 the parentheses, or as the only contents after forward
4392 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4394 struct c_arg_info
*ret
= build_arg_info ();
4395 c_parser_consume_token (parser
);
4398 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4400 struct c_arg_info
*ret
= build_arg_info ();
4402 if (flag_allow_parameterless_variadic_functions
)
4404 /* F (...) is allowed. */
4405 ret
->types
= NULL_TREE
;
4409 /* Suppress -Wold-style-definition for this case. */
4410 ret
->types
= error_mark_node
;
4411 error_at (c_parser_peek_token (parser
)->location
,
4412 "ISO C requires a named argument before %<...%>");
4414 c_parser_consume_token (parser
);
4415 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4417 c_parser_consume_token (parser
);
4422 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4427 /* Nonempty list of parameters, either terminated with semicolon
4428 (forward declarations; recurse) or with close parenthesis (normal
4429 function) or with ", ... )" (variadic function). */
4432 /* Parse a parameter. */
4433 struct c_parm
*parm
= c_parser_parameter_declaration (parser
, attrs
,
4436 have_gnu_attrs
= false;
4440 push_parm_decl (parm
, &expr
);
4441 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4444 c_parser_consume_token (parser
);
4445 mark_forward_parm_decls ();
4446 bool new_have_gnu_attrs
4447 = c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
);
4448 new_attrs
= c_parser_gnu_attributes (parser
);
4449 return c_parser_parms_list_declarator (parser
, new_attrs
, expr
,
4450 new_have_gnu_attrs
);
4452 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4454 c_parser_consume_token (parser
);
4458 return get_parm_info (false, expr
);
4460 if (!c_parser_require (parser
, CPP_COMMA
,
4461 "expected %<;%>, %<,%> or %<)%>",
4462 UNKNOWN_LOCATION
, false))
4464 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4467 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4469 c_parser_consume_token (parser
);
4470 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4472 c_parser_consume_token (parser
);
4476 return get_parm_info (true, expr
);
4480 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4488 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4489 start of the declaration if it is the first parameter;
4490 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4493 static struct c_parm
*
4494 c_parser_parameter_declaration (c_parser
*parser
, tree attrs
,
4495 bool have_gnu_attrs
)
4497 struct c_declspecs
*specs
;
4498 struct c_declarator
*declarator
;
4500 tree postfix_attrs
= NULL_TREE
;
4503 /* Accept #pragmas between parameter declarations. */
4504 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
4505 c_parser_pragma (parser
, pragma_param
, NULL
);
4507 if (!c_parser_next_token_starts_declspecs (parser
)
4508 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4510 c_token
*token
= c_parser_peek_token (parser
);
4513 c_parser_set_source_position_from_token (token
);
4514 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
4516 auto_diagnostic_group d
;
4517 name_hint hint
= lookup_name_fuzzy (token
->value
,
4518 FUZZY_LOOKUP_TYPENAME
,
4520 if (const char *suggestion
= hint
.suggestion ())
4522 gcc_rich_location
richloc (token
->location
);
4523 richloc
.add_fixit_replace (suggestion
);
4525 "unknown type name %qE; did you mean %qs?",
4526 token
->value
, suggestion
);
4529 error_at (token
->location
, "unknown type name %qE", token
->value
);
4530 parser
->error
= true;
4532 /* ??? In some Objective-C cases '...' isn't applicable so there
4533 should be a different message. */
4535 c_parser_error (parser
,
4536 "expected declaration specifiers or %<...%>");
4537 c_parser_skip_to_end_of_parameter (parser
);
4541 location_t start_loc
= c_parser_peek_token (parser
)->location
;
4543 specs
= build_null_declspecs ();
4546 declspecs_add_attrs (input_location
, specs
, attrs
);
4549 c_parser_declspecs (parser
, specs
, true, true, true, true, false,
4550 !have_gnu_attrs
, true, cla_nonabstract_decl
);
4551 finish_declspecs (specs
);
4552 pending_xref_error ();
4553 prefix_attrs
= specs
->attrs
;
4554 specs
->attrs
= NULL_TREE
;
4555 declarator
= c_parser_declarator (parser
,
4556 specs
->typespec_kind
!= ctsk_none
,
4557 C_DTR_PARM
, &dummy
);
4558 if (declarator
== NULL
)
4560 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
4563 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4564 postfix_attrs
= c_parser_gnu_attributes (parser
);
4566 /* Generate a location for the parameter, ranging from the start of the
4567 initial token to the end of the final token.
4569 If we have a identifier, then use it for the caret location, e.g.
4571 extern int callee (int one, int (*two)(int, int), float three);
4572 ~~~~~~^~~~~~~~~~~~~~
4574 otherwise, reuse the start location for the caret location e.g.:
4576 extern int callee (int one, int (*)(int, int), float three);
4579 location_t end_loc
= parser
->last_token_location
;
4581 /* Find any cdk_id declarator; determine if we have an identifier. */
4582 c_declarator
*id_declarator
= declarator
;
4583 while (id_declarator
&& id_declarator
->kind
!= cdk_id
)
4584 id_declarator
= id_declarator
->declarator
;
4585 location_t caret_loc
= (id_declarator
->u
.id
.id
4586 ? id_declarator
->id_loc
4588 location_t param_loc
= make_location (caret_loc
, start_loc
, end_loc
);
4590 return build_c_parm (specs
, chainon (postfix_attrs
, prefix_attrs
),
4591 declarator
, param_loc
);
4594 /* Parse a string literal in an asm expression. It should not be
4595 translated, and wide string literals are an error although
4596 permitted by the syntax. This is a GNU extension.
4603 c_parser_asm_string_literal (c_parser
*parser
)
4606 int save_flag
= warn_overlength_strings
;
4607 warn_overlength_strings
= 0;
4608 str
= c_parser_string_literal (parser
, false, false).value
;
4609 warn_overlength_strings
= save_flag
;
4613 /* Parse a simple asm expression. This is used in restricted
4614 contexts, where a full expression with inputs and outputs does not
4615 make sense. This is a GNU extension.
4618 asm ( asm-string-literal )
4622 c_parser_simple_asm_expr (c_parser
*parser
)
4625 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
4626 c_parser_consume_token (parser
);
4627 matching_parens parens
;
4628 if (!parens
.require_open (parser
))
4630 str
= c_parser_asm_string_literal (parser
);
4631 if (!parens
.require_close (parser
))
4633 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4640 c_parser_gnu_attribute_any_word (c_parser
*parser
)
4642 tree attr_name
= NULL_TREE
;
4644 if (c_parser_next_token_is (parser
, CPP_KEYWORD
))
4646 /* ??? See comment above about what keywords are accepted here. */
4648 switch (c_parser_peek_token (parser
)->keyword
)
4679 case RID_TRANSACTION_ATOMIC
:
4680 case RID_TRANSACTION_CANCEL
:
4696 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4697 attr_name
= ridpointers
[(int) c_parser_peek_token (parser
)->keyword
];
4699 else if (c_parser_next_token_is (parser
, CPP_NAME
))
4700 attr_name
= c_parser_peek_token (parser
)->value
;
4705 /* Parse attribute arguments. This is a common form of syntax
4706 covering all currently valid GNU and standard attributes.
4708 gnu-attribute-arguments:
4710 identifier , nonempty-expr-list
4713 where the "identifier" must not be declared as a type. ??? Why not
4714 allow identifiers declared as types to start the arguments? */
4717 c_parser_attribute_arguments (c_parser
*parser
, bool takes_identifier
,
4718 bool require_string
, bool assume_attr
,
4719 bool allow_empty_args
)
4721 vec
<tree
, va_gc
> *expr_list
;
4723 /* Parse the attribute contents. If they start with an
4724 identifier which is followed by a comma or close
4725 parenthesis, then the arguments start with that
4726 identifier; otherwise they are an expression list.
4727 In objective-c the identifier may be a classname. */
4728 if (c_parser_next_token_is (parser
, CPP_NAME
)
4729 && (c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4730 || (c_dialect_objc ()
4731 && c_parser_peek_token (parser
)->id_kind
4733 && ((c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
4734 || (c_parser_peek_2nd_token (parser
)->type
4735 == CPP_CLOSE_PAREN
))
4736 && (takes_identifier
4737 || (c_dialect_objc ()
4739 && c_parser_peek_token (parser
)->id_kind
4740 == C_ID_CLASSNAME
)))
4742 tree arg1
= c_parser_peek_token (parser
)->value
;
4743 c_parser_consume_token (parser
);
4744 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4745 attr_args
= build_tree_list (NULL_TREE
, arg1
);
4749 c_parser_consume_token (parser
);
4750 expr_list
= c_parser_expr_list (parser
, false, true,
4751 NULL
, NULL
, NULL
, NULL
);
4752 tree_list
= build_tree_list_vec (expr_list
);
4753 attr_args
= tree_cons (NULL_TREE
, arg1
, tree_list
);
4754 release_tree_vector (expr_list
);
4759 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4761 if (!allow_empty_args
)
4762 error_at (c_parser_peek_token (parser
)->location
,
4763 "parentheses must be omitted if "
4764 "attribute argument list is empty");
4765 attr_args
= NULL_TREE
;
4767 else if (require_string
)
4769 /* The only valid argument for this attribute is a string
4770 literal. Handle this specially here to avoid accepting
4771 string literals with excess parentheses. */
4772 tree string
= c_parser_string_literal (parser
, false, true).value
;
4773 attr_args
= build_tree_list (NULL_TREE
, string
);
4775 else if (assume_attr
)
4778 = c_parser_conditional_expression (parser
, NULL
, NULL_TREE
).value
;
4779 if (!c_parser_next_token_is (parser
, CPP_COMMA
))
4780 attr_args
= build_tree_list (NULL_TREE
, cond
);
4784 c_parser_consume_token (parser
);
4785 expr_list
= c_parser_expr_list (parser
, false, true,
4786 NULL
, NULL
, NULL
, NULL
);
4787 tree_list
= build_tree_list_vec (expr_list
);
4788 attr_args
= tree_cons (NULL_TREE
, cond
, tree_list
);
4789 release_tree_vector (expr_list
);
4794 expr_list
= c_parser_expr_list (parser
, false, true,
4795 NULL
, NULL
, NULL
, NULL
);
4796 attr_args
= build_tree_list_vec (expr_list
);
4797 release_tree_vector (expr_list
);
4803 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4807 gnu-attributes gnu-attribute
4810 __attribute__ ( ( gnu-attribute-list ) )
4814 gnu-attribute_list , gnu-attrib
4819 any-word ( gnu-attribute-arguments )
4821 where "any-word" may be any identifier (including one declared as a
4822 type), a reserved word storage class specifier, type specifier or
4823 type qualifier. ??? This still leaves out most reserved keywords
4824 (following the old parser), shouldn't we include them?
4825 When EXPECT_COMMA is true, expect the attribute to be preceded
4826 by a comma and fail if it isn't.
4827 When EMPTY_OK is true, allow and consume any number of consecutive
4828 commas with no attributes in between. */
4831 c_parser_gnu_attribute (c_parser
*parser
, tree attrs
,
4832 bool expect_comma
= false, bool empty_ok
= true)
4834 bool comma_first
= c_parser_next_token_is (parser
, CPP_COMMA
);
4836 && !c_parser_next_token_is (parser
, CPP_NAME
)
4837 && !c_parser_next_token_is (parser
, CPP_KEYWORD
))
4840 while (c_parser_next_token_is (parser
, CPP_COMMA
))
4842 c_parser_consume_token (parser
);
4847 tree attr_name
= c_parser_gnu_attribute_any_word (parser
);
4848 if (attr_name
== NULL_TREE
)
4851 attr_name
= canonicalize_attr_name (attr_name
);
4852 c_parser_consume_token (parser
);
4855 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4857 if (expect_comma
&& !comma_first
)
4859 /* A comma is missing between the last attribute on the chain
4861 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4863 return error_mark_node
;
4865 attr
= build_tree_list (attr_name
, NULL_TREE
);
4866 /* Add this attribute to the list. */
4867 attrs
= chainon (attrs
, attr
);
4870 c_parser_consume_token (parser
);
4873 = c_parser_attribute_arguments (parser
,
4874 attribute_takes_identifier_p (attr_name
),
4876 is_attribute_p ("assume", attr_name
),
4879 attr
= build_tree_list (attr_name
, attr_args
);
4880 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4881 c_parser_consume_token (parser
);
4884 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4886 return error_mark_node
;
4889 if (expect_comma
&& !comma_first
)
4891 /* A comma is missing between the last attribute on the chain
4893 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4895 return error_mark_node
;
4898 /* Add this attribute to the list. */
4899 attrs
= chainon (attrs
, attr
);
4904 c_parser_gnu_attributes (c_parser
*parser
)
4906 tree attrs
= NULL_TREE
;
4907 while (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4909 bool save_translate_strings_p
= parser
->translate_strings_p
;
4910 parser
->translate_strings_p
= false;
4911 /* Consume the `__attribute__' keyword. */
4912 c_parser_consume_token (parser
);
4913 /* Look for the two `(' tokens. */
4914 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4916 parser
->translate_strings_p
= save_translate_strings_p
;
4919 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4921 parser
->translate_strings_p
= save_translate_strings_p
;
4922 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4925 /* Parse the attribute list. Require a comma between successive
4926 (possibly empty) attributes. */
4927 for (bool expect_comma
= false; ; expect_comma
= true)
4929 /* Parse a single attribute. */
4930 tree attr
= c_parser_gnu_attribute (parser
, attrs
, expect_comma
);
4931 if (attr
== error_mark_node
)
4938 /* Look for the two `)' tokens. */
4939 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4940 c_parser_consume_token (parser
);
4943 parser
->translate_strings_p
= save_translate_strings_p
;
4944 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4948 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4949 c_parser_consume_token (parser
);
4952 parser
->translate_strings_p
= save_translate_strings_p
;
4953 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4957 parser
->translate_strings_p
= save_translate_strings_p
;
4963 /* Parse an optional balanced token sequence.
4965 balanced-token-sequence:
4967 balanced-token-sequence balanced-token
4970 ( balanced-token-sequence[opt] )
4971 [ balanced-token-sequence[opt] ]
4972 { balanced-token-sequence[opt] }
4973 any token other than ()[]{}
4977 c_parser_balanced_token_sequence (c_parser
*parser
)
4981 c_token
*token
= c_parser_peek_token (parser
);
4982 switch (token
->type
)
4984 case CPP_OPEN_BRACE
:
4986 matching_braces braces
;
4987 braces
.consume_open (parser
);
4988 c_parser_balanced_token_sequence (parser
);
4989 braces
.require_close (parser
);
4993 case CPP_OPEN_PAREN
:
4995 matching_parens parens
;
4996 parens
.consume_open (parser
);
4997 c_parser_balanced_token_sequence (parser
);
4998 parens
.require_close (parser
);
5002 case CPP_OPEN_SQUARE
:
5003 c_parser_consume_token (parser
);
5004 c_parser_balanced_token_sequence (parser
);
5005 c_parser_require (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5008 case CPP_CLOSE_BRACE
:
5009 case CPP_CLOSE_PAREN
:
5010 case CPP_CLOSE_SQUARE
:
5015 c_parser_consume_pragma (parser
);
5016 c_parser_skip_to_pragma_eol (parser
, false);
5020 c_parser_consume_token (parser
);
5026 /* Parse standard (C2X) attributes (including GNU attributes in the
5029 attribute-specifier-sequence:
5030 attribute-specifier-sequence[opt] attribute-specifier
5032 attribute-specifier:
5033 [ [ attribute-list ] ]
5037 attribute-list, attribute[opt]
5040 attribute-token attribute-argument-clause[opt]
5044 attribute-prefixed-token
5049 attribute-prefixed-token:
5050 attribute-prefix :: identifier
5055 attribute-argument-clause:
5056 ( balanced-token-sequence[opt] )
5058 Keywords are accepted as identifiers for this purpose.
5062 c_parser_std_attribute (c_parser
*parser
, bool for_tm
)
5064 c_token
*token
= c_parser_peek_token (parser
);
5065 tree ns
, name
, attribute
;
5067 /* Parse the attribute-token. */
5068 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
5070 c_parser_error (parser
, "expected identifier");
5071 return error_mark_node
;
5073 name
= canonicalize_attr_name (token
->value
);
5074 c_parser_consume_token (parser
);
5075 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
5078 c_parser_consume_token (parser
);
5079 token
= c_parser_peek_token (parser
);
5080 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
5082 c_parser_error (parser
, "expected identifier");
5083 return error_mark_node
;
5085 name
= canonicalize_attr_name (token
->value
);
5086 c_parser_consume_token (parser
);
5090 attribute
= build_tree_list (build_tree_list (ns
, name
), NULL_TREE
);
5092 /* Parse the arguments, if any. */
5093 const attribute_spec
*as
= lookup_attribute_spec (TREE_PURPOSE (attribute
));
5094 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
5097 location_t open_loc
= c_parser_peek_token (parser
)->location
;
5098 matching_parens parens
;
5099 parens
.consume_open (parser
);
5100 if ((as
&& as
->max_length
== 0)
5101 /* Special-case the transactional-memory attribute "outer",
5102 which is specially handled but not registered as an
5103 attribute, to avoid allowing arbitrary balanced token
5104 sequences as arguments. */
5105 || is_attribute_p ("outer", name
))
5107 error_at (open_loc
, "%qE attribute does not take any arguments", name
);
5108 parens
.skip_until_found_close (parser
);
5109 return error_mark_node
;
5111 /* If this is a fake attribute created to handle -Wno-attributes,
5112 we must skip parsing the arguments. */
5113 if (as
&& !attribute_ignored_p (as
))
5115 bool takes_identifier
5117 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
5118 && attribute_takes_identifier_p (name
));
5121 && (strcmp (IDENTIFIER_POINTER (name
), "deprecated") == 0
5122 || strcmp (IDENTIFIER_POINTER (name
), "nodiscard") == 0));
5125 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
5126 && strcmp (IDENTIFIER_POINTER (name
), "assume") == 0);
5127 TREE_VALUE (attribute
)
5128 = c_parser_attribute_arguments (parser
, takes_identifier
,
5129 require_string
, assume_attr
, false);
5132 c_parser_balanced_token_sequence (parser
);
5133 parens
.require_close (parser
);
5136 if (ns
== NULL_TREE
&& !for_tm
&& !as
)
5138 /* An attribute with standard syntax and no namespace specified
5139 is a constraint violation if it is not one of the known
5140 standard attributes. Diagnose it here with a pedwarn and
5141 then discard it to prevent a duplicate warning later. */
5142 pedwarn (input_location
, OPT_Wattributes
, "%qE attribute ignored",
5144 return error_mark_node
;
5150 c_parser_std_attribute_specifier (c_parser
*parser
, bool for_tm
)
5152 location_t loc
= c_parser_peek_token (parser
)->location
;
5153 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
5155 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
5157 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5161 pedwarn_c11 (loc
, OPT_Wpedantic
,
5162 "ISO C does not support %<[[]]%> attributes before C2X");
5163 tree attributes
= NULL_TREE
;
5166 c_token
*token
= c_parser_peek_token (parser
);
5167 if (token
->type
== CPP_CLOSE_SQUARE
)
5169 if (token
->type
== CPP_COMMA
)
5171 c_parser_consume_token (parser
);
5174 tree attribute
= c_parser_std_attribute (parser
, for_tm
);
5175 if (attribute
!= error_mark_node
)
5177 TREE_CHAIN (attribute
) = attributes
;
5178 attributes
= attribute
;
5180 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5183 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5184 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5185 return nreverse (attributes
);
5188 /* Look past an optional balanced token sequence of raw look-ahead
5189 tokens starting with the *Nth token. *N is updated to point to the
5190 following token. Return true if such a sequence was found, false
5191 if the tokens parsed were not balanced. */
5194 c_parser_check_balanced_raw_token_sequence (c_parser
*parser
, unsigned int *n
)
5198 c_token
*token
= c_parser_peek_nth_token_raw (parser
, *n
);
5199 switch (token
->type
)
5201 case CPP_OPEN_BRACE
:
5204 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5206 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5207 if (token
->type
== CPP_CLOSE_BRACE
)
5217 case CPP_OPEN_PAREN
:
5220 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5222 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5223 if (token
->type
== CPP_CLOSE_PAREN
)
5233 case CPP_OPEN_SQUARE
:
5236 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5238 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5239 if (token
->type
== CPP_CLOSE_SQUARE
)
5249 case CPP_CLOSE_BRACE
:
5250 case CPP_CLOSE_PAREN
:
5251 case CPP_CLOSE_SQUARE
:
5262 /* Return whether standard attributes start with the Nth token. */
5265 c_parser_nth_token_starts_std_attributes (c_parser
*parser
, unsigned int n
)
5267 if (!(c_parser_peek_nth_token (parser
, n
)->type
== CPP_OPEN_SQUARE
5268 && c_parser_peek_nth_token (parser
, n
+ 1)->type
== CPP_OPEN_SQUARE
))
5270 /* In C, '[[' must start attributes. In Objective-C, we need to
5271 check whether '[[' is matched by ']]'. */
5272 if (!c_dialect_objc ())
5275 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
5277 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
5278 if (token
->type
!= CPP_CLOSE_SQUARE
)
5280 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
5281 return token
->type
== CPP_CLOSE_SQUARE
;
5285 c_parser_std_attribute_specifier_sequence (c_parser
*parser
)
5287 tree attributes
= NULL_TREE
;
5290 tree attrs
= c_parser_std_attribute_specifier (parser
, false);
5291 attributes
= chainon (attributes
, attrs
);
5293 while (c_parser_nth_token_starts_std_attributes (parser
, 1));
5297 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5298 says whether alignment specifiers are OK (only in cases that might
5299 be the type name of a compound literal).
5302 specifier-qualifier-list abstract-declarator[opt]
5305 struct c_type_name
*
5306 c_parser_type_name (c_parser
*parser
, bool alignas_ok
)
5308 struct c_declspecs
*specs
= build_null_declspecs ();
5309 struct c_declarator
*declarator
;
5310 struct c_type_name
*ret
;
5312 c_parser_declspecs (parser
, specs
, false, true, true, alignas_ok
, false,
5313 false, true, cla_prefer_type
);
5314 if (!specs
->declspecs_seen_p
)
5316 c_parser_error (parser
, "expected specifier-qualifier-list");
5319 if (specs
->type
!= error_mark_node
)
5321 pending_xref_error ();
5322 finish_declspecs (specs
);
5324 declarator
= c_parser_declarator (parser
,
5325 specs
->typespec_kind
!= ctsk_none
,
5326 C_DTR_ABSTRACT
, &dummy
);
5327 if (declarator
== NULL
)
5329 ret
= XOBNEW (&parser_obstack
, struct c_type_name
);
5331 ret
->declarator
= declarator
;
5335 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5338 assignment-expression
5339 { initializer-list }
5340 { initializer-list , }
5343 designation[opt] initializer
5344 initializer-list , designation[opt] initializer
5351 designator-list designator
5358 [ constant-expression ]
5370 [ constant-expression ... constant-expression ]
5372 Any expression without commas is accepted in the syntax for the
5373 constant-expressions, with non-constant expressions rejected later.
5375 DECL is the declaration we're parsing this initializer for.
5377 This function is only used for top-level initializers; for nested
5378 ones, see c_parser_initval. */
5380 static struct c_expr
5381 c_parser_initializer (c_parser
*parser
, tree decl
)
5383 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
5384 return c_parser_braced_init (parser
, NULL_TREE
, false, NULL
, decl
);
5388 location_t loc
= c_parser_peek_token (parser
)->location
;
5389 if (decl
!= error_mark_node
&& C_DECL_VARIABLE_SIZE (decl
))
5391 "variable-sized object may not be initialized except "
5392 "with an empty initializer");
5393 ret
= c_parser_expr_no_commas (parser
, NULL
);
5394 /* This is handled mostly by gimplify.cc, but we have to deal with
5395 not warning about int x = x; as it is a GCC extension to turn off
5396 this warning but only if warn_init_self is zero. */
5398 && !DECL_EXTERNAL (decl
)
5399 && !TREE_STATIC (decl
)
5400 && ret
.value
== decl
5402 suppress_warning (decl
, OPT_Winit_self
);
5403 if (TREE_CODE (ret
.value
) != STRING_CST
5404 && TREE_CODE (ret
.value
) != COMPOUND_LITERAL_EXPR
)
5405 ret
= convert_lvalue_to_rvalue (loc
, ret
, true, true);
5410 /* The location of the last comma within the current initializer list,
5411 or UNKNOWN_LOCATION if not within one. */
5413 location_t last_init_list_comma
;
5415 /* Parse a braced initializer list. TYPE is the type specified for a
5416 compound literal, and NULL_TREE for other initializers and for
5417 nested braced lists. NESTED_P is true for nested braced lists,
5418 false for the list of a compound literal or the list that is the
5419 top-level initializer in a declaration. DECL is the declaration for
5420 the top-level initializer for a declaration, otherwise NULL_TREE. */
5422 static struct c_expr
5423 c_parser_braced_init (c_parser
*parser
, tree type
, bool nested_p
,
5424 struct obstack
*outer_obstack
, tree decl
)
5427 struct obstack braced_init_obstack
;
5428 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
5429 gcc_obstack_init (&braced_init_obstack
);
5430 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
5431 matching_braces braces
;
5432 braces
.consume_open (parser
);
5435 finish_implicit_inits (brace_loc
, outer_obstack
);
5436 push_init_level (brace_loc
, 0, &braced_init_obstack
);
5439 really_start_incremental_init (type
);
5440 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5442 pedwarn_c11 (brace_loc
, OPT_Wpedantic
,
5443 "ISO C forbids empty initializer braces before C2X");
5447 if (decl
&& decl
!= error_mark_node
&& C_DECL_VARIABLE_SIZE (decl
))
5448 error_at (brace_loc
,
5449 "variable-sized object may not be initialized except "
5450 "with an empty initializer");
5451 /* Parse a non-empty initializer list, possibly with a trailing
5455 c_parser_initelt (parser
, &braced_init_obstack
);
5458 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5460 last_init_list_comma
= c_parser_peek_token (parser
)->location
;
5461 c_parser_consume_token (parser
);
5465 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5469 c_token
*next_tok
= c_parser_peek_token (parser
);
5470 if (next_tok
->type
!= CPP_CLOSE_BRACE
)
5473 ret
.original_code
= ERROR_MARK
;
5474 ret
.original_type
= NULL
;
5475 braces
.skip_until_found_close (parser
);
5476 pop_init_level (brace_loc
, 0, &braced_init_obstack
, last_init_list_comma
);
5477 obstack_free (&braced_init_obstack
, NULL
);
5480 location_t close_loc
= next_tok
->location
;
5481 c_parser_consume_token (parser
);
5482 ret
= pop_init_level (brace_loc
, 0, &braced_init_obstack
, close_loc
);
5483 obstack_free (&braced_init_obstack
, NULL
);
5484 set_c_expr_source_range (&ret
, brace_loc
, close_loc
);
5488 /* Parse a nested initializer, including designators. */
5491 c_parser_initelt (c_parser
*parser
, struct obstack
* braced_init_obstack
)
5493 /* Parse any designator or designator list. A single array
5494 designator may have the subsequent "=" omitted in GNU C, but a
5495 longer list or a structure member designator may not. */
5496 if (c_parser_next_token_is (parser
, CPP_NAME
)
5497 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
5499 /* Old-style structure member designator. */
5500 set_init_label (c_parser_peek_token (parser
)->location
,
5501 c_parser_peek_token (parser
)->value
,
5502 c_parser_peek_token (parser
)->location
,
5503 braced_init_obstack
);
5504 /* Use the colon as the error location. */
5505 pedwarn (c_parser_peek_2nd_token (parser
)->location
, OPT_Wpedantic
,
5506 "obsolete use of designated initializer with %<:%>");
5507 c_parser_consume_token (parser
);
5508 c_parser_consume_token (parser
);
5512 /* des_seen is 0 if there have been no designators, 1 if there
5513 has been a single array designator and 2 otherwise. */
5515 /* Location of a designator. */
5516 location_t des_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5517 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
5518 || c_parser_next_token_is (parser
, CPP_DOT
))
5520 int des_prev
= des_seen
;
5522 des_loc
= c_parser_peek_token (parser
)->location
;
5525 if (c_parser_next_token_is (parser
, CPP_DOT
))
5528 c_parser_consume_token (parser
);
5529 if (c_parser_next_token_is (parser
, CPP_NAME
))
5531 set_init_label (des_loc
, c_parser_peek_token (parser
)->value
,
5532 c_parser_peek_token (parser
)->location
,
5533 braced_init_obstack
);
5534 c_parser_consume_token (parser
);
5540 init
.original_code
= ERROR_MARK
;
5541 init
.original_type
= NULL
;
5542 c_parser_error (parser
, "expected identifier");
5543 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5544 process_init_element (input_location
, init
, false,
5545 braced_init_obstack
);
5552 location_t ellipsis_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5553 location_t array_index_loc
= UNKNOWN_LOCATION
;
5554 /* ??? Following the old parser, [ objc-receiver
5555 objc-message-args ] is accepted as an initializer,
5556 being distinguished from a designator by what follows
5557 the first assignment expression inside the square
5558 brackets, but after a first array designator a
5559 subsequent square bracket is for Objective-C taken to
5560 start an expression, using the obsolete form of
5561 designated initializer without '=', rather than
5562 possibly being a second level of designation: in LALR
5563 terms, the '[' is shifted rather than reducing
5564 designator to designator-list. */
5565 if (des_prev
== 1 && c_dialect_objc ())
5567 des_seen
= des_prev
;
5570 if (des_prev
== 0 && c_dialect_objc ())
5572 /* This might be an array designator or an
5573 Objective-C message expression. If the former,
5574 continue parsing here; if the latter, parse the
5575 remainder of the initializer given the starting
5576 primary-expression. ??? It might make sense to
5577 distinguish when des_prev == 1 as well; see
5578 previous comment. */
5580 struct c_expr mexpr
;
5581 c_parser_consume_token (parser
);
5582 if (c_parser_peek_token (parser
)->type
== CPP_NAME
5583 && ((c_parser_peek_token (parser
)->id_kind
5585 || (c_parser_peek_token (parser
)->id_kind
5586 == C_ID_CLASSNAME
)))
5588 /* Type name receiver. */
5589 tree id
= c_parser_peek_token (parser
)->value
;
5590 c_parser_consume_token (parser
);
5591 rec
= objc_get_class_reference (id
);
5592 goto parse_message_args
;
5594 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
5595 mark_exp_read (first
);
5596 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
)
5597 || c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5598 goto array_desig_after_first
;
5599 /* Expression receiver. So far only one part
5600 without commas has been parsed; there might be
5601 more of the expression. */
5603 while (c_parser_next_token_is (parser
, CPP_COMMA
))
5606 location_t comma_loc
, exp_loc
;
5607 comma_loc
= c_parser_peek_token (parser
)->location
;
5608 c_parser_consume_token (parser
);
5609 exp_loc
= c_parser_peek_token (parser
)->location
;
5610 next
= c_parser_expr_no_commas (parser
, NULL
);
5611 next
= convert_lvalue_to_rvalue (exp_loc
, next
,
5613 rec
= build_compound_expr (comma_loc
, rec
, next
.value
);
5616 /* Now parse the objc-message-args. */
5617 args
= c_parser_objc_message_args (parser
);
5618 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5621 = objc_build_message_expr (rec
, args
);
5622 mexpr
.original_code
= ERROR_MARK
;
5623 mexpr
.original_type
= NULL
;
5624 mexpr
.m_decimal
= 0;
5625 /* Now parse and process the remainder of the
5626 initializer, starting with this message
5627 expression as a primary-expression. */
5628 c_parser_initval (parser
, &mexpr
, braced_init_obstack
);
5631 c_parser_consume_token (parser
);
5632 array_index_loc
= c_parser_peek_token (parser
)->location
;
5633 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
5634 mark_exp_read (first
);
5635 array_desig_after_first
:
5636 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5638 ellipsis_loc
= c_parser_peek_token (parser
)->location
;
5639 c_parser_consume_token (parser
);
5640 second
= c_parser_expr_no_commas (parser
, NULL
).value
;
5641 mark_exp_read (second
);
5645 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5647 c_parser_consume_token (parser
);
5648 set_init_index (array_index_loc
, first
, second
,
5649 braced_init_obstack
);
5651 pedwarn (ellipsis_loc
, OPT_Wpedantic
,
5652 "ISO C forbids specifying range of elements to initialize");
5655 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5661 if (c_parser_next_token_is (parser
, CPP_EQ
))
5663 pedwarn_c90 (des_loc
, OPT_Wpedantic
,
5664 "ISO C90 forbids specifying subobject "
5666 c_parser_consume_token (parser
);
5671 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
5672 "obsolete use of designated initializer without %<=%>");
5677 init
.original_code
= ERROR_MARK
;
5678 init
.original_type
= NULL
;
5679 c_parser_error (parser
, "expected %<=%>");
5680 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5681 process_init_element (input_location
, init
, false,
5682 braced_init_obstack
);
5688 c_parser_initval (parser
, NULL
, braced_init_obstack
);
5691 /* Parse a nested initializer; as c_parser_initializer but parses
5692 initializers within braced lists, after any designators have been
5693 applied. If AFTER is not NULL then it is an Objective-C message
5694 expression which is the primary-expression starting the
5698 c_parser_initval (c_parser
*parser
, struct c_expr
*after
,
5699 struct obstack
* braced_init_obstack
)
5702 gcc_assert (!after
|| c_dialect_objc ());
5703 location_t loc
= c_parser_peek_token (parser
)->location
;
5705 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
) && !after
)
5706 init
= c_parser_braced_init (parser
, NULL_TREE
, true,
5707 braced_init_obstack
, NULL_TREE
);
5710 init
= c_parser_expr_no_commas (parser
, after
);
5711 if (init
.value
!= NULL_TREE
5712 && TREE_CODE (init
.value
) != STRING_CST
5713 && TREE_CODE (init
.value
) != COMPOUND_LITERAL_EXPR
)
5714 init
= convert_lvalue_to_rvalue (loc
, init
, true, true);
5716 process_init_element (loc
, init
, false, braced_init_obstack
);
5719 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5720 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5723 { block-item-list[opt] }
5724 { label-declarations block-item-list }
5728 block-item-list block-item
5741 { label-declarations block-item-list }
5744 __extension__ nested-declaration
5745 nested-function-definition
5749 label-declarations label-declaration
5752 __label__ identifier-list ;
5754 Allowing the mixing of declarations and code is new in C99. The
5755 GNU syntax also permits (not shown above) labels at the end of
5756 compound statements, which yield an error. We don't allow labels
5757 on declarations; this might seem like a natural extension, but
5758 there would be a conflict between gnu-attributes on the label and
5759 prefix gnu-attributes on the declaration. ??? The syntax follows the
5760 old parser in requiring something after label declarations.
5761 Although they are erroneous if the labels declared aren't defined,
5762 is it useful for the syntax to be this way?
5783 cancellation-point-directive */
5786 c_parser_compound_statement (c_parser
*parser
, location_t
*endlocp
)
5789 location_t brace_loc
;
5790 brace_loc
= c_parser_peek_token (parser
)->location
;
5791 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
5793 /* Ensure a scope is entered and left anyway to avoid confusion
5794 if we have just prepared to enter a function body. */
5795 stmt
= c_begin_compound_stmt (true);
5796 c_end_compound_stmt (brace_loc
, stmt
, true);
5797 return error_mark_node
;
5799 stmt
= c_begin_compound_stmt (true);
5800 location_t end_loc
= c_parser_compound_statement_nostart (parser
);
5804 return c_end_compound_stmt (brace_loc
, stmt
, true);
5807 /* Parse a compound statement except for the opening brace. This is
5808 used for parsing both compound statements and statement expressions
5809 (which follow different paths to handling the opening). */
5812 c_parser_compound_statement_nostart (c_parser
*parser
)
5814 bool last_stmt
= false;
5815 bool last_label
= false;
5816 bool save_valid_for_pragma
= valid_location_for_stdc_pragma_p ();
5817 location_t label_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5818 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5820 location_t endloc
= c_parser_peek_token (parser
)->location
;
5821 add_debug_begin_stmt (endloc
);
5822 c_parser_consume_token (parser
);
5825 mark_valid_location_for_stdc_pragma (true);
5826 if (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5828 /* Read zero or more forward-declarations for labels that nested
5829 functions can jump to. */
5830 mark_valid_location_for_stdc_pragma (false);
5831 while (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5833 label_loc
= c_parser_peek_token (parser
)->location
;
5834 c_parser_consume_token (parser
);
5835 /* Any identifiers, including those declared as type names,
5840 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
5842 c_parser_error (parser
, "expected identifier");
5846 = declare_label (c_parser_peek_token (parser
)->value
);
5847 C_DECLARED_LABEL_FLAG (label
) = 1;
5848 add_stmt (build_stmt (label_loc
, DECL_EXPR
, label
));
5849 c_parser_consume_token (parser
);
5850 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5851 c_parser_consume_token (parser
);
5855 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
5857 pedwarn (label_loc
, OPT_Wpedantic
, "ISO C forbids label declarations");
5859 /* We must now have at least one statement, label or declaration. */
5860 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5862 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5863 c_parser_error (parser
, "expected declaration or statement");
5864 location_t endloc
= c_parser_peek_token (parser
)->location
;
5865 c_parser_consume_token (parser
);
5868 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_BRACE
))
5870 location_t loc
= c_parser_peek_token (parser
)->location
;
5871 loc
= expansion_point_location_if_in_system_header (loc
);
5872 /* Standard attributes may start a label, statement or declaration. */
5874 = c_parser_nth_token_starts_std_attributes (parser
, 1);
5875 tree std_attrs
= NULL_TREE
;
5877 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5878 if (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5879 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5880 || (c_parser_next_token_is (parser
, CPP_NAME
)
5881 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5883 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5884 label_loc
= c_parser_peek_2nd_token (parser
)->location
;
5886 label_loc
= c_parser_peek_token (parser
)->location
;
5889 mark_valid_location_for_stdc_pragma (false);
5890 c_parser_label (parser
, std_attrs
);
5892 else if (c_parser_next_tokens_start_declaration (parser
)
5894 && c_parser_next_token_is (parser
, CPP_SEMICOLON
)))
5897 pedwarn_c11 (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
5898 "a label can only be part of a statement and "
5899 "a declaration is not a statement");
5901 mark_valid_location_for_stdc_pragma (false);
5902 bool fallthru_attr_p
= false;
5903 c_parser_declaration_or_fndef (parser
, true, !have_std_attrs
,
5904 true, true, true, NULL
,
5905 NULL
, have_std_attrs
, std_attrs
,
5906 NULL
, &fallthru_attr_p
);
5908 if (last_stmt
&& !fallthru_attr_p
)
5909 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5910 "ISO C90 forbids mixed declarations and code");
5911 last_stmt
= fallthru_attr_p
;
5914 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
5916 /* __extension__ can start a declaration, but is also an
5917 unary operator that can start an expression. Consume all
5918 but the last of a possible series of __extension__ to
5919 determine which. If standard attributes have already
5920 been seen, it must start a statement, not a declaration,
5921 but standard attributes starting a declaration may appear
5922 after __extension__. */
5923 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
5924 && (c_parser_peek_2nd_token (parser
)->keyword
5926 c_parser_consume_token (parser
);
5928 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
5929 || c_parser_nth_token_starts_std_attributes (parser
, 2)))
5932 ext
= disable_extension_diagnostics ();
5933 c_parser_consume_token (parser
);
5935 mark_valid_location_for_stdc_pragma (false);
5936 c_parser_declaration_or_fndef (parser
, true, true, true, true,
5938 /* Following the old parser, __extension__ does not
5939 disable this diagnostic. */
5940 restore_extension_diagnostics (ext
);
5942 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5943 "ISO C90 forbids mixed declarations and code");
5949 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
5952 c_parser_error (parser
, "expected declaration or statement");
5953 /* External pragmas, and some omp pragmas, are not associated
5954 with regular c code, and so are not to be considered statements
5955 syntactically. This ensures that the user doesn't put them
5956 places that would turn into syntax errors if the directive
5958 if (c_parser_pragma (parser
,
5959 last_label
? pragma_stmt
: pragma_compound
,
5961 last_label
= false, last_stmt
= true;
5963 else if (c_parser_next_token_is (parser
, CPP_EOF
))
5965 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5966 c_parser_error (parser
, "expected declaration or statement");
5967 return c_parser_peek_token (parser
)->location
;
5969 else if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
5971 if (parser
->in_if_block
)
5973 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5974 error_at (loc
, "expected %<}%> before %<else%>");
5975 return c_parser_peek_token (parser
)->location
;
5979 error_at (loc
, "%<else%> without a previous %<if%>");
5980 c_parser_consume_token (parser
);
5987 c_warn_unused_attributes (std_attrs
);
5990 mark_valid_location_for_stdc_pragma (false);
5991 c_parser_statement_after_labels (parser
, NULL
);
5994 parser
->error
= false;
5997 pedwarn_c11 (label_loc
, OPT_Wpedantic
, "label at end of compound statement");
5998 location_t endloc
= c_parser_peek_token (parser
)->location
;
5999 c_parser_consume_token (parser
);
6000 /* Restore the value we started with. */
6001 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
6005 /* Parse all consecutive labels, possibly preceded by standard
6006 attributes. In this context, a statement is required, not a
6007 declaration, so attributes must be followed by a statement that is
6008 not just a semicolon. */
6011 c_parser_all_labels (c_parser
*parser
)
6013 tree std_attrs
= NULL
;
6014 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
6016 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
6017 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6018 c_parser_error (parser
, "expected statement");
6020 while (c_parser_next_token_is_keyword (parser
, RID_CASE
)
6021 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
6022 || (c_parser_next_token_is (parser
, CPP_NAME
)
6023 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
6025 c_parser_label (parser
, std_attrs
);
6027 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
6029 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
6030 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6031 c_parser_error (parser
, "expected statement");
6035 c_warn_unused_attributes (std_attrs
);
6038 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
6041 identifier : gnu-attributes[opt]
6042 case constant-expression :
6048 case constant-expression ... constant-expression :
6050 The use of gnu-attributes on labels is a GNU extension. The syntax in
6051 GNU C accepts any expressions without commas, non-constant
6052 expressions being rejected later. Any standard
6053 attribute-specifier-sequence before the first label has been parsed
6054 in the caller, to distinguish statements from declarations. Any
6055 attribute-specifier-sequence after the label is parsed in this
6058 c_parser_label (c_parser
*parser
, tree std_attrs
)
6060 location_t loc1
= c_parser_peek_token (parser
)->location
;
6061 tree label
= NULL_TREE
;
6063 /* Remember whether this case or a user-defined label is allowed to fall
6065 bool fallthrough_p
= c_parser_peek_token (parser
)->flags
& PREV_FALLTHROUGH
;
6067 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
6070 c_parser_consume_token (parser
);
6071 exp1
= c_parser_expr_no_commas (parser
, NULL
).value
;
6072 if (c_parser_next_token_is (parser
, CPP_COLON
))
6074 c_parser_consume_token (parser
);
6075 label
= do_case (loc1
, exp1
, NULL_TREE
, std_attrs
);
6077 else if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
6079 c_parser_consume_token (parser
);
6080 exp2
= c_parser_expr_no_commas (parser
, NULL
).value
;
6081 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
6082 label
= do_case (loc1
, exp1
, exp2
, std_attrs
);
6085 c_parser_error (parser
, "expected %<:%> or %<...%>");
6087 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
6089 c_parser_consume_token (parser
);
6090 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
6091 label
= do_case (loc1
, NULL_TREE
, NULL_TREE
, std_attrs
);
6095 tree name
= c_parser_peek_token (parser
)->value
;
6098 location_t loc2
= c_parser_peek_token (parser
)->location
;
6099 gcc_assert (c_parser_next_token_is (parser
, CPP_NAME
));
6100 c_parser_consume_token (parser
);
6101 gcc_assert (c_parser_next_token_is (parser
, CPP_COLON
));
6102 c_parser_consume_token (parser
);
6103 attrs
= c_parser_gnu_attributes (parser
);
6104 tlab
= define_label (loc2
, name
);
6107 decl_attributes (&tlab
, attrs
, 0);
6108 decl_attributes (&tlab
, std_attrs
, 0);
6109 label
= add_stmt (build_stmt (loc1
, LABEL_EXPR
, tlab
));
6112 && c_parser_next_tokens_start_declaration (parser
))
6113 warning_at (loc2
, OPT_Wattributes
, "GNU-style attribute between"
6114 " label and declaration appertains to the label");
6118 if (TREE_CODE (label
) == LABEL_EXPR
)
6119 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label
)) = fallthrough_p
;
6121 FALLTHROUGH_LABEL_P (CASE_LABEL (label
)) = fallthrough_p
;
6125 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
6129 attribute-specifier-sequence[opt] compound-statement
6130 expression-statement
6131 attribute-specifier-sequence[opt] selection-statement
6132 attribute-specifier-sequence[opt] iteration-statement
6133 attribute-specifier-sequence[opt] jump-statement
6136 attribute-specifier-sequence[opt] label statement
6138 expression-statement:
6140 attribute-specifier-sequence expression ;
6142 selection-statement:
6146 iteration-statement:
6155 return expression[opt] ;
6160 attribute-specifier-sequence[opt] asm-statement
6165 expression-statement:
6171 attribute-specifier-sequence[opt] objc-throw-statement
6172 attribute-specifier-sequence[opt] objc-try-catch-statement
6173 attribute-specifier-sequence[opt] objc-synchronized-statement
6175 objc-throw-statement:
6182 attribute-specifier-sequence[opt] openacc-construct
6191 parallel-directive structured-block
6194 kernels-directive structured-block
6197 data-directive structured-block
6200 loop-directive structured-block
6205 attribute-specifier-sequence[opt] openmp-construct
6214 parallel-for-construct
6215 parallel-for-simd-construct
6216 parallel-sections-construct
6223 parallel-directive structured-block
6226 for-directive iteration-statement
6229 simd-directive iteration-statements
6232 for-simd-directive iteration-statements
6235 sections-directive section-scope
6238 single-directive structured-block
6240 parallel-for-construct:
6241 parallel-for-directive iteration-statement
6243 parallel-for-simd-construct:
6244 parallel-for-simd-directive iteration-statement
6246 parallel-sections-construct:
6247 parallel-sections-directive section-scope
6250 master-directive structured-block
6253 critical-directive structured-block
6256 atomic-directive expression-statement
6259 ordered-directive structured-block
6261 Transactional Memory:
6264 attribute-specifier-sequence[opt] transaction-statement
6265 attribute-specifier-sequence[opt] transaction-cancel-statement
6267 IF_P is used to track whether there's a (possibly labeled) if statement
6268 which is not enclosed in braces and has an else clause. This is used to
6269 implement -Wparentheses. */
6272 c_parser_statement (c_parser
*parser
, bool *if_p
, location_t
*loc_after_labels
)
6274 c_parser_all_labels (parser
);
6275 if (loc_after_labels
)
6276 *loc_after_labels
= c_parser_peek_token (parser
)->location
;
6277 c_parser_statement_after_labels (parser
, if_p
, NULL
);
6280 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6281 of if-else-if conditions. All labels and standard attributes have
6282 been parsed in the caller.
6284 IF_P is used to track whether there's a (possibly labeled) if statement
6285 which is not enclosed in braces and has an else clause. This is used to
6286 implement -Wparentheses. */
6289 c_parser_statement_after_labels (c_parser
*parser
, bool *if_p
,
6292 location_t loc
= c_parser_peek_token (parser
)->location
;
6293 tree stmt
= NULL_TREE
;
6294 bool in_if_block
= parser
->in_if_block
;
6295 parser
->in_if_block
= false;
6299 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_BRACE
)
6300 add_debug_begin_stmt (loc
);
6303 switch (c_parser_peek_token (parser
)->type
)
6305 case CPP_OPEN_BRACE
:
6306 add_stmt (c_parser_compound_statement (parser
));
6309 switch (c_parser_peek_token (parser
)->keyword
)
6312 c_parser_if_statement (parser
, if_p
, chain
);
6315 c_parser_switch_statement (parser
, if_p
);
6318 c_parser_while_statement (parser
, false, 0, if_p
);
6321 c_parser_do_statement (parser
, false, 0);
6324 c_parser_for_statement (parser
, false, 0, if_p
);
6327 c_parser_consume_token (parser
);
6328 if (c_parser_next_token_is (parser
, CPP_NAME
))
6330 stmt
= c_finish_goto_label (loc
,
6331 c_parser_peek_token (parser
)->value
);
6332 c_parser_consume_token (parser
);
6334 else if (c_parser_next_token_is (parser
, CPP_MULT
))
6338 c_parser_consume_token (parser
);
6339 val
= c_parser_expression (parser
);
6340 val
= convert_lvalue_to_rvalue (loc
, val
, false, true);
6341 stmt
= c_finish_goto_ptr (loc
, val
);
6344 c_parser_error (parser
, "expected identifier or %<*%>");
6345 goto expect_semicolon
;
6347 c_parser_consume_token (parser
);
6348 stmt
= c_finish_bc_stmt (loc
, objc_foreach_continue_label
, false);
6349 goto expect_semicolon
;
6351 c_parser_consume_token (parser
);
6352 stmt
= c_finish_bc_stmt (loc
, objc_foreach_break_label
, true);
6353 goto expect_semicolon
;
6355 c_parser_consume_token (parser
);
6356 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6358 stmt
= c_finish_return (loc
, NULL_TREE
, NULL_TREE
);
6359 c_parser_consume_token (parser
);
6363 location_t xloc
= c_parser_peek_token (parser
)->location
;
6364 struct c_expr expr
= c_parser_expression_conv (parser
);
6365 mark_exp_read (expr
.value
);
6366 stmt
= c_finish_return (EXPR_LOC_OR_LOC (expr
.value
, xloc
),
6367 expr
.value
, expr
.original_type
);
6368 goto expect_semicolon
;
6372 stmt
= c_parser_asm_statement (parser
);
6374 case RID_TRANSACTION_ATOMIC
:
6375 case RID_TRANSACTION_RELAXED
:
6376 stmt
= c_parser_transaction (parser
,
6377 c_parser_peek_token (parser
)->keyword
);
6379 case RID_TRANSACTION_CANCEL
:
6380 stmt
= c_parser_transaction_cancel (parser
);
6381 goto expect_semicolon
;
6383 gcc_assert (c_dialect_objc ());
6384 c_parser_consume_token (parser
);
6385 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6387 stmt
= objc_build_throw_stmt (loc
, NULL_TREE
);
6388 c_parser_consume_token (parser
);
6392 struct c_expr expr
= c_parser_expression (parser
);
6393 expr
= convert_lvalue_to_rvalue (loc
, expr
, false, false);
6394 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
6395 stmt
= objc_build_throw_stmt (loc
, expr
.value
);
6396 goto expect_semicolon
;
6400 gcc_assert (c_dialect_objc ());
6401 c_parser_objc_try_catch_finally_statement (parser
);
6403 case RID_AT_SYNCHRONIZED
:
6404 gcc_assert (c_dialect_objc ());
6405 c_parser_objc_synchronized_statement (parser
);
6409 /* Allow '__attribute__((fallthrough));' or
6410 '__attribute__((assume(cond)));'. */
6411 tree attrs
= c_parser_gnu_attributes (parser
);
6412 bool has_assume
= lookup_attribute ("assume", attrs
);
6415 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6416 attrs
= handle_assume_attribute (loc
, attrs
, true);
6419 warning_at (loc
, OPT_Wattributes
,
6420 "%<assume%> attribute not followed by %<;%>");
6424 if (attribute_fallthrough_p (attrs
))
6426 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6428 tree fn
= build_call_expr_internal_loc (loc
,
6433 c_parser_consume_token (parser
);
6436 warning_at (loc
, OPT_Wattributes
,
6437 "%<fallthrough%> attribute not followed "
6440 else if (has_assume
)
6442 c_parser_consume_token (parser
);
6443 else if (attrs
!= NULL_TREE
)
6444 warning_at (loc
, OPT_Wattributes
,
6445 "only attribute %<fallthrough%> or %<assume%> can "
6446 "be applied to a null statement");
6454 c_parser_consume_token (parser
);
6456 case CPP_CLOSE_PAREN
:
6457 case CPP_CLOSE_SQUARE
:
6458 /* Avoid infinite loop in error recovery:
6459 c_parser_skip_until_found stops at a closing nesting
6460 delimiter without consuming it, but here we need to consume
6461 it to proceed further. */
6462 c_parser_error (parser
, "expected statement");
6463 c_parser_consume_token (parser
);
6466 if (!c_parser_pragma (parser
, pragma_stmt
, if_p
))
6471 stmt
= c_finish_expr_stmt (loc
, c_parser_expression_conv (parser
).value
);
6473 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
6476 /* Two cases cannot and do not have line numbers associated: If stmt
6477 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6478 cannot hold line numbers. But that's OK because the statement
6479 will either be changed to a MODIFY_EXPR during gimplification of
6480 the statement expr, or discarded. If stmt was compound, but
6481 without new variables, we will have skipped the creation of a
6482 BIND and will have a bare STATEMENT_LIST. But that's OK because
6483 (recursively) all of the component statements should already have
6484 line numbers assigned. ??? Can we discard no-op statements
6486 if (EXPR_LOCATION (stmt
) == UNKNOWN_LOCATION
)
6487 protected_set_expr_location (stmt
, loc
);
6489 parser
->in_if_block
= in_if_block
;
6492 /* Parse the condition from an if, do, while or for statements. */
6495 c_parser_condition (c_parser
*parser
)
6497 location_t loc
= c_parser_peek_token (parser
)->location
;
6499 cond
= c_parser_expression_conv (parser
).value
;
6500 cond
= c_objc_common_truthvalue_conversion (loc
, cond
);
6501 cond
= c_fully_fold (cond
, false, NULL
);
6502 if (warn_sequence_point
)
6503 verify_sequence_points (cond
);
6507 /* Parse a parenthesized condition from an if, do or while statement.
6513 c_parser_paren_condition (c_parser
*parser
)
6516 matching_parens parens
;
6517 if (!parens
.require_open (parser
))
6518 return error_mark_node
;
6519 cond
= c_parser_condition (parser
);
6520 parens
.skip_until_found_close (parser
);
6524 /* Parse a statement which is a block in C99.
6526 IF_P is used to track whether there's a (possibly labeled) if statement
6527 which is not enclosed in braces and has an else clause. This is used to
6528 implement -Wparentheses. */
6531 c_parser_c99_block_statement (c_parser
*parser
, bool *if_p
,
6532 location_t
*loc_after_labels
)
6534 tree block
= c_begin_compound_stmt (flag_isoc99
);
6535 location_t loc
= c_parser_peek_token (parser
)->location
;
6536 c_parser_statement (parser
, if_p
, loc_after_labels
);
6537 return c_end_compound_stmt (loc
, block
, flag_isoc99
);
6540 /* Parse the body of an if statement. This is just parsing a
6541 statement but (a) it is a block in C99, (b) we track whether the
6542 body is an if statement for the sake of -Wparentheses warnings, (c)
6543 we handle an empty body specially for the sake of -Wempty-body
6544 warnings, and (d) we call parser_compound_statement directly
6545 because c_parser_statement_after_labels resets
6546 parser->in_if_block.
6548 IF_P is used to track whether there's a (possibly labeled) if statement
6549 which is not enclosed in braces and has an else clause. This is used to
6550 implement -Wparentheses. */
6553 c_parser_if_body (c_parser
*parser
, bool *if_p
,
6554 const token_indent_info
&if_tinfo
)
6556 tree block
= c_begin_compound_stmt (flag_isoc99
);
6557 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6558 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6559 token_indent_info body_tinfo
6560 = get_token_indent_info (c_parser_peek_token (parser
));
6562 c_parser_all_labels (parser
);
6563 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6565 location_t loc
= c_parser_peek_token (parser
)->location
;
6566 add_stmt (build_empty_stmt (loc
));
6567 c_parser_consume_token (parser
);
6568 if (!c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6569 warning_at (loc
, OPT_Wempty_body
,
6570 "suggest braces around empty body in an %<if%> statement");
6572 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6573 add_stmt (c_parser_compound_statement (parser
));
6576 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6577 c_parser_statement_after_labels (parser
, if_p
);
6580 token_indent_info next_tinfo
6581 = get_token_indent_info (c_parser_peek_token (parser
));
6582 warn_for_misleading_indentation (if_tinfo
, body_tinfo
, next_tinfo
);
6583 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6584 && next_tinfo
.type
!= CPP_SEMICOLON
)
6585 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6586 if_tinfo
.location
, RID_IF
);
6588 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6591 /* Parse the else body of an if statement. This is just parsing a
6592 statement but (a) it is a block in C99, (b) we handle an empty body
6593 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6594 of if-else-if conditions. */
6597 c_parser_else_body (c_parser
*parser
, const token_indent_info
&else_tinfo
,
6600 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6601 tree block
= c_begin_compound_stmt (flag_isoc99
);
6602 token_indent_info body_tinfo
6603 = get_token_indent_info (c_parser_peek_token (parser
));
6604 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6606 c_parser_all_labels (parser
);
6607 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6609 location_t loc
= c_parser_peek_token (parser
)->location
;
6612 "suggest braces around empty body in an %<else%> statement");
6613 add_stmt (build_empty_stmt (loc
));
6614 c_parser_consume_token (parser
);
6618 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6619 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6620 c_parser_statement_after_labels (parser
, NULL
, chain
);
6623 token_indent_info next_tinfo
6624 = get_token_indent_info (c_parser_peek_token (parser
));
6625 warn_for_misleading_indentation (else_tinfo
, body_tinfo
, next_tinfo
);
6626 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6627 && next_tinfo
.type
!= CPP_SEMICOLON
)
6628 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6629 else_tinfo
.location
, RID_ELSE
);
6631 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6634 /* We might need to reclassify any previously-lexed identifier, e.g.
6635 when we've left a for loop with an if-statement without else in the
6636 body - we might have used a wrong scope for the token. See PR67784. */
6639 c_parser_maybe_reclassify_token (c_parser
*parser
)
6641 if (c_parser_next_token_is (parser
, CPP_NAME
))
6643 c_token
*token
= c_parser_peek_token (parser
);
6645 if (token
->id_kind
!= C_ID_CLASSNAME
)
6647 tree decl
= lookup_name (token
->value
);
6649 token
->id_kind
= C_ID_ID
;
6652 if (TREE_CODE (decl
) == TYPE_DECL
)
6653 token
->id_kind
= C_ID_TYPENAME
;
6655 else if (c_dialect_objc ())
6657 tree objc_interface_decl
= objc_is_class_name (token
->value
);
6658 /* Objective-C class names are in the same namespace as
6659 variables and typedefs, and hence are shadowed by local
6661 if (objc_interface_decl
)
6663 token
->value
= objc_interface_decl
;
6664 token
->id_kind
= C_ID_CLASSNAME
;
6671 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6674 if ( expression ) statement
6675 if ( expression ) statement else statement
6677 CHAIN is a vector of if-else-if conditions.
6678 IF_P is used to track whether there's a (possibly labeled) if statement
6679 which is not enclosed in braces and has an else clause. This is used to
6680 implement -Wparentheses. */
6683 c_parser_if_statement (c_parser
*parser
, bool *if_p
, vec
<tree
> *chain
)
6688 bool nested_if
= false;
6689 tree first_body
, second_body
;
6692 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_IF
));
6693 token_indent_info if_tinfo
6694 = get_token_indent_info (c_parser_peek_token (parser
));
6695 c_parser_consume_token (parser
);
6696 block
= c_begin_compound_stmt (flag_isoc99
);
6697 loc
= c_parser_peek_token (parser
)->location
;
6698 cond
= c_parser_paren_condition (parser
);
6699 in_if_block
= parser
->in_if_block
;
6700 parser
->in_if_block
= true;
6701 first_body
= c_parser_if_body (parser
, &nested_if
, if_tinfo
);
6702 parser
->in_if_block
= in_if_block
;
6704 if (warn_duplicated_cond
)
6705 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond
), cond
, &chain
);
6707 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6709 token_indent_info else_tinfo
6710 = get_token_indent_info (c_parser_peek_token (parser
));
6711 c_parser_consume_token (parser
);
6712 if (warn_duplicated_cond
)
6714 if (c_parser_next_token_is_keyword (parser
, RID_IF
)
6717 /* We've got "if (COND) else if (COND2)". Start the
6718 condition chain and add COND as the first element. */
6719 chain
= new vec
<tree
> ();
6720 if (!CONSTANT_CLASS_P (cond
) && !TREE_SIDE_EFFECTS (cond
))
6721 chain
->safe_push (cond
);
6723 else if (!c_parser_next_token_is_keyword (parser
, RID_IF
))
6724 /* This is if-else without subsequent if. Zap the condition
6725 chain; we would have already warned at this point. */
6728 second_body
= c_parser_else_body (parser
, else_tinfo
, chain
);
6729 /* Set IF_P to true to indicate that this if statement has an
6730 else clause. This may trigger the Wparentheses warning
6731 below when we get back up to the parent if statement. */
6737 second_body
= NULL_TREE
;
6739 /* Diagnose an ambiguous else if if-then-else is nested inside
6742 warning_at (loc
, OPT_Wdangling_else
,
6743 "suggest explicit braces to avoid ambiguous %<else%>");
6745 if (warn_duplicated_cond
)
6746 /* This if statement does not have an else clause. We don't
6747 need the condition chain anymore. */
6750 c_finish_if_stmt (loc
, cond
, first_body
, second_body
);
6751 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6753 c_parser_maybe_reclassify_token (parser
);
6756 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6759 switch (expression) statement
6763 c_parser_switch_statement (c_parser
*parser
, bool *if_p
)
6766 tree block
, expr
, body
;
6767 unsigned char save_in_statement
;
6768 location_t switch_loc
= c_parser_peek_token (parser
)->location
;
6769 location_t switch_cond_loc
;
6770 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SWITCH
));
6771 c_parser_consume_token (parser
);
6772 block
= c_begin_compound_stmt (flag_isoc99
);
6773 bool explicit_cast_p
= false;
6774 matching_parens parens
;
6775 if (parens
.require_open (parser
))
6777 switch_cond_loc
= c_parser_peek_token (parser
)->location
;
6778 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
6779 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
6780 explicit_cast_p
= true;
6781 ce
= c_parser_expression (parser
);
6782 ce
= convert_lvalue_to_rvalue (switch_cond_loc
, ce
, true, true);
6784 /* ??? expr has no valid location? */
6785 parens
.skip_until_found_close (parser
);
6789 switch_cond_loc
= UNKNOWN_LOCATION
;
6790 expr
= error_mark_node
;
6791 ce
.original_type
= error_mark_node
;
6793 c_start_switch (switch_loc
, switch_cond_loc
, expr
, explicit_cast_p
);
6794 save_in_statement
= in_statement
;
6795 in_statement
|= IN_SWITCH_STMT
;
6796 location_t loc_after_labels
;
6797 bool open_brace_p
= c_parser_peek_token (parser
)->type
== CPP_OPEN_BRACE
;
6798 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6799 location_t next_loc
= c_parser_peek_token (parser
)->location
;
6800 if (!open_brace_p
&& c_parser_peek_token (parser
)->type
!= CPP_SEMICOLON
)
6801 warn_for_multistatement_macros (loc_after_labels
, next_loc
, switch_loc
,
6803 c_finish_switch (body
, ce
.original_type
);
6804 in_statement
= save_in_statement
;
6805 add_stmt (c_end_compound_stmt (switch_loc
, block
, flag_isoc99
));
6806 c_parser_maybe_reclassify_token (parser
);
6809 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6812 while (expression) statement
6814 IF_P is used to track whether there's a (possibly labeled) if statement
6815 which is not enclosed in braces and has an else clause. This is used to
6816 implement -Wparentheses. */
6819 c_parser_while_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6822 tree block
, cond
, body
;
6823 unsigned char save_in_statement
;
6825 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_WHILE
));
6826 token_indent_info while_tinfo
6827 = get_token_indent_info (c_parser_peek_token (parser
));
6828 c_parser_consume_token (parser
);
6829 block
= c_begin_compound_stmt (flag_isoc99
);
6830 loc
= c_parser_peek_token (parser
)->location
;
6831 cond
= c_parser_paren_condition (parser
);
6832 if (ivdep
&& cond
!= error_mark_node
)
6833 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6834 build_int_cst (integer_type_node
,
6835 annot_expr_ivdep_kind
),
6837 if (unroll
&& cond
!= error_mark_node
)
6838 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6839 build_int_cst (integer_type_node
,
6840 annot_expr_unroll_kind
),
6841 build_int_cst (integer_type_node
, unroll
));
6842 save_in_statement
= in_statement
;
6843 in_statement
= IN_ITERATION_STMT
;
6845 token_indent_info body_tinfo
6846 = get_token_indent_info (c_parser_peek_token (parser
));
6848 location_t loc_after_labels
;
6849 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
6850 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6851 add_stmt (build_stmt (loc
, WHILE_STMT
, cond
, body
));
6852 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6853 c_parser_maybe_reclassify_token (parser
);
6855 token_indent_info next_tinfo
6856 = get_token_indent_info (c_parser_peek_token (parser
));
6857 warn_for_misleading_indentation (while_tinfo
, body_tinfo
, next_tinfo
);
6859 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
6860 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
6861 while_tinfo
.location
, RID_WHILE
);
6863 in_statement
= save_in_statement
;
6866 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6869 do statement while ( expression ) ;
6873 c_parser_do_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
)
6875 tree block
, cond
, body
;
6876 unsigned char save_in_statement
;
6878 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_DO
));
6879 c_parser_consume_token (parser
);
6880 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6881 warning_at (c_parser_peek_token (parser
)->location
,
6883 "suggest braces around empty body in %<do%> statement");
6884 block
= c_begin_compound_stmt (flag_isoc99
);
6885 loc
= c_parser_peek_token (parser
)->location
;
6886 save_in_statement
= in_statement
;
6887 in_statement
= IN_ITERATION_STMT
;
6888 body
= c_parser_c99_block_statement (parser
, NULL
);
6889 c_parser_require_keyword (parser
, RID_WHILE
, "expected %<while%>");
6890 in_statement
= save_in_statement
;
6891 cond
= c_parser_paren_condition (parser
);
6892 if (ivdep
&& cond
!= error_mark_node
)
6893 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6894 build_int_cst (integer_type_node
,
6895 annot_expr_ivdep_kind
),
6897 if (unroll
&& cond
!= error_mark_node
)
6898 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6899 build_int_cst (integer_type_node
,
6900 annot_expr_unroll_kind
),
6901 build_int_cst (integer_type_node
, unroll
));
6902 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
6903 c_parser_skip_to_end_of_block_or_statement (parser
);
6905 add_stmt (build_stmt (loc
, DO_STMT
, cond
, body
));
6906 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6909 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6912 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6913 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6915 The form with a declaration is new in C99.
6917 ??? In accordance with the old parser, the declaration may be a
6918 nested function, which is then rejected in check_for_loop_decls,
6919 but does it make any sense for this to be included in the grammar?
6920 Note in particular that the nested function does not include a
6921 trailing ';', whereas the "declaration" production includes one.
6922 Also, can we reject bad declarations earlier and cheaper than
6923 check_for_loop_decls?
6925 In Objective-C, there are two additional variants:
6928 for ( expression in expresssion ) statement
6929 for ( declaration in expression ) statement
6931 This is inconsistent with C, because the second variant is allowed
6932 even if c99 is not enabled.
6934 The rest of the comment documents these Objective-C foreach-statement.
6936 Here is the canonical example of the first variant:
6937 for (object in array) { do something with object }
6938 we call the first expression ("object") the "object_expression" and
6939 the second expression ("array") the "collection_expression".
6940 object_expression must be an lvalue of type "id" (a generic Objective-C
6941 object) because the loop works by assigning to object_expression the
6942 various objects from the collection_expression. collection_expression
6943 must evaluate to something of type "id" which responds to the method
6944 countByEnumeratingWithState:objects:count:.
6946 The canonical example of the second variant is:
6947 for (id object in array) { do something with object }
6948 which is completely equivalent to
6951 for (object in array) { do something with object }
6953 Note that initizializing 'object' in some way (eg, "for ((object =
6954 xxx) in array) { do something with object }") is possibly
6955 technically valid, but completely pointless as 'object' will be
6956 assigned to something else as soon as the loop starts. We should
6957 most likely reject it (TODO).
6959 The beginning of the Objective-C foreach-statement looks exactly
6960 like the beginning of the for-statement, and we can tell it is a
6961 foreach-statement only because the initial declaration or
6962 expression is terminated by 'in' instead of ';'.
6964 IF_P is used to track whether there's a (possibly labeled) if statement
6965 which is not enclosed in braces and has an else clause. This is used to
6966 implement -Wparentheses. */
6969 c_parser_for_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6972 tree block
, cond
, incr
, body
;
6973 unsigned char save_in_statement
;
6974 tree save_objc_foreach_break_label
, save_objc_foreach_continue_label
;
6975 /* The following are only used when parsing an ObjC foreach statement. */
6976 tree object_expression
;
6977 /* Silence the bogus uninitialized warning. */
6978 tree collection_expression
= NULL
;
6979 location_t loc
= c_parser_peek_token (parser
)->location
;
6980 location_t for_loc
= loc
;
6981 bool is_foreach_statement
= false;
6982 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
6983 token_indent_info for_tinfo
6984 = get_token_indent_info (c_parser_peek_token (parser
));
6985 c_parser_consume_token (parser
);
6986 /* Open a compound statement in Objective-C as well, just in case this is
6987 as foreach expression. */
6988 block
= c_begin_compound_stmt (flag_isoc99
|| c_dialect_objc ());
6989 cond
= error_mark_node
;
6990 incr
= error_mark_node
;
6991 matching_parens parens
;
6992 if (parens
.require_open (parser
))
6994 /* Parse the initialization declaration or expression. */
6995 object_expression
= error_mark_node
;
6996 parser
->objc_could_be_foreach_context
= c_dialect_objc ();
6997 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6999 parser
->objc_could_be_foreach_context
= false;
7000 c_parser_consume_token (parser
);
7001 c_finish_expr_stmt (loc
, NULL_TREE
);
7003 else if (c_parser_next_tokens_start_declaration (parser
)
7004 || c_parser_nth_token_starts_std_attributes (parser
, 1))
7006 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
7007 &object_expression
);
7008 parser
->objc_could_be_foreach_context
= false;
7010 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
7012 c_parser_consume_token (parser
);
7013 is_foreach_statement
= true;
7014 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
7015 c_parser_error (parser
, "multiple iterating variables in "
7016 "fast enumeration");
7019 check_for_loop_decls (for_loc
, flag_isoc99
);
7021 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
7023 /* __extension__ can start a declaration, but is also an
7024 unary operator that can start an expression. Consume all
7025 but the last of a possible series of __extension__ to
7027 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
7028 && (c_parser_peek_2nd_token (parser
)->keyword
7030 c_parser_consume_token (parser
);
7031 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
7032 || c_parser_nth_token_starts_std_attributes (parser
, 2))
7035 ext
= disable_extension_diagnostics ();
7036 c_parser_consume_token (parser
);
7037 c_parser_declaration_or_fndef (parser
, true, true, true, true,
7038 true, &object_expression
);
7039 parser
->objc_could_be_foreach_context
= false;
7041 restore_extension_diagnostics (ext
);
7042 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
7044 c_parser_consume_token (parser
);
7045 is_foreach_statement
= true;
7046 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
7047 c_parser_error (parser
, "multiple iterating variables in "
7048 "fast enumeration");
7051 check_for_loop_decls (for_loc
, flag_isoc99
);
7061 tree init_expression
;
7062 ce
= c_parser_expression (parser
);
7063 init_expression
= ce
.value
;
7064 parser
->objc_could_be_foreach_context
= false;
7065 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
7067 c_parser_consume_token (parser
);
7068 is_foreach_statement
= true;
7069 if (! lvalue_p (init_expression
))
7070 c_parser_error (parser
, "invalid iterating variable in "
7071 "fast enumeration");
7073 = c_fully_fold (init_expression
, false, NULL
);
7077 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
7078 init_expression
= ce
.value
;
7079 c_finish_expr_stmt (loc
, init_expression
);
7080 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
7085 /* Parse the loop condition. In the case of a foreach
7086 statement, there is no loop condition. */
7087 gcc_assert (!parser
->objc_could_be_foreach_context
);
7088 if (!is_foreach_statement
)
7090 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
7094 c_parser_error (parser
, "missing loop condition in loop "
7095 "with %<GCC ivdep%> pragma");
7096 cond
= error_mark_node
;
7100 c_parser_error (parser
, "missing loop condition in loop "
7101 "with %<GCC unroll%> pragma");
7102 cond
= error_mark_node
;
7106 c_parser_consume_token (parser
);
7112 cond
= c_parser_condition (parser
);
7113 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
7116 if (ivdep
&& cond
!= error_mark_node
)
7117 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
7118 build_int_cst (integer_type_node
,
7119 annot_expr_ivdep_kind
),
7121 if (unroll
&& cond
!= error_mark_node
)
7122 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
7123 build_int_cst (integer_type_node
,
7124 annot_expr_unroll_kind
),
7125 build_int_cst (integer_type_node
, unroll
));
7127 /* Parse the increment expression (the third expression in a
7128 for-statement). In the case of a foreach-statement, this is
7129 the expression that follows the 'in'. */
7130 loc
= c_parser_peek_token (parser
)->location
;
7131 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7133 if (is_foreach_statement
)
7135 c_parser_error (parser
,
7136 "missing collection in fast enumeration");
7137 collection_expression
= error_mark_node
;
7140 incr
= c_process_expr_stmt (loc
, NULL_TREE
);
7144 if (is_foreach_statement
)
7145 collection_expression
7146 = c_fully_fold (c_parser_expression (parser
).value
, false, NULL
);
7149 struct c_expr ce
= c_parser_expression (parser
);
7150 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
7151 incr
= c_process_expr_stmt (loc
, ce
.value
);
7154 parens
.skip_until_found_close (parser
);
7156 save_in_statement
= in_statement
;
7157 if (is_foreach_statement
)
7159 in_statement
= IN_OBJC_FOREACH
;
7160 save_objc_foreach_break_label
= objc_foreach_break_label
;
7161 save_objc_foreach_continue_label
= objc_foreach_continue_label
;
7162 objc_foreach_break_label
= create_artificial_label (loc
);
7163 objc_foreach_continue_label
= create_artificial_label (loc
);
7166 in_statement
= IN_ITERATION_STMT
;
7168 token_indent_info body_tinfo
7169 = get_token_indent_info (c_parser_peek_token (parser
));
7171 location_t loc_after_labels
;
7172 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
7173 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
7175 if (is_foreach_statement
)
7176 objc_finish_foreach_loop (for_loc
, object_expression
,
7177 collection_expression
, body
,
7178 objc_foreach_break_label
,
7179 objc_foreach_continue_label
);
7181 add_stmt (build_stmt (for_loc
, FOR_STMT
, NULL_TREE
, cond
, incr
,
7183 add_stmt (c_end_compound_stmt (for_loc
, block
,
7184 flag_isoc99
|| c_dialect_objc ()));
7185 c_parser_maybe_reclassify_token (parser
);
7187 token_indent_info next_tinfo
7188 = get_token_indent_info (c_parser_peek_token (parser
));
7189 warn_for_misleading_indentation (for_tinfo
, body_tinfo
, next_tinfo
);
7191 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
7192 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
7193 for_tinfo
.location
, RID_FOR
);
7195 in_statement
= save_in_statement
;
7196 if (is_foreach_statement
)
7198 objc_foreach_break_label
= save_objc_foreach_break_label
;
7199 objc_foreach_continue_label
= save_objc_foreach_continue_label
;
7203 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7204 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7213 asm-qualifier-list asm-qualifier
7217 asm asm-qualifier-list[opt] ( asm-argument ) ;
7221 asm-string-literal : asm-operands[opt]
7222 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7223 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7225 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7228 The form with asm-goto-operands is valid if and only if the
7229 asm-qualifier-list contains goto, and is the only allowed form in that case.
7230 Duplicate asm-qualifiers are not allowed.
7232 The :: token is considered equivalent to two consecutive : tokens. */
7235 c_parser_asm_statement (c_parser
*parser
)
7237 tree str
, outputs
, inputs
, clobbers
, labels
, ret
;
7239 location_t asm_loc
= c_parser_peek_token (parser
)->location
;
7240 int section
, nsections
;
7242 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
7243 c_parser_consume_token (parser
);
7245 /* Handle the asm-qualifier-list. */
7246 location_t volatile_loc
= UNKNOWN_LOCATION
;
7247 location_t inline_loc
= UNKNOWN_LOCATION
;
7248 location_t goto_loc
= UNKNOWN_LOCATION
;
7251 c_token
*token
= c_parser_peek_token (parser
);
7252 location_t loc
= token
->location
;
7253 switch (token
->keyword
)
7258 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7259 inform (volatile_loc
, "first seen here");
7263 c_parser_consume_token (parser
);
7269 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7270 inform (inline_loc
, "first seen here");
7274 c_parser_consume_token (parser
);
7280 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7281 inform (goto_loc
, "first seen here");
7285 c_parser_consume_token (parser
);
7290 error_at (loc
, "%qE is not a valid %<asm%> qualifier", token
->value
);
7291 c_parser_consume_token (parser
);
7300 bool is_volatile
= (volatile_loc
!= UNKNOWN_LOCATION
);
7301 bool is_inline
= (inline_loc
!= UNKNOWN_LOCATION
);
7302 bool is_goto
= (goto_loc
!= UNKNOWN_LOCATION
);
7306 matching_parens parens
;
7307 if (!parens
.require_open (parser
))
7310 str
= c_parser_asm_string_literal (parser
);
7311 if (str
== NULL_TREE
)
7312 goto error_close_paren
;
7315 outputs
= NULL_TREE
;
7317 clobbers
= NULL_TREE
;
7320 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7323 /* Parse each colon-delimited section of operands. */
7324 nsections
= 3 + is_goto
;
7325 for (section
= 0; section
< nsections
; ++section
)
7327 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
7330 if (section
== nsections
)
7332 c_parser_error (parser
, "expected %<)%>");
7333 goto error_close_paren
;
7335 c_parser_consume_token (parser
);
7337 else if (!c_parser_require (parser
, CPP_COLON
,
7339 ? G_("expected %<:%>")
7340 : G_("expected %<:%> or %<)%>"),
7341 UNKNOWN_LOCATION
, is_goto
))
7342 goto error_close_paren
;
7344 /* Once past any colon, we're no longer a simple asm. */
7347 if ((!c_parser_next_token_is (parser
, CPP_COLON
)
7348 && !c_parser_next_token_is (parser
, CPP_SCOPE
)
7349 && !c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7354 outputs
= c_parser_asm_operands (parser
);
7357 inputs
= c_parser_asm_operands (parser
);
7360 clobbers
= c_parser_asm_clobbers (parser
);
7363 labels
= c_parser_asm_goto_operands (parser
);
7369 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7374 if (!parens
.require_close (parser
))
7376 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7380 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
7381 c_parser_skip_to_end_of_block_or_statement (parser
);
7383 ret
= build_asm_stmt (is_volatile
,
7384 build_asm_expr (asm_loc
, str
, outputs
, inputs
,
7385 clobbers
, labels
, simple
, is_inline
));
7391 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7395 /* Parse asm operands, a GNU extension.
7399 asm-operands , asm-operand
7402 asm-string-literal ( expression )
7403 [ identifier ] asm-string-literal ( expression )
7407 c_parser_asm_operands (c_parser
*parser
)
7409 tree list
= NULL_TREE
;
7414 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
7416 c_parser_consume_token (parser
);
7417 if (c_parser_next_token_is (parser
, CPP_NAME
))
7419 tree id
= c_parser_peek_token (parser
)->value
;
7420 c_parser_consume_token (parser
);
7421 name
= build_string (IDENTIFIER_LENGTH (id
),
7422 IDENTIFIER_POINTER (id
));
7426 c_parser_error (parser
, "expected identifier");
7427 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
7430 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
7435 str
= c_parser_asm_string_literal (parser
);
7436 if (str
== NULL_TREE
)
7438 matching_parens parens
;
7439 if (!parens
.require_open (parser
))
7441 expr
= c_parser_expression (parser
);
7442 mark_exp_read (expr
.value
);
7443 if (!parens
.require_close (parser
))
7445 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7448 list
= chainon (list
, build_tree_list (build_tree_list (name
, str
),
7450 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7451 c_parser_consume_token (parser
);
7458 /* Parse asm clobbers, a GNU extension.
7462 asm-clobbers , asm-string-literal
7466 c_parser_asm_clobbers (c_parser
*parser
)
7468 tree list
= NULL_TREE
;
7471 tree str
= c_parser_asm_string_literal (parser
);
7473 list
= tree_cons (NULL_TREE
, str
, list
);
7476 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7477 c_parser_consume_token (parser
);
7484 /* Parse asm goto labels, a GNU extension.
7488 asm-goto-operands , identifier
7492 c_parser_asm_goto_operands (c_parser
*parser
)
7494 tree list
= NULL_TREE
;
7499 if (c_parser_next_token_is (parser
, CPP_NAME
))
7501 c_token
*tok
= c_parser_peek_token (parser
);
7503 label
= lookup_label_for_goto (tok
->location
, name
);
7504 c_parser_consume_token (parser
);
7505 TREE_USED (label
) = 1;
7509 c_parser_error (parser
, "expected identifier");
7513 name
= build_string (IDENTIFIER_LENGTH (name
),
7514 IDENTIFIER_POINTER (name
));
7515 list
= tree_cons (name
, label
, list
);
7516 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7517 c_parser_consume_token (parser
);
7519 return nreverse (list
);
7523 /* Parse a possibly concatenated sequence of string literals.
7524 TRANSLATE says whether to translate them to the execution character
7525 set; WIDE_OK says whether any kind of prefixed string literal is
7526 permitted in this context. This code is based on that in
7530 c_parser_string_literal (c_parser
*parser
, bool translate
, bool wide_ok
)
7534 struct obstack str_ob
;
7535 struct obstack loc_ob
;
7536 cpp_string str
, istr
, *strs
;
7538 location_t loc
, last_tok_loc
;
7539 enum cpp_ttype type
;
7540 tree value
, string_tree
;
7542 tok
= c_parser_peek_token (parser
);
7543 loc
= tok
->location
;
7544 last_tok_loc
= linemap_resolve_location (line_table
, loc
,
7545 LRK_MACRO_DEFINITION_LOCATION
,
7554 case CPP_UTF8STRING
:
7555 string_tree
= tok
->value
;
7559 c_parser_error (parser
, "expected string literal");
7561 ret
.value
= NULL_TREE
;
7562 ret
.original_code
= ERROR_MARK
;
7563 ret
.original_type
= NULL_TREE
;
7567 /* Try to avoid the overhead of creating and destroying an obstack
7568 for the common case of just one string. */
7569 switch (c_parser_peek_2nd_token (parser
)->type
)
7572 c_parser_consume_token (parser
);
7573 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7574 str
.len
= TREE_STRING_LENGTH (string_tree
);
7583 case CPP_UTF8STRING
:
7584 gcc_obstack_init (&str_ob
);
7585 gcc_obstack_init (&loc_ob
);
7589 c_parser_consume_token (parser
);
7591 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7592 str
.len
= TREE_STRING_LENGTH (string_tree
);
7593 if (type
!= tok
->type
)
7595 if (type
== CPP_STRING
)
7597 else if (tok
->type
!= CPP_STRING
)
7598 error ("unsupported non-standard concatenation "
7599 "of string literals");
7601 obstack_grow (&str_ob
, &str
, sizeof (cpp_string
));
7602 obstack_grow (&loc_ob
, &last_tok_loc
, sizeof (location_t
));
7603 tok
= c_parser_peek_token (parser
);
7604 string_tree
= tok
->value
;
7606 = linemap_resolve_location (line_table
, tok
->location
,
7607 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
7609 while (tok
->type
== CPP_STRING
7610 || tok
->type
== CPP_WSTRING
7611 || tok
->type
== CPP_STRING16
7612 || tok
->type
== CPP_STRING32
7613 || tok
->type
== CPP_UTF8STRING
);
7614 strs
= (cpp_string
*) obstack_finish (&str_ob
);
7617 if (count
> 1 && !in_system_header_at (input_location
))
7618 warning (OPT_Wtraditional
,
7619 "traditional C rejects string constant concatenation");
7621 if ((type
== CPP_STRING
|| wide_ok
)
7623 ? cpp_interpret_string
: cpp_interpret_string_notranslate
)
7624 (parse_in
, strs
, count
, &istr
, type
)))
7626 value
= build_string (istr
.len
, (const char *) istr
.text
);
7627 free (CONST_CAST (unsigned char *, istr
.text
));
7630 location_t
*locs
= (location_t
*) obstack_finish (&loc_ob
);
7631 gcc_assert (g_string_concat_db
);
7632 g_string_concat_db
->record_string_concatenation (count
, locs
);
7637 if (type
!= CPP_STRING
&& !wide_ok
)
7639 error_at (loc
, "a wide string is invalid in this context");
7642 /* Callers cannot generally handle error_mark_node in this
7643 context, so return the empty string instead. An error has
7644 been issued, either above or from cpp_interpret_string. */
7649 case CPP_UTF8STRING
:
7650 if (type
== CPP_UTF8STRING
&& flag_char8_t
)
7652 value
= build_string (TYPE_PRECISION (char8_type_node
)
7653 / TYPE_PRECISION (char_type_node
),
7654 ""); /* char8_t is 8 bits */
7657 value
= build_string (1, "");
7660 value
= build_string (TYPE_PRECISION (char16_type_node
)
7661 / TYPE_PRECISION (char_type_node
),
7662 "\0"); /* char16_t is 16 bits */
7665 value
= build_string (TYPE_PRECISION (char32_type_node
)
7666 / TYPE_PRECISION (char_type_node
),
7667 "\0\0\0"); /* char32_t is 32 bits */
7670 value
= build_string (TYPE_PRECISION (wchar_type_node
)
7671 / TYPE_PRECISION (char_type_node
),
7672 "\0\0\0"); /* widest supported wchar_t
7682 TREE_TYPE (value
) = char_array_type_node
;
7684 case CPP_UTF8STRING
:
7686 TREE_TYPE (value
) = char8_array_type_node
;
7688 TREE_TYPE (value
) = char_array_type_node
;
7691 TREE_TYPE (value
) = char16_array_type_node
;
7694 TREE_TYPE (value
) = char32_array_type_node
;
7697 TREE_TYPE (value
) = wchar_array_type_node
;
7699 value
= fix_string_type (value
);
7703 obstack_free (&str_ob
, 0);
7704 obstack_free (&loc_ob
, 0);
7708 ret
.original_code
= STRING_CST
;
7709 ret
.original_type
= NULL_TREE
;
7710 set_c_expr_source_range (&ret
, get_range_from_loc (line_table
, loc
));
7712 parser
->seen_string_literal
= true;
7716 /* Parse an expression other than a compound expression; that is, an
7717 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7718 AFTER is not NULL then it is an Objective-C message expression which
7719 is the primary-expression starting the expression as an initializer.
7721 assignment-expression:
7722 conditional-expression
7723 unary-expression assignment-operator assignment-expression
7725 assignment-operator: one of
7726 = *= /= %= += -= <<= >>= &= ^= |=
7728 In GNU C we accept any conditional expression on the LHS and
7729 diagnose the invalid lvalue rather than producing a syntax
7732 static struct c_expr
7733 c_parser_expr_no_commas (c_parser
*parser
, struct c_expr
*after
,
7734 tree omp_atomic_lhs
)
7736 struct c_expr lhs
, rhs
, ret
;
7737 enum tree_code code
;
7738 location_t op_location
, exp_location
;
7739 bool save_in_omp_for
= c_in_omp_for
;
7740 c_in_omp_for
= false;
7741 gcc_assert (!after
|| c_dialect_objc ());
7742 lhs
= c_parser_conditional_expression (parser
, after
, omp_atomic_lhs
);
7743 op_location
= c_parser_peek_token (parser
)->location
;
7744 switch (c_parser_peek_token (parser
)->type
)
7753 code
= TRUNC_DIV_EXPR
;
7756 code
= TRUNC_MOD_EXPR
;
7771 code
= BIT_AND_EXPR
;
7774 code
= BIT_XOR_EXPR
;
7777 code
= BIT_IOR_EXPR
;
7780 c_in_omp_for
= save_in_omp_for
;
7783 c_parser_consume_token (parser
);
7784 exp_location
= c_parser_peek_token (parser
)->location
;
7785 rhs
= c_parser_expr_no_commas (parser
, NULL
);
7786 rhs
= convert_lvalue_to_rvalue (exp_location
, rhs
, true, true);
7788 ret
.value
= build_modify_expr (op_location
, lhs
.value
, lhs
.original_type
,
7789 code
, exp_location
, rhs
.value
,
7792 set_c_expr_source_range (&ret
, lhs
.get_start (), rhs
.get_finish ());
7793 if (code
== NOP_EXPR
)
7794 ret
.original_code
= MODIFY_EXPR
;
7797 suppress_warning (ret
.value
, OPT_Wparentheses
);
7798 ret
.original_code
= ERROR_MARK
;
7800 ret
.original_type
= NULL
;
7801 c_in_omp_for
= save_in_omp_for
;
7805 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7806 AFTER is not NULL then it is an Objective-C message expression which is
7807 the primary-expression starting the expression as an initializer.
7809 conditional-expression:
7810 logical-OR-expression
7811 logical-OR-expression ? expression : conditional-expression
7815 conditional-expression:
7816 logical-OR-expression ? : conditional-expression
7819 static struct c_expr
7820 c_parser_conditional_expression (c_parser
*parser
, struct c_expr
*after
,
7821 tree omp_atomic_lhs
)
7823 struct c_expr cond
, exp1
, exp2
, ret
;
7824 location_t start
, cond_loc
, colon_loc
;
7826 gcc_assert (!after
|| c_dialect_objc ());
7828 cond
= c_parser_binary_expression (parser
, after
, omp_atomic_lhs
);
7830 if (c_parser_next_token_is_not (parser
, CPP_QUERY
))
7832 if (cond
.value
!= error_mark_node
)
7833 start
= cond
.get_start ();
7835 start
= UNKNOWN_LOCATION
;
7836 cond_loc
= c_parser_peek_token (parser
)->location
;
7837 cond
= convert_lvalue_to_rvalue (cond_loc
, cond
, true, true);
7838 c_parser_consume_token (parser
);
7839 if (c_parser_next_token_is (parser
, CPP_COLON
))
7841 tree eptype
= NULL_TREE
;
7843 location_t middle_loc
= c_parser_peek_token (parser
)->location
;
7844 pedwarn (middle_loc
, OPT_Wpedantic
,
7845 "ISO C forbids omitting the middle term of a %<?:%> expression");
7846 if (TREE_CODE (cond
.value
) == EXCESS_PRECISION_EXPR
)
7848 eptype
= TREE_TYPE (cond
.value
);
7849 cond
.value
= TREE_OPERAND (cond
.value
, 0);
7851 tree e
= cond
.value
;
7852 while (TREE_CODE (e
) == COMPOUND_EXPR
)
7853 e
= TREE_OPERAND (e
, 1);
7854 warn_for_omitted_condop (middle_loc
, e
);
7855 /* Make sure first operand is calculated only once. */
7856 exp1
.value
= save_expr (default_conversion (cond
.value
));
7858 exp1
.value
= build1 (EXCESS_PRECISION_EXPR
, eptype
, exp1
.value
);
7859 exp1
.original_type
= NULL
;
7860 exp1
.src_range
= cond
.src_range
;
7861 cond
.value
= c_objc_common_truthvalue_conversion (cond_loc
, exp1
.value
);
7862 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_true_node
;
7867 = c_objc_common_truthvalue_conversion
7868 (cond_loc
, default_conversion (cond
.value
));
7869 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_false_node
;
7870 exp1
= c_parser_expression_conv (parser
);
7871 mark_exp_read (exp1
.value
);
7872 c_inhibit_evaluation_warnings
+=
7873 ((cond
.value
== truthvalue_true_node
)
7874 - (cond
.value
== truthvalue_false_node
));
7877 colon_loc
= c_parser_peek_token (parser
)->location
;
7878 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7880 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7882 ret
.original_code
= ERROR_MARK
;
7883 ret
.original_type
= NULL
;
7887 location_t exp2_loc
= c_parser_peek_token (parser
)->location
;
7888 exp2
= c_parser_conditional_expression (parser
, NULL
, NULL_TREE
);
7889 exp2
= convert_lvalue_to_rvalue (exp2_loc
, exp2
, true, true);
7891 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7892 location_t loc1
= make_location (exp1
.get_start (), exp1
.src_range
);
7893 location_t loc2
= make_location (exp2
.get_start (), exp2
.src_range
);
7894 if (UNLIKELY (omp_atomic_lhs
!= NULL
)
7895 && (TREE_CODE (cond
.value
) == GT_EXPR
7896 || TREE_CODE (cond
.value
) == LT_EXPR
7897 || TREE_CODE (cond
.value
) == EQ_EXPR
)
7898 && c_tree_equal (exp2
.value
, omp_atomic_lhs
)
7899 && (c_tree_equal (TREE_OPERAND (cond
.value
, 0), omp_atomic_lhs
)
7900 || c_tree_equal (TREE_OPERAND (cond
.value
, 1), omp_atomic_lhs
)))
7901 ret
.value
= build3_loc (colon_loc
, COND_EXPR
, TREE_TYPE (omp_atomic_lhs
),
7902 cond
.value
, exp1
.value
, exp2
.value
);
7905 = build_conditional_expr (colon_loc
, cond
.value
,
7906 cond
.original_code
== C_MAYBE_CONST_EXPR
,
7907 exp1
.value
, exp1
.original_type
, loc1
,
7908 exp2
.value
, exp2
.original_type
, loc2
);
7909 ret
.original_code
= ERROR_MARK
;
7910 if (exp1
.value
== error_mark_node
|| exp2
.value
== error_mark_node
)
7911 ret
.original_type
= NULL
;
7916 /* If both sides are enum type, the default conversion will have
7917 made the type of the result be an integer type. We want to
7918 remember the enum types we started with. */
7919 t1
= exp1
.original_type
? exp1
.original_type
: TREE_TYPE (exp1
.value
);
7920 t2
= exp2
.original_type
? exp2
.original_type
: TREE_TYPE (exp2
.value
);
7921 ret
.original_type
= ((t1
!= error_mark_node
7922 && t2
!= error_mark_node
7923 && (TYPE_MAIN_VARIANT (t1
)
7924 == TYPE_MAIN_VARIANT (t2
)))
7928 set_c_expr_source_range (&ret
, start
, exp2
.get_finish ());
7933 /* Parse a binary expression; that is, a logical-OR-expression (C90
7934 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7935 NULL then it is an Objective-C message expression which is the
7936 primary-expression starting the expression as an initializer.
7938 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7939 when it should be the unfolded lhs. In a valid OpenMP source,
7940 one of the operands of the toplevel binary expression must be equal
7941 to it. In that case, just return a build2 created binary operation
7942 rather than result of parser_build_binary_op.
7944 multiplicative-expression:
7946 multiplicative-expression * cast-expression
7947 multiplicative-expression / cast-expression
7948 multiplicative-expression % cast-expression
7950 additive-expression:
7951 multiplicative-expression
7952 additive-expression + multiplicative-expression
7953 additive-expression - multiplicative-expression
7957 shift-expression << additive-expression
7958 shift-expression >> additive-expression
7960 relational-expression:
7962 relational-expression < shift-expression
7963 relational-expression > shift-expression
7964 relational-expression <= shift-expression
7965 relational-expression >= shift-expression
7967 equality-expression:
7968 relational-expression
7969 equality-expression == relational-expression
7970 equality-expression != relational-expression
7974 AND-expression & equality-expression
7976 exclusive-OR-expression:
7978 exclusive-OR-expression ^ AND-expression
7980 inclusive-OR-expression:
7981 exclusive-OR-expression
7982 inclusive-OR-expression | exclusive-OR-expression
7984 logical-AND-expression:
7985 inclusive-OR-expression
7986 logical-AND-expression && inclusive-OR-expression
7988 logical-OR-expression:
7989 logical-AND-expression
7990 logical-OR-expression || logical-AND-expression
7993 static struct c_expr
7994 c_parser_binary_expression (c_parser
*parser
, struct c_expr
*after
,
7995 tree omp_atomic_lhs
)
7997 /* A binary expression is parsed using operator-precedence parsing,
7998 with the operands being cast expressions. All the binary
7999 operators are left-associative. Thus a binary expression is of
8002 E0 op1 E1 op2 E2 ...
8004 which we represent on a stack. On the stack, the precedence
8005 levels are strictly increasing. When a new operator is
8006 encountered of higher precedence than that at the top of the
8007 stack, it is pushed; its LHS is the top expression, and its RHS
8008 is everything parsed until it is popped. When a new operator is
8009 encountered with precedence less than or equal to that at the top
8010 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
8011 by the result of the operation until the operator at the top of
8012 the stack has lower precedence than the new operator or there is
8013 only one element on the stack; then the top expression is the LHS
8014 of the new operator. In the case of logical AND and OR
8015 expressions, we also need to adjust c_inhibit_evaluation_warnings
8016 as appropriate when the operators are pushed and popped. */
8019 /* The expression at this stack level. */
8021 /* The precedence of the operator on its left, PREC_NONE at the
8022 bottom of the stack. */
8023 enum c_parser_prec prec
;
8024 /* The operation on its left. */
8026 /* The source location of this operation. */
8028 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
8032 /* Location of the binary operator. */
8033 location_t binary_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
8036 switch (stack[sp].op) \
8038 case TRUTH_ANDIF_EXPR: \
8039 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
8040 == truthvalue_false_node); \
8042 case TRUTH_ORIF_EXPR: \
8043 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
8044 == truthvalue_true_node); \
8046 case TRUNC_DIV_EXPR: \
8047 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
8048 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
8049 && (stack[sp].expr.original_code == SIZEOF_EXPR \
8050 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
8052 tree type0 = stack[sp - 1].sizeof_arg; \
8053 tree type1 = stack[sp].sizeof_arg; \
8054 tree first_arg = type0; \
8055 if (!TYPE_P (type0)) \
8056 type0 = TREE_TYPE (type0); \
8057 if (!TYPE_P (type1)) \
8058 type1 = TREE_TYPE (type1); \
8059 if (POINTER_TYPE_P (type0) \
8060 && comptypes (TREE_TYPE (type0), type1) \
8061 && !(TREE_CODE (first_arg) == PARM_DECL \
8062 && C_ARRAY_PARAMETER (first_arg) \
8063 && warn_sizeof_array_argument)) \
8065 auto_diagnostic_group d; \
8066 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
8067 "division %<sizeof (%T) / sizeof (%T)%> " \
8068 "does not compute the number of array " \
8071 if (DECL_P (first_arg)) \
8072 inform (DECL_SOURCE_LOCATION (first_arg), \
8073 "first %<sizeof%> operand was declared here"); \
8075 else if (TREE_CODE (type0) == ARRAY_TYPE \
8076 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
8077 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
8078 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
8079 stack[sp].sizeof_arg, type1); \
8085 stack[sp - 1].expr \
8086 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
8087 stack[sp - 1].expr, true, true); \
8089 = convert_lvalue_to_rvalue (stack[sp].loc, \
8090 stack[sp].expr, true, true); \
8091 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
8092 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
8093 && ((1 << stack[sp].prec) \
8094 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
8095 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
8096 | (1 << PREC_ADD) | (1 << PREC_MULT) \
8097 | (1 << PREC_EQ)))) \
8098 || ((c_parser_next_token_is (parser, CPP_QUERY) \
8099 || (omp_atomic_lhs == void_list_node \
8100 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
8101 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
8102 && stack[sp].op != TRUNC_MOD_EXPR \
8103 && stack[sp].op != GE_EXPR \
8104 && stack[sp].op != LE_EXPR \
8105 && stack[sp].op != NE_EXPR \
8106 && stack[0].expr.value != error_mark_node \
8107 && stack[1].expr.value != error_mark_node \
8108 && (omp_atomic_lhs == void_list_node \
8109 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
8110 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
8111 || (stack[sp].op == EQ_EXPR \
8112 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
8114 tree t = make_node (stack[1].op); \
8115 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
8116 TREE_OPERAND (t, 0) = stack[0].expr.value; \
8117 TREE_OPERAND (t, 1) = stack[1].expr.value; \
8118 stack[0].expr.value = t; \
8119 stack[0].expr.m_decimal = 0; \
8122 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
8124 stack[sp - 1].expr, \
8128 gcc_assert (!after
|| c_dialect_objc ());
8129 stack
[0].loc
= c_parser_peek_token (parser
)->location
;
8130 stack
[0].expr
= c_parser_cast_expression (parser
, after
);
8131 stack
[0].prec
= PREC_NONE
;
8132 stack
[0].sizeof_arg
= c_last_sizeof_arg
;
8136 enum c_parser_prec oprec
;
8137 enum tree_code ocode
;
8138 source_range src_range
;
8141 switch (c_parser_peek_token (parser
)->type
)
8149 ocode
= TRUNC_DIV_EXPR
;
8153 ocode
= TRUNC_MOD_EXPR
;
8165 ocode
= LSHIFT_EXPR
;
8169 ocode
= RSHIFT_EXPR
;
8183 case CPP_GREATER_EQ
:
8196 oprec
= PREC_BITAND
;
8197 ocode
= BIT_AND_EXPR
;
8200 oprec
= PREC_BITXOR
;
8201 ocode
= BIT_XOR_EXPR
;
8205 ocode
= BIT_IOR_EXPR
;
8208 oprec
= PREC_LOGAND
;
8209 ocode
= TRUTH_ANDIF_EXPR
;
8213 ocode
= TRUTH_ORIF_EXPR
;
8216 /* Not a binary operator, so end of the binary
8220 binary_loc
= c_parser_peek_token (parser
)->location
;
8221 while (oprec
<= stack
[sp
].prec
)
8223 c_parser_consume_token (parser
);
8226 case TRUTH_ANDIF_EXPR
:
8227 src_range
= stack
[sp
].expr
.src_range
;
8229 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
8230 stack
[sp
].expr
, true, true);
8231 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
8232 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
8233 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
8234 == truthvalue_false_node
);
8235 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
8237 case TRUTH_ORIF_EXPR
:
8238 src_range
= stack
[sp
].expr
.src_range
;
8240 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
8241 stack
[sp
].expr
, true, true);
8242 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
8243 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
8244 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
8245 == truthvalue_true_node
);
8246 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
8252 stack
[sp
].loc
= binary_loc
;
8253 stack
[sp
].expr
= c_parser_cast_expression (parser
, NULL
);
8254 stack
[sp
].prec
= oprec
;
8255 stack
[sp
].op
= ocode
;
8256 stack
[sp
].sizeof_arg
= c_last_sizeof_arg
;
8261 return stack
[0].expr
;
8265 /* Parse any storage class specifiers after an open parenthesis in a
8266 context where a compound literal is permitted. */
8268 static struct c_declspecs
*
8269 c_parser_compound_literal_scspecs (c_parser
*parser
)
8271 bool seen_scspec
= false;
8272 struct c_declspecs
*specs
= build_null_declspecs ();
8273 while (c_parser_next_token_is (parser
, CPP_KEYWORD
))
8275 switch (c_parser_peek_token (parser
)->keyword
)
8281 declspecs_add_scspec (c_parser_peek_token (parser
)->location
,
8282 specs
, c_parser_peek_token (parser
)->value
);
8283 c_parser_consume_token (parser
);
8290 return seen_scspec
? specs
: NULL
;
8293 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8294 is not NULL then it is an Objective-C message expression which is the
8295 primary-expression starting the expression as an initializer.
8299 ( type-name ) unary-expression
8302 static struct c_expr
8303 c_parser_cast_expression (c_parser
*parser
, struct c_expr
*after
)
8305 location_t cast_loc
= c_parser_peek_token (parser
)->location
;
8306 gcc_assert (!after
|| c_dialect_objc ());
8308 return c_parser_postfix_expression_after_primary (parser
,
8310 /* If the expression begins with a parenthesized type name, it may
8311 be either a cast or a compound literal; we need to see whether
8312 the next character is '{' to tell the difference. If not, it is
8313 an unary expression. Full detection of unknown typenames here
8314 would require a 3-token lookahead. */
8315 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8316 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
8318 struct c_declspecs
*scspecs
;
8319 struct c_type_name
*type_name
;
8322 matching_parens parens
;
8323 parens
.consume_open (parser
);
8324 scspecs
= c_parser_compound_literal_scspecs (parser
);
8325 type_name
= c_parser_type_name (parser
, true);
8326 parens
.skip_until_found_close (parser
);
8327 if (type_name
== NULL
)
8330 ret
.original_code
= ERROR_MARK
;
8331 ret
.original_type
= NULL
;
8335 /* Save casted types in the function's used types hash table. */
8336 used_types_insert (type_name
->specs
->type
);
8338 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8339 return c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
8343 error_at (cast_loc
, "storage class specifier in cast");
8344 if (type_name
->specs
->alignas_p
)
8345 error_at (type_name
->specs
->locations
[cdw_alignas
],
8346 "alignment specified for type name in cast");
8348 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
8349 expr
= c_parser_cast_expression (parser
, NULL
);
8350 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
8352 ret
.value
= c_cast_expr (cast_loc
, type_name
, expr
.value
);
8353 if (ret
.value
&& expr
.value
)
8354 set_c_expr_source_range (&ret
, cast_loc
, expr
.get_finish ());
8355 ret
.original_code
= ERROR_MARK
;
8356 ret
.original_type
= NULL
;
8361 return c_parser_unary_expression (parser
);
8364 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8370 unary-operator cast-expression
8371 sizeof unary-expression
8372 sizeof ( type-name )
8374 unary-operator: one of
8380 __alignof__ unary-expression
8381 __alignof__ ( type-name )
8384 (C11 permits _Alignof with type names only.)
8386 unary-operator: one of
8387 __extension__ __real__ __imag__
8389 Transactional Memory:
8392 transaction-expression
8394 In addition, the GNU syntax treats ++ and -- as unary operators, so
8395 they may be applied to cast expressions with errors for non-lvalues
8398 static struct c_expr
8399 c_parser_unary_expression (c_parser
*parser
)
8402 struct c_expr ret
, op
;
8403 location_t op_loc
= c_parser_peek_token (parser
)->location
;
8406 ret
.original_code
= ERROR_MARK
;
8407 ret
.original_type
= NULL
;
8408 switch (c_parser_peek_token (parser
)->type
)
8411 c_parser_consume_token (parser
);
8412 exp_loc
= c_parser_peek_token (parser
)->location
;
8413 op
= c_parser_cast_expression (parser
, NULL
);
8415 op
= default_function_array_read_conversion (exp_loc
, op
);
8416 return parser_build_unary_op (op_loc
, PREINCREMENT_EXPR
, op
);
8417 case CPP_MINUS_MINUS
:
8418 c_parser_consume_token (parser
);
8419 exp_loc
= c_parser_peek_token (parser
)->location
;
8420 op
= c_parser_cast_expression (parser
, NULL
);
8422 op
= default_function_array_read_conversion (exp_loc
, op
);
8423 return parser_build_unary_op (op_loc
, PREDECREMENT_EXPR
, op
);
8425 c_parser_consume_token (parser
);
8426 op
= c_parser_cast_expression (parser
, NULL
);
8427 mark_exp_read (op
.value
);
8428 return parser_build_unary_op (op_loc
, ADDR_EXPR
, op
);
8431 c_parser_consume_token (parser
);
8432 exp_loc
= c_parser_peek_token (parser
)->location
;
8433 op
= c_parser_cast_expression (parser
, NULL
);
8434 finish
= op
.get_finish ();
8435 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8436 location_t combined_loc
= make_location (op_loc
, op_loc
, finish
);
8437 ret
.value
= build_indirect_ref (combined_loc
, op
.value
, RO_UNARY_STAR
);
8438 ret
.src_range
.m_start
= op_loc
;
8439 ret
.src_range
.m_finish
= finish
;
8444 if (!c_dialect_objc () && !in_system_header_at (input_location
))
8447 "traditional C rejects the unary plus operator");
8448 c_parser_consume_token (parser
);
8449 exp_loc
= c_parser_peek_token (parser
)->location
;
8450 op
= c_parser_cast_expression (parser
, NULL
);
8451 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8452 return parser_build_unary_op (op_loc
, CONVERT_EXPR
, op
);
8454 c_parser_consume_token (parser
);
8455 exp_loc
= c_parser_peek_token (parser
)->location
;
8456 op
= c_parser_cast_expression (parser
, NULL
);
8457 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8458 return parser_build_unary_op (op_loc
, NEGATE_EXPR
, op
);
8460 c_parser_consume_token (parser
);
8461 exp_loc
= c_parser_peek_token (parser
)->location
;
8462 op
= c_parser_cast_expression (parser
, NULL
);
8463 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8464 return parser_build_unary_op (op_loc
, BIT_NOT_EXPR
, op
);
8466 c_parser_consume_token (parser
);
8467 exp_loc
= c_parser_peek_token (parser
)->location
;
8468 op
= c_parser_cast_expression (parser
, NULL
);
8469 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8470 return parser_build_unary_op (op_loc
, TRUTH_NOT_EXPR
, op
);
8472 /* Refer to the address of a label as a pointer. */
8473 c_parser_consume_token (parser
);
8474 if (c_parser_next_token_is (parser
, CPP_NAME
))
8476 ret
.value
= finish_label_address_expr
8477 (c_parser_peek_token (parser
)->value
, op_loc
);
8478 set_c_expr_source_range (&ret
, op_loc
,
8479 c_parser_peek_token (parser
)->get_finish ());
8480 c_parser_consume_token (parser
);
8484 c_parser_error (parser
, "expected identifier");
8489 switch (c_parser_peek_token (parser
)->keyword
)
8492 return c_parser_sizeof_expression (parser
);
8494 return c_parser_alignof_expression (parser
);
8495 case RID_BUILTIN_HAS_ATTRIBUTE
:
8496 return c_parser_has_attribute_expression (parser
);
8498 c_parser_consume_token (parser
);
8499 ext
= disable_extension_diagnostics ();
8500 ret
= c_parser_cast_expression (parser
, NULL
);
8501 restore_extension_diagnostics (ext
);
8504 c_parser_consume_token (parser
);
8505 exp_loc
= c_parser_peek_token (parser
)->location
;
8506 op
= c_parser_cast_expression (parser
, NULL
);
8507 op
= default_function_array_conversion (exp_loc
, op
);
8508 return parser_build_unary_op (op_loc
, REALPART_EXPR
, op
);
8510 c_parser_consume_token (parser
);
8511 exp_loc
= c_parser_peek_token (parser
)->location
;
8512 op
= c_parser_cast_expression (parser
, NULL
);
8513 op
= default_function_array_conversion (exp_loc
, op
);
8514 return parser_build_unary_op (op_loc
, IMAGPART_EXPR
, op
);
8515 case RID_TRANSACTION_ATOMIC
:
8516 case RID_TRANSACTION_RELAXED
:
8517 return c_parser_transaction_expression (parser
,
8518 c_parser_peek_token (parser
)->keyword
);
8520 return c_parser_postfix_expression (parser
);
8523 return c_parser_postfix_expression (parser
);
8527 /* Parse a sizeof expression. */
8529 static struct c_expr
8530 c_parser_sizeof_expression (c_parser
*parser
)
8533 struct c_expr result
;
8534 location_t expr_loc
;
8535 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SIZEOF
));
8538 location_t finish
= UNKNOWN_LOCATION
;
8540 start
= c_parser_peek_token (parser
)->location
;
8542 c_parser_consume_token (parser
);
8543 c_inhibit_evaluation_warnings
++;
8545 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8546 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
8548 /* Either sizeof ( type-name ) or sizeof unary-expression
8549 starting with a compound literal. */
8550 struct c_declspecs
*scspecs
;
8551 struct c_type_name
*type_name
;
8552 matching_parens parens
;
8553 parens
.consume_open (parser
);
8554 expr_loc
= c_parser_peek_token (parser
)->location
;
8555 scspecs
= c_parser_compound_literal_scspecs (parser
);
8556 type_name
= c_parser_type_name (parser
, true);
8557 parens
.skip_until_found_close (parser
);
8558 finish
= parser
->tokens_buf
[0].location
;
8559 if (type_name
== NULL
)
8562 c_inhibit_evaluation_warnings
--;
8565 ret
.original_code
= ERROR_MARK
;
8566 ret
.original_type
= NULL
;
8569 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8571 expr
= c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
8574 finish
= expr
.get_finish ();
8577 /* sizeof ( type-name ). */
8579 error_at (expr_loc
, "storage class specifier in %<sizeof%>");
8580 if (type_name
->specs
->alignas_p
)
8581 error_at (type_name
->specs
->locations
[cdw_alignas
],
8582 "alignment specified for type name in %<sizeof%>");
8583 c_inhibit_evaluation_warnings
--;
8585 result
= c_expr_sizeof_type (expr_loc
, type_name
);
8589 expr_loc
= c_parser_peek_token (parser
)->location
;
8590 expr
= c_parser_unary_expression (parser
);
8591 finish
= expr
.get_finish ();
8593 c_inhibit_evaluation_warnings
--;
8595 mark_exp_read (expr
.value
);
8596 if (TREE_CODE (expr
.value
) == COMPONENT_REF
8597 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
8598 error_at (expr_loc
, "%<sizeof%> applied to a bit-field");
8599 result
= c_expr_sizeof_expr (expr_loc
, expr
);
8601 if (finish
== UNKNOWN_LOCATION
)
8603 set_c_expr_source_range (&result
, start
, finish
);
8607 /* Parse an alignof expression. */
8609 static struct c_expr
8610 c_parser_alignof_expression (c_parser
*parser
)
8613 location_t start_loc
= c_parser_peek_token (parser
)->location
;
8615 tree alignof_spelling
= c_parser_peek_token (parser
)->value
;
8616 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNOF
));
8617 bool is_c11_alignof
= (strcmp (IDENTIFIER_POINTER (alignof_spelling
),
8619 || strcmp (IDENTIFIER_POINTER (alignof_spelling
),
8621 /* A diagnostic is not required for the use of this identifier in
8622 the implementation namespace; only diagnose it for the C11 or C2X
8623 spelling because of existing code using the other spellings. */
8627 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C99 does not support %qE",
8630 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C90 does not support %qE",
8633 c_parser_consume_token (parser
);
8634 c_inhibit_evaluation_warnings
++;
8636 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8637 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser
)))
8639 /* Either __alignof__ ( type-name ) or __alignof__
8640 unary-expression starting with a compound literal. */
8642 struct c_declspecs
*scspecs
;
8643 struct c_type_name
*type_name
;
8645 matching_parens parens
;
8646 parens
.consume_open (parser
);
8647 loc
= c_parser_peek_token (parser
)->location
;
8648 scspecs
= c_parser_compound_literal_scspecs (parser
);
8649 type_name
= c_parser_type_name (parser
, true);
8650 end_loc
= c_parser_peek_token (parser
)->location
;
8651 parens
.skip_until_found_close (parser
);
8652 if (type_name
== NULL
)
8655 c_inhibit_evaluation_warnings
--;
8658 ret
.original_code
= ERROR_MARK
;
8659 ret
.original_type
= NULL
;
8662 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8664 expr
= c_parser_postfix_expression_after_paren_type (parser
, scspecs
,
8669 /* alignof ( type-name ). */
8671 error_at (loc
, "storage class specifier in %qE", alignof_spelling
);
8672 if (type_name
->specs
->alignas_p
)
8673 error_at (type_name
->specs
->locations
[cdw_alignas
],
8674 "alignment specified for type name in %qE",
8676 c_inhibit_evaluation_warnings
--;
8678 ret
.value
= c_sizeof_or_alignof_type (loc
, groktypename (type_name
,
8680 false, is_c11_alignof
, 1);
8681 ret
.original_code
= ERROR_MARK
;
8682 ret
.original_type
= NULL
;
8683 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
8690 expr
= c_parser_unary_expression (parser
);
8691 end_loc
= expr
.src_range
.m_finish
;
8693 mark_exp_read (expr
.value
);
8694 c_inhibit_evaluation_warnings
--;
8698 OPT_Wpedantic
, "ISO C does not allow %<%E (expression)%>",
8700 ret
.value
= c_alignof_expr (start_loc
, expr
.value
);
8701 ret
.original_code
= ERROR_MARK
;
8702 ret
.original_type
= NULL
;
8703 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
8709 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8712 static struct c_expr
8713 c_parser_has_attribute_expression (c_parser
*parser
)
8715 gcc_assert (c_parser_next_token_is_keyword (parser
,
8716 RID_BUILTIN_HAS_ATTRIBUTE
));
8717 location_t start
= c_parser_peek_token (parser
)->location
;
8718 c_parser_consume_token (parser
);
8720 c_inhibit_evaluation_warnings
++;
8722 matching_parens parens
;
8723 if (!parens
.require_open (parser
))
8725 c_inhibit_evaluation_warnings
--;
8728 struct c_expr result
;
8729 result
.set_error ();
8730 result
.original_code
= ERROR_MARK
;
8731 result
.original_type
= NULL
;
8735 /* Treat the type argument the same way as in typeof for the purposes
8736 of warnings. FIXME: Generalize this so the warning refers to
8737 __builtin_has_attribute rather than typeof. */
8740 /* The first operand: one of DECL, EXPR, or TYPE. */
8741 tree oper
= NULL_TREE
;
8742 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
8744 struct c_type_name
*tname
= c_parser_type_name (parser
);
8748 oper
= groktypename (tname
, NULL
, NULL
);
8749 pop_maybe_used (variably_modified_type_p (oper
, NULL_TREE
));
8754 struct c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
8755 c_inhibit_evaluation_warnings
--;
8757 if (cexpr
.value
!= error_mark_node
)
8759 mark_exp_read (cexpr
.value
);
8761 tree etype
= TREE_TYPE (oper
);
8762 bool was_vm
= variably_modified_type_p (etype
, NULL_TREE
);
8763 /* This is returned with the type so that when the type is
8764 evaluated, this can be evaluated. */
8766 oper
= c_fully_fold (oper
, false, NULL
);
8767 pop_maybe_used (was_vm
);
8771 struct c_expr result
;
8772 result
.original_code
= ERROR_MARK
;
8773 result
.original_type
= NULL
;
8775 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8777 /* Consume the closing parenthesis if that's the next token
8778 in the likely case the built-in was invoked with fewer
8779 than two arguments. */
8780 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8781 c_parser_consume_token (parser
);
8782 c_inhibit_evaluation_warnings
--;
8783 result
.set_error ();
8787 bool save_translate_strings_p
= parser
->translate_strings_p
;
8789 location_t atloc
= c_parser_peek_token (parser
)->location
;
8790 /* Parse a single attribute. Require no leading comma and do not
8791 allow empty attributes. */
8792 tree attr
= c_parser_gnu_attribute (parser
, NULL_TREE
, false, false);
8794 parser
->translate_strings_p
= save_translate_strings_p
;
8796 location_t finish
= c_parser_peek_token (parser
)->location
;
8797 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8798 c_parser_consume_token (parser
);
8801 c_parser_error (parser
, "expected identifier");
8802 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8804 result
.set_error ();
8810 error_at (atloc
, "expected identifier");
8811 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8813 result
.set_error ();
8817 result
.original_code
= INTEGER_CST
;
8818 result
.original_type
= boolean_type_node
;
8820 if (has_attribute (atloc
, oper
, attr
, default_conversion
))
8821 result
.value
= boolean_true_node
;
8823 result
.value
= boolean_false_node
;
8825 set_c_expr_source_range (&result
, start
, finish
);
8826 result
.m_decimal
= 0;
8830 /* Helper function to read arguments of builtins which are interfaces
8831 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8832 others. The name of the builtin is passed using BNAME parameter.
8833 Function returns true if there were no errors while parsing and
8834 stores the arguments in CEXPR_LIST. If it returns true,
8835 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8838 c_parser_get_builtin_args (c_parser
*parser
, const char *bname
,
8839 vec
<c_expr_t
, va_gc
> **ret_cexpr_list
,
8841 location_t
*out_close_paren_loc
)
8843 location_t loc
= c_parser_peek_token (parser
)->location
;
8844 vec
<c_expr_t
, va_gc
> *cexpr_list
;
8846 bool saved_force_folding_builtin_constant_p
;
8848 *ret_cexpr_list
= NULL
;
8849 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
8851 error_at (loc
, "cannot take address of %qs", bname
);
8855 c_parser_consume_token (parser
);
8857 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8859 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
8860 c_parser_consume_token (parser
);
8864 saved_force_folding_builtin_constant_p
8865 = force_folding_builtin_constant_p
;
8866 force_folding_builtin_constant_p
|= choose_expr_p
;
8867 expr
= c_parser_expr_no_commas (parser
, NULL
);
8868 force_folding_builtin_constant_p
8869 = saved_force_folding_builtin_constant_p
;
8870 vec_alloc (cexpr_list
, 1);
8871 vec_safe_push (cexpr_list
, expr
);
8872 while (c_parser_next_token_is (parser
, CPP_COMMA
))
8874 c_parser_consume_token (parser
);
8875 expr
= c_parser_expr_no_commas (parser
, NULL
);
8876 vec_safe_push (cexpr_list
, expr
);
8879 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
8880 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
8883 *ret_cexpr_list
= cexpr_list
;
8887 /* This represents a single generic-association. */
8889 struct c_generic_association
8891 /* The location of the starting token of the type. */
8892 location_t type_location
;
8893 /* The association's type, or NULL_TREE for 'default'. */
8895 /* The association's expression. */
8896 struct c_expr expression
;
8899 /* Parse a generic-selection. (C11 6.5.1.1).
8902 _Generic ( assignment-expression , generic-assoc-list )
8906 generic-assoc-list , generic-association
8908 generic-association:
8909 type-name : assignment-expression
8910 default : assignment-expression
8913 static struct c_expr
8914 c_parser_generic_selection (c_parser
*parser
)
8916 struct c_expr selector
, error_expr
;
8918 struct c_generic_association matched_assoc
;
8919 int match_found
= -1;
8920 location_t generic_loc
, selector_loc
;
8922 error_expr
.original_code
= ERROR_MARK
;
8923 error_expr
.original_type
= NULL
;
8924 error_expr
.set_error ();
8925 matched_assoc
.type_location
= UNKNOWN_LOCATION
;
8926 matched_assoc
.type
= NULL_TREE
;
8927 matched_assoc
.expression
= error_expr
;
8929 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_GENERIC
));
8930 generic_loc
= c_parser_peek_token (parser
)->location
;
8931 c_parser_consume_token (parser
);
8933 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
8934 "ISO C99 does not support %<_Generic%>");
8936 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
8937 "ISO C90 does not support %<_Generic%>");
8939 matching_parens parens
;
8940 if (!parens
.require_open (parser
))
8943 c_inhibit_evaluation_warnings
++;
8944 selector_loc
= c_parser_peek_token (parser
)->location
;
8945 selector
= c_parser_expr_no_commas (parser
, NULL
);
8946 selector
= default_function_array_conversion (selector_loc
, selector
);
8947 c_inhibit_evaluation_warnings
--;
8949 if (selector
.value
== error_mark_node
)
8951 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8954 mark_exp_read (selector
.value
);
8955 selector_type
= TREE_TYPE (selector
.value
);
8956 /* In ISO C terms, rvalues (including the controlling expression of
8957 _Generic) do not have qualified types. */
8958 if (TREE_CODE (selector_type
) != ARRAY_TYPE
)
8959 selector_type
= TYPE_MAIN_VARIANT (selector_type
);
8960 /* In ISO C terms, _Noreturn is not part of the type of expressions
8961 such as &abort, but in GCC it is represented internally as a type
8963 if (FUNCTION_POINTER_TYPE_P (selector_type
)
8964 && TYPE_QUALS (TREE_TYPE (selector_type
)) != TYPE_UNQUALIFIED
)
8966 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type
)));
8968 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8970 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8974 auto_vec
<c_generic_association
> associations
;
8977 struct c_generic_association assoc
, *iter
;
8979 c_token
*token
= c_parser_peek_token (parser
);
8981 assoc
.type_location
= token
->location
;
8982 if (token
->type
== CPP_KEYWORD
&& token
->keyword
== RID_DEFAULT
)
8984 c_parser_consume_token (parser
);
8985 assoc
.type
= NULL_TREE
;
8989 struct c_type_name
*type_name
;
8991 type_name
= c_parser_type_name (parser
);
8992 if (type_name
== NULL
)
8994 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8997 assoc
.type
= groktypename (type_name
, NULL
, NULL
);
8998 if (assoc
.type
== error_mark_node
)
9000 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9004 if (TREE_CODE (assoc
.type
) == FUNCTION_TYPE
)
9005 error_at (assoc
.type_location
,
9006 "%<_Generic%> association has function type");
9007 else if (!COMPLETE_TYPE_P (assoc
.type
))
9008 error_at (assoc
.type_location
,
9009 "%<_Generic%> association has incomplete type");
9011 if (variably_modified_type_p (assoc
.type
, NULL_TREE
))
9012 error_at (assoc
.type_location
,
9013 "%<_Generic%> association has "
9014 "variable length type");
9017 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
9019 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9023 assoc
.expression
= c_parser_expr_no_commas (parser
, NULL
);
9024 if (assoc
.expression
.value
== error_mark_node
)
9026 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9030 for (ix
= 0; associations
.iterate (ix
, &iter
); ++ix
)
9032 if (assoc
.type
== NULL_TREE
)
9034 if (iter
->type
== NULL_TREE
)
9036 error_at (assoc
.type_location
,
9037 "duplicate %<default%> case in %<_Generic%>");
9038 inform (iter
->type_location
, "original %<default%> is here");
9041 else if (iter
->type
!= NULL_TREE
)
9043 if (comptypes (assoc
.type
, iter
->type
))
9045 error_at (assoc
.type_location
,
9046 "%<_Generic%> specifies two compatible types");
9047 inform (iter
->type_location
, "compatible type is here");
9052 if (assoc
.type
== NULL_TREE
)
9054 if (match_found
< 0)
9056 matched_assoc
= assoc
;
9057 match_found
= associations
.length ();
9060 else if (comptypes (assoc
.type
, selector_type
))
9062 if (match_found
< 0 || matched_assoc
.type
== NULL_TREE
)
9064 matched_assoc
= assoc
;
9065 match_found
= associations
.length ();
9069 error_at (assoc
.type_location
,
9070 "%<_Generic%> selector matches multiple associations");
9071 inform (matched_assoc
.type_location
,
9072 "other match is here");
9076 associations
.safe_push (assoc
);
9078 if (c_parser_peek_token (parser
)->type
!= CPP_COMMA
)
9080 c_parser_consume_token (parser
);
9084 struct c_generic_association
*iter
;
9085 FOR_EACH_VEC_ELT (associations
, ix
, iter
)
9086 if (ix
!= (unsigned) match_found
)
9087 mark_exp_read (iter
->expression
.value
);
9089 if (!parens
.require_close (parser
))
9091 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9095 if (match_found
< 0)
9097 error_at (selector_loc
, "%<_Generic%> selector of type %qT is not "
9098 "compatible with any association",
9103 return matched_assoc
.expression
;
9106 /* Check the validity of a function pointer argument *EXPR (argument
9107 position POS) to __builtin_tgmath. Return the number of function
9108 arguments if possibly valid; return 0 having reported an error if
9112 check_tgmath_function (c_expr
*expr
, unsigned int pos
)
9114 tree type
= TREE_TYPE (expr
->value
);
9115 if (!FUNCTION_POINTER_TYPE_P (type
))
9117 error_at (expr
->get_location (),
9118 "argument %u of %<__builtin_tgmath%> is not a function pointer",
9122 type
= TREE_TYPE (type
);
9123 if (!prototype_p (type
))
9125 error_at (expr
->get_location (),
9126 "argument %u of %<__builtin_tgmath%> is unprototyped", pos
);
9129 if (stdarg_p (type
))
9131 error_at (expr
->get_location (),
9132 "argument %u of %<__builtin_tgmath%> has variable arguments",
9136 unsigned int nargs
= 0;
9137 function_args_iterator iter
;
9139 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9141 if (t
== void_type_node
)
9147 error_at (expr
->get_location (),
9148 "argument %u of %<__builtin_tgmath%> has no arguments", pos
);
9154 /* Ways in which a parameter or return value of a type-generic macro
9155 may vary between the different functions the macro may call. */
9156 enum tgmath_parm_kind
9158 tgmath_fixed
, tgmath_real
, tgmath_complex
9161 /* Helper function for c_parser_postfix_expression. Parse predefined
9164 static struct c_expr
9165 c_parser_predefined_identifier (c_parser
*parser
)
9167 location_t loc
= c_parser_peek_token (parser
)->location
;
9168 switch (c_parser_peek_token (parser
)->keyword
)
9170 case RID_FUNCTION_NAME
:
9171 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
9172 "identifier", "__FUNCTION__");
9174 case RID_PRETTY_FUNCTION_NAME
:
9175 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
9176 "identifier", "__PRETTY_FUNCTION__");
9178 case RID_C99_FUNCTION_NAME
:
9179 pedwarn_c90 (loc
, OPT_Wpedantic
, "ISO C90 does not support "
9180 "%<__func__%> predefined identifier");
9187 expr
.original_code
= ERROR_MARK
;
9188 expr
.original_type
= NULL
;
9189 expr
.value
= fname_decl (loc
, c_parser_peek_token (parser
)->keyword
,
9190 c_parser_peek_token (parser
)->value
);
9191 set_c_expr_source_range (&expr
, loc
, loc
);
9193 c_parser_consume_token (parser
);
9197 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
9198 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
9199 call c_parser_postfix_expression_after_paren_type on encountering them.
9203 postfix-expression [ expression ]
9204 postfix-expression ( argument-expression-list[opt] )
9205 postfix-expression . identifier
9206 postfix-expression -> identifier
9207 postfix-expression ++
9208 postfix-expression --
9209 ( storage-class-specifiers[opt] type-name ) { initializer-list[opt] }
9210 ( storage-class-specifiers[opt] type-name ) { initializer-list , }
9212 argument-expression-list:
9214 argument-expression-list , argument-expression
9227 (treated as a keyword in GNU C)
9230 ( compound-statement )
9231 __builtin_va_arg ( assignment-expression , type-name )
9232 __builtin_offsetof ( type-name , offsetof-member-designator )
9233 __builtin_choose_expr ( assignment-expression ,
9234 assignment-expression ,
9235 assignment-expression )
9236 __builtin_types_compatible_p ( type-name , type-name )
9237 __builtin_tgmath ( expr-list )
9238 __builtin_complex ( assignment-expression , assignment-expression )
9239 __builtin_shuffle ( assignment-expression , assignment-expression )
9240 __builtin_shuffle ( assignment-expression ,
9241 assignment-expression ,
9242 assignment-expression, )
9243 __builtin_convertvector ( assignment-expression , type-name )
9244 __builtin_assoc_barrier ( assignment-expression )
9246 offsetof-member-designator:
9248 offsetof-member-designator . identifier
9249 offsetof-member-designator [ expression ]
9254 [ objc-receiver objc-message-args ]
9255 @selector ( objc-selector-arg )
9256 @protocol ( identifier )
9257 @encode ( type-name )
9259 Classname . identifier
9262 static struct c_expr
9263 c_parser_postfix_expression (c_parser
*parser
)
9265 struct c_expr expr
, e1
;
9266 struct c_type_name
*t1
, *t2
;
9267 location_t loc
= c_parser_peek_token (parser
)->location
;
9268 source_range tok_range
= c_parser_peek_token (parser
)->get_range ();
9269 expr
.original_code
= ERROR_MARK
;
9270 expr
.original_type
= NULL
;
9272 switch (c_parser_peek_token (parser
)->type
)
9275 expr
.value
= c_parser_peek_token (parser
)->value
;
9276 set_c_expr_source_range (&expr
, tok_range
);
9277 loc
= c_parser_peek_token (parser
)->location
;
9278 expr
.m_decimal
= c_parser_peek_token (parser
)->flags
& DECIMAL_INT
;
9279 c_parser_consume_token (parser
);
9280 if (TREE_CODE (expr
.value
) == FIXED_CST
9281 && !targetm
.fixed_point_supported_p ())
9283 error_at (loc
, "fixed-point types not supported for this target");
9292 expr
.value
= c_parser_peek_token (parser
)->value
;
9293 /* For the purpose of warning when a pointer is compared with
9294 a zero character constant. */
9295 expr
.original_type
= char_type_node
;
9296 set_c_expr_source_range (&expr
, tok_range
);
9297 c_parser_consume_token (parser
);
9303 case CPP_UTF8STRING
:
9304 expr
= c_parser_string_literal (parser
, parser
->translate_strings_p
,
9307 case CPP_OBJC_STRING
:
9308 gcc_assert (c_dialect_objc ());
9310 = objc_build_string_object (c_parser_peek_token (parser
)->value
);
9311 set_c_expr_source_range (&expr
, tok_range
);
9312 c_parser_consume_token (parser
);
9315 switch (c_parser_peek_token (parser
)->id_kind
)
9319 tree id
= c_parser_peek_token (parser
)->value
;
9320 c_parser_consume_token (parser
);
9321 expr
.value
= build_external_ref (loc
, id
,
9322 (c_parser_peek_token (parser
)->type
9324 &expr
.original_type
);
9325 set_c_expr_source_range (&expr
, tok_range
);
9328 case C_ID_CLASSNAME
:
9330 /* Here we parse the Objective-C 2.0 Class.name dot
9332 tree class_name
= c_parser_peek_token (parser
)->value
;
9334 c_parser_consume_token (parser
);
9335 gcc_assert (c_dialect_objc ());
9336 if (!c_parser_require (parser
, CPP_DOT
, "expected %<.%>"))
9341 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9343 c_parser_error (parser
, "expected identifier");
9347 c_token
*component_tok
= c_parser_peek_token (parser
);
9348 component
= component_tok
->value
;
9349 location_t end_loc
= component_tok
->get_finish ();
9350 c_parser_consume_token (parser
);
9351 expr
.value
= objc_build_class_component_ref (class_name
,
9353 set_c_expr_source_range (&expr
, loc
, end_loc
);
9357 c_parser_error (parser
, "expected expression");
9362 case CPP_OPEN_PAREN
:
9363 /* A parenthesized expression, statement expression or compound
9365 if (c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_BRACE
)
9367 /* A statement expression. */
9369 location_t brace_loc
;
9370 c_parser_consume_token (parser
);
9371 brace_loc
= c_parser_peek_token (parser
)->location
;
9372 c_parser_consume_token (parser
);
9373 /* If we've not yet started the current function's statement list,
9374 or we're in the parameter scope of an old-style function
9375 declaration, statement expressions are not allowed. */
9376 if (!building_stmt_list_p () || old_style_parameter_scope ())
9378 error_at (loc
, "braced-group within expression allowed "
9379 "only inside a function");
9380 parser
->error
= true;
9381 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
9382 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9386 stmt
= c_begin_stmt_expr ();
9387 c_parser_compound_statement_nostart (parser
);
9388 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9389 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9391 pedwarn (loc
, OPT_Wpedantic
,
9392 "ISO C forbids braced-groups within expressions");
9393 expr
.value
= c_finish_stmt_expr (brace_loc
, stmt
);
9394 set_c_expr_source_range (&expr
, loc
, close_loc
);
9395 mark_exp_read (expr
.value
);
9399 /* A parenthesized expression. */
9400 location_t loc_open_paren
= c_parser_peek_token (parser
)->location
;
9401 c_parser_consume_token (parser
);
9402 expr
= c_parser_expression (parser
);
9403 if (TREE_CODE (expr
.value
) == MODIFY_EXPR
)
9404 suppress_warning (expr
.value
, OPT_Wparentheses
);
9405 if (expr
.original_code
!= C_MAYBE_CONST_EXPR
9406 && expr
.original_code
!= SIZEOF_EXPR
)
9407 expr
.original_code
= ERROR_MARK
;
9408 /* Remember that we saw ( ) around the sizeof. */
9409 if (expr
.original_code
== SIZEOF_EXPR
)
9410 expr
.original_code
= PAREN_SIZEOF_EXPR
;
9411 /* Don't change EXPR.ORIGINAL_TYPE. */
9412 location_t loc_close_paren
= c_parser_peek_token (parser
)->location
;
9413 set_c_expr_source_range (&expr
, loc_open_paren
, loc_close_paren
);
9414 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9415 "expected %<)%>", loc_open_paren
);
9419 switch (c_parser_peek_token (parser
)->keyword
)
9421 case RID_FUNCTION_NAME
:
9422 case RID_PRETTY_FUNCTION_NAME
:
9423 case RID_C99_FUNCTION_NAME
:
9424 expr
= c_parser_predefined_identifier (parser
);
9428 location_t start_loc
= loc
;
9429 c_parser_consume_token (parser
);
9430 matching_parens parens
;
9431 if (!parens
.require_open (parser
))
9436 e1
= c_parser_expr_no_commas (parser
, NULL
);
9437 mark_exp_read (e1
.value
);
9438 e1
.value
= c_fully_fold (e1
.value
, false, NULL
);
9439 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9441 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9445 loc
= c_parser_peek_token (parser
)->location
;
9446 t1
= c_parser_type_name (parser
);
9447 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9448 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9456 tree type_expr
= NULL_TREE
;
9457 expr
.value
= c_build_va_arg (start_loc
, e1
.value
, loc
,
9458 groktypename (t1
, &type_expr
, NULL
));
9461 expr
.value
= build2 (C_MAYBE_CONST_EXPR
,
9462 TREE_TYPE (expr
.value
), type_expr
,
9464 C_MAYBE_CONST_EXPR_NON_CONST (expr
.value
) = true;
9466 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
9472 c_parser_consume_token (parser
);
9473 matching_parens parens
;
9474 if (!parens
.require_open (parser
))
9479 t1
= c_parser_type_name (parser
);
9481 parser
->error
= true;
9482 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9483 gcc_assert (parser
->error
);
9486 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9490 tree type
= groktypename (t1
, NULL
, NULL
);
9492 if (type
== error_mark_node
)
9493 offsetof_ref
= error_mark_node
;
9496 offsetof_ref
= build1 (INDIRECT_REF
, type
, null_pointer_node
);
9497 SET_EXPR_LOCATION (offsetof_ref
, loc
);
9499 /* Parse the second argument to __builtin_offsetof. We
9500 must have one identifier, and beyond that we want to
9501 accept sub structure and sub array references. */
9502 if (c_parser_next_token_is (parser
, CPP_NAME
))
9504 c_token
*comp_tok
= c_parser_peek_token (parser
);
9506 = build_component_ref (loc
, offsetof_ref
, comp_tok
->value
,
9507 comp_tok
->location
, UNKNOWN_LOCATION
);
9508 c_parser_consume_token (parser
);
9509 while (c_parser_next_token_is (parser
, CPP_DOT
)
9510 || c_parser_next_token_is (parser
,
9512 || c_parser_next_token_is (parser
,
9515 if (c_parser_next_token_is (parser
, CPP_DEREF
))
9517 loc
= c_parser_peek_token (parser
)->location
;
9518 offsetof_ref
= build_array_ref (loc
,
9523 else if (c_parser_next_token_is (parser
, CPP_DOT
))
9526 c_parser_consume_token (parser
);
9527 if (c_parser_next_token_is_not (parser
,
9530 c_parser_error (parser
, "expected identifier");
9533 c_token
*comp_tok
= c_parser_peek_token (parser
);
9535 = build_component_ref (loc
, offsetof_ref
,
9539 c_parser_consume_token (parser
);
9545 loc
= c_parser_peek_token (parser
)->location
;
9546 c_parser_consume_token (parser
);
9547 ce
= c_parser_expression (parser
);
9548 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
9550 idx
= c_fully_fold (idx
, false, NULL
);
9551 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
9553 offsetof_ref
= build_array_ref (loc
, offsetof_ref
, idx
);
9558 c_parser_error (parser
, "expected identifier");
9559 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9560 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9562 expr
.value
= fold_offsetof (offsetof_ref
);
9563 set_c_expr_source_range (&expr
, loc
, end_loc
);
9566 case RID_CHOOSE_EXPR
:
9568 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9569 c_expr_t
*e1_p
, *e2_p
, *e3_p
;
9571 location_t close_paren_loc
;
9573 c_parser_consume_token (parser
);
9574 if (!c_parser_get_builtin_args (parser
,
9575 "__builtin_choose_expr",
9583 if (vec_safe_length (cexpr_list
) != 3)
9585 error_at (loc
, "wrong number of arguments to "
9586 "%<__builtin_choose_expr%>");
9591 e1_p
= &(*cexpr_list
)[0];
9592 e2_p
= &(*cexpr_list
)[1];
9593 e3_p
= &(*cexpr_list
)[2];
9596 mark_exp_read (e2_p
->value
);
9597 mark_exp_read (e3_p
->value
);
9598 if (TREE_CODE (c
) != INTEGER_CST
9599 || !INTEGRAL_TYPE_P (TREE_TYPE (c
)))
9601 "first argument to %<__builtin_choose_expr%> not"
9603 constant_expression_warning (c
);
9604 expr
= integer_zerop (c
) ? *e3_p
: *e2_p
;
9605 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9608 case RID_TYPES_COMPATIBLE_P
:
9610 c_parser_consume_token (parser
);
9611 matching_parens parens
;
9612 if (!parens
.require_open (parser
))
9617 t1
= c_parser_type_name (parser
);
9623 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9625 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9629 t2
= c_parser_type_name (parser
);
9635 location_t close_paren_loc
= c_parser_peek_token (parser
)->location
;
9636 parens
.skip_until_found_close (parser
);
9638 e1
= groktypename (t1
, NULL
, NULL
);
9639 e2
= groktypename (t2
, NULL
, NULL
);
9640 if (e1
== error_mark_node
|| e2
== error_mark_node
)
9646 e1
= TYPE_MAIN_VARIANT (e1
);
9647 e2
= TYPE_MAIN_VARIANT (e2
);
9650 = comptypes (e1
, e2
) ? integer_one_node
: integer_zero_node
;
9651 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9654 case RID_BUILTIN_TGMATH
:
9656 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9657 location_t close_paren_loc
;
9659 c_parser_consume_token (parser
);
9660 if (!c_parser_get_builtin_args (parser
,
9669 if (vec_safe_length (cexpr_list
) < 3)
9671 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9678 FOR_EACH_VEC_ELT (*cexpr_list
, i
, p
)
9679 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
9680 unsigned int nargs
= check_tgmath_function (&(*cexpr_list
)[0], 1);
9686 if (vec_safe_length (cexpr_list
) < nargs
)
9688 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9692 unsigned int num_functions
= vec_safe_length (cexpr_list
) - nargs
;
9693 if (num_functions
< 2)
9695 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9700 /* The first NUM_FUNCTIONS expressions are the function
9701 pointers. The remaining NARGS expressions are the
9702 arguments that are to be passed to one of those
9703 functions, chosen following <tgmath.h> rules. */
9704 for (unsigned int j
= 1; j
< num_functions
; j
++)
9706 unsigned int this_nargs
9707 = check_tgmath_function (&(*cexpr_list
)[j
], j
+ 1);
9708 if (this_nargs
== 0)
9713 if (this_nargs
!= nargs
)
9715 error_at ((*cexpr_list
)[j
].get_location (),
9716 "argument %u of %<__builtin_tgmath%> has "
9717 "wrong number of arguments", j
+ 1);
9723 /* The functions all have the same number of arguments.
9724 Determine whether arguments and return types vary in
9725 ways permitted for <tgmath.h> functions. */
9726 /* The first entry in each of these vectors is for the
9727 return type, subsequent entries for parameter
9729 auto_vec
<enum tgmath_parm_kind
> parm_kind (nargs
+ 1);
9730 auto_vec
<tree
> parm_first (nargs
+ 1);
9731 auto_vec
<bool> parm_complex (nargs
+ 1);
9732 auto_vec
<bool> parm_varies (nargs
+ 1);
9733 tree first_type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[0].value
));
9734 tree first_ret
= TYPE_MAIN_VARIANT (TREE_TYPE (first_type
));
9735 parm_first
.quick_push (first_ret
);
9736 parm_complex
.quick_push (TREE_CODE (first_ret
) == COMPLEX_TYPE
);
9737 parm_varies
.quick_push (false);
9738 function_args_iterator iter
;
9740 unsigned int argpos
;
9741 FOREACH_FUNCTION_ARGS (first_type
, t
, iter
)
9743 if (t
== void_type_node
)
9745 parm_first
.quick_push (TYPE_MAIN_VARIANT (t
));
9746 parm_complex
.quick_push (TREE_CODE (t
) == COMPLEX_TYPE
);
9747 parm_varies
.quick_push (false);
9749 for (unsigned int j
= 1; j
< num_functions
; j
++)
9751 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9752 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
9753 if (ret
!= parm_first
[0])
9755 parm_varies
[0] = true;
9756 if (!SCALAR_FLOAT_TYPE_P (parm_first
[0])
9757 && !COMPLEX_FLOAT_TYPE_P (parm_first
[0]))
9759 error_at ((*cexpr_list
)[0].get_location (),
9760 "invalid type-generic return type for "
9761 "argument %u of %<__builtin_tgmath%>",
9766 if (!SCALAR_FLOAT_TYPE_P (ret
)
9767 && !COMPLEX_FLOAT_TYPE_P (ret
))
9769 error_at ((*cexpr_list
)[j
].get_location (),
9770 "invalid type-generic return type for "
9771 "argument %u of %<__builtin_tgmath%>",
9777 if (TREE_CODE (ret
) == COMPLEX_TYPE
)
9778 parm_complex
[0] = true;
9780 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9782 if (t
== void_type_node
)
9784 t
= TYPE_MAIN_VARIANT (t
);
9785 if (t
!= parm_first
[argpos
])
9787 parm_varies
[argpos
] = true;
9788 if (!SCALAR_FLOAT_TYPE_P (parm_first
[argpos
])
9789 && !COMPLEX_FLOAT_TYPE_P (parm_first
[argpos
]))
9791 error_at ((*cexpr_list
)[0].get_location (),
9792 "invalid type-generic type for "
9793 "argument %u of argument %u of "
9794 "%<__builtin_tgmath%>", argpos
, 1);
9798 if (!SCALAR_FLOAT_TYPE_P (t
)
9799 && !COMPLEX_FLOAT_TYPE_P (t
))
9801 error_at ((*cexpr_list
)[j
].get_location (),
9802 "invalid type-generic type for "
9803 "argument %u of argument %u of "
9804 "%<__builtin_tgmath%>", argpos
, j
+ 1);
9809 if (TREE_CODE (t
) == COMPLEX_TYPE
)
9810 parm_complex
[argpos
] = true;
9814 enum tgmath_parm_kind max_variation
= tgmath_fixed
;
9815 for (unsigned int j
= 0; j
<= nargs
; j
++)
9817 enum tgmath_parm_kind this_kind
;
9820 if (parm_complex
[j
])
9821 max_variation
= this_kind
= tgmath_complex
;
9824 this_kind
= tgmath_real
;
9825 if (max_variation
!= tgmath_complex
)
9826 max_variation
= tgmath_real
;
9830 this_kind
= tgmath_fixed
;
9831 parm_kind
.quick_push (this_kind
);
9833 if (max_variation
== tgmath_fixed
)
9835 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
9836 "all have the same type");
9841 /* Identify a parameter (not the return type) that varies,
9842 including with complex types if any variation includes
9843 complex types; there must be at least one such
9845 unsigned int tgarg
= 0;
9846 for (unsigned int j
= 1; j
<= nargs
; j
++)
9847 if (parm_kind
[j
] == max_variation
)
9854 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
9855 "lack type-generic parameter");
9860 /* Determine the type of the relevant parameter for each
9862 auto_vec
<tree
> tg_type (num_functions
);
9863 for (unsigned int j
= 0; j
< num_functions
; j
++)
9865 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9867 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9869 if (argpos
== tgarg
)
9871 tg_type
.quick_push (TYPE_MAIN_VARIANT (t
));
9878 /* Verify that the corresponding types are different for
9879 all the listed functions. Also determine whether all
9880 the types are complex, whether all the types are
9881 standard or binary, and whether all the types are
9883 bool all_complex
= true;
9884 bool all_binary
= true;
9885 bool all_decimal
= true;
9886 hash_set
<tree
> tg_types
;
9887 FOR_EACH_VEC_ELT (tg_type
, i
, t
)
9889 if (TREE_CODE (t
) == COMPLEX_TYPE
)
9890 all_decimal
= false;
9893 all_complex
= false;
9894 if (DECIMAL_FLOAT_TYPE_P (t
))
9897 all_decimal
= false;
9899 if (tg_types
.add (t
))
9901 error_at ((*cexpr_list
)[i
].get_location (),
9902 "duplicate type-generic parameter type for "
9903 "function argument %u of %<__builtin_tgmath%>",
9910 /* Verify that other parameters and the return type whose
9911 types vary have their types varying in the correct
9913 for (unsigned int j
= 0; j
< num_functions
; j
++)
9915 tree exp_type
= tg_type
[j
];
9916 tree exp_real_type
= exp_type
;
9917 if (TREE_CODE (exp_type
) == COMPLEX_TYPE
)
9918 exp_real_type
= TREE_TYPE (exp_type
);
9919 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9920 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
9921 if ((parm_kind
[0] == tgmath_complex
&& ret
!= exp_type
)
9922 || (parm_kind
[0] == tgmath_real
&& ret
!= exp_real_type
))
9924 error_at ((*cexpr_list
)[j
].get_location (),
9925 "bad return type for function argument %u "
9926 "of %<__builtin_tgmath%>", j
+ 1);
9931 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9933 if (t
== void_type_node
)
9935 t
= TYPE_MAIN_VARIANT (t
);
9936 if ((parm_kind
[argpos
] == tgmath_complex
9938 || (parm_kind
[argpos
] == tgmath_real
9939 && t
!= exp_real_type
))
9941 error_at ((*cexpr_list
)[j
].get_location (),
9942 "bad type for argument %u of "
9943 "function argument %u of "
9944 "%<__builtin_tgmath%>", argpos
, j
+ 1);
9952 /* The functions listed are a valid set of functions for a
9953 <tgmath.h> macro to select between. Identify the
9954 matching function, if any. First, the argument types
9955 must be combined following <tgmath.h> rules. Integer
9956 types are treated as _Decimal64 if any type-generic
9957 argument is decimal, or if the only alternatives for
9958 type-generic arguments are of decimal types, and are
9959 otherwise treated as double (or _Complex double for
9960 complex integer types, or _Float64 or _Complex _Float64
9961 if all the return types are the same _FloatN or
9962 _FloatNx type). After that adjustment, types are
9963 combined following the usual arithmetic conversions.
9964 If the function only accepts complex arguments, a
9965 complex type is produced. */
9966 bool arg_complex
= all_complex
;
9967 bool arg_binary
= all_binary
;
9968 bool arg_int_decimal
= all_decimal
;
9969 for (unsigned int j
= 1; j
<= nargs
; j
++)
9971 if (parm_kind
[j
] == tgmath_fixed
)
9973 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9974 tree type
= TREE_TYPE (ce
->value
);
9975 if (!INTEGRAL_TYPE_P (type
)
9976 && !SCALAR_FLOAT_TYPE_P (type
)
9977 && TREE_CODE (type
) != COMPLEX_TYPE
)
9979 error_at (ce
->get_location (),
9980 "invalid type of argument %u of type-generic "
9985 if (DECIMAL_FLOAT_TYPE_P (type
))
9987 arg_int_decimal
= true;
9990 error_at (ce
->get_location (),
9991 "decimal floating-point argument %u to "
9992 "complex-only type-generic function", j
);
9996 else if (all_binary
)
9998 error_at (ce
->get_location (),
9999 "decimal floating-point argument %u to "
10000 "binary-only type-generic function", j
);
10004 else if (arg_complex
)
10006 error_at (ce
->get_location (),
10007 "both complex and decimal floating-point "
10008 "arguments to type-generic function");
10012 else if (arg_binary
)
10014 error_at (ce
->get_location (),
10015 "both binary and decimal floating-point "
10016 "arguments to type-generic function");
10021 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
10023 arg_complex
= true;
10024 if (COMPLEX_FLOAT_TYPE_P (type
))
10028 error_at (ce
->get_location (),
10029 "complex argument %u to "
10030 "decimal-only type-generic function", j
);
10034 else if (arg_int_decimal
)
10036 error_at (ce
->get_location (),
10037 "both complex and decimal floating-point "
10038 "arguments to type-generic function");
10043 else if (SCALAR_FLOAT_TYPE_P (type
))
10048 error_at (ce
->get_location (),
10049 "binary argument %u to "
10050 "decimal-only type-generic function", j
);
10054 else if (arg_int_decimal
)
10056 error_at (ce
->get_location (),
10057 "both binary and decimal floating-point "
10058 "arguments to type-generic function");
10064 /* For a macro rounding its result to a narrower type, map
10065 integer types to _Float64 not double if the return type
10066 is a _FloatN or _FloatNx type. */
10067 bool arg_int_float64
= false;
10068 if (parm_kind
[0] == tgmath_fixed
10069 && SCALAR_FLOAT_TYPE_P (parm_first
[0])
10070 && float64_type_node
!= NULL_TREE
)
10071 for (unsigned int j
= 0; j
< NUM_FLOATN_NX_TYPES
; j
++)
10072 if (parm_first
[0] == FLOATN_TYPE_NODE (j
))
10074 arg_int_float64
= true;
10077 tree arg_real
= NULL_TREE
;
10078 for (unsigned int j
= 1; j
<= nargs
; j
++)
10080 if (parm_kind
[j
] == tgmath_fixed
)
10082 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
10083 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (ce
->value
));
10084 if (TREE_CODE (type
) == COMPLEX_TYPE
)
10085 type
= TREE_TYPE (type
);
10086 if (INTEGRAL_TYPE_P (type
))
10087 type
= (arg_int_decimal
10088 ? dfloat64_type_node
10090 ? float64_type_node
10091 : double_type_node
);
10092 if (arg_real
== NULL_TREE
)
10095 arg_real
= common_type (arg_real
, type
);
10096 if (arg_real
== error_mark_node
)
10102 tree arg_type
= (arg_complex
10103 ? build_complex_type (arg_real
)
10106 /* Look for a function to call with type-generic parameter
10108 c_expr_t
*fn
= NULL
;
10109 for (unsigned int j
= 0; j
< num_functions
; j
++)
10111 if (tg_type
[j
] == arg_type
)
10113 fn
= &(*cexpr_list
)[j
];
10118 && parm_kind
[0] == tgmath_fixed
10119 && SCALAR_FLOAT_TYPE_P (parm_first
[0]))
10121 /* Presume this is a macro that rounds its result to a
10122 narrower type, and look for the first function with
10123 at least the range and precision of the argument
10125 for (unsigned int j
= 0; j
< num_functions
; j
++)
10128 != (TREE_CODE (tg_type
[j
]) == COMPLEX_TYPE
))
10130 tree real_tg_type
= (arg_complex
10131 ? TREE_TYPE (tg_type
[j
])
10133 if (DECIMAL_FLOAT_TYPE_P (arg_real
)
10134 != DECIMAL_FLOAT_TYPE_P (real_tg_type
))
10136 scalar_float_mode arg_mode
10137 = SCALAR_FLOAT_TYPE_MODE (arg_real
);
10138 scalar_float_mode tg_mode
10139 = SCALAR_FLOAT_TYPE_MODE (real_tg_type
);
10140 const real_format
*arg_fmt
= REAL_MODE_FORMAT (arg_mode
);
10141 const real_format
*tg_fmt
= REAL_MODE_FORMAT (tg_mode
);
10142 if (arg_fmt
->b
== tg_fmt
->b
10143 && arg_fmt
->p
<= tg_fmt
->p
10144 && arg_fmt
->emax
<= tg_fmt
->emax
10145 && (arg_fmt
->emin
- arg_fmt
->p
10146 >= tg_fmt
->emin
- tg_fmt
->p
))
10148 fn
= &(*cexpr_list
)[j
];
10155 error_at (loc
, "no matching function for type-generic call");
10160 /* Construct a call to FN. */
10161 vec
<tree
, va_gc
> *args
;
10162 vec_alloc (args
, nargs
);
10163 vec
<tree
, va_gc
> *origtypes
;
10164 vec_alloc (origtypes
, nargs
);
10165 auto_vec
<location_t
> arg_loc (nargs
);
10166 for (unsigned int j
= 0; j
< nargs
; j
++)
10168 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
];
10169 args
->quick_push (ce
->value
);
10170 arg_loc
.quick_push (ce
->get_location ());
10171 origtypes
->quick_push (ce
->original_type
);
10173 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fn
->value
,
10175 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10178 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN
:
10180 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10183 location_t close_paren_loc
;
10185 c_parser_consume_token (parser
);
10186 if (!c_parser_get_builtin_args (parser
,
10187 "__builtin_call_with_static_chain",
10188 &cexpr_list
, false,
10194 if (vec_safe_length (cexpr_list
) != 2)
10196 error_at (loc
, "wrong number of arguments to "
10197 "%<__builtin_call_with_static_chain%>");
10202 expr
= (*cexpr_list
)[0];
10203 e2_p
= &(*cexpr_list
)[1];
10204 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
10205 chain_value
= e2_p
->value
;
10206 mark_exp_read (chain_value
);
10208 if (TREE_CODE (expr
.value
) != CALL_EXPR
)
10209 error_at (loc
, "first argument to "
10210 "%<__builtin_call_with_static_chain%> "
10211 "must be a call expression");
10212 else if (TREE_CODE (TREE_TYPE (chain_value
)) != POINTER_TYPE
)
10213 error_at (loc
, "second argument to "
10214 "%<__builtin_call_with_static_chain%> "
10215 "must be a pointer type");
10217 CALL_EXPR_STATIC_CHAIN (expr
.value
) = chain_value
;
10218 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10221 case RID_BUILTIN_COMPLEX
:
10223 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10224 c_expr_t
*e1_p
, *e2_p
;
10225 location_t close_paren_loc
;
10227 c_parser_consume_token (parser
);
10228 if (!c_parser_get_builtin_args (parser
,
10229 "__builtin_complex",
10230 &cexpr_list
, false,
10237 if (vec_safe_length (cexpr_list
) != 2)
10239 error_at (loc
, "wrong number of arguments to "
10240 "%<__builtin_complex%>");
10245 e1_p
= &(*cexpr_list
)[0];
10246 e2_p
= &(*cexpr_list
)[1];
10248 *e1_p
= convert_lvalue_to_rvalue (loc
, *e1_p
, true, true);
10249 if (TREE_CODE (e1_p
->value
) == EXCESS_PRECISION_EXPR
)
10250 e1_p
->value
= convert (TREE_TYPE (e1_p
->value
),
10251 TREE_OPERAND (e1_p
->value
, 0));
10252 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
10253 if (TREE_CODE (e2_p
->value
) == EXCESS_PRECISION_EXPR
)
10254 e2_p
->value
= convert (TREE_TYPE (e2_p
->value
),
10255 TREE_OPERAND (e2_p
->value
, 0));
10256 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
10257 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
10258 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
))
10259 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
)))
10261 error_at (loc
, "%<__builtin_complex%> operand "
10262 "not of real binary floating-point type");
10266 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p
->value
))
10267 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p
->value
)))
10270 "%<__builtin_complex%> operands of different types");
10274 pedwarn_c90 (loc
, OPT_Wpedantic
,
10275 "ISO C90 does not support complex types");
10276 expr
.value
= build2_loc (loc
, COMPLEX_EXPR
,
10279 (TREE_TYPE (e1_p
->value
))),
10280 e1_p
->value
, e2_p
->value
);
10281 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10284 case RID_BUILTIN_SHUFFLE
:
10286 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10289 location_t close_paren_loc
;
10291 c_parser_consume_token (parser
);
10292 if (!c_parser_get_builtin_args (parser
,
10293 "__builtin_shuffle",
10294 &cexpr_list
, false,
10301 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
10302 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
10304 if (vec_safe_length (cexpr_list
) == 2)
10305 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10307 (*cexpr_list
)[1].value
);
10309 else if (vec_safe_length (cexpr_list
) == 3)
10310 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10311 (*cexpr_list
)[1].value
,
10312 (*cexpr_list
)[2].value
);
10315 error_at (loc
, "wrong number of arguments to "
10316 "%<__builtin_shuffle%>");
10319 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10322 case RID_BUILTIN_SHUFFLEVECTOR
:
10324 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10327 location_t close_paren_loc
;
10329 c_parser_consume_token (parser
);
10330 if (!c_parser_get_builtin_args (parser
,
10331 "__builtin_shufflevector",
10332 &cexpr_list
, false,
10339 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
10340 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
10342 if (vec_safe_length (cexpr_list
) < 3)
10344 error_at (loc
, "wrong number of arguments to "
10345 "%<__builtin_shuffle%>");
10350 auto_vec
<tree
, 16> mask
;
10351 for (i
= 2; i
< cexpr_list
->length (); ++i
)
10352 mask
.safe_push ((*cexpr_list
)[i
].value
);
10353 expr
.value
= c_build_shufflevector (loc
, (*cexpr_list
)[0].value
,
10354 (*cexpr_list
)[1].value
,
10357 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10360 case RID_BUILTIN_CONVERTVECTOR
:
10362 location_t start_loc
= loc
;
10363 c_parser_consume_token (parser
);
10364 matching_parens parens
;
10365 if (!parens
.require_open (parser
))
10370 e1
= c_parser_expr_no_commas (parser
, NULL
);
10371 mark_exp_read (e1
.value
);
10372 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10374 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10378 loc
= c_parser_peek_token (parser
)->location
;
10379 t1
= c_parser_type_name (parser
);
10380 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10381 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10387 tree type_expr
= NULL_TREE
;
10388 expr
.value
= c_build_vec_convert (start_loc
, e1
.value
, loc
,
10389 groktypename (t1
, &type_expr
,
10391 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10395 case RID_BUILTIN_ASSOC_BARRIER
:
10397 location_t start_loc
= loc
;
10398 c_parser_consume_token (parser
);
10399 matching_parens parens
;
10400 if (!parens
.require_open (parser
))
10405 e1
= c_parser_expr_no_commas (parser
, NULL
);
10406 mark_exp_read (e1
.value
);
10407 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10408 parens
.skip_until_found_close (parser
);
10409 expr
= parser_build_unary_op (loc
, PAREN_EXPR
, e1
);
10410 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10413 case RID_AT_SELECTOR
:
10415 gcc_assert (c_dialect_objc ());
10416 c_parser_consume_token (parser
);
10417 matching_parens parens
;
10418 if (!parens
.require_open (parser
))
10423 tree sel
= c_parser_objc_selector_arg (parser
);
10424 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10425 parens
.skip_until_found_close (parser
);
10426 expr
.value
= objc_build_selector_expr (loc
, sel
);
10427 set_c_expr_source_range (&expr
, loc
, close_loc
);
10430 case RID_AT_PROTOCOL
:
10432 gcc_assert (c_dialect_objc ());
10433 c_parser_consume_token (parser
);
10434 matching_parens parens
;
10435 if (!parens
.require_open (parser
))
10440 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10442 c_parser_error (parser
, "expected identifier");
10443 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10447 tree id
= c_parser_peek_token (parser
)->value
;
10448 c_parser_consume_token (parser
);
10449 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10450 parens
.skip_until_found_close (parser
);
10451 expr
.value
= objc_build_protocol_expr (id
);
10452 set_c_expr_source_range (&expr
, loc
, close_loc
);
10455 case RID_AT_ENCODE
:
10457 /* Extension to support C-structures in the archiver. */
10458 gcc_assert (c_dialect_objc ());
10459 c_parser_consume_token (parser
);
10460 matching_parens parens
;
10461 if (!parens
.require_open (parser
))
10466 t1
= c_parser_type_name (parser
);
10470 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10473 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10474 parens
.skip_until_found_close (parser
);
10475 tree type
= groktypename (t1
, NULL
, NULL
);
10476 expr
.value
= objc_build_encode_expr (type
);
10477 set_c_expr_source_range (&expr
, loc
, close_loc
);
10481 expr
= c_parser_generic_selection (parser
);
10483 case RID_OMP_ALL_MEMORY
:
10484 gcc_assert (flag_openmp
);
10485 c_parser_consume_token (parser
);
10486 error_at (loc
, "%<omp_all_memory%> may only be used in OpenMP "
10487 "%<depend%> clause");
10490 /* C23 'nullptr' literal. */
10492 c_parser_consume_token (parser
);
10493 expr
.value
= nullptr_node
;
10494 set_c_expr_source_range (&expr
, tok_range
);
10495 pedwarn_c11 (loc
, OPT_Wpedantic
,
10496 "ISO C does not support %qs before C2X", "nullptr");
10499 c_parser_consume_token (parser
);
10500 expr
.value
= boolean_true_node
;
10501 set_c_expr_source_range (&expr
, tok_range
);
10504 c_parser_consume_token (parser
);
10505 expr
.value
= boolean_false_node
;
10506 set_c_expr_source_range (&expr
, tok_range
);
10509 c_parser_error (parser
, "expected expression");
10514 case CPP_OPEN_SQUARE
:
10515 if (c_dialect_objc ())
10517 tree receiver
, args
;
10518 c_parser_consume_token (parser
);
10519 receiver
= c_parser_objc_receiver (parser
);
10520 args
= c_parser_objc_message_args (parser
);
10521 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10522 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10524 expr
.value
= objc_build_message_expr (receiver
, args
);
10525 set_c_expr_source_range (&expr
, loc
, close_loc
);
10528 /* Else fall through to report error. */
10531 c_parser_error (parser
, "expected expression");
10536 return c_parser_postfix_expression_after_primary
10537 (parser
, EXPR_LOC_OR_LOC (expr
.value
, loc
), expr
);
10540 /* Parse a postfix expression after a parenthesized type name: the
10541 brace-enclosed initializer of a compound literal, possibly followed
10542 by some postfix operators. This is separate because it is not
10543 possible to tell until after the type name whether a cast
10544 expression has a cast or a compound literal, or whether the operand
10545 of sizeof is a parenthesized type name or starts with a compound
10546 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10547 location of the first token after the parentheses around the type
10550 static struct c_expr
10551 c_parser_postfix_expression_after_paren_type (c_parser
*parser
,
10552 struct c_declspecs
*scspecs
,
10553 struct c_type_name
*type_name
,
10554 location_t type_loc
)
10557 struct c_expr init
;
10559 struct c_expr expr
;
10560 location_t start_loc
;
10561 tree type_expr
= NULL_TREE
;
10562 bool type_expr_const
= true;
10563 check_compound_literal_type (type_loc
, type_name
);
10564 rich_location
richloc (line_table
, type_loc
);
10565 start_init (NULL_TREE
, NULL
, 0, &richloc
);
10566 type
= groktypename (type_name
, &type_expr
, &type_expr_const
);
10567 start_loc
= c_parser_peek_token (parser
)->location
;
10568 if (type
!= error_mark_node
&& C_TYPE_VARIABLE_SIZE (type
))
10570 error_at (type_loc
, "compound literal has variable size");
10571 type
= error_mark_node
;
10573 init
= c_parser_braced_init (parser
, type
, false, NULL
, NULL_TREE
);
10575 maybe_warn_string_init (type_loc
, type
, init
);
10577 if (type
!= error_mark_node
10578 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type
))
10579 && current_function_decl
)
10581 error ("compound literal qualified by address-space qualifier");
10582 type
= error_mark_node
;
10585 if (!pedwarn_c90 (start_loc
, OPT_Wpedantic
,
10586 "ISO C90 forbids compound literals") && scspecs
)
10587 pedwarn_c11 (start_loc
, OPT_Wpedantic
,
10588 "ISO C forbids storage class specifiers in compound literals "
10590 non_const
= ((init
.value
&& TREE_CODE (init
.value
) == CONSTRUCTOR
)
10591 ? CONSTRUCTOR_NON_CONST (init
.value
)
10592 : init
.original_code
== C_MAYBE_CONST_EXPR
);
10593 non_const
|= !type_expr_const
;
10594 unsigned int alignas_align
= 0;
10595 if (type
!= error_mark_node
10596 && type_name
->specs
->align_log
!= -1)
10598 alignas_align
= 1U << type_name
->specs
->align_log
;
10599 if (alignas_align
< min_align_of_type (type
))
10601 error_at (type_name
->specs
->locations
[cdw_alignas
],
10602 "%<_Alignas%> specifiers cannot reduce "
10603 "alignment of compound literal");
10607 expr
.value
= build_compound_literal (start_loc
, type
, init
.value
, non_const
,
10608 alignas_align
, scspecs
);
10609 set_c_expr_source_range (&expr
, init
.src_range
);
10610 expr
.m_decimal
= 0;
10611 expr
.original_code
= ERROR_MARK
;
10612 expr
.original_type
= NULL
;
10613 if (type
!= error_mark_node
10614 && expr
.value
!= error_mark_node
10617 if (TREE_CODE (expr
.value
) == C_MAYBE_CONST_EXPR
)
10619 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr
.value
) == NULL_TREE
);
10620 C_MAYBE_CONST_EXPR_PRE (expr
.value
) = type_expr
;
10624 gcc_assert (!non_const
);
10625 expr
.value
= build2 (C_MAYBE_CONST_EXPR
, type
,
10626 type_expr
, expr
.value
);
10629 return c_parser_postfix_expression_after_primary (parser
, start_loc
, expr
);
10632 /* Callback function for sizeof_pointer_memaccess_warning to compare
10636 sizeof_ptr_memacc_comptypes (tree type1
, tree type2
)
10638 return comptypes (type1
, type2
) == 1;
10641 /* Warn for patterns where abs-like function appears to be used incorrectly,
10642 gracefully ignore any non-abs-like function. The warning location should
10643 be LOC. FNDECL is the declaration of called function, it must be a
10644 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10648 warn_for_abs (location_t loc
, tree fndecl
, tree arg
)
10650 /* Avoid warning in unreachable subexpressions. */
10651 if (c_inhibit_evaluation_warnings
)
10654 tree atype
= TREE_TYPE (arg
);
10656 /* Casts from pointers (and thus arrays and fndecls) will generate
10657 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10658 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10659 types and possibly other exotic types. */
10660 if (!INTEGRAL_TYPE_P (atype
)
10661 && !SCALAR_FLOAT_TYPE_P (atype
)
10662 && TREE_CODE (atype
) != COMPLEX_TYPE
)
10665 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
10670 case BUILT_IN_LABS
:
10671 case BUILT_IN_LLABS
:
10672 case BUILT_IN_IMAXABS
:
10673 if (!INTEGRAL_TYPE_P (atype
))
10675 if (SCALAR_FLOAT_TYPE_P (atype
))
10676 warning_at (loc
, OPT_Wabsolute_value
,
10677 "using integer absolute value function %qD when "
10678 "argument is of floating-point type %qT",
10680 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10681 warning_at (loc
, OPT_Wabsolute_value
,
10682 "using integer absolute value function %qD when "
10683 "argument is of complex type %qT", fndecl
, atype
);
10685 gcc_unreachable ();
10688 if (TYPE_UNSIGNED (atype
))
10689 warning_at (loc
, OPT_Wabsolute_value
,
10690 "taking the absolute value of unsigned type %qT "
10691 "has no effect", atype
);
10694 CASE_FLT_FN (BUILT_IN_FABS
):
10695 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS
):
10696 if (!SCALAR_FLOAT_TYPE_P (atype
)
10697 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype
)))
10699 if (INTEGRAL_TYPE_P (atype
))
10700 warning_at (loc
, OPT_Wabsolute_value
,
10701 "using floating-point absolute value function %qD "
10702 "when argument is of integer type %qT", fndecl
, atype
);
10703 else if (DECIMAL_FLOAT_TYPE_P (atype
))
10704 warning_at (loc
, OPT_Wabsolute_value
,
10705 "using floating-point absolute value function %qD "
10706 "when argument is of decimal floating-point type %qT",
10708 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10709 warning_at (loc
, OPT_Wabsolute_value
,
10710 "using floating-point absolute value function %qD when "
10711 "argument is of complex type %qT", fndecl
, atype
);
10713 gcc_unreachable ();
10718 CASE_FLT_FN (BUILT_IN_CABS
):
10719 if (TREE_CODE (atype
) != COMPLEX_TYPE
)
10721 if (INTEGRAL_TYPE_P (atype
))
10722 warning_at (loc
, OPT_Wabsolute_value
,
10723 "using complex absolute value function %qD when "
10724 "argument is of integer type %qT", fndecl
, atype
);
10725 else if (SCALAR_FLOAT_TYPE_P (atype
))
10726 warning_at (loc
, OPT_Wabsolute_value
,
10727 "using complex absolute value function %qD when "
10728 "argument is of floating-point type %qT",
10731 gcc_unreachable ();
10737 case BUILT_IN_FABSD32
:
10738 case BUILT_IN_FABSD64
:
10739 case BUILT_IN_FABSD128
:
10740 if (!DECIMAL_FLOAT_TYPE_P (atype
))
10742 if (INTEGRAL_TYPE_P (atype
))
10743 warning_at (loc
, OPT_Wabsolute_value
,
10744 "using decimal floating-point absolute value "
10745 "function %qD when argument is of integer type %qT",
10747 else if (SCALAR_FLOAT_TYPE_P (atype
))
10748 warning_at (loc
, OPT_Wabsolute_value
,
10749 "using decimal floating-point absolute value "
10750 "function %qD when argument is of floating-point "
10751 "type %qT", fndecl
, atype
);
10752 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10753 warning_at (loc
, OPT_Wabsolute_value
,
10754 "using decimal floating-point absolute value "
10755 "function %qD when argument is of complex type %qT",
10758 gcc_unreachable ();
10767 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl
)))
10770 tree ftype
= TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
10771 if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10773 gcc_assert (TREE_CODE (ftype
) == COMPLEX_TYPE
);
10774 atype
= TREE_TYPE (atype
);
10775 ftype
= TREE_TYPE (ftype
);
10778 if (TYPE_PRECISION (ftype
) < TYPE_PRECISION (atype
))
10779 warning_at (loc
, OPT_Wabsolute_value
,
10780 "absolute value function %qD given an argument of type %qT "
10781 "but has parameter of type %qT which may cause truncation "
10782 "of value", fndecl
, atype
, ftype
);
10786 /* Parse a postfix expression after the initial primary or compound
10787 literal; that is, parse a series of postfix operators.
10789 EXPR_LOC is the location of the primary expression. */
10791 static struct c_expr
10792 c_parser_postfix_expression_after_primary (c_parser
*parser
,
10793 location_t expr_loc
,
10794 struct c_expr expr
)
10796 struct c_expr orig_expr
;
10798 location_t sizeof_arg_loc
[3], comp_loc
;
10799 tree sizeof_arg
[3];
10800 unsigned int literal_zero_mask
;
10802 vec
<tree
, va_gc
> *exprlist
;
10803 vec
<tree
, va_gc
> *origtypes
= NULL
;
10804 vec
<location_t
> arg_loc
= vNULL
;
10810 location_t op_loc
= c_parser_peek_token (parser
)->location
;
10811 switch (c_parser_peek_token (parser
)->type
)
10813 case CPP_OPEN_SQUARE
:
10814 /* Array reference. */
10815 c_parser_consume_token (parser
);
10816 idx
= c_parser_expression (parser
).value
;
10817 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10819 start
= expr
.get_start ();
10820 finish
= parser
->tokens_buf
[0].location
;
10821 expr
.value
= build_array_ref (op_loc
, expr
.value
, idx
);
10822 set_c_expr_source_range (&expr
, start
, finish
);
10823 expr
.original_code
= ERROR_MARK
;
10824 expr
.original_type
= NULL
;
10825 expr
.m_decimal
= 0;
10827 case CPP_OPEN_PAREN
:
10828 /* Function call. */
10830 matching_parens parens
;
10831 parens
.consume_open (parser
);
10832 for (i
= 0; i
< 3; i
++)
10834 sizeof_arg
[i
] = NULL_TREE
;
10835 sizeof_arg_loc
[i
] = UNKNOWN_LOCATION
;
10837 literal_zero_mask
= 0;
10838 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10841 exprlist
= c_parser_expr_list (parser
, true, false, &origtypes
,
10842 sizeof_arg_loc
, sizeof_arg
,
10843 &arg_loc
, &literal_zero_mask
);
10844 parens
.skip_until_found_close (parser
);
10847 mark_exp_read (expr
.value
);
10848 if (warn_sizeof_pointer_memaccess
)
10849 sizeof_pointer_memaccess_warning (sizeof_arg_loc
,
10850 expr
.value
, exprlist
,
10852 sizeof_ptr_memacc_comptypes
);
10853 if (TREE_CODE (expr
.value
) == FUNCTION_DECL
)
10855 if (fndecl_built_in_p (expr
.value
, BUILT_IN_MEMSET
)
10856 && vec_safe_length (exprlist
) == 3)
10858 tree arg0
= (*exprlist
)[0];
10859 tree arg2
= (*exprlist
)[2];
10860 warn_for_memset (expr_loc
, arg0
, arg2
, literal_zero_mask
);
10862 if (warn_absolute_value
10863 && fndecl_built_in_p (expr
.value
, BUILT_IN_NORMAL
)
10864 && vec_safe_length (exprlist
) == 1)
10865 warn_for_abs (expr_loc
, expr
.value
, (*exprlist
)[0]);
10868 start
= expr
.get_start ();
10869 finish
= parser
->tokens_buf
[0].get_finish ();
10871 = c_build_function_call_vec (expr_loc
, arg_loc
, expr
.value
,
10872 exprlist
, origtypes
);
10873 set_c_expr_source_range (&expr
, start
, finish
);
10874 expr
.m_decimal
= 0;
10876 expr
.original_code
= ERROR_MARK
;
10877 if (TREE_CODE (expr
.value
) == INTEGER_CST
10878 && TREE_CODE (orig_expr
.value
) == FUNCTION_DECL
10879 && fndecl_built_in_p (orig_expr
.value
, BUILT_IN_CONSTANT_P
))
10880 expr
.original_code
= C_MAYBE_CONST_EXPR
;
10881 expr
.original_type
= NULL
;
10884 release_tree_vector (exprlist
);
10885 release_tree_vector (origtypes
);
10887 arg_loc
.release ();
10890 /* Structure element reference. */
10891 c_parser_consume_token (parser
);
10892 expr
= default_function_array_conversion (expr_loc
, expr
);
10893 if (c_parser_next_token_is (parser
, CPP_NAME
))
10895 c_token
*comp_tok
= c_parser_peek_token (parser
);
10896 ident
= comp_tok
->value
;
10897 comp_loc
= comp_tok
->location
;
10901 c_parser_error (parser
, "expected identifier");
10903 expr
.original_code
= ERROR_MARK
;
10904 expr
.original_type
= NULL
;
10907 start
= expr
.get_start ();
10908 finish
= c_parser_peek_token (parser
)->get_finish ();
10909 c_parser_consume_token (parser
);
10910 expr
.value
= build_component_ref (op_loc
, expr
.value
, ident
,
10911 comp_loc
, UNKNOWN_LOCATION
);
10912 set_c_expr_source_range (&expr
, start
, finish
);
10913 expr
.original_code
= ERROR_MARK
;
10914 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
10915 expr
.original_type
= NULL
;
10918 /* Remember the original type of a bitfield. */
10919 tree field
= TREE_OPERAND (expr
.value
, 1);
10920 if (TREE_CODE (field
) != FIELD_DECL
)
10921 expr
.original_type
= NULL
;
10923 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
10925 expr
.m_decimal
= 0;
10928 /* Structure element reference. */
10929 c_parser_consume_token (parser
);
10930 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, false);
10931 if (c_parser_next_token_is (parser
, CPP_NAME
))
10933 c_token
*comp_tok
= c_parser_peek_token (parser
);
10934 ident
= comp_tok
->value
;
10935 comp_loc
= comp_tok
->location
;
10939 c_parser_error (parser
, "expected identifier");
10941 expr
.original_code
= ERROR_MARK
;
10942 expr
.original_type
= NULL
;
10945 start
= expr
.get_start ();
10946 finish
= c_parser_peek_token (parser
)->get_finish ();
10947 c_parser_consume_token (parser
);
10948 expr
.value
= build_component_ref (op_loc
,
10949 build_indirect_ref (op_loc
,
10953 expr
.get_location ());
10954 set_c_expr_source_range (&expr
, start
, finish
);
10955 expr
.original_code
= ERROR_MARK
;
10956 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
10957 expr
.original_type
= NULL
;
10960 /* Remember the original type of a bitfield. */
10961 tree field
= TREE_OPERAND (expr
.value
, 1);
10962 if (TREE_CODE (field
) != FIELD_DECL
)
10963 expr
.original_type
= NULL
;
10965 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
10967 expr
.m_decimal
= 0;
10969 case CPP_PLUS_PLUS
:
10970 /* Postincrement. */
10971 start
= expr
.get_start ();
10972 finish
= c_parser_peek_token (parser
)->get_finish ();
10973 c_parser_consume_token (parser
);
10974 expr
= default_function_array_read_conversion (expr_loc
, expr
);
10975 expr
.value
= build_unary_op (op_loc
, POSTINCREMENT_EXPR
,
10976 expr
.value
, false);
10977 set_c_expr_source_range (&expr
, start
, finish
);
10978 expr
.original_code
= ERROR_MARK
;
10979 expr
.original_type
= NULL
;
10981 case CPP_MINUS_MINUS
:
10982 /* Postdecrement. */
10983 start
= expr
.get_start ();
10984 finish
= c_parser_peek_token (parser
)->get_finish ();
10985 c_parser_consume_token (parser
);
10986 expr
= default_function_array_read_conversion (expr_loc
, expr
);
10987 expr
.value
= build_unary_op (op_loc
, POSTDECREMENT_EXPR
,
10988 expr
.value
, false);
10989 set_c_expr_source_range (&expr
, start
, finish
);
10990 expr
.original_code
= ERROR_MARK
;
10991 expr
.original_type
= NULL
;
10999 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
11002 assignment-expression
11003 expression , assignment-expression
11006 static struct c_expr
11007 c_parser_expression (c_parser
*parser
)
11009 location_t tloc
= c_parser_peek_token (parser
)->location
;
11010 struct c_expr expr
;
11011 expr
= c_parser_expr_no_commas (parser
, NULL
);
11012 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11013 expr
= convert_lvalue_to_rvalue (tloc
, expr
, true, false);
11014 while (c_parser_next_token_is (parser
, CPP_COMMA
))
11016 struct c_expr next
;
11018 location_t loc
= c_parser_peek_token (parser
)->location
;
11019 location_t expr_loc
;
11020 c_parser_consume_token (parser
);
11021 expr_loc
= c_parser_peek_token (parser
)->location
;
11022 lhsval
= expr
.value
;
11023 while (TREE_CODE (lhsval
) == COMPOUND_EXPR
11024 || TREE_CODE (lhsval
) == NOP_EXPR
)
11026 if (TREE_CODE (lhsval
) == COMPOUND_EXPR
)
11027 lhsval
= TREE_OPERAND (lhsval
, 1);
11029 lhsval
= TREE_OPERAND (lhsval
, 0);
11031 if (DECL_P (lhsval
) || handled_component_p (lhsval
))
11032 mark_exp_read (lhsval
);
11033 next
= c_parser_expr_no_commas (parser
, NULL
);
11034 next
= convert_lvalue_to_rvalue (expr_loc
, next
, true, false);
11035 expr
.value
= build_compound_expr (loc
, expr
.value
, next
.value
);
11036 expr
.original_code
= COMPOUND_EXPR
;
11037 expr
.original_type
= next
.original_type
;
11038 expr
.m_decimal
= 0;
11043 /* Parse an expression and convert functions or arrays to pointers and
11044 lvalues to rvalues. */
11046 static struct c_expr
11047 c_parser_expression_conv (c_parser
*parser
)
11049 struct c_expr expr
;
11050 location_t loc
= c_parser_peek_token (parser
)->location
;
11051 expr
= c_parser_expression (parser
);
11052 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, false);
11056 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
11057 argument is a literal zero alone and if so, set it in literal_zero_mask. */
11060 c_parser_check_literal_zero (c_parser
*parser
, unsigned *literal_zero_mask
,
11063 if (idx
>= HOST_BITS_PER_INT
)
11066 c_token
*tok
= c_parser_peek_token (parser
);
11075 /* If a parameter is literal zero alone, remember it
11076 for -Wmemset-transposed-args warning. */
11077 if (integer_zerop (tok
->value
)
11078 && !TREE_OVERFLOW (tok
->value
)
11079 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
11080 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
11081 *literal_zero_mask
|= 1U << idx
;
11087 /* Parse a non-empty list of expressions. If CONVERT_P, convert
11088 functions and arrays to pointers and lvalues to rvalues. If
11089 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
11090 locations of function arguments into this vector.
11092 nonempty-expr-list:
11093 assignment-expression
11094 nonempty-expr-list , assignment-expression
11097 static vec
<tree
, va_gc
> *
11098 c_parser_expr_list (c_parser
*parser
, bool convert_p
, bool fold_p
,
11099 vec
<tree
, va_gc
> **p_orig_types
,
11100 location_t
*sizeof_arg_loc
, tree
*sizeof_arg
,
11101 vec
<location_t
> *locations
,
11102 unsigned int *literal_zero_mask
)
11104 vec
<tree
, va_gc
> *ret
;
11105 vec
<tree
, va_gc
> *orig_types
;
11106 struct c_expr expr
;
11107 unsigned int idx
= 0;
11109 ret
= make_tree_vector ();
11110 if (p_orig_types
== NULL
)
11113 orig_types
= make_tree_vector ();
11115 if (literal_zero_mask
)
11116 c_parser_check_literal_zero (parser
, literal_zero_mask
, 0);
11117 expr
= c_parser_expr_no_commas (parser
, NULL
);
11119 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true, true);
11121 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
11122 ret
->quick_push (expr
.value
);
11124 orig_types
->quick_push (expr
.original_type
);
11126 locations
->safe_push (expr
.get_location ());
11127 if (sizeof_arg
!= NULL
11128 && (expr
.original_code
== SIZEOF_EXPR
11129 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
11131 sizeof_arg
[0] = c_last_sizeof_arg
;
11132 sizeof_arg_loc
[0] = c_last_sizeof_loc
;
11134 while (c_parser_next_token_is (parser
, CPP_COMMA
))
11136 c_parser_consume_token (parser
);
11137 if (literal_zero_mask
)
11138 c_parser_check_literal_zero (parser
, literal_zero_mask
, idx
+ 1);
11139 expr
= c_parser_expr_no_commas (parser
, NULL
);
11141 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true,
11144 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
11145 vec_safe_push (ret
, expr
.value
);
11147 vec_safe_push (orig_types
, expr
.original_type
);
11149 locations
->safe_push (expr
.get_location ());
11151 && sizeof_arg
!= NULL
11152 && (expr
.original_code
== SIZEOF_EXPR
11153 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
11155 sizeof_arg
[idx
] = c_last_sizeof_arg
;
11156 sizeof_arg_loc
[idx
] = c_last_sizeof_loc
;
11160 *p_orig_types
= orig_types
;
11164 /* Parse Objective-C-specific constructs. */
11166 /* Parse an objc-class-definition.
11168 objc-class-definition:
11169 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
11170 objc-class-instance-variables[opt] objc-methodprotolist @end
11171 @implementation identifier objc-superclass[opt]
11172 objc-class-instance-variables[opt]
11173 @interface identifier ( identifier ) objc-protocol-refs[opt]
11174 objc-methodprotolist @end
11175 @interface identifier ( ) objc-protocol-refs[opt]
11176 objc-methodprotolist @end
11177 @implementation identifier ( identifier )
11182 "@interface identifier (" must start "@interface identifier (
11183 identifier ) ...": objc-methodprotolist in the first production may
11184 not start with a parenthesized identifier as a declarator of a data
11185 definition with no declaration specifiers if the objc-superclass,
11186 objc-protocol-refs and objc-class-instance-variables are omitted. */
11189 c_parser_objc_class_definition (c_parser
*parser
, tree attributes
)
11194 if (c_parser_next_token_is_keyword (parser
, RID_AT_INTERFACE
))
11196 else if (c_parser_next_token_is_keyword (parser
, RID_AT_IMPLEMENTATION
))
11199 gcc_unreachable ();
11201 c_parser_consume_token (parser
);
11202 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11204 c_parser_error (parser
, "expected identifier");
11207 id1
= c_parser_peek_token (parser
)->value
;
11208 location_t loc1
= c_parser_peek_token (parser
)->location
;
11209 c_parser_consume_token (parser
);
11210 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11212 /* We have a category or class extension. */
11214 tree proto
= NULL_TREE
;
11215 matching_parens parens
;
11216 parens
.consume_open (parser
);
11217 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11219 if (iface_p
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
11221 /* We have a class extension. */
11226 c_parser_error (parser
, "expected identifier or %<)%>");
11227 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
11233 id2
= c_parser_peek_token (parser
)->value
;
11234 c_parser_consume_token (parser
);
11236 parens
.skip_until_found_close (parser
);
11239 objc_start_category_implementation (id1
, id2
);
11242 if (c_parser_next_token_is (parser
, CPP_LESS
))
11243 proto
= c_parser_objc_protocol_refs (parser
);
11244 objc_start_category_interface (id1
, id2
, proto
, attributes
);
11245 c_parser_objc_methodprotolist (parser
);
11246 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
11247 objc_finish_interface ();
11250 if (c_parser_next_token_is (parser
, CPP_COLON
))
11252 c_parser_consume_token (parser
);
11253 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11255 c_parser_error (parser
, "expected identifier");
11258 superclass
= c_parser_peek_token (parser
)->value
;
11259 c_parser_consume_token (parser
);
11262 superclass
= NULL_TREE
;
11265 tree proto
= NULL_TREE
;
11266 if (c_parser_next_token_is (parser
, CPP_LESS
))
11267 proto
= c_parser_objc_protocol_refs (parser
);
11268 objc_start_class_interface (id1
, loc1
, superclass
, proto
, attributes
);
11271 objc_start_class_implementation (id1
, superclass
);
11272 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11273 c_parser_objc_class_instance_variables (parser
);
11276 objc_continue_interface ();
11277 c_parser_objc_methodprotolist (parser
);
11278 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
11279 objc_finish_interface ();
11283 objc_continue_implementation ();
11288 /* Parse objc-class-instance-variables.
11290 objc-class-instance-variables:
11291 { objc-instance-variable-decl-list[opt] }
11293 objc-instance-variable-decl-list:
11294 objc-visibility-spec
11295 objc-instance-variable-decl ;
11297 objc-instance-variable-decl-list objc-visibility-spec
11298 objc-instance-variable-decl-list objc-instance-variable-decl ;
11299 objc-instance-variable-decl-list ;
11301 objc-visibility-spec:
11306 objc-instance-variable-decl:
11311 c_parser_objc_class_instance_variables (c_parser
*parser
)
11313 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
11314 c_parser_consume_token (parser
);
11315 while (c_parser_next_token_is_not (parser
, CPP_EOF
))
11318 /* Parse any stray semicolon. */
11319 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11321 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11322 "extra semicolon");
11323 c_parser_consume_token (parser
);
11326 /* Stop if at the end of the instance variables. */
11327 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
11329 c_parser_consume_token (parser
);
11332 /* Parse any objc-visibility-spec. */
11333 if (c_parser_next_token_is_keyword (parser
, RID_AT_PRIVATE
))
11335 c_parser_consume_token (parser
);
11336 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE
);
11339 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROTECTED
))
11341 c_parser_consume_token (parser
);
11342 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED
);
11345 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PUBLIC
))
11347 c_parser_consume_token (parser
);
11348 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC
);
11351 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PACKAGE
))
11353 c_parser_consume_token (parser
);
11354 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE
);
11357 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
11359 c_parser_pragma (parser
, pragma_external
, NULL
);
11363 /* Parse some comma-separated declarations. */
11364 decls
= c_parser_struct_declaration (parser
);
11367 /* There is a syntax error. We want to skip the offending
11368 tokens up to the next ';' (included) or '}'
11371 /* First, skip manually a ')' or ']'. This is because they
11372 reduce the nesting level, so c_parser_skip_until_found()
11373 wouldn't be able to skip past them. */
11374 c_token
*token
= c_parser_peek_token (parser
);
11375 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_CLOSE_SQUARE
)
11376 c_parser_consume_token (parser
);
11378 /* Then, do the standard skipping. */
11379 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11381 /* We hopefully recovered. Start normal parsing again. */
11382 parser
->error
= false;
11387 /* Comma-separated instance variables are chained together
11388 in reverse order; add them one by one. */
11389 tree ivar
= nreverse (decls
);
11390 for (; ivar
; ivar
= DECL_CHAIN (ivar
))
11391 objc_add_instance_variable (copy_node (ivar
));
11393 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11397 /* Parse an objc-class-declaration.
11399 objc-class-declaration:
11400 @class identifier-list ;
11404 c_parser_objc_class_declaration (c_parser
*parser
)
11406 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_CLASS
));
11407 c_parser_consume_token (parser
);
11408 /* Any identifiers, including those declared as type names, are OK
11413 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11415 c_parser_error (parser
, "expected identifier");
11416 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11417 parser
->error
= false;
11420 id
= c_parser_peek_token (parser
)->value
;
11421 objc_declare_class (id
);
11422 c_parser_consume_token (parser
);
11423 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11424 c_parser_consume_token (parser
);
11428 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11431 /* Parse an objc-alias-declaration.
11433 objc-alias-declaration:
11434 @compatibility_alias identifier identifier ;
11438 c_parser_objc_alias_declaration (c_parser
*parser
)
11441 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_ALIAS
));
11442 c_parser_consume_token (parser
);
11443 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11445 c_parser_error (parser
, "expected identifier");
11446 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11449 id1
= c_parser_peek_token (parser
)->value
;
11450 c_parser_consume_token (parser
);
11451 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11453 c_parser_error (parser
, "expected identifier");
11454 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11457 id2
= c_parser_peek_token (parser
)->value
;
11458 c_parser_consume_token (parser
);
11459 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11460 objc_declare_alias (id1
, id2
);
11463 /* Parse an objc-protocol-definition.
11465 objc-protocol-definition:
11466 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11467 @protocol identifier-list ;
11469 "@protocol identifier ;" should be resolved as "@protocol
11470 identifier-list ;": objc-methodprotolist may not start with a
11471 semicolon in the first alternative if objc-protocol-refs are
11475 c_parser_objc_protocol_definition (c_parser
*parser
, tree attributes
)
11477 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROTOCOL
));
11479 c_parser_consume_token (parser
);
11480 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11482 c_parser_error (parser
, "expected identifier");
11485 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
11486 || c_parser_peek_2nd_token (parser
)->type
== CPP_SEMICOLON
)
11488 /* Any identifiers, including those declared as type names, are
11493 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11495 c_parser_error (parser
, "expected identifier");
11498 id
= c_parser_peek_token (parser
)->value
;
11499 objc_declare_protocol (id
, attributes
);
11500 c_parser_consume_token (parser
);
11501 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11502 c_parser_consume_token (parser
);
11506 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11510 tree id
= c_parser_peek_token (parser
)->value
;
11511 tree proto
= NULL_TREE
;
11512 c_parser_consume_token (parser
);
11513 if (c_parser_next_token_is (parser
, CPP_LESS
))
11514 proto
= c_parser_objc_protocol_refs (parser
);
11515 parser
->objc_pq_context
= true;
11516 objc_start_protocol (id
, proto
, attributes
);
11517 c_parser_objc_methodprotolist (parser
);
11518 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
11519 parser
->objc_pq_context
= false;
11520 objc_finish_interface ();
11524 /* Parse an objc-method-type.
11530 Return true if it is a class method (+) and false if it is
11531 an instance method (-).
11534 c_parser_objc_method_type (c_parser
*parser
)
11536 switch (c_parser_peek_token (parser
)->type
)
11539 c_parser_consume_token (parser
);
11542 c_parser_consume_token (parser
);
11545 gcc_unreachable ();
11549 /* Parse an objc-method-definition.
11551 objc-method-definition:
11552 objc-method-type objc-method-decl ;[opt] compound-statement
11556 c_parser_objc_method_definition (c_parser
*parser
)
11558 bool is_class_method
= c_parser_objc_method_type (parser
);
11559 tree decl
, attributes
= NULL_TREE
, expr
= NULL_TREE
;
11560 parser
->objc_pq_context
= true;
11561 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11563 if (decl
== error_mark_node
)
11564 return; /* Bail here. */
11566 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11568 c_parser_consume_token (parser
);
11569 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11570 "extra semicolon in method definition specified");
11573 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11575 c_parser_error (parser
, "expected %<{%>");
11579 parser
->objc_pq_context
= false;
11580 if (objc_start_method_definition (is_class_method
, decl
, attributes
, expr
))
11582 add_stmt (c_parser_compound_statement (parser
));
11583 objc_finish_method_definition (current_function_decl
);
11587 /* This code is executed when we find a method definition
11588 outside of an @implementation context (or invalid for other
11589 reasons). Parse the method (to keep going) but do not emit
11592 c_parser_compound_statement (parser
);
11596 /* Parse an objc-methodprotolist.
11598 objc-methodprotolist:
11600 objc-methodprotolist objc-methodproto
11601 objc-methodprotolist declaration
11602 objc-methodprotolist ;
11606 The declaration is a data definition, which may be missing
11607 declaration specifiers under the same rules and diagnostics as
11608 other data definitions outside functions, and the stray semicolon
11609 is diagnosed the same way as a stray semicolon outside a
11613 c_parser_objc_methodprotolist (c_parser
*parser
)
11617 /* The list is terminated by @end. */
11618 switch (c_parser_peek_token (parser
)->type
)
11620 case CPP_SEMICOLON
:
11621 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11622 "ISO C does not allow extra %<;%> outside of a function");
11623 c_parser_consume_token (parser
);
11627 c_parser_objc_methodproto (parser
);
11630 c_parser_pragma (parser
, pragma_external
, NULL
);
11635 if (c_parser_next_token_is_keyword (parser
, RID_AT_END
))
11637 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
))
11638 c_parser_objc_at_property_declaration (parser
);
11639 else if (c_parser_next_token_is_keyword (parser
, RID_AT_OPTIONAL
))
11641 objc_set_method_opt (true);
11642 c_parser_consume_token (parser
);
11644 else if (c_parser_next_token_is_keyword (parser
, RID_AT_REQUIRED
))
11646 objc_set_method_opt (false);
11647 c_parser_consume_token (parser
);
11650 c_parser_declaration_or_fndef (parser
, false, false, true,
11657 /* Parse an objc-methodproto.
11660 objc-method-type objc-method-decl ;
11664 c_parser_objc_methodproto (c_parser
*parser
)
11666 bool is_class_method
= c_parser_objc_method_type (parser
);
11667 tree decl
, attributes
= NULL_TREE
;
11669 /* Remember protocol qualifiers in prototypes. */
11670 parser
->objc_pq_context
= true;
11671 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11673 /* Forget protocol qualifiers now. */
11674 parser
->objc_pq_context
= false;
11676 /* Do not allow the presence of attributes to hide an erroneous
11677 method implementation in the interface section. */
11678 if (!c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11680 c_parser_error (parser
, "expected %<;%>");
11684 if (decl
!= error_mark_node
)
11685 objc_add_method_declaration (is_class_method
, decl
, attributes
);
11687 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11690 /* If we are at a position that method attributes may be present, check that
11691 there are not any parsed already (a syntax error) and then collect any
11692 specified at the current location. Finally, if new attributes were present,
11693 check that the next token is legal ( ';' for decls and '{' for defs). */
11696 c_parser_objc_maybe_method_attributes (c_parser
* parser
, tree
* attributes
)
11701 c_parser_error (parser
,
11702 "method attributes must be specified at the end only");
11703 *attributes
= NULL_TREE
;
11707 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
11708 *attributes
= c_parser_gnu_attributes (parser
);
11710 /* If there were no attributes here, just report any earlier error. */
11711 if (*attributes
== NULL_TREE
|| bad
)
11714 /* If the attributes are followed by a ; or {, then just report any earlier
11716 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
11717 || c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11720 /* We've got attributes, but not at the end. */
11721 c_parser_error (parser
,
11722 "expected %<;%> or %<{%> after method attribute definition");
11726 /* Parse an objc-method-decl.
11729 ( objc-type-name ) objc-selector
11731 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11732 objc-keyword-selector objc-optparmlist
11735 objc-keyword-selector:
11737 objc-keyword-selector objc-keyword-decl
11740 objc-selector : ( objc-type-name ) identifier
11741 objc-selector : identifier
11742 : ( objc-type-name ) identifier
11746 objc-optparms objc-optellipsis
11750 objc-opt-parms , parameter-declaration
11758 c_parser_objc_method_decl (c_parser
*parser
, bool is_class_method
,
11759 tree
*attributes
, tree
*expr
)
11761 tree type
= NULL_TREE
;
11763 tree parms
= NULL_TREE
;
11764 bool ellipsis
= false;
11765 bool attr_err
= false;
11767 *attributes
= NULL_TREE
;
11768 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11770 matching_parens parens
;
11771 parens
.consume_open (parser
);
11772 type
= c_parser_objc_type_name (parser
);
11773 parens
.skip_until_found_close (parser
);
11775 sel
= c_parser_objc_selector (parser
);
11776 /* If there is no selector, or a colon follows, we have an
11777 objc-keyword-selector. If there is a selector, and a colon does
11778 not follow, that selector ends the objc-method-decl. */
11779 if (!sel
|| c_parser_next_token_is (parser
, CPP_COLON
))
11782 tree list
= NULL_TREE
;
11785 tree atype
= NULL_TREE
, id
, keyworddecl
;
11786 tree param_attr
= NULL_TREE
;
11787 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11789 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11791 c_parser_consume_token (parser
);
11792 atype
= c_parser_objc_type_name (parser
);
11793 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
11796 /* New ObjC allows attributes on method parameters. */
11797 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
11798 param_attr
= c_parser_gnu_attributes (parser
);
11799 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11801 c_parser_error (parser
, "expected identifier");
11802 return error_mark_node
;
11804 id
= c_parser_peek_token (parser
)->value
;
11805 c_parser_consume_token (parser
);
11806 keyworddecl
= objc_build_keyword_decl (tsel
, atype
, id
, param_attr
);
11807 list
= chainon (list
, keyworddecl
);
11808 tsel
= c_parser_objc_selector (parser
);
11809 if (!tsel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11813 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
11815 /* Parse the optional parameter list. Optional Objective-C
11816 method parameters follow the C syntax, and may include '...'
11817 to denote a variable number of arguments. */
11818 parms
= make_node (TREE_LIST
);
11819 while (c_parser_next_token_is (parser
, CPP_COMMA
))
11821 struct c_parm
*parm
;
11822 c_parser_consume_token (parser
);
11823 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
11826 c_parser_consume_token (parser
);
11827 attr_err
|= c_parser_objc_maybe_method_attributes
11828 (parser
, attributes
) ;
11831 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
11834 parms
= chainon (parms
,
11835 build_tree_list (NULL_TREE
, grokparm (parm
, expr
)));
11840 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
11844 c_parser_error (parser
, "objective-c method declaration is expected");
11845 return error_mark_node
;
11849 return error_mark_node
;
11851 return objc_build_method_signature (is_class_method
, type
, sel
, parms
, ellipsis
);
11854 /* Parse an objc-type-name.
11857 objc-type-qualifiers[opt] type-name
11858 objc-type-qualifiers[opt]
11860 objc-type-qualifiers:
11861 objc-type-qualifier
11862 objc-type-qualifiers objc-type-qualifier
11864 objc-type-qualifier: one of
11865 in out inout bycopy byref oneway
11869 c_parser_objc_type_name (c_parser
*parser
)
11871 tree quals
= NULL_TREE
;
11872 struct c_type_name
*type_name
= NULL
;
11873 tree type
= NULL_TREE
;
11876 c_token
*token
= c_parser_peek_token (parser
);
11877 if (token
->type
== CPP_KEYWORD
11878 && (token
->keyword
== RID_IN
11879 || token
->keyword
== RID_OUT
11880 || token
->keyword
== RID_INOUT
11881 || token
->keyword
== RID_BYCOPY
11882 || token
->keyword
== RID_BYREF
11883 || token
->keyword
== RID_ONEWAY
))
11885 quals
= chainon (build_tree_list (NULL_TREE
, token
->value
), quals
);
11886 c_parser_consume_token (parser
);
11891 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
11892 type_name
= c_parser_type_name (parser
);
11894 type
= groktypename (type_name
, NULL
, NULL
);
11896 /* If the type is unknown, and error has already been produced and
11897 we need to recover from the error. In that case, use NULL_TREE
11898 for the type, as if no type had been specified; this will use the
11899 default type ('id') which is good for error recovery. */
11900 if (type
== error_mark_node
)
11903 return build_tree_list (quals
, type
);
11906 /* Parse objc-protocol-refs.
11908 objc-protocol-refs:
11909 < identifier-list >
11913 c_parser_objc_protocol_refs (c_parser
*parser
)
11915 tree list
= NULL_TREE
;
11916 gcc_assert (c_parser_next_token_is (parser
, CPP_LESS
));
11917 c_parser_consume_token (parser
);
11918 /* Any identifiers, including those declared as type names, are OK
11923 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11925 c_parser_error (parser
, "expected identifier");
11928 id
= c_parser_peek_token (parser
)->value
;
11929 list
= chainon (list
, build_tree_list (NULL_TREE
, id
));
11930 c_parser_consume_token (parser
);
11931 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11932 c_parser_consume_token (parser
);
11936 c_parser_require (parser
, CPP_GREATER
, "expected %<>%>");
11940 /* Parse an objc-try-catch-finally-statement.
11942 objc-try-catch-finally-statement:
11943 @try compound-statement objc-catch-list[opt]
11944 @try compound-statement objc-catch-list[opt] @finally compound-statement
11947 @catch ( objc-catch-parameter-declaration ) compound-statement
11948 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11950 objc-catch-parameter-declaration:
11951 parameter-declaration
11954 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11956 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11957 for C++. Keep them in sync. */
11960 c_parser_objc_try_catch_finally_statement (c_parser
*parser
)
11962 location_t location
;
11965 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_TRY
));
11966 c_parser_consume_token (parser
);
11967 location
= c_parser_peek_token (parser
)->location
;
11968 objc_maybe_warn_exceptions (location
);
11969 stmt
= c_parser_compound_statement (parser
);
11970 objc_begin_try_stmt (location
, stmt
);
11972 while (c_parser_next_token_is_keyword (parser
, RID_AT_CATCH
))
11974 struct c_parm
*parm
;
11975 tree parameter_declaration
= error_mark_node
;
11976 bool seen_open_paren
= false;
11978 c_parser_consume_token (parser
);
11979 matching_parens parens
;
11980 if (!parens
.require_open (parser
))
11981 seen_open_paren
= true;
11982 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
11984 /* We have "@catch (...)" (where the '...' are literally
11985 what is in the code). Skip the '...'.
11986 parameter_declaration is set to NULL_TREE, and
11987 objc_being_catch_clauses() knows that that means
11989 c_parser_consume_token (parser
);
11990 parameter_declaration
= NULL_TREE
;
11994 /* We have "@catch (NSException *exception)" or something
11995 like that. Parse the parameter declaration. */
11996 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
11998 parameter_declaration
= error_mark_node
;
12000 parameter_declaration
= grokparm (parm
, NULL
);
12002 if (seen_open_paren
)
12003 parens
.require_close (parser
);
12006 /* If there was no open parenthesis, we are recovering from
12007 an error, and we are trying to figure out what mistake
12008 the user has made. */
12010 /* If there is an immediate closing parenthesis, the user
12011 probably forgot the opening one (ie, they typed "@catch
12012 NSException *e)". Parse the closing parenthesis and keep
12014 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
12015 c_parser_consume_token (parser
);
12017 /* If these is no immediate closing parenthesis, the user
12018 probably doesn't know that parenthesis are required at
12019 all (ie, they typed "@catch NSException *e"). So, just
12020 forget about the closing parenthesis and keep going. */
12022 objc_begin_catch_clause (parameter_declaration
);
12023 if (c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
12024 c_parser_compound_statement_nostart (parser
);
12025 objc_finish_catch_clause ();
12027 if (c_parser_next_token_is_keyword (parser
, RID_AT_FINALLY
))
12029 c_parser_consume_token (parser
);
12030 location
= c_parser_peek_token (parser
)->location
;
12031 stmt
= c_parser_compound_statement (parser
);
12032 objc_build_finally_clause (location
, stmt
);
12034 objc_finish_try_stmt ();
12037 /* Parse an objc-synchronized-statement.
12039 objc-synchronized-statement:
12040 @synchronized ( expression ) compound-statement
12044 c_parser_objc_synchronized_statement (c_parser
*parser
)
12048 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNCHRONIZED
));
12049 c_parser_consume_token (parser
);
12050 loc
= c_parser_peek_token (parser
)->location
;
12051 objc_maybe_warn_exceptions (loc
);
12052 matching_parens parens
;
12053 if (parens
.require_open (parser
))
12055 struct c_expr ce
= c_parser_expression (parser
);
12056 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
12058 expr
= c_fully_fold (expr
, false, NULL
);
12059 parens
.skip_until_found_close (parser
);
12062 expr
= error_mark_node
;
12063 stmt
= c_parser_compound_statement (parser
);
12064 objc_build_synchronized (loc
, expr
, stmt
);
12067 /* Parse an objc-selector; return NULL_TREE without an error if the
12068 next token is not an objc-selector.
12073 enum struct union if else while do for switch case default
12074 break continue return goto asm sizeof typeof typeof_unqual __alignof
12075 unsigned long const short volatile signed restrict _Complex
12076 in out inout bycopy byref oneway int char float double void _Bool
12079 ??? Why this selection of keywords but not, for example, storage
12080 class specifiers? */
12083 c_parser_objc_selector (c_parser
*parser
)
12085 c_token
*token
= c_parser_peek_token (parser
);
12086 tree value
= token
->value
;
12087 if (token
->type
== CPP_NAME
)
12089 c_parser_consume_token (parser
);
12092 if (token
->type
!= CPP_KEYWORD
)
12094 switch (token
->keyword
)
12114 case RID_TYPEOF_UNQUAL
:
12134 CASE_RID_FLOATN_NX
:
12138 case RID_AUTO_TYPE
:
12143 c_parser_consume_token (parser
);
12150 /* Parse an objc-selector-arg.
12154 objc-keywordname-list
12156 objc-keywordname-list:
12158 objc-keywordname-list objc-keywordname
12166 c_parser_objc_selector_arg (c_parser
*parser
)
12168 tree sel
= c_parser_objc_selector (parser
);
12169 tree list
= NULL_TREE
;
12171 && c_parser_next_token_is_not (parser
, CPP_COLON
)
12172 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
12176 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
12178 c_parser_consume_token (parser
);
12179 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
12180 list
= chainon (list
, build_tree_list (NULL_TREE
, NULL_TREE
));
12184 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
12186 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
12188 sel
= c_parser_objc_selector (parser
);
12190 && c_parser_next_token_is_not (parser
, CPP_COLON
)
12191 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
12197 /* Parse an objc-receiver.
12206 c_parser_objc_receiver (c_parser
*parser
)
12208 location_t loc
= c_parser_peek_token (parser
)->location
;
12210 if (c_parser_peek_token (parser
)->type
== CPP_NAME
12211 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
12212 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
12214 tree id
= c_parser_peek_token (parser
)->value
;
12215 c_parser_consume_token (parser
);
12216 return objc_get_class_reference (id
);
12218 struct c_expr ce
= c_parser_expression (parser
);
12219 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
12220 return c_fully_fold (ce
.value
, false, NULL
);
12223 /* Parse objc-message-args.
12227 objc-keywordarg-list
12229 objc-keywordarg-list:
12231 objc-keywordarg-list objc-keywordarg
12234 objc-selector : objc-keywordexpr
12239 c_parser_objc_message_args (c_parser
*parser
)
12241 tree sel
= c_parser_objc_selector (parser
);
12242 tree list
= NULL_TREE
;
12243 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
12248 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
12249 return error_mark_node
;
12250 keywordexpr
= c_parser_objc_keywordexpr (parser
);
12251 list
= chainon (list
, build_tree_list (sel
, keywordexpr
));
12252 sel
= c_parser_objc_selector (parser
);
12253 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
12259 /* Parse an objc-keywordexpr.
12266 c_parser_objc_keywordexpr (c_parser
*parser
)
12269 vec
<tree
, va_gc
> *expr_list
= c_parser_expr_list (parser
, true, true,
12270 NULL
, NULL
, NULL
, NULL
);
12271 if (vec_safe_length (expr_list
) == 1)
12273 /* Just return the expression, remove a level of
12275 ret
= (*expr_list
)[0];
12279 /* We have a comma expression, we will collapse later. */
12280 ret
= build_tree_list_vec (expr_list
);
12282 release_tree_vector (expr_list
);
12286 /* A check, needed in several places, that ObjC interface, implementation or
12287 method definitions are not prefixed by incorrect items. */
12289 c_parser_objc_diagnose_bad_element_prefix (c_parser
*parser
,
12290 struct c_declspecs
*specs
)
12292 if (!specs
->declspecs_seen_p
|| specs
->non_sc_seen_p
12293 || specs
->typespec_kind
!= ctsk_none
)
12295 c_parser_error (parser
,
12296 "no type or storage class may be specified here,");
12297 c_parser_skip_to_end_of_block_or_statement (parser
);
12303 /* Parse an Objective-C @property declaration. The syntax is:
12305 objc-property-declaration:
12306 '@property' objc-property-attributes[opt] struct-declaration ;
12308 objc-property-attributes:
12309 '(' objc-property-attribute-list ')'
12311 objc-property-attribute-list:
12312 objc-property-attribute
12313 objc-property-attribute-list, objc-property-attribute
12315 objc-property-attribute
12316 'getter' = identifier
12317 'setter' = identifier
12326 @property NSString *name;
12327 @property (readonly) id object;
12328 @property (retain, nonatomic, getter=getTheName) id name;
12329 @property int a, b, c;
12331 PS: This function is identical to cp_parser_objc_at_propery_declaration
12332 for C++. Keep them in sync. */
12334 c_parser_objc_at_property_declaration (c_parser
*parser
)
12336 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
));
12337 location_t loc
= c_parser_peek_token (parser
)->location
;
12338 c_parser_consume_token (parser
); /* Eat '@property'. */
12340 /* Parse the optional attribute list.
12342 A list of parsed, but not verified, attributes. */
12343 vec
<property_attribute_info
*> prop_attr_list
= vNULL
;
12345 bool syntax_error
= false;
12346 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
12348 matching_parens parens
;
12350 location_t attr_start
= c_parser_peek_token (parser
)->location
;
12352 parens
.consume_open (parser
);
12354 /* Property attribute keywords are valid now. */
12355 parser
->objc_property_attr_context
= true;
12357 /* Allow @property (), with a warning. */
12358 location_t attr_end
= c_parser_peek_token (parser
)->location
;
12360 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
12362 location_t attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
12363 warning_at (attr_comb
, OPT_Wattributes
,
12364 "empty property attribute list");
12369 c_token
*token
= c_parser_peek_token (parser
);
12370 attr_start
= token
->location
;
12371 attr_end
= get_finish (token
->location
);
12372 location_t attr_comb
= make_location (attr_start
, attr_start
,
12375 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_COMMA
)
12377 warning_at (attr_comb
, OPT_Wattributes
,
12378 "missing property attribute");
12379 if (token
->type
== CPP_CLOSE_PAREN
)
12381 c_parser_consume_token (parser
);
12385 tree attr_name
= NULL_TREE
;
12386 enum rid keyword
= RID_MAX
; /* Not a valid property attribute. */
12387 bool add_at
= false;
12388 if (token
->type
== CPP_KEYWORD
)
12390 keyword
= token
->keyword
;
12391 if (OBJC_IS_AT_KEYWORD (keyword
))
12393 /* For '@' keywords the token value has the keyword,
12394 prepend the '@' for diagnostics. */
12395 attr_name
= token
->value
;
12399 attr_name
= ridpointers
[(int)keyword
];
12401 else if (token
->type
== CPP_NAME
)
12402 attr_name
= token
->value
;
12403 c_parser_consume_token (parser
);
12405 enum objc_property_attribute_kind prop_kind
12406 = objc_prop_attr_kind_for_rid (keyword
);
12407 property_attribute_info
*prop
12408 = new property_attribute_info (attr_name
, attr_comb
, prop_kind
);
12409 prop_attr_list
.safe_push (prop
);
12412 switch (prop
->prop_kind
)
12415 case OBJC_PROPERTY_ATTR_UNKNOWN
:
12417 error_at (attr_comb
, "unknown property attribute %<%s%s%>",
12418 add_at
? "@" : "", IDENTIFIER_POINTER (attr_name
));
12420 error_at (attr_comb
, "unknown property attribute");
12421 prop
->parse_error
= syntax_error
= true;
12424 case OBJC_PROPERTY_ATTR_GETTER
:
12425 case OBJC_PROPERTY_ATTR_SETTER
:
12426 if (c_parser_next_token_is_not (parser
, CPP_EQ
))
12428 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
12429 error_at (attr_comb
, "expected %<=%> after Objective-C %qE",
12431 prop
->parse_error
= syntax_error
= true;
12434 token
= c_parser_peek_token (parser
);
12435 attr_end
= token
->location
;
12436 c_parser_consume_token (parser
); /* eat the = */
12437 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12439 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
12440 error_at (attr_comb
, "expected %qE selector name",
12442 prop
->parse_error
= syntax_error
= true;
12445 /* Get the end of the method name, and consume the name. */
12446 token
= c_parser_peek_token (parser
);
12447 attr_end
= get_finish (token
->location
);
12448 meth_name
= token
->value
;
12449 c_parser_consume_token (parser
);
12450 if (prop
->prop_kind
== OBJC_PROPERTY_ATTR_SETTER
)
12452 if (c_parser_next_token_is_not (parser
, CPP_COLON
))
12454 attr_comb
= make_location (attr_end
, attr_start
,
12456 error_at (attr_comb
, "setter method names must"
12457 " terminate with %<:%>");
12458 prop
->parse_error
= syntax_error
= true;
12462 attr_end
= get_finish (c_parser_peek_token
12463 (parser
)->location
);
12464 c_parser_consume_token (parser
);
12466 attr_comb
= make_location (attr_start
, attr_start
,
12470 attr_comb
= make_location (attr_start
, attr_start
,
12472 prop
->ident
= meth_name
;
12473 /* Updated location including all that was successfully
12475 prop
->prop_loc
= attr_comb
;
12479 /* If we see a comma here, then keep going - even if we already
12480 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12481 this makes a more useful output and avoid spurious warnings about
12482 missing attributes that are, in fact, specified after the one with
12483 the syntax error. */
12484 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12485 c_parser_consume_token (parser
);
12489 parser
->objc_property_attr_context
= false;
12491 if (syntax_error
&& c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
12492 /* We don't really want to chew the whole of the file looking for a
12493 matching closing parenthesis, so we will try to read the decl and
12494 let the error handling for that close out the statement. */
12497 syntax_error
= false, parens
.skip_until_found_close (parser
);
12500 /* 'properties' is the list of properties that we read. Usually a
12501 single one, but maybe more (eg, in "@property int a, b, c;" there
12503 tree properties
= c_parser_struct_declaration (parser
);
12505 if (properties
== error_mark_node
)
12506 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12509 if (properties
== NULL_TREE
)
12510 c_parser_error (parser
, "expected identifier");
12513 /* Comma-separated properties are chained together in reverse order;
12514 add them one by one. */
12515 properties
= nreverse (properties
);
12516 for (; properties
; properties
= TREE_CHAIN (properties
))
12517 objc_add_property_declaration (loc
, copy_node (properties
),
12520 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12523 while (!prop_attr_list
.is_empty())
12524 delete prop_attr_list
.pop ();
12525 prop_attr_list
.release ();
12526 parser
->error
= false;
12529 /* Parse an Objective-C @synthesize declaration. The syntax is:
12531 objc-synthesize-declaration:
12532 @synthesize objc-synthesize-identifier-list ;
12534 objc-synthesize-identifier-list:
12535 objc-synthesize-identifier
12536 objc-synthesize-identifier-list, objc-synthesize-identifier
12538 objc-synthesize-identifier
12540 identifier = identifier
12543 @synthesize MyProperty;
12544 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12546 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12547 for C++. Keep them in sync.
12550 c_parser_objc_at_synthesize_declaration (c_parser
*parser
)
12552 tree list
= NULL_TREE
;
12554 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNTHESIZE
));
12555 loc
= c_parser_peek_token (parser
)->location
;
12557 c_parser_consume_token (parser
);
12560 tree property
, ivar
;
12561 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12563 c_parser_error (parser
, "expected identifier");
12564 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12565 /* Once we find the semicolon, we can resume normal parsing.
12566 We have to reset parser->error manually because
12567 c_parser_skip_until_found() won't reset it for us if the
12568 next token is precisely a semicolon. */
12569 parser
->error
= false;
12572 property
= c_parser_peek_token (parser
)->value
;
12573 c_parser_consume_token (parser
);
12574 if (c_parser_next_token_is (parser
, CPP_EQ
))
12576 c_parser_consume_token (parser
);
12577 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12579 c_parser_error (parser
, "expected identifier");
12580 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12581 parser
->error
= false;
12584 ivar
= c_parser_peek_token (parser
)->value
;
12585 c_parser_consume_token (parser
);
12589 list
= chainon (list
, build_tree_list (ivar
, property
));
12590 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12591 c_parser_consume_token (parser
);
12595 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12596 objc_add_synthesize_declaration (loc
, list
);
12599 /* Parse an Objective-C @dynamic declaration. The syntax is:
12601 objc-dynamic-declaration:
12602 @dynamic identifier-list ;
12605 @dynamic MyProperty;
12606 @dynamic MyProperty, AnotherProperty;
12608 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12609 for C++. Keep them in sync.
12612 c_parser_objc_at_dynamic_declaration (c_parser
*parser
)
12614 tree list
= NULL_TREE
;
12616 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_DYNAMIC
));
12617 loc
= c_parser_peek_token (parser
)->location
;
12619 c_parser_consume_token (parser
);
12623 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12625 c_parser_error (parser
, "expected identifier");
12626 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12627 parser
->error
= false;
12630 property
= c_parser_peek_token (parser
)->value
;
12631 list
= chainon (list
, build_tree_list (NULL_TREE
, property
));
12632 c_parser_consume_token (parser
);
12633 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12634 c_parser_consume_token (parser
);
12638 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12639 objc_add_dynamic_declaration (loc
, list
);
12643 /* Parse a pragma GCC ivdep. */
12646 c_parse_pragma_ivdep (c_parser
*parser
)
12648 c_parser_consume_pragma (parser
);
12649 c_parser_skip_to_pragma_eol (parser
);
12653 /* Parse a pragma GCC unroll. */
12655 static unsigned short
12656 c_parser_pragma_unroll (c_parser
*parser
)
12658 unsigned short unroll
;
12659 c_parser_consume_pragma (parser
);
12660 location_t location
= c_parser_peek_token (parser
)->location
;
12661 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
12662 mark_exp_read (expr
);
12663 expr
= c_fully_fold (expr
, false, NULL
);
12664 HOST_WIDE_INT lunroll
= 0;
12665 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
12666 || TREE_CODE (expr
) != INTEGER_CST
12667 || (lunroll
= tree_to_shwi (expr
)) < 0
12668 || lunroll
>= USHRT_MAX
)
12670 error_at (location
, "%<#pragma GCC unroll%> requires an"
12671 " assignment-expression that evaluates to a non-negative"
12672 " integral constant less than %u", USHRT_MAX
);
12677 unroll
= (unsigned short)lunroll
;
12682 c_parser_skip_to_pragma_eol (parser
);
12686 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12687 should be considered, statements. ALLOW_STMT is true if we're within
12688 the context of a function and such pragmas are to be allowed. Returns
12689 true if we actually parsed such a pragma. */
12692 c_parser_pragma (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
12695 const char *construct
= NULL
;
12697 input_location
= c_parser_peek_token (parser
)->location
;
12698 id
= c_parser_peek_token (parser
)->pragma_kind
;
12699 gcc_assert (id
!= PRAGMA_NONE
);
12703 case PRAGMA_OACC_DECLARE
:
12704 c_parser_oacc_declare (parser
);
12707 case PRAGMA_OACC_ENTER_DATA
:
12708 if (context
!= pragma_compound
)
12710 construct
= "acc enter data";
12712 if (context
== pragma_stmt
)
12714 error_at (c_parser_peek_token (parser
)->location
,
12715 "%<#pragma %s%> may only be used in compound "
12716 "statements", construct
);
12717 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12722 c_parser_oacc_enter_exit_data (parser
, true);
12725 case PRAGMA_OACC_EXIT_DATA
:
12726 if (context
!= pragma_compound
)
12728 construct
= "acc exit data";
12731 c_parser_oacc_enter_exit_data (parser
, false);
12734 case PRAGMA_OACC_ROUTINE
:
12735 if (context
!= pragma_external
)
12737 error_at (c_parser_peek_token (parser
)->location
,
12738 "%<#pragma acc routine%> must be at file scope");
12739 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12742 c_parser_oacc_routine (parser
, context
);
12745 case PRAGMA_OACC_UPDATE
:
12746 if (context
!= pragma_compound
)
12748 construct
= "acc update";
12751 c_parser_oacc_update (parser
);
12754 case PRAGMA_OMP_BARRIER
:
12755 if (context
!= pragma_compound
)
12757 construct
= "omp barrier";
12760 c_parser_omp_barrier (parser
);
12763 case PRAGMA_OMP_DEPOBJ
:
12764 if (context
!= pragma_compound
)
12766 construct
= "omp depobj";
12769 c_parser_omp_depobj (parser
);
12772 case PRAGMA_OMP_FLUSH
:
12773 if (context
!= pragma_compound
)
12775 construct
= "omp flush";
12778 c_parser_omp_flush (parser
);
12781 case PRAGMA_OMP_TASKWAIT
:
12782 if (context
!= pragma_compound
)
12784 construct
= "omp taskwait";
12787 c_parser_omp_taskwait (parser
);
12790 case PRAGMA_OMP_TASKYIELD
:
12791 if (context
!= pragma_compound
)
12793 construct
= "omp taskyield";
12796 c_parser_omp_taskyield (parser
);
12799 case PRAGMA_OMP_CANCEL
:
12800 if (context
!= pragma_compound
)
12802 construct
= "omp cancel";
12805 c_parser_omp_cancel (parser
);
12808 case PRAGMA_OMP_CANCELLATION_POINT
:
12809 return c_parser_omp_cancellation_point (parser
, context
);
12811 case PRAGMA_OMP_THREADPRIVATE
:
12812 c_parser_omp_threadprivate (parser
);
12815 case PRAGMA_OMP_TARGET
:
12816 return c_parser_omp_target (parser
, context
, if_p
);
12818 case PRAGMA_OMP_BEGIN
:
12819 c_parser_omp_begin (parser
);
12822 case PRAGMA_OMP_END
:
12823 c_parser_omp_end (parser
);
12826 case PRAGMA_OMP_SCAN
:
12827 error_at (c_parser_peek_token (parser
)->location
,
12828 "%<#pragma omp scan%> may only be used in "
12829 "a loop construct with %<inscan%> %<reduction%> clause");
12830 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12833 case PRAGMA_OMP_SECTION
:
12834 error_at (c_parser_peek_token (parser
)->location
,
12835 "%<#pragma omp section%> may only be used in "
12836 "%<#pragma omp sections%> construct");
12837 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12840 case PRAGMA_OMP_DECLARE
:
12841 return c_parser_omp_declare (parser
, context
);
12843 case PRAGMA_OMP_REQUIRES
:
12844 if (context
!= pragma_external
)
12846 error_at (c_parser_peek_token (parser
)->location
,
12847 "%<#pragma %s%> may only be used at file scope",
12849 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12852 c_parser_omp_requires (parser
);
12855 case PRAGMA_OMP_ASSUMES
:
12856 if (context
!= pragma_external
)
12858 error_at (c_parser_peek_token (parser
)->location
,
12859 "%<#pragma %s%> may only be used at file scope",
12861 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12864 c_parser_omp_assumes (parser
);
12867 case PRAGMA_OMP_NOTHING
:
12868 c_parser_omp_nothing (parser
);
12871 case PRAGMA_OMP_ERROR
:
12872 return c_parser_omp_error (parser
, context
);
12874 case PRAGMA_OMP_ORDERED
:
12875 return c_parser_omp_ordered (parser
, context
, if_p
);
12879 const bool ivdep
= c_parse_pragma_ivdep (parser
);
12880 unsigned short unroll
;
12881 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_UNROLL
)
12882 unroll
= c_parser_pragma_unroll (parser
);
12885 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12886 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12887 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12889 c_parser_error (parser
, "for, while or do statement expected");
12892 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12893 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12894 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12895 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12897 c_parser_do_statement (parser
, ivdep
, unroll
);
12901 case PRAGMA_UNROLL
:
12903 unsigned short unroll
= c_parser_pragma_unroll (parser
);
12905 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_IVDEP
)
12906 ivdep
= c_parse_pragma_ivdep (parser
);
12909 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12910 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12911 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12913 c_parser_error (parser
, "for, while or do statement expected");
12916 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12917 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12918 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12919 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12921 c_parser_do_statement (parser
, ivdep
, unroll
);
12925 case PRAGMA_GCC_PCH_PREPROCESS
:
12926 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
12927 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12930 case PRAGMA_OACC_WAIT
:
12931 if (context
!= pragma_compound
)
12933 construct
= "acc wait";
12936 /* FALL THROUGH. */
12939 if (id
< PRAGMA_FIRST_EXTERNAL
)
12941 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
12944 c_parser_error (parser
, "expected declaration specifiers");
12945 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12948 c_parser_omp_construct (parser
, if_p
);
12954 c_parser_consume_pragma (parser
);
12955 c_invoke_pragma_handler (id
);
12957 /* Skip to EOL, but suppress any error message. Those will have been
12958 generated by the handler routine through calling error, as opposed
12959 to calling c_parser_error. */
12960 parser
->error
= true;
12961 c_parser_skip_to_pragma_eol (parser
);
12966 /* The interface the pragma parsers have to the lexer. */
12969 pragma_lex (tree
*value
, location_t
*loc
)
12971 c_token
*tok
= c_parser_peek_token (the_parser
);
12972 enum cpp_ttype ret
= tok
->type
;
12974 *value
= tok
->value
;
12976 *loc
= tok
->location
;
12978 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
12980 else if (ret
== CPP_STRING
)
12981 *value
= c_parser_string_literal (the_parser
, false, false).value
;
12984 if (ret
== CPP_KEYWORD
)
12986 c_parser_consume_token (the_parser
);
12993 c_parser_pragma_pch_preprocess (c_parser
*parser
)
12997 parser
->lex_joined_string
= true;
12998 c_parser_consume_pragma (parser
);
12999 if (c_parser_next_token_is (parser
, CPP_STRING
))
13001 name
= c_parser_peek_token (parser
)->value
;
13002 c_parser_consume_token (parser
);
13005 c_parser_error (parser
, "expected string literal");
13006 c_parser_skip_to_pragma_eol (parser
);
13007 parser
->lex_joined_string
= false;
13010 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
13013 /* OpenACC and OpenMP parsing routines. */
13015 /* Returns name of the next clause.
13016 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
13017 the token is not consumed. Otherwise appropriate pragma_omp_clause is
13018 returned and the token is consumed. */
13020 static pragma_omp_clause
13021 c_parser_omp_clause_name (c_parser
*parser
)
13023 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
13025 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
13026 result
= PRAGMA_OACC_CLAUSE_AUTO
;
13027 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
13028 result
= PRAGMA_OMP_CLAUSE_IF
;
13029 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
13030 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
13031 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
13032 result
= PRAGMA_OMP_CLAUSE_FOR
;
13033 else if (c_parser_next_token_is (parser
, CPP_NAME
))
13035 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13040 if (!strcmp ("affinity", p
))
13041 result
= PRAGMA_OMP_CLAUSE_AFFINITY
;
13042 else if (!strcmp ("aligned", p
))
13043 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
13044 else if (!strcmp ("allocate", p
))
13045 result
= PRAGMA_OMP_CLAUSE_ALLOCATE
;
13046 else if (!strcmp ("async", p
))
13047 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
13048 else if (!strcmp ("attach", p
))
13049 result
= PRAGMA_OACC_CLAUSE_ATTACH
;
13052 if (!strcmp ("bind", p
))
13053 result
= PRAGMA_OMP_CLAUSE_BIND
;
13056 if (!strcmp ("collapse", p
))
13057 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
13058 else if (!strcmp ("copy", p
))
13059 result
= PRAGMA_OACC_CLAUSE_COPY
;
13060 else if (!strcmp ("copyin", p
))
13061 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
13062 else if (!strcmp ("copyout", p
))
13063 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
13064 else if (!strcmp ("copyprivate", p
))
13065 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
13066 else if (!strcmp ("create", p
))
13067 result
= PRAGMA_OACC_CLAUSE_CREATE
;
13070 if (!strcmp ("defaultmap", p
))
13071 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
13072 else if (!strcmp ("delete", p
))
13073 result
= PRAGMA_OACC_CLAUSE_DELETE
;
13074 else if (!strcmp ("depend", p
))
13075 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
13076 else if (!strcmp ("detach", p
))
13077 result
= PRAGMA_OACC_CLAUSE_DETACH
;
13078 else if (!strcmp ("device", p
))
13079 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
13080 else if (!strcmp ("deviceptr", p
))
13081 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
13082 else if (!strcmp ("device_resident", p
))
13083 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
13084 else if (!strcmp ("device_type", p
))
13085 result
= PRAGMA_OMP_CLAUSE_DEVICE_TYPE
;
13086 else if (!strcmp ("dist_schedule", p
))
13087 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
13088 else if (!strcmp ("doacross", p
))
13089 result
= PRAGMA_OMP_CLAUSE_DOACROSS
;
13092 if (!strcmp ("enter", p
))
13093 result
= PRAGMA_OMP_CLAUSE_ENTER
;
13096 if (!strcmp ("filter", p
))
13097 result
= PRAGMA_OMP_CLAUSE_FILTER
;
13098 else if (!strcmp ("final", p
))
13099 result
= PRAGMA_OMP_CLAUSE_FINAL
;
13100 else if (!strcmp ("finalize", p
))
13101 result
= PRAGMA_OACC_CLAUSE_FINALIZE
;
13102 else if (!strcmp ("firstprivate", p
))
13103 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
13104 else if (!strcmp ("from", p
))
13105 result
= PRAGMA_OMP_CLAUSE_FROM
;
13108 if (!strcmp ("gang", p
))
13109 result
= PRAGMA_OACC_CLAUSE_GANG
;
13110 else if (!strcmp ("grainsize", p
))
13111 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
13114 if (!strcmp ("has_device_addr", p
))
13115 result
= PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
;
13116 else if (!strcmp ("hint", p
))
13117 result
= PRAGMA_OMP_CLAUSE_HINT
;
13118 else if (!strcmp ("host", p
))
13119 result
= PRAGMA_OACC_CLAUSE_HOST
;
13122 if (!strcmp ("if_present", p
))
13123 result
= PRAGMA_OACC_CLAUSE_IF_PRESENT
;
13124 else if (!strcmp ("in_reduction", p
))
13125 result
= PRAGMA_OMP_CLAUSE_IN_REDUCTION
;
13126 else if (!strcmp ("inbranch", p
))
13127 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
13128 else if (!strcmp ("independent", p
))
13129 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
13130 else if (!strcmp ("is_device_ptr", p
))
13131 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
13134 if (!strcmp ("lastprivate", p
))
13135 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
13136 else if (!strcmp ("linear", p
))
13137 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
13138 else if (!strcmp ("link", p
))
13139 result
= PRAGMA_OMP_CLAUSE_LINK
;
13142 if (!strcmp ("map", p
))
13143 result
= PRAGMA_OMP_CLAUSE_MAP
;
13144 else if (!strcmp ("mergeable", p
))
13145 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
13148 if (!strcmp ("no_create", p
))
13149 result
= PRAGMA_OACC_CLAUSE_NO_CREATE
;
13150 else if (!strcmp ("nogroup", p
))
13151 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
13152 else if (!strcmp ("nohost", p
))
13153 result
= PRAGMA_OACC_CLAUSE_NOHOST
;
13154 else if (!strcmp ("nontemporal", p
))
13155 result
= PRAGMA_OMP_CLAUSE_NONTEMPORAL
;
13156 else if (!strcmp ("notinbranch", p
))
13157 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
13158 else if (!strcmp ("nowait", p
))
13159 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
13160 else if (!strcmp ("num_gangs", p
))
13161 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
13162 else if (!strcmp ("num_tasks", p
))
13163 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
13164 else if (!strcmp ("num_teams", p
))
13165 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
13166 else if (!strcmp ("num_threads", p
))
13167 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
13168 else if (!strcmp ("num_workers", p
))
13169 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
13172 if (!strcmp ("ordered", p
))
13173 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
13174 else if (!strcmp ("order", p
))
13175 result
= PRAGMA_OMP_CLAUSE_ORDER
;
13178 if (!strcmp ("parallel", p
))
13179 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
13180 else if (!strcmp ("present", p
))
13181 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
13182 /* As of OpenACC 2.5, these are now aliases of the non-present_or
13184 else if (!strcmp ("present_or_copy", p
)
13185 || !strcmp ("pcopy", p
))
13186 result
= PRAGMA_OACC_CLAUSE_COPY
;
13187 else if (!strcmp ("present_or_copyin", p
)
13188 || !strcmp ("pcopyin", p
))
13189 result
= PRAGMA_OACC_CLAUSE_COPYIN
;
13190 else if (!strcmp ("present_or_copyout", p
)
13191 || !strcmp ("pcopyout", p
))
13192 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
13193 else if (!strcmp ("present_or_create", p
)
13194 || !strcmp ("pcreate", p
))
13195 result
= PRAGMA_OACC_CLAUSE_CREATE
;
13196 else if (!strcmp ("priority", p
))
13197 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
13198 else if (!strcmp ("private", p
))
13199 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
13200 else if (!strcmp ("proc_bind", p
))
13201 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
13204 if (!strcmp ("reduction", p
))
13205 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
13208 if (!strcmp ("safelen", p
))
13209 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
13210 else if (!strcmp ("schedule", p
))
13211 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
13212 else if (!strcmp ("sections", p
))
13213 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
13214 else if (!strcmp ("self", p
)) /* "self" is a synonym for "host". */
13215 result
= PRAGMA_OACC_CLAUSE_HOST
;
13216 else if (!strcmp ("seq", p
))
13217 result
= PRAGMA_OACC_CLAUSE_SEQ
;
13218 else if (!strcmp ("shared", p
))
13219 result
= PRAGMA_OMP_CLAUSE_SHARED
;
13220 else if (!strcmp ("simd", p
))
13221 result
= PRAGMA_OMP_CLAUSE_SIMD
;
13222 else if (!strcmp ("simdlen", p
))
13223 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
13226 if (!strcmp ("task_reduction", p
))
13227 result
= PRAGMA_OMP_CLAUSE_TASK_REDUCTION
;
13228 else if (!strcmp ("taskgroup", p
))
13229 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
13230 else if (!strcmp ("thread_limit", p
))
13231 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
13232 else if (!strcmp ("threads", p
))
13233 result
= PRAGMA_OMP_CLAUSE_THREADS
;
13234 else if (!strcmp ("tile", p
))
13235 result
= PRAGMA_OACC_CLAUSE_TILE
;
13236 else if (!strcmp ("to", p
))
13237 result
= PRAGMA_OMP_CLAUSE_TO
;
13240 if (!strcmp ("uniform", p
))
13241 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
13242 else if (!strcmp ("untied", p
))
13243 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
13244 else if (!strcmp ("use_device", p
))
13245 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
13246 else if (!strcmp ("use_device_addr", p
))
13247 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
;
13248 else if (!strcmp ("use_device_ptr", p
))
13249 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
13252 if (!strcmp ("vector", p
))
13253 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
13254 else if (!strcmp ("vector_length", p
))
13255 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
13258 if (!strcmp ("wait", p
))
13259 result
= PRAGMA_OACC_CLAUSE_WAIT
;
13260 else if (!strcmp ("worker", p
))
13261 result
= PRAGMA_OACC_CLAUSE_WORKER
;
13266 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
13267 c_parser_consume_token (parser
);
13272 /* Validate that a clause of the given type does not already exist. */
13275 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
13278 if (tree c
= omp_find_clause (clauses
, code
))
13279 error_at (OMP_CLAUSE_LOCATION (c
), "too many %qs clauses", name
);
13283 Parse wait clause or wait directive parameters. */
13286 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
13288 vec
<tree
, va_gc
> *args
;
13291 matching_parens parens
;
13292 if (!parens
.require_open (parser
))
13295 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
13296 args_tree
= build_tree_list_vec (args
);
13298 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
13300 tree targ
= TREE_VALUE (t
);
13302 if (targ
!= error_mark_node
)
13304 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
13306 c_parser_error (parser
, "expression must be integral");
13307 targ
= error_mark_node
;
13311 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
13313 OMP_CLAUSE_DECL (c
) = targ
;
13314 OMP_CLAUSE_CHAIN (c
) = list
;
13320 release_tree_vector (args
);
13321 parens
.require_close (parser
);
13325 /* OpenACC 2.0, OpenMP 2.5:
13328 variable-list , identifier
13330 If KIND is nonzero, create the appropriate node and install the
13331 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
13332 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
13334 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
13335 return the list created.
13337 The optional ALLOW_DEREF argument is true if list items can use the deref
13342 tree low_bound
, length
;
13345 omp_dim (tree lb
, tree len
, location_t lo
, bool nc
)
13346 : low_bound (lb
), length (len
), loc (lo
), no_colon (nc
) {}
13350 c_parser_omp_variable_list (c_parser
*parser
,
13351 location_t clause_loc
,
13352 enum omp_clause_code kind
, tree list
,
13353 bool allow_deref
= false)
13355 auto_vec
<omp_dim
> dims
;
13356 bool array_section_p
;
13357 auto_vec
<c_token
> tokens
;
13358 unsigned int tokens_avail
= 0;
13363 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13365 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
13366 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
13368 struct c_expr expr
;
13369 if (kind
== OMP_CLAUSE_DEPEND
13370 && c_parser_next_token_is_keyword (parser
,
13371 RID_OMP_ALL_MEMORY
)
13372 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
13373 || (c_parser_peek_2nd_token (parser
)->type
13374 == CPP_CLOSE_PAREN
)))
13376 expr
.value
= ridpointers
[RID_OMP_ALL_MEMORY
];
13377 c_parser_consume_token (parser
);
13380 expr
= c_parser_expr_no_commas (parser
, NULL
);
13381 if (expr
.value
!= error_mark_node
)
13383 tree u
= build_omp_clause (clause_loc
, kind
);
13384 OMP_CLAUSE_DECL (u
) = expr
.value
;
13385 OMP_CLAUSE_CHAIN (u
) = list
;
13389 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
13392 c_parser_consume_token (parser
);
13397 tokens
.truncate (0);
13398 unsigned int nesting_depth
= 0;
13401 c_token
*token
= c_parser_peek_token (parser
);
13402 switch (token
->type
)
13405 case CPP_PRAGMA_EOL
:
13407 case CPP_OPEN_BRACE
:
13408 case CPP_OPEN_PAREN
:
13409 case CPP_OPEN_SQUARE
:
13412 case CPP_CLOSE_BRACE
:
13413 case CPP_CLOSE_PAREN
:
13414 case CPP_CLOSE_SQUARE
:
13415 if (nesting_depth
-- == 0)
13419 if (nesting_depth
== 0)
13424 tokens
.safe_push (*token
);
13425 c_parser_consume_token (parser
);
13431 /* Make sure nothing tries to read past the end of the tokens. */
13433 memset (&eof_token
, 0, sizeof (eof_token
));
13434 eof_token
.type
= CPP_EOF
;
13435 tokens
.safe_push (eof_token
);
13436 tokens
.safe_push (eof_token
);
13438 tokens_avail
= parser
->tokens_avail
;
13439 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
13440 parser
->tokens
= tokens
.address ();
13441 parser
->tokens_avail
= tokens
.length ();
13444 tree t
= NULL_TREE
;
13446 if (c_parser_next_token_is (parser
, CPP_NAME
)
13447 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
13449 t
= lookup_name (c_parser_peek_token (parser
)->value
);
13451 if (t
== NULL_TREE
)
13453 undeclared_variable (c_parser_peek_token (parser
)->location
,
13454 c_parser_peek_token (parser
)->value
);
13455 t
= error_mark_node
;
13458 c_parser_consume_token (parser
);
13460 else if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
13461 && (c_parser_peek_token (parser
)->keyword
== RID_FUNCTION_NAME
13462 || (c_parser_peek_token (parser
)->keyword
13463 == RID_PRETTY_FUNCTION_NAME
)
13464 || (c_parser_peek_token (parser
)->keyword
13465 == RID_C99_FUNCTION_NAME
)))
13466 t
= c_parser_predefined_identifier (parser
).value
;
13470 c_parser_error (parser
, "expected identifier");
13474 if (t
== error_mark_node
)
13476 else if (kind
!= 0)
13480 case OMP_CLAUSE__CACHE_
:
13481 /* The OpenACC cache directive explicitly only allows "array
13482 elements or subarrays". */
13483 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
13485 c_parser_error (parser
, "expected %<[%>");
13486 t
= error_mark_node
;
13490 case OMP_CLAUSE_MAP
:
13491 case OMP_CLAUSE_FROM
:
13492 case OMP_CLAUSE_TO
:
13493 start_component_ref
:
13494 while (c_parser_next_token_is (parser
, CPP_DOT
)
13496 && c_parser_next_token_is (parser
, CPP_DEREF
)))
13498 location_t op_loc
= c_parser_peek_token (parser
)->location
;
13499 location_t arrow_loc
= UNKNOWN_LOCATION
;
13500 if (c_parser_next_token_is (parser
, CPP_DEREF
))
13504 t_expr
.original_code
= ERROR_MARK
;
13505 t_expr
.original_type
= NULL
;
13506 set_c_expr_source_range (&t_expr
, op_loc
, op_loc
);
13507 t_expr
.m_decimal
= 0;
13508 t_expr
= convert_lvalue_to_rvalue (op_loc
, t_expr
,
13510 t
= build_indirect_ref (op_loc
, t_expr
.value
, RO_ARROW
);
13511 arrow_loc
= t_expr
.get_location ();
13513 c_parser_consume_token (parser
);
13514 if (!c_parser_next_token_is (parser
, CPP_NAME
))
13516 c_parser_error (parser
, "expected identifier");
13517 t
= error_mark_node
;
13521 c_token
*comp_tok
= c_parser_peek_token (parser
);
13522 tree ident
= comp_tok
->value
;
13523 location_t comp_loc
= comp_tok
->location
;
13524 c_parser_consume_token (parser
);
13525 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
,
13529 case OMP_CLAUSE_AFFINITY
:
13530 case OMP_CLAUSE_DEPEND
:
13531 case OMP_CLAUSE_REDUCTION
:
13532 case OMP_CLAUSE_IN_REDUCTION
:
13533 case OMP_CLAUSE_TASK_REDUCTION
:
13534 case OMP_CLAUSE_HAS_DEVICE_ADDR
:
13535 array_section_p
= false;
13537 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
13539 location_t loc
= UNKNOWN_LOCATION
;
13540 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
13541 bool no_colon
= false;
13543 c_parser_consume_token (parser
);
13544 if (!c_parser_next_token_is (parser
, CPP_COLON
))
13546 location_t expr_loc
13547 = c_parser_peek_token (parser
)->location
;
13548 c_expr expr
= c_parser_expression (parser
);
13549 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13551 low_bound
= expr
.value
;
13554 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13556 length
= integer_one_node
;
13561 /* Look for `:'. */
13562 if (!c_parser_require (parser
, CPP_COLON
,
13565 t
= error_mark_node
;
13568 array_section_p
= true;
13569 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13571 location_t expr_loc
13572 = c_parser_peek_token (parser
)->location
;
13573 c_expr expr
= c_parser_expression (parser
);
13574 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13576 length
= expr
.value
;
13579 /* Look for the closing `]'. */
13580 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
13583 t
= error_mark_node
;
13587 dims
.safe_push (omp_dim (low_bound
, length
, loc
, no_colon
));
13590 if (t
!= error_mark_node
)
13592 if ((kind
== OMP_CLAUSE_MAP
13593 || kind
== OMP_CLAUSE_FROM
13594 || kind
== OMP_CLAUSE_TO
)
13595 && !array_section_p
13596 && (c_parser_next_token_is (parser
, CPP_DOT
)
13598 && c_parser_next_token_is (parser
,
13601 for (unsigned i
= 0; i
< dims
.length (); i
++)
13603 gcc_assert (dims
[i
].length
== integer_one_node
);
13604 t
= build_array_ref (dims
[i
].loc
,
13605 t
, dims
[i
].low_bound
);
13607 goto start_component_ref
;
13610 for (unsigned i
= 0; i
< dims
.length (); i
++)
13611 t
= tree_cons (dims
[i
].low_bound
, dims
[i
].length
, t
);
13614 if ((kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13615 && t
!= error_mark_node
13616 && parser
->tokens_avail
!= 2)
13618 if (array_section_p
)
13620 error_at (c_parser_peek_token (parser
)->location
,
13621 "expected %<)%> or %<,%>");
13622 t
= error_mark_node
;
13626 parser
->tokens
= tokens
.address ();
13627 parser
->tokens_avail
= tokens
.length ();
13629 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
13630 if (t
!= error_mark_node
&& parser
->tokens_avail
!= 2)
13632 error_at (c_parser_peek_token (parser
)->location
,
13633 "expected %<)%> or %<,%>");
13634 t
= error_mark_node
;
13643 if (t
!= error_mark_node
)
13645 tree u
= build_omp_clause (clause_loc
, kind
);
13646 OMP_CLAUSE_DECL (u
) = t
;
13647 OMP_CLAUSE_CHAIN (u
) = list
;
13652 list
= tree_cons (t
, NULL_TREE
, list
);
13654 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13656 parser
->tokens
= &parser
->tokens_buf
[0];
13657 parser
->tokens_avail
= tokens_avail
;
13659 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
13662 c_parser_consume_token (parser
);
13669 /* Similarly, but expect leading and trailing parenthesis. This is a very
13670 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13671 argument is true if list items can use the deref (->) operator. */
13674 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
13675 tree list
, bool allow_deref
= false)
13677 /* The clauses location. */
13678 location_t loc
= c_parser_peek_token (parser
)->location
;
13680 matching_parens parens
;
13681 if (parens
.require_open (parser
))
13683 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
, allow_deref
);
13684 parens
.skip_until_found_close (parser
);
13690 copy ( variable-list )
13691 copyin ( variable-list )
13692 copyout ( variable-list )
13693 create ( variable-list )
13694 delete ( variable-list )
13695 present ( variable-list )
13698 no_create ( variable-list )
13699 attach ( variable-list )
13700 detach ( variable-list ) */
13703 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
13706 enum gomp_map_kind kind
;
13709 case PRAGMA_OACC_CLAUSE_ATTACH
:
13710 kind
= GOMP_MAP_ATTACH
;
13712 case PRAGMA_OACC_CLAUSE_COPY
:
13713 kind
= GOMP_MAP_TOFROM
;
13715 case PRAGMA_OACC_CLAUSE_COPYIN
:
13716 kind
= GOMP_MAP_TO
;
13718 case PRAGMA_OACC_CLAUSE_COPYOUT
:
13719 kind
= GOMP_MAP_FROM
;
13721 case PRAGMA_OACC_CLAUSE_CREATE
:
13722 kind
= GOMP_MAP_ALLOC
;
13724 case PRAGMA_OACC_CLAUSE_DELETE
:
13725 kind
= GOMP_MAP_RELEASE
;
13727 case PRAGMA_OACC_CLAUSE_DETACH
:
13728 kind
= GOMP_MAP_DETACH
;
13730 case PRAGMA_OACC_CLAUSE_DEVICE
:
13731 kind
= GOMP_MAP_FORCE_TO
;
13733 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
13734 kind
= GOMP_MAP_DEVICE_RESIDENT
;
13736 case PRAGMA_OACC_CLAUSE_HOST
:
13737 kind
= GOMP_MAP_FORCE_FROM
;
13739 case PRAGMA_OACC_CLAUSE_LINK
:
13740 kind
= GOMP_MAP_LINK
;
13742 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
13743 kind
= GOMP_MAP_IF_PRESENT
;
13745 case PRAGMA_OACC_CLAUSE_PRESENT
:
13746 kind
= GOMP_MAP_FORCE_PRESENT
;
13749 gcc_unreachable ();
13752 nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_MAP
, list
, true);
13754 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13755 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
13761 deviceptr ( variable-list ) */
13764 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
13766 location_t loc
= c_parser_peek_token (parser
)->location
;
13769 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13770 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13771 variable-list must only allow for pointer variables. */
13772 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
13773 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
13775 tree v
= TREE_PURPOSE (t
);
13777 /* FIXME diagnostics: Ideally we should keep individual
13778 locations for all the variables in the var list to make the
13779 following errors more precise. Perhaps
13780 c_parser_omp_var_list_parens() should construct a list of
13781 locations to go along with the var list. */
13783 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
13784 error_at (loc
, "%qD is not a variable", v
);
13785 else if (TREE_TYPE (v
) == error_mark_node
)
13787 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
13788 error_at (loc
, "%qD is not a pointer variable", v
);
13790 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
13791 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
13792 OMP_CLAUSE_DECL (u
) = v
;
13793 OMP_CLAUSE_CHAIN (u
) = list
;
13800 /* OpenACC 2.0, OpenMP 3.0:
13801 collapse ( constant-expression ) */
13804 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
13806 tree c
, num
= error_mark_node
;
13810 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
13811 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
13813 loc
= c_parser_peek_token (parser
)->location
;
13814 matching_parens parens
;
13815 if (parens
.require_open (parser
))
13817 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
13818 parens
.skip_until_found_close (parser
);
13820 if (num
== error_mark_node
)
13822 mark_exp_read (num
);
13823 num
= c_fully_fold (num
, false, NULL
);
13824 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
13825 || !tree_fits_shwi_p (num
)
13826 || (n
= tree_to_shwi (num
)) <= 0
13830 "collapse argument needs positive constant integer expression");
13833 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
13834 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
13835 OMP_CLAUSE_CHAIN (c
) = list
;
13840 copyin ( variable-list ) */
13843 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
13845 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
13849 copyprivate ( variable-list ) */
13852 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
13854 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
13858 default ( none | shared )
13861 default ( private | firstprivate )
13864 default ( none | present ) */
13867 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
13869 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
13870 location_t loc
= c_parser_peek_token (parser
)->location
;
13873 matching_parens parens
;
13874 if (!parens
.require_open (parser
))
13876 if (c_parser_next_token_is (parser
, CPP_NAME
))
13878 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13883 if (strcmp ("none", p
) != 0)
13885 kind
= OMP_CLAUSE_DEFAULT_NONE
;
13891 if (strcmp ("present", p
) != 0)
13893 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
13897 if (strcmp ("private", p
) != 0)
13899 kind
= OMP_CLAUSE_DEFAULT_PRIVATE
;
13904 if (strcmp ("firstprivate", p
) != 0 || is_oacc
)
13906 kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
13910 if (strcmp ("shared", p
) != 0 || is_oacc
)
13912 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
13919 c_parser_consume_token (parser
);
13925 c_parser_error (parser
, "expected %<none%> or %<present%>");
13927 c_parser_error (parser
, "expected %<none%>, %<shared%>, "
13928 "%<private%> or %<firstprivate%>");
13930 parens
.skip_until_found_close (parser
);
13932 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
13935 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
13936 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
13937 OMP_CLAUSE_CHAIN (c
) = list
;
13938 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
13944 firstprivate ( variable-list ) */
13947 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
13949 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
13953 final ( expression ) */
13956 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
13958 location_t loc
= c_parser_peek_token (parser
)->location
;
13959 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13961 matching_parens parens
;
13963 if (!parens
.require_open (parser
))
13964 t
= error_mark_node
;
13967 location_t eloc
= c_parser_peek_token (parser
)->location
;
13968 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13969 t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
13970 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
13971 t
= c_fully_fold (t
, false, NULL
);
13972 parens
.skip_until_found_close (parser
);
13975 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
13977 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
13978 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
13979 OMP_CLAUSE_CHAIN (c
) = list
;
13983 c_parser_error (parser
, "expected %<(%>");
13988 /* OpenACC, OpenMP 2.5:
13992 if ( directive-name-modifier : expression )
13994 directive-name-modifier:
13995 parallel | task | taskloop | target data | target | target update
13996 | target enter data | target exit data
13999 directive-name-modifier:
14000 ... | simd | cancel */
14003 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
14005 location_t location
= c_parser_peek_token (parser
)->location
;
14006 enum tree_code if_modifier
= ERROR_MARK
;
14008 matching_parens parens
;
14009 if (!parens
.require_open (parser
))
14012 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
14014 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14016 if (strcmp (p
, "cancel") == 0)
14017 if_modifier
= VOID_CST
;
14018 else if (strcmp (p
, "parallel") == 0)
14019 if_modifier
= OMP_PARALLEL
;
14020 else if (strcmp (p
, "simd") == 0)
14021 if_modifier
= OMP_SIMD
;
14022 else if (strcmp (p
, "task") == 0)
14023 if_modifier
= OMP_TASK
;
14024 else if (strcmp (p
, "taskloop") == 0)
14025 if_modifier
= OMP_TASKLOOP
;
14026 else if (strcmp (p
, "target") == 0)
14028 if_modifier
= OMP_TARGET
;
14029 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
14031 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
14032 if (strcmp ("data", p
) == 0)
14033 if_modifier
= OMP_TARGET_DATA
;
14034 else if (strcmp ("update", p
) == 0)
14035 if_modifier
= OMP_TARGET_UPDATE
;
14036 else if (strcmp ("enter", p
) == 0)
14037 if_modifier
= OMP_TARGET_ENTER_DATA
;
14038 else if (strcmp ("exit", p
) == 0)
14039 if_modifier
= OMP_TARGET_EXIT_DATA
;
14040 if (if_modifier
!= OMP_TARGET
)
14043 c_parser_consume_token (parser
);
14047 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
14048 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
14050 if_modifier
= ERROR_MARK
;
14052 if (if_modifier
== OMP_TARGET_ENTER_DATA
14053 || if_modifier
== OMP_TARGET_EXIT_DATA
)
14055 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
14057 p
= IDENTIFIER_POINTER
14058 (c_parser_peek_2nd_token (parser
)->value
);
14059 if (strcmp ("data", p
) == 0)
14063 c_parser_consume_token (parser
);
14067 = c_parser_peek_2nd_token (parser
)->location
;
14068 error_at (loc
, "expected %<data%>");
14069 if_modifier
= ERROR_MARK
;
14074 if (if_modifier
!= ERROR_MARK
)
14076 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14078 c_parser_consume_token (parser
);
14079 c_parser_consume_token (parser
);
14085 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
14086 error_at (loc
, "expected %<:%>");
14088 if_modifier
= ERROR_MARK
;
14093 location_t loc
= c_parser_peek_token (parser
)->location
;
14094 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14095 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
14096 tree t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
), c
;
14097 t
= c_fully_fold (t
, false, NULL
);
14098 parens
.skip_until_found_close (parser
);
14100 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
14101 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
14103 if (if_modifier
!= ERROR_MARK
14104 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
14106 const char *p
= NULL
;
14107 switch (if_modifier
)
14109 case VOID_CST
: p
= "cancel"; break;
14110 case OMP_PARALLEL
: p
= "parallel"; break;
14111 case OMP_SIMD
: p
= "simd"; break;
14112 case OMP_TASK
: p
= "task"; break;
14113 case OMP_TASKLOOP
: p
= "taskloop"; break;
14114 case OMP_TARGET_DATA
: p
= "target data"; break;
14115 case OMP_TARGET
: p
= "target"; break;
14116 case OMP_TARGET_UPDATE
: p
= "target update"; break;
14117 case OMP_TARGET_ENTER_DATA
: p
= "target enter data"; break;
14118 case OMP_TARGET_EXIT_DATA
: p
= "target exit data"; break;
14119 default: gcc_unreachable ();
14121 error_at (location
, "too many %<if%> clauses with %qs modifier",
14125 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
14128 error_at (location
, "too many %<if%> clauses");
14130 error_at (location
, "too many %<if%> clauses without modifier");
14133 else if (if_modifier
== ERROR_MARK
14134 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
14136 error_at (location
, "if any %<if%> clause has modifier, then all "
14137 "%<if%> clauses have to use modifier");
14142 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
14143 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
14144 OMP_CLAUSE_IF_EXPR (c
) = t
;
14145 OMP_CLAUSE_CHAIN (c
) = list
;
14150 lastprivate ( variable-list )
14153 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
14156 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
14158 /* The clauses location. */
14159 location_t loc
= c_parser_peek_token (parser
)->location
;
14161 if (c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
14163 bool conditional
= false;
14164 if (c_parser_next_token_is (parser
, CPP_NAME
)
14165 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14168 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14169 if (strcmp (p
, "conditional") == 0)
14171 conditional
= true;
14172 c_parser_consume_token (parser
);
14173 c_parser_consume_token (parser
);
14176 tree nlist
= c_parser_omp_variable_list (parser
, loc
,
14177 OMP_CLAUSE_LASTPRIVATE
, list
);
14178 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
14180 for (tree c
= nlist
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
14181 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 1;
14191 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
14195 /* FIXME: Should we allow duplicates? */
14196 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
14198 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
14199 OMP_CLAUSE_MERGEABLE
);
14200 OMP_CLAUSE_CHAIN (c
) = list
;
14209 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
14212 location_t loc
= c_parser_peek_token (parser
)->location
;
14214 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
14216 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
14217 OMP_CLAUSE_CHAIN (c
) = list
;
14222 num_threads ( expression ) */
14225 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
14227 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
14228 matching_parens parens
;
14229 if (parens
.require_open (parser
))
14231 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14232 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14233 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14234 tree c
, t
= expr
.value
;
14235 t
= c_fully_fold (t
, false, NULL
);
14237 parens
.skip_until_found_close (parser
);
14239 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14241 c_parser_error (parser
, "expected integer expression");
14245 /* Attempt to statically determine when the number isn't positive. */
14246 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14247 build_int_cst (TREE_TYPE (t
), 0));
14248 protected_set_expr_location (c
, expr_loc
);
14249 if (c
== boolean_true_node
)
14251 warning_at (expr_loc
, 0,
14252 "%<num_threads%> value must be positive");
14253 t
= integer_one_node
;
14256 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
14258 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
14259 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
14260 OMP_CLAUSE_CHAIN (c
) = list
;
14268 num_tasks ( expression )
14271 num_tasks ( strict : expression ) */
14274 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
14276 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
14277 matching_parens parens
;
14278 if (parens
.require_open (parser
))
14280 bool strict
= false;
14281 if (c_parser_next_token_is (parser
, CPP_NAME
)
14282 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
14283 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
14287 c_parser_consume_token (parser
);
14288 c_parser_consume_token (parser
);
14291 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14292 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14293 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14294 tree c
, t
= expr
.value
;
14295 t
= c_fully_fold (t
, false, NULL
);
14297 parens
.skip_until_found_close (parser
);
14299 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14301 c_parser_error (parser
, "expected integer expression");
14305 /* Attempt to statically determine when the number isn't positive. */
14306 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14307 build_int_cst (TREE_TYPE (t
), 0));
14308 if (CAN_HAVE_LOCATION_P (c
))
14309 SET_EXPR_LOCATION (c
, expr_loc
);
14310 if (c
== boolean_true_node
)
14312 warning_at (expr_loc
, 0, "%<num_tasks%> value must be positive");
14313 t
= integer_one_node
;
14316 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
14318 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
14319 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
14320 OMP_CLAUSE_NUM_TASKS_STRICT (c
) = strict
;
14321 OMP_CLAUSE_CHAIN (c
) = list
;
14329 grainsize ( expression )
14332 grainsize ( strict : expression ) */
14335 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
14337 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
14338 matching_parens parens
;
14339 if (parens
.require_open (parser
))
14341 bool strict
= false;
14342 if (c_parser_next_token_is (parser
, CPP_NAME
)
14343 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
14344 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
14348 c_parser_consume_token (parser
);
14349 c_parser_consume_token (parser
);
14352 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14353 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14354 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14355 tree c
, t
= expr
.value
;
14356 t
= c_fully_fold (t
, false, NULL
);
14358 parens
.skip_until_found_close (parser
);
14360 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14362 c_parser_error (parser
, "expected integer expression");
14366 /* Attempt to statically determine when the number isn't positive. */
14367 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14368 build_int_cst (TREE_TYPE (t
), 0));
14369 if (CAN_HAVE_LOCATION_P (c
))
14370 SET_EXPR_LOCATION (c
, expr_loc
);
14371 if (c
== boolean_true_node
)
14373 warning_at (expr_loc
, 0, "%<grainsize%> value must be positive");
14374 t
= integer_one_node
;
14377 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
14379 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
14380 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
14381 OMP_CLAUSE_GRAINSIZE_STRICT (c
) = strict
;
14382 OMP_CLAUSE_CHAIN (c
) = list
;
14390 priority ( expression ) */
14393 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
14395 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
14396 matching_parens parens
;
14397 if (parens
.require_open (parser
))
14399 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14400 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14401 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14402 tree c
, t
= expr
.value
;
14403 t
= c_fully_fold (t
, false, NULL
);
14405 parens
.skip_until_found_close (parser
);
14407 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14409 c_parser_error (parser
, "expected integer expression");
14413 /* Attempt to statically determine when the number isn't
14415 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
14416 build_int_cst (TREE_TYPE (t
), 0));
14417 if (CAN_HAVE_LOCATION_P (c
))
14418 SET_EXPR_LOCATION (c
, expr_loc
);
14419 if (c
== boolean_true_node
)
14421 warning_at (expr_loc
, 0, "%<priority%> value must be non-negative");
14422 t
= integer_one_node
;
14425 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
14427 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
14428 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
14429 OMP_CLAUSE_CHAIN (c
) = list
;
14437 hint ( expression ) */
14440 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
14442 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
14443 matching_parens parens
;
14444 if (parens
.require_open (parser
))
14446 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14447 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14448 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14449 tree c
, t
= expr
.value
;
14450 t
= c_fully_fold (t
, false, NULL
);
14451 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
14452 || TREE_CODE (t
) != INTEGER_CST
14453 || tree_int_cst_sgn (t
) == -1)
14455 c_parser_error (parser
, "expected constant integer expression "
14456 "with valid sync-hint value");
14459 parens
.skip_until_found_close (parser
);
14460 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
14462 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
14463 OMP_CLAUSE_HINT_EXPR (c
) = t
;
14464 OMP_CLAUSE_CHAIN (c
) = list
;
14472 filter ( integer-expression ) */
14475 c_parser_omp_clause_filter (c_parser
*parser
, tree list
)
14477 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
14478 matching_parens parens
;
14479 if (parens
.require_open (parser
))
14481 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14482 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14483 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14484 tree c
, t
= expr
.value
;
14485 t
= c_fully_fold (t
, false, NULL
);
14486 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14488 c_parser_error (parser
, "expected integer expression");
14491 parens
.skip_until_found_close (parser
);
14492 check_no_duplicate_clause (list
, OMP_CLAUSE_FILTER
, "filter");
14494 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_FILTER
);
14495 OMP_CLAUSE_FILTER_EXPR (c
) = t
;
14496 OMP_CLAUSE_CHAIN (c
) = list
;
14504 defaultmap ( tofrom : scalar )
14507 defaultmap ( implicit-behavior [ : variable-category ] ) */
14510 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
14512 location_t loc
= c_parser_peek_token (parser
)->location
;
14515 enum omp_clause_defaultmap_kind behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
14516 enum omp_clause_defaultmap_kind category
14517 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
14519 matching_parens parens
;
14520 if (!parens
.require_open (parser
))
14522 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
14524 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
14527 c_parser_error (parser
, "expected %<alloc%>, %<to%>, %<from%>, "
14528 "%<tofrom%>, %<firstprivate%>, %<none%> "
14533 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14538 if (strcmp ("alloc", p
) == 0)
14539 behavior
= OMP_CLAUSE_DEFAULTMAP_ALLOC
;
14541 goto invalid_behavior
;
14545 if (strcmp ("default", p
) == 0)
14546 behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
14548 goto invalid_behavior
;
14552 if (strcmp ("firstprivate", p
) == 0)
14553 behavior
= OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
14554 else if (strcmp ("from", p
) == 0)
14555 behavior
= OMP_CLAUSE_DEFAULTMAP_FROM
;
14557 goto invalid_behavior
;
14561 if (strcmp ("none", p
) == 0)
14562 behavior
= OMP_CLAUSE_DEFAULTMAP_NONE
;
14564 goto invalid_behavior
;
14568 if (strcmp ("tofrom", p
) == 0)
14569 behavior
= OMP_CLAUSE_DEFAULTMAP_TOFROM
;
14570 else if (strcmp ("to", p
) == 0)
14571 behavior
= OMP_CLAUSE_DEFAULTMAP_TO
;
14573 goto invalid_behavior
;
14577 goto invalid_behavior
;
14579 c_parser_consume_token (parser
);
14581 if (!c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
14583 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14585 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14588 c_parser_error (parser
, "expected %<scalar%>, %<aggregate%> or "
14592 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14596 if (strcmp ("aggregate", p
) == 0)
14597 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
;
14599 goto invalid_category
;
14603 if (strcmp ("pointer", p
) == 0)
14604 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
;
14606 goto invalid_category
;
14610 if (strcmp ("scalar", p
) == 0)
14611 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
;
14613 goto invalid_category
;
14617 goto invalid_category
;
14620 c_parser_consume_token (parser
);
14622 parens
.skip_until_found_close (parser
);
14624 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
14625 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEFAULTMAP
14626 && (category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14627 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
) == category
14628 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
14629 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)))
14631 enum omp_clause_defaultmap_kind cat
= category
;
14632 location_t loc
= OMP_CLAUSE_LOCATION (c
);
14633 if (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
14634 cat
= OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
);
14638 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
14641 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
14644 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
14647 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
14651 gcc_unreachable ();
14654 error_at (loc
, "too many %<defaultmap%> clauses with %qs category",
14657 error_at (loc
, "too many %<defaultmap%> clauses with unspecified "
14662 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
14663 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c
, behavior
, category
);
14664 OMP_CLAUSE_CHAIN (c
) = list
;
14668 parens
.skip_until_found_close (parser
);
14673 use_device ( variable-list )
14676 use_device_ptr ( variable-list ) */
14679 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
14681 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
14686 use_device_addr ( variable-list ) */
14689 c_parser_omp_clause_use_device_addr (c_parser
*parser
, tree list
)
14691 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_ADDR
,
14696 has_device_addr ( variable-list ) */
14699 c_parser_omp_clause_has_device_addr (c_parser
*parser
, tree list
)
14701 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_HAS_DEVICE_ADDR
,
14706 is_device_ptr ( variable-list ) */
14709 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
14711 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
14715 num_gangs ( expression )
14716 num_workers ( expression )
14717 vector_length ( expression ) */
14720 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
14723 location_t loc
= c_parser_peek_token (parser
)->location
;
14725 matching_parens parens
;
14726 if (!parens
.require_open (parser
))
14729 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14730 c_expr expr
= c_parser_expression (parser
);
14731 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14732 tree c
, t
= expr
.value
;
14733 t
= c_fully_fold (t
, false, NULL
);
14735 parens
.skip_until_found_close (parser
);
14737 if (t
== error_mark_node
)
14739 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14741 error_at (expr_loc
, "%qs expression must be integral",
14742 omp_clause_code_name
[code
]);
14746 /* Attempt to statically determine when the number isn't positive. */
14747 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14748 build_int_cst (TREE_TYPE (t
), 0));
14749 protected_set_expr_location (c
, expr_loc
);
14750 if (c
== boolean_true_node
)
14752 warning_at (expr_loc
, 0,
14753 "%qs value must be positive",
14754 omp_clause_code_name
[code
]);
14755 t
= integer_one_node
;
14758 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14760 c
= build_omp_clause (loc
, code
);
14761 OMP_CLAUSE_OPERAND (c
, 0) = t
;
14762 OMP_CLAUSE_CHAIN (c
) = list
;
14768 gang [( gang-arg-list )]
14769 worker [( [num:] int-expr )]
14770 vector [( [length:] int-expr )]
14772 where gang-arg is one of:
14777 and size-expr may be:
14784 c_parser_oacc_shape_clause (c_parser
*parser
, location_t loc
,
14785 omp_clause_code kind
,
14786 const char *str
, tree list
)
14788 const char *id
= "num";
14789 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
14791 if (kind
== OMP_CLAUSE_VECTOR
)
14794 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14796 c_parser_consume_token (parser
);
14800 c_token
*next
= c_parser_peek_token (parser
);
14803 /* Gang static argument. */
14804 if (kind
== OMP_CLAUSE_GANG
14805 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
14807 c_parser_consume_token (parser
);
14809 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14810 goto cleanup_error
;
14813 if (ops
[idx
] != NULL_TREE
)
14815 c_parser_error (parser
, "too many %<static%> arguments");
14816 goto cleanup_error
;
14819 /* Check for the '*' argument. */
14820 if (c_parser_next_token_is (parser
, CPP_MULT
)
14821 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14822 || c_parser_peek_2nd_token (parser
)->type
14823 == CPP_CLOSE_PAREN
))
14825 c_parser_consume_token (parser
);
14826 ops
[idx
] = integer_minus_one_node
;
14828 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14830 c_parser_consume_token (parser
);
14837 /* Worker num: argument and vector length: arguments. */
14838 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14839 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
14840 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14842 c_parser_consume_token (parser
); /* id */
14843 c_parser_consume_token (parser
); /* ':' */
14846 /* Now collect the actual argument. */
14847 if (ops
[idx
] != NULL_TREE
)
14849 c_parser_error (parser
, "unexpected argument");
14850 goto cleanup_error
;
14853 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14854 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14855 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14856 tree expr
= cexpr
.value
;
14857 if (expr
== error_mark_node
)
14858 goto cleanup_error
;
14860 expr
= c_fully_fold (expr
, false, NULL
);
14862 /* Attempt to statically determine when the number isn't a
14863 positive integer. */
14865 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
14867 c_parser_error (parser
, "expected integer expression");
14871 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
14872 build_int_cst (TREE_TYPE (expr
), 0));
14873 if (c
== boolean_true_node
)
14875 warning_at (loc
, 0,
14876 "%qs value must be positive", str
);
14877 expr
= integer_one_node
;
14882 if (kind
== OMP_CLAUSE_GANG
14883 && c_parser_next_token_is (parser
, CPP_COMMA
))
14885 c_parser_consume_token (parser
);
14892 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14893 goto cleanup_error
;
14896 check_no_duplicate_clause (list
, kind
, str
);
14898 c
= build_omp_clause (loc
, kind
);
14901 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
14903 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
14904 OMP_CLAUSE_CHAIN (c
) = list
;
14909 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14921 c_parser_oacc_simple_clause (location_t loc
, enum omp_clause_code code
,
14924 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14926 tree c
= build_omp_clause (loc
, code
);
14927 OMP_CLAUSE_CHAIN (c
) = list
;
14933 async [( int-expr )] */
14936 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
14939 location_t loc
= c_parser_peek_token (parser
)->location
;
14941 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14943 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14945 c_parser_consume_token (parser
);
14947 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
14948 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14949 c_parser_error (parser
, "expected integer expression");
14950 else if (t
== error_mark_node
14951 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14955 t
= c_fully_fold (t
, false, NULL
);
14957 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
14959 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
14960 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
14961 OMP_CLAUSE_CHAIN (c
) = list
;
14968 tile ( size-expr-list ) */
14971 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
14973 tree c
, expr
= error_mark_node
;
14975 tree tile
= NULL_TREE
;
14977 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
14978 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
14980 loc
= c_parser_peek_token (parser
)->location
;
14981 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
14986 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
14989 if (c_parser_next_token_is (parser
, CPP_MULT
)
14990 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14991 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
14993 c_parser_consume_token (parser
);
14994 expr
= integer_zero_node
;
14998 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14999 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
15000 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
15001 expr
= cexpr
.value
;
15003 if (expr
== error_mark_node
)
15005 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15010 expr
= c_fully_fold (expr
, false, NULL
);
15012 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
15013 || !tree_fits_shwi_p (expr
)
15014 || tree_to_shwi (expr
) <= 0)
15016 error_at (expr_loc
, "%<tile%> argument needs positive"
15017 " integral constant");
15018 expr
= integer_zero_node
;
15022 tile
= tree_cons (NULL_TREE
, expr
, tile
);
15024 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
15026 /* Consume the trailing ')'. */
15027 c_parser_consume_token (parser
);
15029 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
15030 tile
= nreverse (tile
);
15031 OMP_CLAUSE_TILE_LIST (c
) = tile
;
15032 OMP_CLAUSE_CHAIN (c
) = list
;
15037 wait [( int-expr-list )] */
15040 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
15042 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15044 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
15045 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
15048 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
15050 OMP_CLAUSE_DECL (c
) = build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
15051 OMP_CLAUSE_CHAIN (c
) = list
;
15060 order ( concurrent )
15063 order ( order-modifier : concurrent )
15070 c_parser_omp_clause_order (c_parser
*parser
, tree list
)
15072 location_t loc
= c_parser_peek_token (parser
)->location
;
15075 bool unconstrained
= false;
15076 bool reproducible
= false;
15078 matching_parens parens
;
15079 if (!parens
.require_open (parser
))
15081 if (c_parser_next_token_is (parser
, CPP_NAME
)
15082 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
15084 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15085 if (strcmp (p
, "unconstrained") == 0)
15086 unconstrained
= true;
15087 else if (strcmp (p
, "reproducible") == 0)
15088 reproducible
= true;
15091 c_parser_error (parser
, "expected %<reproducible%> or "
15092 "%<unconstrained%>");
15095 c_parser_consume_token (parser
);
15096 c_parser_consume_token (parser
);
15098 if (!c_parser_next_token_is (parser
, CPP_NAME
))
15100 c_parser_error (parser
, "expected %<concurrent%>");
15103 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15104 if (strcmp (p
, "concurrent") != 0)
15106 c_parser_error (parser
, "expected %<concurrent%>");
15109 c_parser_consume_token (parser
);
15110 parens
.skip_until_found_close (parser
);
15111 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDER
, "order");
15112 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDER
);
15113 OMP_CLAUSE_ORDER_UNCONSTRAINED (c
) = unconstrained
;
15114 OMP_CLAUSE_ORDER_REPRODUCIBLE (c
) = reproducible
;
15115 OMP_CLAUSE_CHAIN (c
) = list
;
15119 parens
.skip_until_found_close (parser
);
15125 bind ( teams | parallel | thread ) */
15128 c_parser_omp_clause_bind (c_parser
*parser
, tree list
)
15130 location_t loc
= c_parser_peek_token (parser
)->location
;
15133 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
15135 matching_parens parens
;
15136 if (!parens
.require_open (parser
))
15138 if (!c_parser_next_token_is (parser
, CPP_NAME
))
15141 c_parser_error (parser
,
15142 "expected %<teams%>, %<parallel%> or %<thread%>");
15143 parens
.skip_until_found_close (parser
);
15146 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15147 if (strcmp (p
, "teams") == 0)
15148 kind
= OMP_CLAUSE_BIND_TEAMS
;
15149 else if (strcmp (p
, "parallel") == 0)
15150 kind
= OMP_CLAUSE_BIND_PARALLEL
;
15151 else if (strcmp (p
, "thread") != 0)
15153 c_parser_consume_token (parser
);
15154 parens
.skip_until_found_close (parser
);
15155 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
15156 c
= build_omp_clause (loc
, OMP_CLAUSE_BIND
);
15157 OMP_CLAUSE_BIND_KIND (c
) = kind
;
15158 OMP_CLAUSE_CHAIN (c
) = list
;
15167 ordered ( constant-expression ) */
15170 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
15172 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
15174 tree c
, num
= NULL_TREE
;
15176 location_t loc
= c_parser_peek_token (parser
)->location
;
15177 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
15179 matching_parens parens
;
15180 parens
.consume_open (parser
);
15181 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
15182 parens
.skip_until_found_close (parser
);
15184 if (num
== error_mark_node
)
15188 mark_exp_read (num
);
15189 num
= c_fully_fold (num
, false, NULL
);
15190 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
15191 || !tree_fits_shwi_p (num
)
15192 || (n
= tree_to_shwi (num
)) <= 0
15195 error_at (loc
, "ordered argument needs positive "
15196 "constant integer expression");
15200 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
15201 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
15202 OMP_CLAUSE_CHAIN (c
) = list
;
15207 private ( variable-list ) */
15210 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
15212 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
15216 reduction ( reduction-operator : variable-list )
15218 reduction-operator:
15219 One of: + * - & ^ | && ||
15223 reduction-operator:
15224 One of: + * - & ^ | && || max min
15228 reduction-operator:
15229 One of: + * - & ^ | && ||
15233 reduction ( reduction-modifier, reduction-operator : variable-list )
15234 in_reduction ( reduction-operator : variable-list )
15235 task_reduction ( reduction-operator : variable-list ) */
15238 c_parser_omp_clause_reduction (c_parser
*parser
, enum omp_clause_code kind
,
15239 bool is_omp
, tree list
)
15241 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15242 matching_parens parens
;
15243 if (parens
.require_open (parser
))
15246 bool inscan
= false;
15247 enum tree_code code
= ERROR_MARK
;
15248 tree reduc_id
= NULL_TREE
;
15250 if (kind
== OMP_CLAUSE_REDUCTION
&& is_omp
)
15252 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
15253 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
15255 c_parser_consume_token (parser
);
15256 c_parser_consume_token (parser
);
15258 else if (c_parser_next_token_is (parser
, CPP_NAME
)
15259 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
15262 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15263 if (strcmp (p
, "task") == 0)
15265 else if (strcmp (p
, "inscan") == 0)
15267 if (task
|| inscan
)
15269 c_parser_consume_token (parser
);
15270 c_parser_consume_token (parser
);
15275 switch (c_parser_peek_token (parser
)->type
)
15287 code
= BIT_AND_EXPR
;
15290 code
= BIT_XOR_EXPR
;
15293 code
= BIT_IOR_EXPR
;
15296 code
= TRUTH_ANDIF_EXPR
;
15299 code
= TRUTH_ORIF_EXPR
;
15304 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15305 if (strcmp (p
, "min") == 0)
15310 if (strcmp (p
, "max") == 0)
15315 reduc_id
= c_parser_peek_token (parser
)->value
;
15319 c_parser_error (parser
,
15320 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
15321 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
15322 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
15325 c_parser_consume_token (parser
);
15326 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
15327 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15331 nl
= c_parser_omp_variable_list (parser
, clause_loc
, kind
, list
);
15332 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15334 tree d
= OMP_CLAUSE_DECL (c
), type
;
15335 if (TREE_CODE (d
) != TREE_LIST
)
15336 type
= TREE_TYPE (d
);
15341 for (t
= d
; TREE_CODE (t
) == TREE_LIST
; t
= TREE_CHAIN (t
))
15343 type
= TREE_TYPE (t
);
15346 if (TREE_CODE (type
) != POINTER_TYPE
15347 && TREE_CODE (type
) != ARRAY_TYPE
)
15349 type
= TREE_TYPE (type
);
15353 while (TREE_CODE (type
) == ARRAY_TYPE
)
15354 type
= TREE_TYPE (type
);
15355 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
15357 OMP_CLAUSE_REDUCTION_TASK (c
) = 1;
15359 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 1;
15360 if (code
== ERROR_MARK
15361 || !(INTEGRAL_TYPE_P (type
)
15362 || TREE_CODE (type
) == REAL_TYPE
15363 || TREE_CODE (type
) == COMPLEX_TYPE
))
15364 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
15365 = c_omp_reduction_lookup (reduc_id
,
15366 TYPE_MAIN_VARIANT (type
));
15371 parens
.skip_until_found_close (parser
);
15377 schedule ( schedule-kind )
15378 schedule ( schedule-kind , expression )
15381 static | dynamic | guided | runtime | auto
15384 schedule ( schedule-modifier : schedule-kind )
15385 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15393 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
15396 location_t loc
= c_parser_peek_token (parser
)->location
;
15397 int modifiers
= 0, nmodifiers
= 0;
15399 matching_parens parens
;
15400 if (!parens
.require_open (parser
))
15403 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
15405 location_t comma
= UNKNOWN_LOCATION
;
15406 while (c_parser_next_token_is (parser
, CPP_NAME
))
15408 tree kind
= c_parser_peek_token (parser
)->value
;
15409 const char *p
= IDENTIFIER_POINTER (kind
);
15410 if (strcmp ("simd", p
) == 0)
15411 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
15412 else if (strcmp ("monotonic", p
) == 0)
15413 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
15414 else if (strcmp ("nonmonotonic", p
) == 0)
15415 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
15418 comma
= UNKNOWN_LOCATION
;
15419 c_parser_consume_token (parser
);
15420 if (nmodifiers
++ == 0
15421 && c_parser_next_token_is (parser
, CPP_COMMA
))
15423 comma
= c_parser_peek_token (parser
)->location
;
15424 c_parser_consume_token (parser
);
15428 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
15432 if (comma
!= UNKNOWN_LOCATION
)
15433 error_at (comma
, "expected %<:%>");
15435 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
15436 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
15437 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15438 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
15440 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15445 if (c_parser_next_token_is (parser
, CPP_NAME
))
15447 tree kind
= c_parser_peek_token (parser
)->value
;
15448 const char *p
= IDENTIFIER_POINTER (kind
);
15453 if (strcmp ("dynamic", p
) != 0)
15455 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
15459 if (strcmp ("guided", p
) != 0)
15461 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
15465 if (strcmp ("runtime", p
) != 0)
15467 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
15474 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
15475 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
15476 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
15477 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
15481 c_parser_consume_token (parser
);
15482 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15485 c_parser_consume_token (parser
);
15487 here
= c_parser_peek_token (parser
)->location
;
15488 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15489 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
15491 t
= c_fully_fold (t
, false, NULL
);
15493 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
15494 error_at (here
, "schedule %<runtime%> does not take "
15495 "a %<chunk_size%> parameter");
15496 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
15498 "schedule %<auto%> does not take "
15499 "a %<chunk_size%> parameter");
15500 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
)
15502 /* Attempt to statically determine when the number isn't
15504 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
15505 build_int_cst (TREE_TYPE (t
), 0));
15506 protected_set_expr_location (s
, loc
);
15507 if (s
== boolean_true_node
)
15509 warning_at (loc
, 0,
15510 "chunk size value must be positive");
15511 t
= integer_one_node
;
15513 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
15516 c_parser_error (parser
, "expected integer expression");
15518 parens
.skip_until_found_close (parser
);
15521 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15522 "expected %<,%> or %<)%>");
15524 OMP_CLAUSE_SCHEDULE_KIND (c
)
15525 = (enum omp_clause_schedule_kind
)
15526 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
15528 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
15529 OMP_CLAUSE_CHAIN (c
) = list
;
15533 c_parser_error (parser
, "invalid schedule kind");
15534 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
15539 shared ( variable-list ) */
15542 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
15544 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
15551 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
15555 /* FIXME: Should we allow duplicates? */
15556 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
15558 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
15559 OMP_CLAUSE_UNTIED
);
15560 OMP_CLAUSE_CHAIN (c
) = list
;
15570 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
15571 enum omp_clause_code code
, tree list
)
15573 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15575 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15576 OMP_CLAUSE_CHAIN (c
) = list
;
15588 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
15589 enum omp_clause_code code
, tree list
)
15591 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15592 OMP_CLAUSE_CHAIN (c
) = list
;
15601 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
15603 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
15604 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
15605 OMP_CLAUSE_NOGROUP
);
15606 OMP_CLAUSE_CHAIN (c
) = list
;
15615 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
15616 enum omp_clause_code code
, tree list
)
15618 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15619 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15620 OMP_CLAUSE_CHAIN (c
) = list
;
15625 num_teams ( expression )
15628 num_teams ( expression : expression ) */
15631 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
15633 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
15634 matching_parens parens
;
15635 if (parens
.require_open (parser
))
15637 location_t upper_loc
= c_parser_peek_token (parser
)->location
;
15638 location_t lower_loc
= UNKNOWN_LOCATION
;
15639 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15640 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
15641 tree c
, upper
= expr
.value
, lower
= NULL_TREE
;
15642 upper
= c_fully_fold (upper
, false, NULL
);
15644 if (c_parser_next_token_is (parser
, CPP_COLON
))
15646 c_parser_consume_token (parser
);
15647 lower_loc
= upper_loc
;
15649 upper_loc
= c_parser_peek_token (parser
)->location
;
15650 expr
= c_parser_expr_no_commas (parser
, NULL
);
15651 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
15652 upper
= expr
.value
;
15653 upper
= c_fully_fold (upper
, false, NULL
);
15656 parens
.skip_until_found_close (parser
);
15658 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper
))
15659 || (lower
&& !INTEGRAL_TYPE_P (TREE_TYPE (lower
))))
15661 c_parser_error (parser
, "expected integer expression");
15665 /* Attempt to statically determine when the number isn't positive. */
15666 c
= fold_build2_loc (upper_loc
, LE_EXPR
, boolean_type_node
, upper
,
15667 build_int_cst (TREE_TYPE (upper
), 0));
15668 protected_set_expr_location (c
, upper_loc
);
15669 if (c
== boolean_true_node
)
15671 warning_at (upper_loc
, 0, "%<num_teams%> value must be positive");
15672 upper
= integer_one_node
;
15676 c
= fold_build2_loc (lower_loc
, LE_EXPR
, boolean_type_node
, lower
,
15677 build_int_cst (TREE_TYPE (lower
), 0));
15678 protected_set_expr_location (c
, lower_loc
);
15679 if (c
== boolean_true_node
)
15681 warning_at (lower_loc
, 0, "%<num_teams%> value must be positive");
15684 else if (TREE_CODE (lower
) == INTEGER_CST
15685 && TREE_CODE (upper
) == INTEGER_CST
15686 && tree_int_cst_lt (upper
, lower
))
15688 warning_at (lower_loc
, 0, "%<num_teams%> lower bound %qE bigger "
15689 "than upper bound %qE", lower
, upper
);
15694 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
15696 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
15697 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c
) = upper
;
15698 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
) = lower
;
15699 OMP_CLAUSE_CHAIN (c
) = list
;
15707 thread_limit ( expression ) */
15710 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
15712 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
15713 matching_parens parens
;
15714 if (parens
.require_open (parser
))
15716 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15717 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15718 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15719 tree c
, t
= expr
.value
;
15720 t
= c_fully_fold (t
, false, NULL
);
15722 parens
.skip_until_found_close (parser
);
15724 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15726 c_parser_error (parser
, "expected integer expression");
15730 /* Attempt to statically determine when the number isn't positive. */
15731 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
15732 build_int_cst (TREE_TYPE (t
), 0));
15733 protected_set_expr_location (c
, expr_loc
);
15734 if (c
== boolean_true_node
)
15736 warning_at (expr_loc
, 0, "%<thread_limit%> value must be positive");
15737 t
= integer_one_node
;
15740 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
15743 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
15744 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
15745 OMP_CLAUSE_CHAIN (c
) = list
;
15753 aligned ( variable-list )
15754 aligned ( variable-list : constant-expression ) */
15757 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
15759 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15762 matching_parens parens
;
15763 if (!parens
.require_open (parser
))
15766 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15767 OMP_CLAUSE_ALIGNED
, list
);
15769 if (c_parser_next_token_is (parser
, CPP_COLON
))
15771 c_parser_consume_token (parser
);
15772 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15773 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15774 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15775 tree alignment
= expr
.value
;
15776 alignment
= c_fully_fold (alignment
, false, NULL
);
15777 if (TREE_CODE (alignment
) != INTEGER_CST
15778 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
15779 || tree_int_cst_sgn (alignment
) != 1)
15781 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
15782 "be positive constant integer expression");
15783 alignment
= NULL_TREE
;
15786 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15787 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
15790 parens
.skip_until_found_close (parser
);
15795 allocate ( variable-list )
15796 allocate ( expression : variable-list )
15799 allocate ( allocator-modifier : variable-list )
15800 allocate ( allocator-modifier , allocator-modifier : variable-list )
15802 allocator-modifier:
15803 allocator ( expression )
15804 align ( expression ) */
15807 c_parser_omp_clause_allocate (c_parser
*parser
, tree list
)
15809 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15811 tree allocator
= NULL_TREE
;
15812 tree align
= NULL_TREE
;
15814 matching_parens parens
;
15815 if (!parens
.require_open (parser
))
15818 if ((c_parser_next_token_is_not (parser
, CPP_NAME
)
15819 && c_parser_next_token_is_not (parser
, CPP_KEYWORD
))
15820 || (c_parser_peek_2nd_token (parser
)->type
!= CPP_COMMA
15821 && c_parser_peek_2nd_token (parser
)->type
!= CPP_CLOSE_PAREN
))
15823 bool has_modifiers
= false;
15824 tree orig_type
= NULL_TREE
;
15825 if (c_parser_next_token_is (parser
, CPP_NAME
)
15826 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
15828 unsigned int n
= 3;
15830 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15831 if ((strcmp (p
, "allocator") == 0 || strcmp (p
, "align") == 0)
15832 && c_parser_check_balanced_raw_token_sequence (parser
, &n
)
15833 && (c_parser_peek_nth_token_raw (parser
, n
)->type
15834 == CPP_CLOSE_PAREN
))
15836 if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
15838 has_modifiers
= true;
15839 else if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
15841 && (c_parser_peek_nth_token_raw (parser
, n
+ 2)->type
15843 && (c_parser_peek_nth_token_raw (parser
, n
+ 3)->type
15844 == CPP_OPEN_PAREN
))
15846 c_token
*tok
= c_parser_peek_nth_token_raw (parser
, n
+ 2);
15847 const char *q
= IDENTIFIER_POINTER (tok
->value
);
15849 if ((strcmp (q
, "allocator") == 0
15850 || strcmp (q
, "align") == 0)
15851 && c_parser_check_balanced_raw_token_sequence (parser
,
15853 && (c_parser_peek_nth_token_raw (parser
, n
)->type
15854 == CPP_CLOSE_PAREN
)
15855 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
15857 has_modifiers
= true;
15862 c_parser_consume_token (parser
);
15863 matching_parens parens2
;;
15864 parens2
.require_open (parser
);
15865 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15866 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15867 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15868 if (strcmp (p
, "allocator") == 0)
15870 allocator
= expr
.value
;
15871 allocator
= c_fully_fold (allocator
, false, NULL
);
15872 orig_type
= expr
.original_type
15873 ? expr
.original_type
: TREE_TYPE (allocator
);
15874 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
15878 align
= expr
.value
;
15879 align
= c_fully_fold (align
, false, NULL
);
15881 parens2
.skip_until_found_close (parser
);
15882 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15884 c_parser_consume_token (parser
);
15885 c_token
*tok
= c_parser_peek_token (parser
);
15886 const char *q
= "";
15887 if (c_parser_next_token_is (parser
, CPP_NAME
))
15888 q
= IDENTIFIER_POINTER (tok
->value
);
15889 if (strcmp (q
, "allocator") != 0 && strcmp (q
, "align") != 0)
15891 c_parser_error (parser
, "expected %<allocator%> or "
15893 parens
.skip_until_found_close (parser
);
15896 else if (strcmp (p
, q
) == 0)
15898 error_at (tok
->location
, "duplicate %qs modifier", p
);
15899 parens
.skip_until_found_close (parser
);
15902 c_parser_consume_token (parser
);
15903 if (!parens2
.require_open (parser
))
15905 parens
.skip_until_found_close (parser
);
15908 expr_loc
= c_parser_peek_token (parser
)->location
;
15909 expr
= c_parser_expr_no_commas (parser
, NULL
);
15910 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
15912 if (strcmp (q
, "allocator") == 0)
15914 allocator
= expr
.value
;
15915 allocator
= c_fully_fold (allocator
, false, NULL
);
15916 orig_type
= expr
.original_type
15917 ? expr
.original_type
: TREE_TYPE (allocator
);
15918 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
15922 align
= expr
.value
;
15923 align
= c_fully_fold (align
, false, NULL
);
15925 parens2
.skip_until_found_close (parser
);
15929 if (!has_modifiers
)
15931 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15932 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15933 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15934 allocator
= expr
.value
;
15935 allocator
= c_fully_fold (allocator
, false, NULL
);
15936 orig_type
= expr
.original_type
15937 ? expr
.original_type
: TREE_TYPE (allocator
);
15938 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
15941 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
15942 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
15943 || (TYPE_NAME (orig_type
)
15944 != get_identifier ("omp_allocator_handle_t"))))
15946 error_at (clause_loc
, "%<allocate%> clause allocator expression "
15947 "has type %qT rather than "
15948 "%<omp_allocator_handle_t%>",
15949 TREE_TYPE (allocator
));
15950 allocator
= NULL_TREE
;
15953 && (!INTEGRAL_TYPE_P (TREE_TYPE (align
))
15954 || !tree_fits_uhwi_p (align
)
15955 || !integer_pow2p (align
)))
15957 error_at (clause_loc
, "%<allocate%> clause %<align%> modifier "
15958 "argument needs to be positive constant "
15959 "power of two integer expression");
15962 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15964 parens
.skip_until_found_close (parser
);
15969 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15970 OMP_CLAUSE_ALLOCATE
, list
);
15972 if (allocator
|| align
)
15973 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15975 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
15976 OMP_CLAUSE_ALLOCATE_ALIGN (c
) = align
;
15979 parens
.skip_until_found_close (parser
);
15984 linear ( variable-list )
15985 linear ( variable-list : expression )
15988 linear ( modifier ( variable-list ) )
15989 linear ( modifier ( variable-list ) : expression )
15995 linear ( variable-list : modifiers-list )
15999 step ( expression ) */
16002 c_parser_omp_clause_linear (c_parser
*parser
, tree list
)
16004 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16006 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
16007 bool old_linear_modifier
= false;
16009 matching_parens parens
;
16010 if (!parens
.require_open (parser
))
16013 if (c_parser_next_token_is (parser
, CPP_NAME
))
16015 c_token
*tok
= c_parser_peek_token (parser
);
16016 const char *p
= IDENTIFIER_POINTER (tok
->value
);
16017 if (strcmp ("val", p
) == 0)
16018 kind
= OMP_CLAUSE_LINEAR_VAL
;
16019 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
16020 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
16021 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
16023 old_linear_modifier
= true;
16024 c_parser_consume_token (parser
);
16025 c_parser_consume_token (parser
);
16029 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
16030 OMP_CLAUSE_LINEAR
, list
);
16032 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
16033 parens
.skip_until_found_close (parser
);
16035 if (c_parser_next_token_is (parser
, CPP_COLON
))
16037 c_parser_consume_token (parser
);
16038 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16039 bool has_modifiers
= false;
16040 if (kind
== OMP_CLAUSE_LINEAR_DEFAULT
16041 && c_parser_next_token_is (parser
, CPP_NAME
))
16043 c_token
*tok
= c_parser_peek_token (parser
);
16044 const char *p
= IDENTIFIER_POINTER (tok
->value
);
16045 unsigned int pos
= 0;
16046 if (strcmp ("val", p
) == 0)
16048 else if (strcmp ("step", p
) == 0
16049 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
16052 if (c_parser_check_balanced_raw_token_sequence (parser
, &pos
)
16053 && (c_parser_peek_nth_token_raw (parser
, pos
)->type
16054 == CPP_CLOSE_PAREN
))
16061 tok
= c_parser_peek_nth_token_raw (parser
, pos
);
16062 if (tok
->type
== CPP_COMMA
|| tok
->type
== CPP_CLOSE_PAREN
)
16063 has_modifiers
= true;
16069 while (c_parser_next_token_is (parser
, CPP_NAME
))
16071 c_token
*tok
= c_parser_peek_token (parser
);
16072 const char *p
= IDENTIFIER_POINTER (tok
->value
);
16073 if (strcmp ("val", p
) == 0)
16075 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
16076 error_at (tok
->location
, "multiple linear modifiers");
16077 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
16078 c_parser_consume_token (parser
);
16080 else if (strcmp ("step", p
) == 0)
16082 c_parser_consume_token (parser
);
16083 matching_parens parens2
;
16084 if (parens2
.require_open (parser
))
16087 error_at (tok
->location
,
16088 "multiple %<step%> modifiers");
16089 expr_loc
= c_parser_peek_token (parser
)->location
;
16090 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16091 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
16093 step
= c_fully_fold (expr
.value
, false, NULL
);
16094 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
16096 error_at (clause_loc
, "%<linear%> clause step "
16097 "expression must be integral");
16098 step
= integer_one_node
;
16100 parens2
.skip_until_found_close (parser
);
16107 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16109 c_parser_consume_token (parser
);
16115 step
= integer_one_node
;
16119 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16120 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16121 step
= c_fully_fold (expr
.value
, false, NULL
);
16122 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
16124 error_at (clause_loc
, "%<linear%> clause step expression must "
16126 step
= integer_one_node
;
16132 step
= integer_one_node
;
16134 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16136 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
16137 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
16138 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c
) = old_linear_modifier
;
16141 parens
.skip_until_found_close (parser
);
16146 nontemporal ( variable-list ) */
16149 c_parser_omp_clause_nontemporal (c_parser
*parser
, tree list
)
16151 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_NONTEMPORAL
, list
);
16155 safelen ( constant-expression ) */
16158 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
16160 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16163 matching_parens parens
;
16164 if (!parens
.require_open (parser
))
16167 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16168 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16169 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16171 t
= c_fully_fold (t
, false, NULL
);
16172 if (TREE_CODE (t
) != INTEGER_CST
16173 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
16174 || tree_int_cst_sgn (t
) != 1)
16176 error_at (clause_loc
, "%<safelen%> clause expression must "
16177 "be positive constant integer expression");
16181 parens
.skip_until_found_close (parser
);
16182 if (t
== NULL_TREE
|| t
== error_mark_node
)
16185 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
16187 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
16188 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
16189 OMP_CLAUSE_CHAIN (c
) = list
;
16194 simdlen ( constant-expression ) */
16197 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
16199 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16202 matching_parens parens
;
16203 if (!parens
.require_open (parser
))
16206 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16207 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16208 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16210 t
= c_fully_fold (t
, false, NULL
);
16211 if (TREE_CODE (t
) != INTEGER_CST
16212 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
16213 || tree_int_cst_sgn (t
) != 1)
16215 error_at (clause_loc
, "%<simdlen%> clause expression must "
16216 "be positive constant integer expression");
16220 parens
.skip_until_found_close (parser
);
16221 if (t
== NULL_TREE
|| t
== error_mark_node
)
16224 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
16226 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
16227 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
16228 OMP_CLAUSE_CHAIN (c
) = list
;
16234 identifier [+/- integer]
16235 vec , identifier [+/- integer]
16239 c_parser_omp_clause_doacross_sink (c_parser
*parser
, location_t clause_loc
,
16240 tree list
, bool depend_p
)
16243 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
16244 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
16246 c_parser_error (parser
, "expected identifier");
16252 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16253 if (strcmp (p
, "omp_cur_iteration") == 0
16254 && c_parser_peek_2nd_token (parser
)->type
== CPP_MINUS
16255 && c_parser_peek_nth_token (parser
, 3)->type
== CPP_NUMBER
16256 && c_parser_peek_nth_token (parser
, 4)->type
== CPP_CLOSE_PAREN
)
16258 tree val
= c_parser_peek_nth_token (parser
, 3)->value
;
16259 if (integer_onep (val
))
16261 c_parser_consume_token (parser
);
16262 c_parser_consume_token (parser
);
16263 c_parser_consume_token (parser
);
16264 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
16265 OMP_CLAUSE_DOACROSS_KIND (u
) = OMP_CLAUSE_DOACROSS_SINK
;
16266 OMP_CLAUSE_CHAIN (u
) = list
;
16274 while (c_parser_next_token_is (parser
, CPP_NAME
)
16275 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
16277 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
16278 tree addend
= NULL
;
16280 if (t
== NULL_TREE
)
16282 undeclared_variable (c_parser_peek_token (parser
)->location
,
16283 c_parser_peek_token (parser
)->value
);
16284 t
= error_mark_node
;
16287 c_parser_consume_token (parser
);
16290 if (c_parser_next_token_is (parser
, CPP_MINUS
))
16292 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
16294 addend
= integer_zero_node
;
16296 goto add_to_vector
;
16298 c_parser_consume_token (parser
);
16300 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
16302 c_parser_error (parser
, "expected integer");
16306 addend
= c_parser_peek_token (parser
)->value
;
16307 if (TREE_CODE (addend
) != INTEGER_CST
)
16309 c_parser_error (parser
, "expected integer");
16312 c_parser_consume_token (parser
);
16315 if (t
!= error_mark_node
)
16317 vec
= tree_cons (addend
, t
, vec
);
16319 OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec
) = 1;
16322 if (c_parser_next_token_is_not (parser
, CPP_COMMA
)
16323 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
16324 || c_parser_peek_2nd_token (parser
)->id_kind
!= C_ID_ID
)
16327 c_parser_consume_token (parser
);
16330 if (vec
== NULL_TREE
)
16333 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
16334 OMP_CLAUSE_DOACROSS_KIND (u
) = OMP_CLAUSE_DOACROSS_SINK
;
16335 OMP_CLAUSE_DOACROSS_DEPEND (u
) = depend_p
;
16336 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
16337 OMP_CLAUSE_CHAIN (u
) = list
;
16342 iterators ( iterators-definition )
16344 iterators-definition:
16346 iterator-specifier , iterators-definition
16348 iterator-specifier:
16349 identifier = range-specification
16350 iterator-type identifier = range-specification
16352 range-specification:
16354 begin : end : step */
16357 c_parser_omp_iterators (c_parser
*parser
)
16359 tree ret
= NULL_TREE
, *last
= &ret
;
16360 c_parser_consume_token (parser
);
16364 matching_parens parens
;
16365 if (!parens
.require_open (parser
))
16366 return error_mark_node
;
16370 tree iter_type
= NULL_TREE
, type_expr
= NULL_TREE
;
16371 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
16373 struct c_type_name
*type
= c_parser_type_name (parser
);
16375 iter_type
= groktypename (type
, &type_expr
, NULL
);
16377 if (iter_type
== NULL_TREE
)
16378 iter_type
= integer_type_node
;
16380 location_t loc
= c_parser_peek_token (parser
)->location
;
16381 if (!c_parser_next_token_is (parser
, CPP_NAME
))
16383 c_parser_error (parser
, "expected identifier");
16387 tree id
= c_parser_peek_token (parser
)->value
;
16388 c_parser_consume_token (parser
);
16390 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
16393 location_t eloc
= c_parser_peek_token (parser
)->location
;
16394 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16395 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
16396 tree begin
= expr
.value
;
16398 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16401 eloc
= c_parser_peek_token (parser
)->location
;
16402 expr
= c_parser_expr_no_commas (parser
, NULL
);
16403 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
16404 tree end
= expr
.value
;
16406 tree step
= integer_one_node
;
16407 if (c_parser_next_token_is (parser
, CPP_COLON
))
16409 c_parser_consume_token (parser
);
16410 eloc
= c_parser_peek_token (parser
)->location
;
16411 expr
= c_parser_expr_no_commas (parser
, NULL
);
16412 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
16416 tree iter_var
= build_decl (loc
, VAR_DECL
, id
, iter_type
);
16417 DECL_ARTIFICIAL (iter_var
) = 1;
16418 DECL_CONTEXT (iter_var
) = current_function_decl
;
16419 pushdecl (iter_var
);
16421 *last
= make_tree_vec (6);
16422 TREE_VEC_ELT (*last
, 0) = iter_var
;
16423 TREE_VEC_ELT (*last
, 1) = begin
;
16424 TREE_VEC_ELT (*last
, 2) = end
;
16425 TREE_VEC_ELT (*last
, 3) = step
;
16426 last
= &TREE_CHAIN (*last
);
16428 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16430 c_parser_consume_token (parser
);
16437 parens
.skip_until_found_close (parser
);
16438 return ret
? ret
: error_mark_node
;
16442 affinity ( [aff-modifier :] variable-list )
16444 iterator ( iterators-definition ) */
16447 c_parser_omp_clause_affinity (c_parser
*parser
, tree list
)
16449 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16450 tree nl
, iterators
= NULL_TREE
;
16452 matching_parens parens
;
16453 if (!parens
.require_open (parser
))
16456 if (c_parser_next_token_is (parser
, CPP_NAME
))
16458 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16459 bool parse_iter
= ((strcmp ("iterator", p
) == 0)
16460 && (c_parser_peek_2nd_token (parser
)->type
16461 == CPP_OPEN_PAREN
));
16465 parse_iter
= (c_parser_check_balanced_raw_token_sequence (parser
, &n
)
16466 && (c_parser_peek_nth_token_raw (parser
, n
)->type
16467 == CPP_CLOSE_PAREN
)
16468 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
16473 iterators
= c_parser_omp_iterators (parser
);
16474 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16478 parens
.skip_until_found_close (parser
);
16483 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_AFFINITY
,
16487 tree block
= pop_scope ();
16488 if (iterators
!= error_mark_node
)
16490 TREE_VEC_ELT (iterators
, 5) = block
;
16491 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16492 OMP_CLAUSE_DECL (c
) = build_tree_list (iterators
,
16493 OMP_CLAUSE_DECL (c
));
16497 parens
.skip_until_found_close (parser
);
16503 depend ( depend-kind: variable-list )
16511 depend ( sink : vec )
16514 depend ( depend-modifier , depend-kind: variable-list )
16517 in | out | inout | mutexinoutset | depobj | inoutset
16520 iterator ( iterators-definition ) */
16523 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
16525 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16526 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_LAST
;
16527 enum omp_clause_doacross_kind dkind
= OMP_CLAUSE_DOACROSS_LAST
;
16528 tree nl
, c
, iterators
= NULL_TREE
;
16530 matching_parens parens
;
16531 if (!parens
.require_open (parser
))
16536 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
16539 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16540 if (strcmp ("iterator", p
) == 0 && iterators
== NULL_TREE
)
16542 iterators
= c_parser_omp_iterators (parser
);
16543 c_parser_require (parser
, CPP_COMMA
, "expected %<,%>");
16546 if (strcmp ("in", p
) == 0)
16547 kind
= OMP_CLAUSE_DEPEND_IN
;
16548 else if (strcmp ("inout", p
) == 0)
16549 kind
= OMP_CLAUSE_DEPEND_INOUT
;
16550 else if (strcmp ("inoutset", p
) == 0)
16551 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
16552 else if (strcmp ("mutexinoutset", p
) == 0)
16553 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
16554 else if (strcmp ("out", p
) == 0)
16555 kind
= OMP_CLAUSE_DEPEND_OUT
;
16556 else if (strcmp ("depobj", p
) == 0)
16557 kind
= OMP_CLAUSE_DEPEND_DEPOBJ
;
16558 else if (strcmp ("sink", p
) == 0)
16559 dkind
= OMP_CLAUSE_DOACROSS_SINK
;
16560 else if (strcmp ("source", p
) == 0)
16561 dkind
= OMP_CLAUSE_DOACROSS_SOURCE
;
16568 c_parser_consume_token (parser
);
16571 && (dkind
== OMP_CLAUSE_DOACROSS_SOURCE
16572 || dkind
== OMP_CLAUSE_DOACROSS_SINK
))
16575 error_at (clause_loc
, "%<iterator%> modifier incompatible with %qs",
16576 dkind
== OMP_CLAUSE_DOACROSS_SOURCE
? "source" : "sink");
16577 iterators
= NULL_TREE
;
16580 if (dkind
== OMP_CLAUSE_DOACROSS_SOURCE
)
16582 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
16583 OMP_CLAUSE_DOACROSS_KIND (c
) = dkind
;
16584 OMP_CLAUSE_DOACROSS_DEPEND (c
) = 1;
16585 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
16586 OMP_CLAUSE_CHAIN (c
) = list
;
16587 parens
.skip_until_found_close (parser
);
16591 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16594 if (dkind
== OMP_CLAUSE_DOACROSS_SINK
)
16595 nl
= c_parser_omp_clause_doacross_sink (parser
, clause_loc
, list
, true);
16598 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
16599 OMP_CLAUSE_DEPEND
, list
);
16603 tree block
= pop_scope ();
16604 if (iterators
== error_mark_node
)
16605 iterators
= NULL_TREE
;
16607 TREE_VEC_ELT (iterators
, 5) = block
;
16610 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16612 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
16614 OMP_CLAUSE_DECL (c
)
16615 = build_tree_list (iterators
, OMP_CLAUSE_DECL (c
));
16619 parens
.skip_until_found_close (parser
);
16623 c_parser_error (parser
, "invalid depend kind");
16625 parens
.skip_until_found_close (parser
);
16632 doacross ( source : )
16633 doacross ( source : omp_cur_iteration )
16635 doacross ( sink : vec )
16636 doacross ( sink : omp_cur_iteration - logical_iteration ) */
16639 c_parser_omp_clause_doacross (c_parser
*parser
, tree list
)
16641 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16642 enum omp_clause_doacross_kind kind
= OMP_CLAUSE_DOACROSS_LAST
;
16646 matching_parens parens
;
16647 if (!parens
.require_open (parser
))
16650 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
16653 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16654 if (strcmp ("sink", p
) == 0)
16655 kind
= OMP_CLAUSE_DOACROSS_SINK
;
16656 else if (strcmp ("source", p
) == 0)
16657 kind
= OMP_CLAUSE_DOACROSS_SOURCE
;
16661 c_parser_consume_token (parser
);
16663 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16666 if (kind
== OMP_CLAUSE_DOACROSS_SOURCE
)
16668 if (c_parser_next_token_is (parser
, CPP_NAME
)
16669 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
16670 "omp_cur_iteration") == 0)
16671 c_parser_consume_token (parser
);
16672 nl
= build_omp_clause (clause_loc
, OMP_CLAUSE_DOACROSS
);
16673 OMP_CLAUSE_DOACROSS_KIND (nl
) = OMP_CLAUSE_DOACROSS_SOURCE
;
16674 OMP_CLAUSE_DECL (nl
) = NULL_TREE
;
16675 OMP_CLAUSE_CHAIN (nl
) = list
;
16678 nl
= c_parser_omp_clause_doacross_sink (parser
, clause_loc
, list
, false);
16680 parens
.skip_until_found_close (parser
);
16684 c_parser_error (parser
, "invalid doacross kind");
16686 parens
.skip_until_found_close (parser
);
16691 map ( map-kind: variable-list )
16692 map ( variable-list )
16695 alloc | to | from | tofrom
16699 alloc | to | from | tofrom | release | delete
16701 map ( always [,] map-kind: variable-list )
16704 map ( [map-type-modifier[,] ...] map-kind: variable-list )
16710 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
16712 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16713 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
16716 matching_parens parens
;
16717 if (!parens
.require_open (parser
))
16721 int map_kind_pos
= 0;
16722 while (c_parser_peek_nth_token_raw (parser
, pos
)->type
== CPP_NAME
)
16724 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COLON
)
16726 map_kind_pos
= pos
;
16730 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COMMA
)
16735 int always_modifier
= 0;
16736 int close_modifier
= 0;
16737 for (int pos
= 1; pos
< map_kind_pos
; ++pos
)
16739 c_token
*tok
= c_parser_peek_token (parser
);
16741 if (tok
->type
== CPP_COMMA
)
16743 c_parser_consume_token (parser
);
16747 const char *p
= IDENTIFIER_POINTER (tok
->value
);
16748 if (strcmp ("always", p
) == 0)
16750 if (always_modifier
)
16752 c_parser_error (parser
, "too many %<always%> modifiers");
16753 parens
.skip_until_found_close (parser
);
16758 else if (strcmp ("close", p
) == 0)
16760 if (close_modifier
)
16762 c_parser_error (parser
, "too many %<close%> modifiers");
16763 parens
.skip_until_found_close (parser
);
16770 c_parser_error (parser
, "%<#pragma omp target%> with "
16771 "modifier other than %<always%> or "
16772 "%<close%> on %<map%> clause");
16773 parens
.skip_until_found_close (parser
);
16777 c_parser_consume_token (parser
);
16780 if (c_parser_next_token_is (parser
, CPP_NAME
)
16781 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16783 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16784 if (strcmp ("alloc", p
) == 0)
16785 kind
= GOMP_MAP_ALLOC
;
16786 else if (strcmp ("to", p
) == 0)
16787 kind
= always_modifier
? GOMP_MAP_ALWAYS_TO
: GOMP_MAP_TO
;
16788 else if (strcmp ("from", p
) == 0)
16789 kind
= always_modifier
? GOMP_MAP_ALWAYS_FROM
: GOMP_MAP_FROM
;
16790 else if (strcmp ("tofrom", p
) == 0)
16791 kind
= always_modifier
? GOMP_MAP_ALWAYS_TOFROM
: GOMP_MAP_TOFROM
;
16792 else if (strcmp ("release", p
) == 0)
16793 kind
= GOMP_MAP_RELEASE
;
16794 else if (strcmp ("delete", p
) == 0)
16795 kind
= GOMP_MAP_DELETE
;
16798 c_parser_error (parser
, "invalid map kind");
16799 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
16803 c_parser_consume_token (parser
);
16804 c_parser_consume_token (parser
);
16807 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
,
16810 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16811 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
16813 parens
.skip_until_found_close (parser
);
16818 device ( expression )
16821 device ( [device-modifier :] integer-expression )
16824 ancestor | device_num */
16827 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
16829 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16830 location_t expr_loc
;
16833 bool ancestor
= false;
16835 matching_parens parens
;
16836 if (!parens
.require_open (parser
))
16839 if (c_parser_next_token_is (parser
, CPP_NAME
)
16840 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16842 c_token
*tok
= c_parser_peek_token (parser
);
16843 const char *p
= IDENTIFIER_POINTER (tok
->value
);
16844 if (strcmp ("ancestor", p
) == 0)
16846 /* A requires directive with the reverse_offload clause must be
16848 if ((omp_requires_mask
& OMP_REQUIRES_REVERSE_OFFLOAD
) == 0)
16850 error_at (tok
->location
, "%<ancestor%> device modifier not "
16851 "preceded by %<requires%> directive "
16852 "with %<reverse_offload%> clause");
16853 parens
.skip_until_found_close (parser
);
16858 else if (strcmp ("device_num", p
) == 0)
16862 error_at (tok
->location
, "expected %<ancestor%> or %<device_num%>");
16863 parens
.skip_until_found_close (parser
);
16866 c_parser_consume_token (parser
);
16867 c_parser_consume_token (parser
);
16870 expr_loc
= c_parser_peek_token (parser
)->location
;
16871 expr
= c_parser_expr_no_commas (parser
, NULL
);
16872 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16874 t
= c_fully_fold (t
, false, NULL
);
16876 parens
.skip_until_found_close (parser
);
16878 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16880 c_parser_error (parser
, "expected integer expression");
16883 if (ancestor
&& TREE_CODE (t
) == INTEGER_CST
&& !integer_onep (t
))
16885 error_at (expr_loc
, "the %<device%> clause expression must evaluate to "
16890 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
16892 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
16894 OMP_CLAUSE_DEVICE_ID (c
) = t
;
16895 OMP_CLAUSE_CHAIN (c
) = list
;
16896 OMP_CLAUSE_DEVICE_ANCESTOR (c
) = ancestor
;
16903 dist_schedule ( static )
16904 dist_schedule ( static , expression ) */
16907 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
16909 tree c
, t
= NULL_TREE
;
16910 location_t loc
= c_parser_peek_token (parser
)->location
;
16912 matching_parens parens
;
16913 if (!parens
.require_open (parser
))
16916 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
16918 c_parser_error (parser
, "invalid dist_schedule kind");
16919 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
16924 c_parser_consume_token (parser
);
16925 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16927 c_parser_consume_token (parser
);
16929 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16930 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16931 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16933 t
= c_fully_fold (t
, false, NULL
);
16934 parens
.skip_until_found_close (parser
);
16937 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
16938 "expected %<,%> or %<)%>");
16940 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
16941 "dist_schedule"); */
16942 if (omp_find_clause (list
, OMP_CLAUSE_DIST_SCHEDULE
))
16943 warning_at (loc
, 0, "too many %qs clauses", "dist_schedule");
16944 if (t
== error_mark_node
)
16947 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
16948 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
16949 OMP_CLAUSE_CHAIN (c
) = list
;
16954 proc_bind ( proc-bind-kind )
16957 primary | master | close | spread
16958 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
16961 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
16963 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16964 enum omp_clause_proc_bind_kind kind
;
16967 matching_parens parens
;
16968 if (!parens
.require_open (parser
))
16971 if (c_parser_next_token_is (parser
, CPP_NAME
))
16973 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16974 if (strcmp ("primary", p
) == 0)
16975 kind
= OMP_CLAUSE_PROC_BIND_PRIMARY
;
16976 else if (strcmp ("master", p
) == 0)
16977 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
16978 else if (strcmp ("close", p
) == 0)
16979 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
16980 else if (strcmp ("spread", p
) == 0)
16981 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
16988 check_no_duplicate_clause (list
, OMP_CLAUSE_PROC_BIND
, "proc_bind");
16989 c_parser_consume_token (parser
);
16990 parens
.skip_until_found_close (parser
);
16991 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
16992 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
16993 OMP_CLAUSE_CHAIN (c
) = list
;
16997 c_parser_error (parser
, "invalid proc_bind kind");
16998 parens
.skip_until_found_close (parser
);
17003 device_type ( host | nohost | any ) */
17006 c_parser_omp_clause_device_type (c_parser
*parser
, tree list
)
17008 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17009 enum omp_clause_device_type_kind kind
;
17012 matching_parens parens
;
17013 if (!parens
.require_open (parser
))
17016 if (c_parser_next_token_is (parser
, CPP_NAME
))
17018 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17019 if (strcmp ("host", p
) == 0)
17020 kind
= OMP_CLAUSE_DEVICE_TYPE_HOST
;
17021 else if (strcmp ("nohost", p
) == 0)
17022 kind
= OMP_CLAUSE_DEVICE_TYPE_NOHOST
;
17023 else if (strcmp ("any", p
) == 0)
17024 kind
= OMP_CLAUSE_DEVICE_TYPE_ANY
;
17031 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE_TYPE
,
17033 c_parser_consume_token (parser
);
17034 parens
.skip_until_found_close (parser
);
17035 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE_TYPE
);
17036 OMP_CLAUSE_DEVICE_TYPE_KIND (c
) = kind
;
17037 OMP_CLAUSE_CHAIN (c
) = list
;
17041 c_parser_error (parser
, "expected %<host%>, %<nohost%> or %<any%>");
17042 parens
.skip_until_found_close (parser
);
17047 to ( variable-list ) */
17050 c_parser_omp_clause_to (c_parser
*parser
, tree list
)
17052 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO
, list
, true);
17056 from ( variable-list ) */
17059 c_parser_omp_clause_from (c_parser
*parser
, tree list
)
17061 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FROM
, list
, true);
17065 uniform ( variable-list ) */
17068 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
17070 /* The clauses location. */
17071 location_t loc
= c_parser_peek_token (parser
)->location
;
17073 matching_parens parens
;
17074 if (parens
.require_open (parser
))
17076 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
17078 parens
.skip_until_found_close (parser
);
17084 detach ( event-handle ) */
17087 c_parser_omp_clause_detach (c_parser
*parser
, tree list
)
17089 matching_parens parens
;
17090 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
17092 if (!parens
.require_open (parser
))
17095 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
17096 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
17098 c_parser_error (parser
, "expected identifier");
17099 parens
.skip_until_found_close (parser
);
17103 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
17104 if (t
== NULL_TREE
)
17106 undeclared_variable (c_parser_peek_token (parser
)->location
,
17107 c_parser_peek_token (parser
)->value
);
17108 parens
.skip_until_found_close (parser
);
17111 c_parser_consume_token (parser
);
17113 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (t
));
17114 if (!INTEGRAL_TYPE_P (type
)
17115 || TREE_CODE (type
) != ENUMERAL_TYPE
17116 || TYPE_NAME (type
) != get_identifier ("omp_event_handle_t"))
17118 error_at (clause_loc
, "%<detach%> clause event handle "
17119 "has type %qT rather than "
17120 "%<omp_event_handle_t%>",
17122 parens
.skip_until_found_close (parser
);
17126 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DETACH
);
17127 OMP_CLAUSE_DECL (u
) = t
;
17128 OMP_CLAUSE_CHAIN (u
) = list
;
17129 parens
.skip_until_found_close (parser
);
17133 /* Parse all OpenACC clauses. The set clauses allowed by the directive
17134 is a bitmask in MASK. Return the list of clauses found. */
17137 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
17138 const char *where
, bool finish_p
= true)
17140 tree clauses
= NULL
;
17143 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17146 pragma_omp_clause c_kind
;
17147 const char *c_name
;
17148 tree prev
= clauses
;
17150 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
17151 c_parser_consume_token (parser
);
17153 here
= c_parser_peek_token (parser
)->location
;
17154 c_kind
= c_parser_omp_clause_name (parser
);
17158 case PRAGMA_OACC_CLAUSE_ASYNC
:
17159 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
17162 case PRAGMA_OACC_CLAUSE_AUTO
:
17163 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_AUTO
,
17167 case PRAGMA_OACC_CLAUSE_ATTACH
:
17168 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17171 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
17172 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
17173 c_name
= "collapse";
17175 case PRAGMA_OACC_CLAUSE_COPY
:
17176 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17179 case PRAGMA_OACC_CLAUSE_COPYIN
:
17180 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17183 case PRAGMA_OACC_CLAUSE_COPYOUT
:
17184 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17185 c_name
= "copyout";
17187 case PRAGMA_OACC_CLAUSE_CREATE
:
17188 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17191 case PRAGMA_OACC_CLAUSE_DELETE
:
17192 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17195 case PRAGMA_OMP_CLAUSE_DEFAULT
:
17196 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
17197 c_name
= "default";
17199 case PRAGMA_OACC_CLAUSE_DETACH
:
17200 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17203 case PRAGMA_OACC_CLAUSE_DEVICE
:
17204 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17207 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
17208 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
17209 c_name
= "deviceptr";
17211 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
17212 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17213 c_name
= "device_resident";
17215 case PRAGMA_OACC_CLAUSE_FINALIZE
:
17216 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_FINALIZE
,
17218 c_name
= "finalize";
17220 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
17221 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
17222 c_name
= "firstprivate";
17224 case PRAGMA_OACC_CLAUSE_GANG
:
17226 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_GANG
,
17229 case PRAGMA_OACC_CLAUSE_HOST
:
17230 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17233 case PRAGMA_OACC_CLAUSE_IF
:
17234 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
17237 case PRAGMA_OACC_CLAUSE_IF_PRESENT
:
17238 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_IF_PRESENT
,
17240 c_name
= "if_present";
17242 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
17243 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_INDEPENDENT
,
17245 c_name
= "independent";
17247 case PRAGMA_OACC_CLAUSE_LINK
:
17248 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17251 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
17252 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17253 c_name
= "no_create";
17255 case PRAGMA_OACC_CLAUSE_NOHOST
:
17256 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_NOHOST
,
17260 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
17261 clauses
= c_parser_oacc_single_int_clause (parser
,
17262 OMP_CLAUSE_NUM_GANGS
,
17264 c_name
= "num_gangs";
17266 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
17267 clauses
= c_parser_oacc_single_int_clause (parser
,
17268 OMP_CLAUSE_NUM_WORKERS
,
17270 c_name
= "num_workers";
17272 case PRAGMA_OACC_CLAUSE_PRESENT
:
17273 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
17274 c_name
= "present";
17276 case PRAGMA_OACC_CLAUSE_PRIVATE
:
17277 clauses
= c_parser_omp_clause_private (parser
, clauses
);
17278 c_name
= "private";
17280 case PRAGMA_OACC_CLAUSE_REDUCTION
:
17282 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
17284 c_name
= "reduction";
17286 case PRAGMA_OACC_CLAUSE_SEQ
:
17287 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_SEQ
,
17291 case PRAGMA_OACC_CLAUSE_TILE
:
17292 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
17295 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
17296 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
17297 c_name
= "use_device";
17299 case PRAGMA_OACC_CLAUSE_VECTOR
:
17301 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_VECTOR
,
17304 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
17305 clauses
= c_parser_oacc_single_int_clause (parser
,
17306 OMP_CLAUSE_VECTOR_LENGTH
,
17308 c_name
= "vector_length";
17310 case PRAGMA_OACC_CLAUSE_WAIT
:
17311 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
17314 case PRAGMA_OACC_CLAUSE_WORKER
:
17316 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_WORKER
,
17320 c_parser_error (parser
, "expected %<#pragma acc%> clause");
17326 if (((mask
>> c_kind
) & 1) == 0)
17328 /* Remove the invalid clause(s) from the list to avoid
17329 confusing the rest of the compiler. */
17331 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
17336 c_parser_skip_to_pragma_eol (parser
);
17339 return c_finish_omp_clauses (clauses
, C_ORT_ACC
);
17344 /* Parse all OpenMP clauses. The set clauses allowed by the directive
17345 is a bitmask in MASK. Return the list of clauses found.
17346 FINISH_P set if c_finish_omp_clauses should be called.
17347 NESTED non-zero if clauses should be terminated by closing paren instead
17348 of end of pragma. If it is 2, additionally commas are required in between
17352 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
17353 const char *where
, bool finish_p
= true,
17356 tree clauses
= NULL
;
17359 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
17362 pragma_omp_clause c_kind
;
17363 const char *c_name
;
17364 tree prev
= clauses
;
17366 if (nested
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
17371 if (c_parser_next_token_is (parser
, CPP_COMMA
))
17372 c_parser_consume_token (parser
);
17373 else if (nested
== 2)
17374 error_at (c_parser_peek_token (parser
)->location
,
17375 "clauses in %<simd%> trait should be separated "
17379 here
= c_parser_peek_token (parser
)->location
;
17380 c_kind
= c_parser_omp_clause_name (parser
);
17384 case PRAGMA_OMP_CLAUSE_BIND
:
17385 clauses
= c_parser_omp_clause_bind (parser
, clauses
);
17388 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
17389 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
17390 c_name
= "collapse";
17392 case PRAGMA_OMP_CLAUSE_COPYIN
:
17393 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
17396 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
17397 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
17398 c_name
= "copyprivate";
17400 case PRAGMA_OMP_CLAUSE_DEFAULT
:
17401 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
17402 c_name
= "default";
17404 case PRAGMA_OMP_CLAUSE_DETACH
:
17405 clauses
= c_parser_omp_clause_detach (parser
, clauses
);
17408 case PRAGMA_OMP_CLAUSE_FILTER
:
17409 clauses
= c_parser_omp_clause_filter (parser
, clauses
);
17412 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
17413 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
17414 c_name
= "firstprivate";
17416 case PRAGMA_OMP_CLAUSE_FINAL
:
17417 clauses
= c_parser_omp_clause_final (parser
, clauses
);
17420 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
17421 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
17422 c_name
= "grainsize";
17424 case PRAGMA_OMP_CLAUSE_HINT
:
17425 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
17428 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
17429 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
17430 c_name
= "defaultmap";
17432 case PRAGMA_OMP_CLAUSE_IF
:
17433 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
17436 case PRAGMA_OMP_CLAUSE_IN_REDUCTION
:
17438 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_IN_REDUCTION
,
17440 c_name
= "in_reduction";
17442 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
17443 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
17444 c_name
= "lastprivate";
17446 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
17447 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
17448 c_name
= "mergeable";
17450 case PRAGMA_OMP_CLAUSE_NOWAIT
:
17451 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
17454 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
17455 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
17456 c_name
= "num_tasks";
17458 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
17459 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
17460 c_name
= "num_threads";
17462 case PRAGMA_OMP_CLAUSE_ORDER
:
17463 clauses
= c_parser_omp_clause_order (parser
, clauses
);
17466 case PRAGMA_OMP_CLAUSE_ORDERED
:
17467 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
17468 c_name
= "ordered";
17470 case PRAGMA_OMP_CLAUSE_PRIORITY
:
17471 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
17472 c_name
= "priority";
17474 case PRAGMA_OMP_CLAUSE_PRIVATE
:
17475 clauses
= c_parser_omp_clause_private (parser
, clauses
);
17476 c_name
= "private";
17478 case PRAGMA_OMP_CLAUSE_REDUCTION
:
17480 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
17482 c_name
= "reduction";
17484 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
17485 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
17486 c_name
= "schedule";
17488 case PRAGMA_OMP_CLAUSE_SHARED
:
17489 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
17492 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION
:
17494 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_TASK_REDUCTION
,
17496 c_name
= "task_reduction";
17498 case PRAGMA_OMP_CLAUSE_UNTIED
:
17499 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
17502 case PRAGMA_OMP_CLAUSE_INBRANCH
:
17503 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
17505 c_name
= "inbranch";
17507 case PRAGMA_OMP_CLAUSE_NONTEMPORAL
:
17508 clauses
= c_parser_omp_clause_nontemporal (parser
, clauses
);
17509 c_name
= "nontemporal";
17511 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
17512 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
17514 c_name
= "notinbranch";
17516 case PRAGMA_OMP_CLAUSE_PARALLEL
:
17518 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
17520 c_name
= "parallel";
17524 error_at (here
, "%qs must be the first clause of %qs",
17529 case PRAGMA_OMP_CLAUSE_FOR
:
17531 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
17535 goto clause_not_first
;
17537 case PRAGMA_OMP_CLAUSE_SECTIONS
:
17539 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
17541 c_name
= "sections";
17543 goto clause_not_first
;
17545 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
17547 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
17549 c_name
= "taskgroup";
17551 goto clause_not_first
;
17553 case PRAGMA_OMP_CLAUSE_LINK
:
17555 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
17558 case PRAGMA_OMP_CLAUSE_TO
:
17559 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
17561 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
17563 for (tree c
= nl
; c
!= clauses
; c
= OMP_CLAUSE_CHAIN (c
))
17564 OMP_CLAUSE_ENTER_TO (c
) = 1;
17568 clauses
= c_parser_omp_clause_to (parser
, clauses
);
17571 case PRAGMA_OMP_CLAUSE_FROM
:
17572 clauses
= c_parser_omp_clause_from (parser
, clauses
);
17575 case PRAGMA_OMP_CLAUSE_UNIFORM
:
17576 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
17577 c_name
= "uniform";
17579 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
17580 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
17581 c_name
= "num_teams";
17583 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
17584 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
17585 c_name
= "thread_limit";
17587 case PRAGMA_OMP_CLAUSE_ALIGNED
:
17588 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
17589 c_name
= "aligned";
17591 case PRAGMA_OMP_CLAUSE_ALLOCATE
:
17592 clauses
= c_parser_omp_clause_allocate (parser
, clauses
);
17593 c_name
= "allocate";
17595 case PRAGMA_OMP_CLAUSE_LINEAR
:
17596 clauses
= c_parser_omp_clause_linear (parser
, clauses
);
17599 case PRAGMA_OMP_CLAUSE_AFFINITY
:
17600 clauses
= c_parser_omp_clause_affinity (parser
, clauses
);
17601 c_name
= "affinity";
17603 case PRAGMA_OMP_CLAUSE_DEPEND
:
17604 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
17607 case PRAGMA_OMP_CLAUSE_DOACROSS
:
17608 clauses
= c_parser_omp_clause_doacross (parser
, clauses
);
17609 c_name
= "doacross";
17611 case PRAGMA_OMP_CLAUSE_MAP
:
17612 clauses
= c_parser_omp_clause_map (parser
, clauses
);
17615 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
17616 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
17617 c_name
= "use_device_ptr";
17619 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
:
17620 clauses
= c_parser_omp_clause_use_device_addr (parser
, clauses
);
17621 c_name
= "use_device_addr";
17623 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
:
17624 clauses
= c_parser_omp_clause_has_device_addr (parser
, clauses
);
17625 c_name
= "has_device_addr";
17627 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
17628 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
17629 c_name
= "is_device_ptr";
17631 case PRAGMA_OMP_CLAUSE_DEVICE
:
17632 clauses
= c_parser_omp_clause_device (parser
, clauses
);
17635 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
17636 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
17637 c_name
= "dist_schedule";
17639 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
17640 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
17641 c_name
= "proc_bind";
17643 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE
:
17644 clauses
= c_parser_omp_clause_device_type (parser
, clauses
);
17645 c_name
= "device_type";
17647 case PRAGMA_OMP_CLAUSE_SAFELEN
:
17648 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
17649 c_name
= "safelen";
17651 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
17652 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
17653 c_name
= "simdlen";
17655 case PRAGMA_OMP_CLAUSE_NOGROUP
:
17656 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
17657 c_name
= "nogroup";
17659 case PRAGMA_OMP_CLAUSE_THREADS
:
17661 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
17663 c_name
= "threads";
17665 case PRAGMA_OMP_CLAUSE_SIMD
:
17667 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
17671 case PRAGMA_OMP_CLAUSE_ENTER
:
17673 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
17678 c_parser_error (parser
, "expected %<#pragma omp%> clause");
17684 if (((mask
>> c_kind
) & 1) == 0)
17686 /* Remove the invalid clause(s) from the list to avoid
17687 confusing the rest of the compiler. */
17689 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
17695 c_parser_skip_to_pragma_eol (parser
);
17699 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
17700 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
17701 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
17707 /* OpenACC 2.0, OpenMP 2.5:
17711 In practice, we're also interested in adding the statement to an
17712 outer node. So it is convenient if we work around the fact that
17713 c_parser_statement calls add_stmt. */
17716 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
17718 tree stmt
= push_stmt_list ();
17719 c_parser_statement (parser
, if_p
);
17720 return pop_stmt_list (stmt
);
17724 # pragma acc cache (variable-list) new-line
17726 LOC is the location of the #pragma token.
17730 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
17732 tree stmt
, clauses
;
17734 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE__CACHE_
, NULL
);
17735 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
17737 c_parser_skip_to_pragma_eol (parser
);
17739 stmt
= make_node (OACC_CACHE
);
17740 TREE_TYPE (stmt
) = void_type_node
;
17741 OACC_CACHE_CLAUSES (stmt
) = clauses
;
17742 SET_EXPR_LOCATION (stmt
, loc
);
17749 # pragma acc data oacc-data-clause[optseq] new-line
17752 LOC is the location of the #pragma token.
17755 #define OACC_DATA_CLAUSE_MASK \
17756 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17757 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17758 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17759 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17760 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17761 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17762 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17763 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17764 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17767 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
17769 tree stmt
, clauses
, block
;
17771 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
17772 "#pragma acc data");
17774 block
= c_begin_omp_parallel ();
17775 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
17777 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
17783 # pragma acc declare oacc-data-clause[optseq] new-line
17786 #define OACC_DECLARE_CLAUSE_MASK \
17787 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17788 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17789 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17790 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17791 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17792 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
17793 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
17794 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17797 c_parser_oacc_declare (c_parser
*parser
)
17799 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
17800 tree clauses
, stmt
, t
, decl
;
17802 bool error
= false;
17804 c_parser_consume_pragma (parser
);
17806 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
17807 "#pragma acc declare");
17810 error_at (pragma_loc
,
17811 "no valid clauses specified in %<#pragma acc declare%>");
17815 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
17817 location_t loc
= OMP_CLAUSE_LOCATION (t
);
17818 decl
= OMP_CLAUSE_DECL (t
);
17819 if (!DECL_P (decl
))
17821 error_at (loc
, "array section in %<#pragma acc declare%>");
17826 switch (OMP_CLAUSE_MAP_KIND (t
))
17828 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
17829 case GOMP_MAP_ALLOC
:
17831 case GOMP_MAP_FORCE_DEVICEPTR
:
17832 case GOMP_MAP_DEVICE_RESIDENT
:
17835 case GOMP_MAP_LINK
:
17836 if (!global_bindings_p ()
17837 && (TREE_STATIC (decl
)
17838 || !DECL_EXTERNAL (decl
)))
17841 "%qD must be a global variable in "
17842 "%<#pragma acc declare link%>",
17850 if (global_bindings_p ())
17852 error_at (loc
, "invalid OpenACC clause at file scope");
17856 if (DECL_EXTERNAL (decl
))
17859 "invalid use of %<extern%> variable %qD "
17860 "in %<#pragma acc declare%>", decl
);
17864 else if (TREE_PUBLIC (decl
))
17867 "invalid use of %<global%> variable %qD "
17868 "in %<#pragma acc declare%>", decl
);
17875 if (!c_check_in_current_scope (decl
))
17878 "%qD must be a variable declared in the same scope as "
17879 "%<#pragma acc declare%>", decl
);
17884 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
17885 || lookup_attribute ("omp declare target link",
17886 DECL_ATTRIBUTES (decl
)))
17888 error_at (loc
, "variable %qD used more than once with "
17889 "%<#pragma acc declare%>", decl
);
17898 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
17899 id
= get_identifier ("omp declare target link");
17901 id
= get_identifier ("omp declare target");
17903 DECL_ATTRIBUTES (decl
)
17904 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
17906 if (global_bindings_p ())
17908 symtab_node
*node
= symtab_node::get (decl
);
17911 node
->offloadable
= 1;
17912 if (ENABLE_OFFLOADING
)
17914 g
->have_offload
= true;
17915 if (is_a
<varpool_node
*> (node
))
17916 vec_safe_push (offload_vars
, decl
);
17923 if (error
|| global_bindings_p ())
17926 stmt
= make_node (OACC_DECLARE
);
17927 TREE_TYPE (stmt
) = void_type_node
;
17928 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
17929 SET_EXPR_LOCATION (stmt
, pragma_loc
);
17937 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
17941 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
17944 LOC is the location of the #pragma token.
17947 #define OACC_ENTER_DATA_CLAUSE_MASK \
17948 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17949 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17950 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17951 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17952 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17953 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17955 #define OACC_EXIT_DATA_CLAUSE_MASK \
17956 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17957 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17958 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17959 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
17960 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
17961 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
17962 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17965 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
17967 location_t loc
= c_parser_peek_token (parser
)->location
;
17968 tree clauses
, stmt
;
17969 const char *p
= "";
17971 c_parser_consume_pragma (parser
);
17973 if (c_parser_next_token_is (parser
, CPP_NAME
))
17975 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17976 c_parser_consume_token (parser
);
17979 if (strcmp (p
, "data") != 0)
17981 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
17982 enter
? "enter" : "exit");
17983 parser
->error
= true;
17984 c_parser_skip_to_pragma_eol (parser
);
17989 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
17990 "#pragma acc enter data");
17992 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
17993 "#pragma acc exit data");
17995 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
17997 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
17998 enter
? "enter" : "exit");
18002 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
18003 TREE_TYPE (stmt
) = void_type_node
;
18004 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
18005 SET_EXPR_LOCATION (stmt
, loc
);
18011 # pragma acc host_data oacc-data-clause[optseq] new-line
18015 #define OACC_HOST_DATA_CLAUSE_MASK \
18016 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
18017 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18018 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
18021 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
18023 tree stmt
, clauses
, block
;
18025 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
18026 "#pragma acc host_data");
18028 block
= c_begin_omp_parallel ();
18029 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
18030 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
18037 # pragma acc loop oacc-loop-clause[optseq] new-line
18040 LOC is the location of the #pragma token.
18043 #define OACC_LOOP_CLAUSE_MASK \
18044 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
18045 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
18046 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
18047 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
18048 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
18049 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
18050 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
18051 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
18052 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
18053 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
18055 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
18056 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
18058 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
18060 strcat (p_name
, " loop");
18061 mask
|= OACC_LOOP_CLAUSE_MASK
;
18063 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
18067 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
18069 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC
);
18071 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
18074 tree block
= c_begin_compound_stmt (true);
18075 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
18077 block
= c_end_compound_stmt (loc
, block
, true);
18084 # pragma acc kernels oacc-kernels-clause[optseq] new-line
18089 # pragma acc parallel oacc-parallel-clause[optseq] new-line
18094 # pragma acc serial oacc-serial-clause[optseq] new-line
18097 LOC is the location of the #pragma token.
18100 #define OACC_KERNELS_CLAUSE_MASK \
18101 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18102 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18103 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18104 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18105 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18106 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18107 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
18108 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18109 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18110 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
18111 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
18112 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
18113 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
18114 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
18115 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18117 #define OACC_PARALLEL_CLAUSE_MASK \
18118 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18119 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18120 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18121 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18122 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18123 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18124 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
18125 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18126 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18127 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
18128 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
18129 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
18130 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
18131 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
18132 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
18133 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
18134 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
18135 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18137 #define OACC_SERIAL_CLAUSE_MASK \
18138 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18139 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18140 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18141 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18142 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18143 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18144 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
18145 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18146 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18147 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
18148 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
18149 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
18150 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
18151 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
18152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18155 c_parser_oacc_compute (location_t loc
, c_parser
*parser
,
18156 enum pragma_kind p_kind
, char *p_name
, bool *if_p
)
18158 omp_clause_mask mask
;
18159 enum tree_code code
;
18162 case PRAGMA_OACC_KERNELS
:
18163 strcat (p_name
, " kernels");
18164 mask
= OACC_KERNELS_CLAUSE_MASK
;
18165 code
= OACC_KERNELS
;
18167 case PRAGMA_OACC_PARALLEL
:
18168 strcat (p_name
, " parallel");
18169 mask
= OACC_PARALLEL_CLAUSE_MASK
;
18170 code
= OACC_PARALLEL
;
18172 case PRAGMA_OACC_SERIAL
:
18173 strcat (p_name
, " serial");
18174 mask
= OACC_SERIAL_CLAUSE_MASK
;
18175 code
= OACC_SERIAL
;
18178 gcc_unreachable ();
18181 if (c_parser_next_token_is (parser
, CPP_NAME
))
18183 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18184 if (strcmp (p
, "loop") == 0)
18186 c_parser_consume_token (parser
);
18187 tree block
= c_begin_omp_parallel ();
18189 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
18190 return c_finish_omp_construct (loc
, code
, block
, clauses
);
18194 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
);
18196 tree block
= c_begin_omp_parallel ();
18197 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
18199 return c_finish_omp_construct (loc
, code
, block
, clauses
);
18203 # pragma acc routine oacc-routine-clause[optseq] new-line
18204 function-definition
18206 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
18209 #define OACC_ROUTINE_CLAUSE_MASK \
18210 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
18211 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
18212 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
18213 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
18214 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
18216 /* Parse an OpenACC routine directive. For named directives, we apply
18217 immediately to the named function. For unnamed ones we then parse
18218 a declaration or definition, which must be for a function. */
18221 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
18223 gcc_checking_assert (context
== pragma_external
);
18225 oacc_routine_data data
;
18226 data
.error_seen
= false;
18227 data
.fndecl_seen
= false;
18228 data
.loc
= c_parser_peek_token (parser
)->location
;
18230 c_parser_consume_pragma (parser
);
18232 /* Look for optional '( name )'. */
18233 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
18235 c_parser_consume_token (parser
); /* '(' */
18237 tree decl
= NULL_TREE
;
18238 c_token
*name_token
= c_parser_peek_token (parser
);
18239 location_t name_loc
= name_token
->location
;
18240 if (name_token
->type
== CPP_NAME
18241 && (name_token
->id_kind
== C_ID_ID
18242 || name_token
->id_kind
== C_ID_TYPENAME
))
18244 decl
= lookup_name (name_token
->value
);
18246 error_at (name_loc
,
18247 "%qE has not been declared", name_token
->value
);
18248 c_parser_consume_token (parser
);
18251 c_parser_error (parser
, "expected function name");
18254 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
18256 c_parser_skip_to_pragma_eol (parser
, false);
18261 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
18262 "#pragma acc routine");
18263 /* The clauses are in reverse order; fix that to make later diagnostic
18264 emission easier. */
18265 data
.clauses
= nreverse (data
.clauses
);
18267 if (TREE_CODE (decl
) != FUNCTION_DECL
)
18269 error_at (name_loc
, "%qD does not refer to a function", decl
);
18273 c_finish_oacc_routine (&data
, decl
, false);
18275 else /* No optional '( name )'. */
18278 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
18279 "#pragma acc routine");
18280 /* The clauses are in reverse order; fix that to make later diagnostic
18281 emission easier. */
18282 data
.clauses
= nreverse (data
.clauses
);
18284 /* Emit a helpful diagnostic if there's another pragma following this
18285 one. Also don't allow a static assertion declaration, as in the
18286 following we'll just parse a *single* "declaration or function
18287 definition", and the static assertion counts an one. */
18288 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
18289 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
18291 error_at (data
.loc
,
18292 "%<#pragma acc routine%> not immediately followed by"
18293 " function declaration or definition");
18294 /* ..., and then just keep going. */
18298 /* We only have to consider the pragma_external case here. */
18299 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
18300 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
18302 int ext
= disable_extension_diagnostics ();
18304 c_parser_consume_token (parser
);
18305 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
18306 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
18307 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
18308 NULL
, NULL
, false, NULL
, &data
);
18309 restore_extension_diagnostics (ext
);
18312 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
18313 NULL
, NULL
, false, NULL
, &data
);
18317 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
18318 IS_DEFN is true if we're applying it to the definition. */
18321 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
18324 /* Keep going if we're in error reporting mode. */
18325 if (data
->error_seen
18326 || fndecl
== error_mark_node
)
18329 if (data
->fndecl_seen
)
18331 error_at (data
->loc
,
18332 "%<#pragma acc routine%> not immediately followed by"
18333 " a single function declaration or definition");
18334 data
->error_seen
= true;
18337 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
18339 error_at (data
->loc
,
18340 "%<#pragma acc routine%> not immediately followed by"
18341 " function declaration or definition");
18342 data
->error_seen
= true;
18347 = oacc_verify_routine_clauses (fndecl
, &data
->clauses
, data
->loc
,
18348 "#pragma acc routine");
18349 if (compatible
< 0)
18351 data
->error_seen
= true;
18354 if (compatible
> 0)
18359 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
18361 error_at (data
->loc
,
18363 ? G_("%<#pragma acc routine%> must be applied before use")
18364 : G_("%<#pragma acc routine%> must be applied before"
18366 data
->error_seen
= true;
18370 /* Set the routine's level of parallelism. */
18371 tree dims
= oacc_build_routine_dims (data
->clauses
);
18372 oacc_replace_fn_attrib (fndecl
, dims
);
18374 /* Add an "omp declare target" attribute. */
18375 DECL_ATTRIBUTES (fndecl
)
18376 = tree_cons (get_identifier ("omp declare target"),
18377 data
->clauses
, DECL_ATTRIBUTES (fndecl
));
18380 /* Remember that we've used this "#pragma acc routine". */
18381 data
->fndecl_seen
= true;
18385 # pragma acc update oacc-update-clause[optseq] new-line
18388 #define OACC_UPDATE_CLAUSE_MASK \
18389 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18390 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
18391 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
18392 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18393 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
18394 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18397 c_parser_oacc_update (c_parser
*parser
)
18399 location_t loc
= c_parser_peek_token (parser
)->location
;
18401 c_parser_consume_pragma (parser
);
18403 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
18404 "#pragma acc update");
18405 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
18408 "%<#pragma acc update%> must contain at least one "
18409 "%<device%> or %<host%> or %<self%> clause");
18416 tree stmt
= make_node (OACC_UPDATE
);
18417 TREE_TYPE (stmt
) = void_type_node
;
18418 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
18419 SET_EXPR_LOCATION (stmt
, loc
);
18424 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
18426 LOC is the location of the #pragma token.
18429 #define OACC_WAIT_CLAUSE_MASK \
18430 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
18433 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
18435 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
18437 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
18438 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
18440 strcpy (p_name
, " wait");
18441 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
18442 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
18449 # pragma omp allocate (list) [allocator(allocator)] */
18452 c_parser_omp_allocate (location_t loc
, c_parser
*parser
)
18454 tree allocator
= NULL_TREE
;
18455 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ALLOCATE
, NULL_TREE
);
18456 if (c_parser_next_token_is (parser
, CPP_NAME
))
18458 matching_parens parens
;
18459 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18460 c_parser_consume_token (parser
);
18461 if (strcmp ("allocator", p
) != 0)
18462 error_at (c_parser_peek_token (parser
)->location
,
18463 "expected %<allocator%>");
18464 else if (parens
.require_open (parser
))
18466 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
18467 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
18468 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
18469 allocator
= expr
.value
;
18470 allocator
= c_fully_fold (allocator
, false, NULL
);
18472 = expr
.original_type
? expr
.original_type
: TREE_TYPE (allocator
);
18473 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
18474 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
18475 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
18476 || TYPE_NAME (orig_type
)
18477 != get_identifier ("omp_allocator_handle_t"))
18479 error_at (expr_loc
, "%<allocator%> clause allocator expression "
18480 "has type %qT rather than "
18481 "%<omp_allocator_handle_t%>",
18482 TREE_TYPE (allocator
));
18483 allocator
= NULL_TREE
;
18485 parens
.skip_until_found_close (parser
);
18488 c_parser_skip_to_pragma_eol (parser
);
18491 for (tree c
= nl
; c
!= NULL_TREE
; c
= OMP_CLAUSE_CHAIN (c
))
18492 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
18494 sorry_at (loc
, "%<#pragma omp allocate%> not yet supported");
18498 # pragma omp atomic new-line
18502 x binop= expr | x++ | ++x | x-- | --x
18504 +, *, -, /, &, ^, |, <<, >>
18506 where x is an lvalue expression with scalar type.
18509 # pragma omp atomic new-line
18512 # pragma omp atomic read new-line
18515 # pragma omp atomic write new-line
18518 # pragma omp atomic update new-line
18521 # pragma omp atomic capture new-line
18524 # pragma omp atomic capture new-line
18532 expression-stmt | x = x binop expr
18534 v = expression-stmt
18536 { v = x; update-stmt; } | { update-stmt; v = x; }
18540 expression-stmt | x = x binop expr | x = expr binop x
18544 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
18547 # pragma omp atomic compare new-line
18548 conditional-update-atomic
18550 # pragma omp atomic compare capture new-line
18551 conditional-update-capture-atomic
18553 conditional-update-atomic:
18554 cond-expr-stmt | cond-update-stmt
18556 x = expr ordop x ? expr : x;
18557 x = x ordop expr ? expr : x;
18558 x = x == e ? d : x;
18560 if (expr ordop x) { x = expr; }
18561 if (x ordop expr) { x = expr; }
18562 if (x == e) { x = d; }
18565 conditional-update-capture-atomic:
18567 { v = x; cond-expr-stmt }
18568 { cond-expr-stmt v = x; }
18569 { v = x; cond-update-stmt }
18570 { cond-update-stmt v = x; }
18571 if (x == e) { x = d; } else { v = x; }
18572 { r = x == e; if (r) { x = d; } }
18573 { r = x == e; if (r) { x = d; } else { v = x; } }
18575 where x, r and v are lvalue expressions with scalar type,
18576 expr, e and d are expressions with scalar type and e might be
18579 LOC is the location of the #pragma token. */
18582 c_parser_omp_atomic (location_t loc
, c_parser
*parser
, bool openacc
)
18584 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
, r
= NULL_TREE
;
18585 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
18586 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
18587 enum tree_code code
= ERROR_MARK
, opcode
= NOP_EXPR
;
18588 enum omp_memory_order memory_order
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18589 struct c_expr expr
;
18591 bool structured_block
= false;
18592 bool swapped
= false;
18595 tree clauses
= NULL_TREE
;
18596 bool capture
= false;
18597 bool compare
= false;
18599 enum omp_memory_order fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18600 bool no_semicolon
= false;
18601 bool extra_scope
= false;
18603 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
18606 && c_parser_next_token_is (parser
, CPP_COMMA
)
18607 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
18608 c_parser_consume_token (parser
);
18612 if (c_parser_next_token_is (parser
, CPP_NAME
))
18615 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18616 location_t cloc
= c_parser_peek_token (parser
)->location
;
18617 enum tree_code new_code
= ERROR_MARK
;
18618 enum omp_memory_order new_memory_order
18619 = OMP_MEMORY_ORDER_UNSPECIFIED
;
18620 bool new_capture
= false;
18621 bool new_compare
= false;
18622 bool new_weak
= false;
18623 enum omp_memory_order new_fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18625 if (!strcmp (p
, "read"))
18626 new_code
= OMP_ATOMIC_READ
;
18627 else if (!strcmp (p
, "write"))
18628 new_code
= NOP_EXPR
;
18629 else if (!strcmp (p
, "update"))
18630 new_code
= OMP_ATOMIC
;
18631 else if (openacc
&& !strcmp (p
, "capture"))
18632 new_code
= OMP_ATOMIC_CAPTURE_NEW
;
18636 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
18637 "or %<capture%> clause");
18639 else if (!strcmp (p
, "capture"))
18640 new_capture
= true;
18641 else if (!strcmp (p
, "compare"))
18642 new_compare
= true;
18643 else if (!strcmp (p
, "weak"))
18645 else if (!strcmp (p
, "fail"))
18647 matching_parens parens
;
18649 c_parser_consume_token (parser
);
18650 if (!parens
.require_open (parser
))
18653 if (c_parser_next_token_is (parser
, CPP_NAME
))
18656 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18658 if (!strcmp (q
, "seq_cst"))
18659 new_fail
= OMP_MEMORY_ORDER_SEQ_CST
;
18660 else if (!strcmp (q
, "acquire"))
18661 new_fail
= OMP_MEMORY_ORDER_ACQUIRE
;
18662 else if (!strcmp (q
, "relaxed"))
18663 new_fail
= OMP_MEMORY_ORDER_RELAXED
;
18666 if (new_fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18668 c_parser_consume_token (parser
);
18669 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18670 error_at (cloc
, "too many %qs clauses", "fail");
18675 c_parser_error (parser
, "expected %<seq_cst%>, %<acquire%> "
18677 parens
.skip_until_found_close (parser
);
18680 else if (!strcmp (p
, "seq_cst"))
18681 new_memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18682 else if (!strcmp (p
, "acq_rel"))
18683 new_memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
18684 else if (!strcmp (p
, "release"))
18685 new_memory_order
= OMP_MEMORY_ORDER_RELEASE
;
18686 else if (!strcmp (p
, "acquire"))
18687 new_memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
18688 else if (!strcmp (p
, "relaxed"))
18689 new_memory_order
= OMP_MEMORY_ORDER_RELAXED
;
18690 else if (!strcmp (p
, "hint"))
18692 c_parser_consume_token (parser
);
18693 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
18699 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
18700 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
18701 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
18702 "%<relaxed%> or %<hint%> clause");
18706 if (new_code
!= ERROR_MARK
)
18708 /* OpenACC permits 'update capture'. */
18710 && code
== OMP_ATOMIC
18711 && new_code
== OMP_ATOMIC_CAPTURE_NEW
)
18713 else if (code
!= ERROR_MARK
)
18714 error_at (cloc
, "too many atomic clauses");
18718 else if (new_memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18720 if (memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18721 error_at (cloc
, "too many memory order clauses");
18723 memory_order
= new_memory_order
;
18725 else if (new_capture
)
18728 error_at (cloc
, "too many %qs clauses", "capture");
18732 else if (new_compare
)
18735 error_at (cloc
, "too many %qs clauses", "compare");
18742 error_at (cloc
, "too many %qs clauses", "weak");
18746 c_parser_consume_token (parser
);
18752 c_parser_skip_to_pragma_eol (parser
);
18754 if (code
== ERROR_MARK
)
18758 if (code
!= OMP_ATOMIC
)
18759 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
18760 "clauses", "capture");
18762 code
= OMP_ATOMIC_CAPTURE_NEW
;
18764 if (compare
&& code
!= OMP_ATOMIC
&& code
!= OMP_ATOMIC_CAPTURE_NEW
)
18766 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
18767 "clauses", "compare");
18770 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
&& !compare
)
18772 error_at (loc
, "%qs clause requires %qs clause", "fail", "compare");
18773 fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18775 if (weak
&& !compare
)
18777 error_at (loc
, "%qs clause requires %qs clause", "weak", "compare");
18781 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
18782 else if (memory_order
== OMP_MEMORY_ORDER_UNSPECIFIED
)
18785 = (enum omp_requires
) (omp_requires_mask
18786 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
);
18787 switch ((enum omp_memory_order
)
18788 (omp_requires_mask
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
))
18790 case OMP_MEMORY_ORDER_UNSPECIFIED
:
18791 case OMP_MEMORY_ORDER_RELAXED
:
18792 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
18794 case OMP_MEMORY_ORDER_SEQ_CST
:
18795 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18797 case OMP_MEMORY_ORDER_ACQ_REL
:
18800 case OMP_ATOMIC_READ
:
18801 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
18803 case NOP_EXPR
: /* atomic write */
18804 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
18807 memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
18812 gcc_unreachable ();
18818 case OMP_ATOMIC_READ
:
18819 if (memory_order
== OMP_MEMORY_ORDER_RELEASE
)
18821 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
18822 "%<release%> clause");
18823 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18825 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
18826 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
18828 case NOP_EXPR
: /* atomic write */
18829 if (memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
18831 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
18832 "%<acquire%> clause");
18833 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18835 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
18836 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
18841 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18843 = (enum omp_memory_order
) (memory_order
18844 | (fail
<< OMP_FAIL_MEMORY_ORDER_SHIFT
));
18848 case OMP_ATOMIC_READ
:
18849 case NOP_EXPR
: /* atomic write */
18850 v
= c_parser_cast_expression (parser
, NULL
).value
;
18851 non_lvalue_p
= !lvalue_p (v
);
18852 v
= c_fully_fold (v
, false, NULL
, true);
18853 if (v
== error_mark_node
)
18856 v
= non_lvalue (v
);
18857 loc
= c_parser_peek_token (parser
)->location
;
18858 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18860 if (code
== NOP_EXPR
)
18862 lhs
= c_parser_expression (parser
).value
;
18863 lhs
= c_fully_fold (lhs
, false, NULL
);
18864 if (lhs
== error_mark_node
)
18869 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
18870 non_lvalue_p
= !lvalue_p (lhs
);
18871 lhs
= c_fully_fold (lhs
, false, NULL
, true);
18872 if (lhs
== error_mark_node
)
18875 lhs
= non_lvalue (lhs
);
18877 if (code
== NOP_EXPR
)
18879 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
18887 case OMP_ATOMIC_CAPTURE_NEW
:
18888 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
18890 c_parser_consume_token (parser
);
18891 structured_block
= true;
18894 && c_parser_next_token_is_keyword (parser
, RID_IF
))
18898 v
= c_parser_cast_expression (parser
, NULL
).value
;
18899 non_lvalue_p
= !lvalue_p (v
);
18900 v
= c_fully_fold (v
, false, NULL
, true);
18901 if (v
== error_mark_node
)
18904 v
= non_lvalue (v
);
18905 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18907 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
18909 eloc
= c_parser_peek_token (parser
)->location
;
18910 error_at (eloc
, "expected expression");
18919 /* For structured_block case we don't know yet whether
18920 old or new x should be captured. */
18922 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
18924 c_parser_consume_token (parser
);
18926 matching_parens parens
;
18927 if (!parens
.require_open (parser
))
18929 eloc
= c_parser_peek_token (parser
)->location
;
18933 cmp_expr
= c_parser_cast_expression (parser
, NULL
);
18934 cmp_expr
= default_function_array_conversion (eloc
, cmp_expr
);
18937 cmp_expr
= c_parser_binary_expression (parser
, NULL
, void_list_node
);
18938 parens
.skip_until_found_close (parser
);
18939 if (cmp_expr
.value
== error_mark_node
)
18943 if (!c_tree_equal (cmp_expr
.value
, unfolded_lhs
))
18945 cmp_expr
.value
= rhs1
;
18947 gcc_assert (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
);
18949 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
18951 else if (!structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
18953 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
18954 "expected %<==%> comparison in %<if%> condition");
18957 else if (TREE_CODE (cmp_expr
.value
) != GT_EXPR
18958 && TREE_CODE (cmp_expr
.value
) != LT_EXPR
)
18960 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
18961 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
18965 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
18968 extra_scope
= true;
18969 eloc
= c_parser_peek_token (parser
)->location
;
18970 expr
= c_parser_cast_expression (parser
, NULL
);
18972 expr
= default_function_array_conversion (eloc
, expr
);
18973 unfolded_lhs
= expr
.value
;
18974 lhs
= c_fully_fold (lhs
, false, NULL
, true);
18976 if (lhs
== error_mark_node
)
18978 if (!lvalue_p (unfolded_lhs
))
18979 lhs
= non_lvalue (lhs
);
18980 if (!c_parser_next_token_is (parser
, CPP_EQ
))
18982 c_parser_error (parser
, "expected %<=%>");
18985 c_parser_consume_token (parser
);
18986 eloc
= c_parser_peek_token (parser
)->location
;
18987 expr
= c_parser_expr_no_commas (parser
, NULL
);
18990 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
18993 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
18996 extra_scope
= false;
18997 no_semicolon
= true;
18999 if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), unfolded_lhs
))
19001 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
19003 opcode
= COND_EXPR
;
19004 rhs
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
19005 false, NULL
, true);
19006 rhs1
= c_fully_fold (rhs1
, false, NULL
, true);
19008 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), rhs1
))
19010 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
19011 ? MIN_EXPR
: MAX_EXPR
);
19012 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
19013 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 0),
19014 false, NULL
, true);
19019 else if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
19021 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), unfolded_lhs
)
19022 && c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), rhs1
))
19024 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
19025 ? MAX_EXPR
: MIN_EXPR
);
19026 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
19027 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
19028 false, NULL
, true);
19033 c_parser_error (parser
,
19034 "invalid form of %<#pragma omp atomic compare%>");
19038 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
19040 if (code
!= OMP_ATOMIC_CAPTURE_NEW
19041 || (structured_block
&& r
== NULL_TREE
)
19042 || TREE_CODE (cmp_expr
.value
) != EQ_EXPR
)
19044 eloc
= c_parser_peek_token (parser
)->location
;
19045 error_at (eloc
, "unexpected %<else%>");
19049 c_parser_consume_token (parser
);
19051 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
19054 extra_scope
= true;
19055 v
= c_parser_cast_expression (parser
, NULL
).value
;
19056 non_lvalue_p
= !lvalue_p (v
);
19057 v
= c_fully_fold (v
, false, NULL
, true);
19058 if (v
== error_mark_node
)
19061 v
= non_lvalue (v
);
19062 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
19065 expr
= c_parser_expr_no_commas (parser
, NULL
);
19067 if (!c_tree_equal (expr
.value
, unfolded_lhs
))
19070 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
19073 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
19076 extra_scope
= false;
19077 code
= OMP_ATOMIC_CAPTURE_OLD
;
19078 if (r
== NULL_TREE
)
19079 /* Signal to c_finish_omp_atomic that in
19080 if (x == e) { x = d; } else { v = x; }
19081 case the store to v should be conditional. */
19082 r
= void_list_node
;
19084 else if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
19086 c_parser_require_keyword (parser
, RID_ELSE
, "expected %<else%>");
19089 else if (code
== OMP_ATOMIC_CAPTURE_NEW
19095 eloc
= c_parser_peek_token (parser
)->location
;
19096 expr
= c_parser_cast_expression (parser
, NULL
);
19098 expr
= default_function_array_conversion (eloc
, expr
);
19099 unfolded_lhs
= expr
.value
;
19100 lhs
= c_fully_fold (lhs
, false, NULL
, true);
19102 switch (TREE_CODE (lhs
))
19105 error_at (eloc
, "invalid form of %<pragma omp atomic compare%>");
19109 c_parser_skip_to_end_of_block_or_statement (parser
);
19110 if (extra_scope
&& c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
19111 c_parser_consume_token (parser
);
19112 if (structured_block
)
19114 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
19115 c_parser_consume_token (parser
);
19116 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
19118 c_parser_skip_to_end_of_block_or_statement (parser
);
19119 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
19120 c_parser_consume_token (parser
);
19125 case POSTINCREMENT_EXPR
:
19126 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
19127 code
= OMP_ATOMIC_CAPTURE_OLD
;
19129 case PREINCREMENT_EXPR
:
19130 lhs
= TREE_OPERAND (lhs
, 0);
19131 unfolded_lhs
= NULL_TREE
;
19132 opcode
= PLUS_EXPR
;
19133 rhs
= integer_one_node
;
19135 goto invalid_compare
;
19138 case POSTDECREMENT_EXPR
:
19139 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
19140 code
= OMP_ATOMIC_CAPTURE_OLD
;
19142 case PREDECREMENT_EXPR
:
19143 lhs
= TREE_OPERAND (lhs
, 0);
19144 unfolded_lhs
= NULL_TREE
;
19145 opcode
= MINUS_EXPR
;
19146 rhs
= integer_one_node
;
19148 goto invalid_compare
;
19151 case COMPOUND_EXPR
:
19152 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
19153 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
19154 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
19155 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
19156 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
19157 (TREE_OPERAND (lhs
, 1), 0), 0)))
19159 /* Undo effects of boolean_increment for post {in,de}crement. */
19160 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
19163 if (TREE_CODE (lhs
) == MODIFY_EXPR
19164 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs
, 0))) == BOOLEAN_TYPE
)
19166 /* Undo effects of boolean_increment. */
19167 if (integer_onep (TREE_OPERAND (lhs
, 1)))
19169 /* This is pre or post increment. */
19170 rhs
= TREE_OPERAND (lhs
, 1);
19171 lhs
= TREE_OPERAND (lhs
, 0);
19172 unfolded_lhs
= NULL_TREE
;
19174 if (code
== OMP_ATOMIC_CAPTURE_NEW
19175 && !structured_block
19176 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
19177 code
= OMP_ATOMIC_CAPTURE_OLD
;
19179 goto invalid_compare
;
19182 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
19183 && TREE_OPERAND (lhs
, 0)
19184 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
19186 /* This is pre or post decrement. */
19187 rhs
= TREE_OPERAND (lhs
, 1);
19188 lhs
= TREE_OPERAND (lhs
, 0);
19189 unfolded_lhs
= NULL_TREE
;
19191 if (code
== OMP_ATOMIC_CAPTURE_NEW
19192 && !structured_block
19193 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
19194 code
= OMP_ATOMIC_CAPTURE_OLD
;
19196 goto invalid_compare
;
19202 if (!lvalue_p (unfolded_lhs
))
19203 lhs
= non_lvalue (lhs
);
19204 if (compare
&& !c_parser_next_token_is (parser
, CPP_EQ
))
19206 c_parser_error (parser
, "expected %<=%>");
19209 switch (c_parser_peek_token (parser
)->type
)
19212 opcode
= MULT_EXPR
;
19215 opcode
= TRUNC_DIV_EXPR
;
19218 opcode
= PLUS_EXPR
;
19221 opcode
= MINUS_EXPR
;
19223 case CPP_LSHIFT_EQ
:
19224 opcode
= LSHIFT_EXPR
;
19226 case CPP_RSHIFT_EQ
:
19227 opcode
= RSHIFT_EXPR
;
19230 opcode
= BIT_AND_EXPR
;
19233 opcode
= BIT_IOR_EXPR
;
19236 opcode
= BIT_XOR_EXPR
;
19239 c_parser_consume_token (parser
);
19240 eloc
= c_parser_peek_token (parser
)->location
;
19241 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
19243 switch (TREE_CODE (rhs1
))
19246 case TRUNC_DIV_EXPR
:
19257 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
19259 opcode
= TREE_CODE (rhs1
);
19260 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
19262 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
19266 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
19268 opcode
= TREE_CODE (rhs1
);
19269 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
19271 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
19273 swapped
= !commutative_tree_code (opcode
);
19280 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) != GT_EXPR
19281 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != LT_EXPR
19282 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != EQ_EXPR
)
19284 if (!TREE_OPERAND (rhs1
, 1))
19286 if (!c_tree_equal (TREE_OPERAND (rhs1
, 2), unfolded_lhs
))
19288 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
19291 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
19293 opcode
= COND_EXPR
;
19294 rhs
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
19296 false, NULL
, true);
19297 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false,
19301 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
19302 TREE_OPERAND (rhs1
, 1)))
19304 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
19305 ? MIN_EXPR
: MAX_EXPR
);
19306 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
19308 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
19310 false, NULL
, true);
19314 else if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
19316 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
19319 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
19320 TREE_OPERAND (rhs1
, 1)))
19322 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
19323 ? MAX_EXPR
: MIN_EXPR
);
19324 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
19326 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
19328 false, NULL
, true);
19335 || code
!= OMP_ATOMIC_CAPTURE_NEW
19336 || !structured_block
19340 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
19341 && c_parser_peek_2nd_token (parser
)->keyword
== RID_IF
)
19345 c_parser_consume_token (parser
);
19354 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
19356 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
19358 code
= OMP_ATOMIC_CAPTURE_OLD
;
19361 expr
= default_function_array_read_conversion (eloc
, expr
);
19362 unfolded_lhs1
= expr
.value
;
19363 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
19365 c_parser_consume_token (parser
);
19368 if (structured_block
&& !compare
)
19371 expr
= default_function_array_read_conversion (eloc
, expr
);
19372 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
19377 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
19380 c_parser_error (parser
,
19381 "invalid operator for %<#pragma omp atomic%>");
19385 /* Arrange to pass the location of the assignment operator to
19386 c_finish_omp_atomic. */
19387 loc
= c_parser_peek_token (parser
)->location
;
19388 c_parser_consume_token (parser
);
19389 eloc
= c_parser_peek_token (parser
)->location
;
19390 expr
= c_parser_expression (parser
);
19391 expr
= default_function_array_read_conversion (eloc
, expr
);
19393 rhs
= c_fully_fold (rhs
, false, NULL
, true);
19397 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
&& r
== NULL_TREE
)
19400 && !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
19402 no_semicolon
= false;
19403 v
= c_parser_cast_expression (parser
, NULL
).value
;
19404 non_lvalue_p
= !lvalue_p (v
);
19405 v
= c_fully_fold (v
, false, NULL
, true);
19406 if (v
== error_mark_node
)
19409 v
= non_lvalue (v
);
19410 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
19412 eloc
= c_parser_peek_token (parser
)->location
;
19413 expr
= c_parser_cast_expression (parser
, NULL
);
19415 expr
= default_function_array_read_conversion (eloc
, expr
);
19416 unfolded_lhs1
= expr
.value
;
19417 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
19418 if (lhs1
== error_mark_node
)
19420 if (!lvalue_p (unfolded_lhs1
))
19421 lhs1
= non_lvalue (lhs1
);
19423 if (structured_block
)
19426 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19427 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
19430 if (weak
&& opcode
!= COND_EXPR
)
19432 error_at (loc
, "%<weak%> clause requires atomic equality comparison");
19435 if (unfolded_lhs
&& unfolded_lhs1
19436 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
19438 error ("%<#pragma omp atomic capture%> uses two different "
19439 "expressions for memory");
19440 stmt
= error_mark_node
;
19443 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
, r
,
19444 swapped
, memory_order
, weak
);
19445 if (stmt
!= error_mark_node
)
19448 if (!structured_block
&& !no_semicolon
)
19449 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19454 # pragma omp barrier new-line
19458 c_parser_omp_barrier (c_parser
*parser
)
19460 location_t loc
= c_parser_peek_token (parser
)->location
;
19461 c_parser_consume_pragma (parser
);
19462 c_parser_skip_to_pragma_eol (parser
);
19464 c_finish_omp_barrier (loc
);
19468 # pragma omp critical [(name)] new-line
19472 # pragma omp critical [(name) [hint(expression)]] new-line
19474 LOC is the location of the #pragma itself. */
19476 #define OMP_CRITICAL_CLAUSE_MASK \
19477 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
19480 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
19482 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
19484 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
19486 c_parser_consume_token (parser
);
19487 if (c_parser_next_token_is (parser
, CPP_NAME
))
19489 name
= c_parser_peek_token (parser
)->value
;
19490 c_parser_consume_token (parser
);
19491 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
19494 c_parser_error (parser
, "expected identifier");
19496 if (c_parser_next_token_is (parser
, CPP_COMMA
)
19497 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
19498 c_parser_consume_token (parser
);
19500 clauses
= c_parser_omp_all_clauses (parser
, OMP_CRITICAL_CLAUSE_MASK
,
19501 "#pragma omp critical");
19502 stmt
= c_parser_omp_structured_block (parser
, if_p
);
19503 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
19507 # pragma omp depobj ( depobj ) depobj-clause new-line
19510 depend (dependence-type : locator)
19512 update (dependence-type)
19521 c_parser_omp_depobj (c_parser
*parser
)
19523 location_t loc
= c_parser_peek_token (parser
)->location
;
19524 c_parser_consume_pragma (parser
);
19525 matching_parens parens
;
19526 if (!parens
.require_open (parser
))
19528 c_parser_skip_to_pragma_eol (parser
);
19532 tree depobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
19533 if (depobj
!= error_mark_node
)
19535 if (!lvalue_p (depobj
))
19537 error_at (EXPR_LOC_OR_LOC (depobj
, loc
),
19538 "%<depobj%> expression is not lvalue expression");
19539 depobj
= error_mark_node
;
19543 tree addr
= build_unary_op (EXPR_LOC_OR_LOC (depobj
, loc
), ADDR_EXPR
,
19545 if (addr
== error_mark_node
)
19546 depobj
= error_mark_node
;
19548 depobj
= build_indirect_ref (EXPR_LOC_OR_LOC (depobj
, loc
),
19549 addr
, RO_UNARY_STAR
);
19553 parens
.skip_until_found_close (parser
);
19554 tree clause
= NULL_TREE
;
19555 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_INVALID
;
19556 location_t c_loc
= c_parser_peek_token (parser
)->location
;
19557 if (c_parser_next_token_is (parser
, CPP_NAME
))
19559 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19561 c_parser_consume_token (parser
);
19562 if (!strcmp ("depend", p
))
19564 clause
= c_parser_omp_clause_depend (parser
, NULL_TREE
);
19565 clause
= c_finish_omp_clauses (clause
, C_ORT_OMP
);
19567 clause
= error_mark_node
;
19569 else if (!strcmp ("destroy", p
))
19570 kind
= OMP_CLAUSE_DEPEND_LAST
;
19571 else if (!strcmp ("update", p
))
19573 matching_parens c_parens
;
19574 if (c_parens
.require_open (parser
))
19576 location_t c2_loc
= c_parser_peek_token (parser
)->location
;
19577 if (c_parser_next_token_is (parser
, CPP_NAME
))
19580 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19582 c_parser_consume_token (parser
);
19583 if (!strcmp ("in", p2
))
19584 kind
= OMP_CLAUSE_DEPEND_IN
;
19585 else if (!strcmp ("out", p2
))
19586 kind
= OMP_CLAUSE_DEPEND_OUT
;
19587 else if (!strcmp ("inout", p2
))
19588 kind
= OMP_CLAUSE_DEPEND_INOUT
;
19589 else if (!strcmp ("mutexinoutset", p2
))
19590 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
19591 else if (!strcmp ("inoutset", p2
))
19592 kind
= OMP_CLAUSE_DEPEND_INOUTSET
;
19594 if (kind
== OMP_CLAUSE_DEPEND_INVALID
)
19596 clause
= error_mark_node
;
19597 error_at (c2_loc
, "expected %<in%>, %<out%>, %<inout%>, "
19598 "%<mutexinoutset%> or %<inoutset%>");
19600 c_parens
.skip_until_found_close (parser
);
19603 clause
= error_mark_node
;
19606 if (!clause
&& kind
== OMP_CLAUSE_DEPEND_INVALID
)
19608 clause
= error_mark_node
;
19609 error_at (c_loc
, "expected %<depend%>, %<destroy%> or %<update%> clause");
19611 c_parser_skip_to_pragma_eol (parser
);
19613 c_finish_omp_depobj (loc
, depobj
, kind
, clause
);
19618 # pragma omp flush flush-vars[opt] new-line
19624 # pragma omp flush memory-order-clause new-line */
19627 c_parser_omp_flush (c_parser
*parser
)
19629 location_t loc
= c_parser_peek_token (parser
)->location
;
19630 c_parser_consume_pragma (parser
);
19631 enum memmodel mo
= MEMMODEL_LAST
;
19632 if (c_parser_next_token_is (parser
, CPP_NAME
))
19635 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19637 if (!strcmp (p
, "seq_cst"))
19638 mo
= MEMMODEL_SEQ_CST
;
19639 else if (!strcmp (p
, "acq_rel"))
19640 mo
= MEMMODEL_ACQ_REL
;
19641 else if (!strcmp (p
, "release"))
19642 mo
= MEMMODEL_RELEASE
;
19643 else if (!strcmp (p
, "acquire"))
19644 mo
= MEMMODEL_ACQUIRE
;
19646 error_at (c_parser_peek_token (parser
)->location
,
19647 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
19649 c_parser_consume_token (parser
);
19651 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
19653 if (mo
!= MEMMODEL_LAST
)
19654 error_at (c_parser_peek_token (parser
)->location
,
19655 "%<flush%> list specified together with memory order "
19657 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
19659 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19660 c_parser_error (parser
, "expected %<(%> or end of line");
19661 c_parser_skip_to_pragma_eol (parser
);
19663 c_finish_omp_flush (loc
, mo
);
19666 /* Parse an OpenMP structured block sequence. KIND is the corresponding
19667 separating directive. */
19670 c_parser_omp_structured_block_sequence (c_parser
*parser
,
19671 enum pragma_kind kind
)
19673 tree stmt
= push_stmt_list ();
19674 c_parser_statement (parser
, NULL
);
19677 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
19679 if (c_parser_next_token_is (parser
, CPP_EOF
))
19682 if (kind
!= PRAGMA_NONE
19683 && c_parser_peek_token (parser
)->pragma_kind
== kind
)
19685 c_parser_statement (parser
, NULL
);
19688 return pop_stmt_list (stmt
);
19694 { structured-block scan-directive structured-block } */
19697 c_parser_omp_scan_loop_body (c_parser
*parser
, bool open_brace_parsed
)
19701 tree clauses
= NULL_TREE
;
19703 loc
= c_parser_peek_token (parser
)->location
;
19704 if (!open_brace_parsed
19705 && !c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
19707 /* Avoid skipping until the end of the block. */
19708 parser
->error
= false;
19712 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_OMP_SCAN
);
19713 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, NULL_TREE
);
19714 SET_EXPR_LOCATION (substmt
, loc
);
19715 add_stmt (substmt
);
19717 loc
= c_parser_peek_token (parser
)->location
;
19718 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SCAN
)
19720 enum omp_clause_code clause
= OMP_CLAUSE_ERROR
;
19722 c_parser_consume_pragma (parser
);
19724 if (c_parser_next_token_is (parser
, CPP_NAME
))
19727 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19728 if (strcmp (p
, "inclusive") == 0)
19729 clause
= OMP_CLAUSE_INCLUSIVE
;
19730 else if (strcmp (p
, "exclusive") == 0)
19731 clause
= OMP_CLAUSE_EXCLUSIVE
;
19733 if (clause
!= OMP_CLAUSE_ERROR
)
19735 c_parser_consume_token (parser
);
19736 clauses
= c_parser_omp_var_list_parens (parser
, clause
, NULL_TREE
);
19739 c_parser_error (parser
, "expected %<inclusive%> or "
19740 "%<exclusive%> clause");
19741 c_parser_skip_to_pragma_eol (parser
);
19744 error ("expected %<#pragma omp scan%>");
19746 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
19747 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_NONE
);
19748 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, clauses
);
19749 SET_EXPR_LOCATION (substmt
, loc
);
19750 add_stmt (substmt
);
19752 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
19756 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
19757 The real trick here is to determine the loop control variable early
19758 so that we can push a new decl if necessary to make it private.
19759 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
19763 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
19764 tree clauses
, tree
*cclauses
, bool *if_p
)
19766 tree decl
, cond
, incr
, body
, init
, stmt
, cl
;
19767 unsigned char save_in_statement
;
19768 tree declv
, condv
, incrv
, initv
, ret
= NULL_TREE
;
19769 tree pre_body
= NULL_TREE
, this_pre_body
;
19770 tree ordered_cl
= NULL_TREE
;
19771 bool fail
= false, open_brace_parsed
= false;
19772 int i
, collapse
= 1, ordered
= 0, count
, nbraces
= 0;
19773 location_t for_loc
;
19774 bool tiling
= false;
19775 bool inscan
= false;
19776 vec
<tree
, va_gc
> *for_block
= make_tree_vector ();
19778 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
19779 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
19780 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
19781 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
19784 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
19786 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
19787 && OMP_CLAUSE_ORDERED_EXPR (cl
))
19790 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
19792 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_REDUCTION
19793 && OMP_CLAUSE_REDUCTION_INSCAN (cl
)
19794 && (code
== OMP_SIMD
|| code
== OMP_FOR
))
19797 if (ordered
&& ordered
< collapse
)
19799 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
19800 "%<ordered%> clause parameter is less than %<collapse%>");
19801 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
19802 = build_int_cst (NULL_TREE
, collapse
);
19803 ordered
= collapse
;
19806 gcc_assert (tiling
|| (collapse
>= 1 && ordered
>= 0));
19807 count
= ordered
? ordered
: collapse
;
19809 declv
= make_tree_vec (count
);
19810 initv
= make_tree_vec (count
);
19811 condv
= make_tree_vec (count
);
19812 incrv
= make_tree_vec (count
);
19814 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
))
19816 c_parser_error (parser
, "for statement expected");
19819 for_loc
= c_parser_peek_token (parser
)->location
;
19820 c_parser_consume_token (parser
);
19822 /* Forbid break/continue in the loop initializer, condition, and
19823 increment expressions. */
19824 save_in_statement
= in_statement
;
19825 in_statement
= IN_OMP_BLOCK
;
19827 for (i
= 0; i
< count
; i
++)
19829 int bracecount
= 0;
19831 matching_parens parens
;
19832 if (!parens
.require_open (parser
))
19835 /* Parse the initialization declaration or expression. */
19836 if (c_parser_next_tokens_start_declaration (parser
))
19839 vec_safe_push (for_block
, c_begin_compound_stmt (true));
19840 this_pre_body
= push_stmt_list ();
19841 c_in_omp_for
= true;
19842 c_parser_declaration_or_fndef (parser
, true, true, true, true, true);
19843 c_in_omp_for
= false;
19846 this_pre_body
= pop_stmt_list (this_pre_body
);
19850 pre_body
= push_stmt_list ();
19852 add_stmt (this_pre_body
);
19853 pre_body
= pop_stmt_list (pre_body
);
19856 pre_body
= this_pre_body
;
19858 decl
= check_for_loop_decls (for_loc
, flag_isoc99
);
19861 if (DECL_INITIAL (decl
) == error_mark_node
)
19862 decl
= error_mark_node
;
19865 else if (c_parser_next_token_is (parser
, CPP_NAME
)
19866 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
19868 struct c_expr decl_exp
;
19869 struct c_expr init_exp
;
19870 location_t init_loc
;
19872 decl_exp
= c_parser_postfix_expression (parser
);
19873 decl
= decl_exp
.value
;
19875 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
19877 init_loc
= c_parser_peek_token (parser
)->location
;
19878 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
19879 init_exp
= default_function_array_read_conversion (init_loc
,
19881 c_in_omp_for
= true;
19882 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
19883 NOP_EXPR
, init_loc
, init_exp
.value
,
19884 init_exp
.original_type
);
19885 c_in_omp_for
= false;
19886 init
= c_process_expr_stmt (init_loc
, init
);
19888 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19893 c_parser_error (parser
,
19894 "expected iteration declaration or initialization");
19895 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
19901 /* Parse the loop condition. */
19903 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
19905 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
19906 c_in_omp_for
= true;
19907 struct c_expr cond_expr
19908 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
19909 c_in_omp_for
= false;
19911 cond
= cond_expr
.value
;
19912 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
19913 switch (cond_expr
.original_code
)
19921 if (code
!= OACC_LOOP
)
19925 /* Can't be cond = error_mark_node, because we want to preserve
19926 the location until c_finish_omp_for. */
19927 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
19930 protected_set_expr_location (cond
, cond_loc
);
19932 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19934 /* Parse the increment expression. */
19936 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
19938 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
19940 incr
= c_process_expr_stmt (incr_loc
,
19941 c_parser_expression (parser
).value
);
19943 parens
.skip_until_found_close (parser
);
19945 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
19949 TREE_VEC_ELT (declv
, i
) = decl
;
19950 TREE_VEC_ELT (initv
, i
) = init
;
19951 TREE_VEC_ELT (condv
, i
) = cond
;
19952 TREE_VEC_ELT (incrv
, i
) = incr
;
19956 if (i
== count
- 1)
19959 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
19960 in between the collapsed for loops to be still considered perfectly
19961 nested. Hopefully the final version clarifies this.
19962 For now handle (multiple) {'s and empty statements. */
19965 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
19967 c_parser_consume_token (parser
);
19970 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
19972 c_parser_consume_token (parser
);
19975 else if (bracecount
19976 && c_parser_next_token_is (parser
, CPP_SEMICOLON
))
19977 c_parser_consume_token (parser
);
19980 c_parser_error (parser
, "not enough perfectly nested loops");
19983 open_brace_parsed
= true;
19993 nbraces
+= bracecount
;
19999 in_statement
= IN_OMP_FOR
;
20000 body
= push_stmt_list ();
20003 c_parser_omp_scan_loop_body (parser
, open_brace_parsed
);
20004 else if (open_brace_parsed
)
20006 location_t here
= c_parser_peek_token (parser
)->location
;
20007 stmt
= c_begin_compound_stmt (true);
20008 c_parser_compound_statement_nostart (parser
);
20009 add_stmt (c_end_compound_stmt (here
, stmt
, true));
20012 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
20014 body
= pop_stmt_list (body
);
20015 in_statement
= save_in_statement
;
20019 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
20021 c_parser_consume_token (parser
);
20024 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
20025 c_parser_consume_token (parser
);
20028 c_parser_error (parser
, "collapsed loops not perfectly nested");
20031 location_t here
= c_parser_peek_token (parser
)->location
;
20032 stmt
= c_begin_compound_stmt (true);
20034 c_parser_compound_statement_nostart (parser
);
20035 body
= c_end_compound_stmt (here
, stmt
, true);
20042 /* Only bother calling c_finish_omp_for if we haven't already generated
20043 an error from the initialization parsing. */
20046 c_in_omp_for
= true;
20047 stmt
= c_finish_omp_for (loc
, code
, declv
, NULL
, initv
, condv
,
20048 incrv
, body
, pre_body
, true);
20049 c_in_omp_for
= false;
20051 /* Check for iterators appearing in lb, b or incr expressions. */
20052 if (stmt
&& !c_omp_check_loop_iv (stmt
, declv
, NULL
))
20059 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (stmt
)); i
++)
20061 tree init
= TREE_VEC_ELT (OMP_FOR_INIT (stmt
), i
);
20062 gcc_assert (TREE_CODE (init
) == MODIFY_EXPR
);
20063 tree decl
= TREE_OPERAND (init
, 0);
20064 tree cond
= TREE_VEC_ELT (OMP_FOR_COND (stmt
), i
);
20065 gcc_assert (COMPARISON_CLASS_P (cond
));
20066 gcc_assert (TREE_OPERAND (cond
, 0) == decl
);
20068 tree op0
= TREE_OPERAND (init
, 1);
20069 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
20070 || TREE_CODE (op0
) != TREE_VEC
)
20071 TREE_OPERAND (init
, 1) = c_fully_fold (op0
, false, NULL
);
20074 TREE_VEC_ELT (op0
, 1)
20075 = c_fully_fold (TREE_VEC_ELT (op0
, 1), false, NULL
);
20076 TREE_VEC_ELT (op0
, 2)
20077 = c_fully_fold (TREE_VEC_ELT (op0
, 2), false, NULL
);
20080 tree op1
= TREE_OPERAND (cond
, 1);
20081 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
20082 || TREE_CODE (op1
) != TREE_VEC
)
20083 TREE_OPERAND (cond
, 1) = c_fully_fold (op1
, false, NULL
);
20086 TREE_VEC_ELT (op1
, 1)
20087 = c_fully_fold (TREE_VEC_ELT (op1
, 1), false, NULL
);
20088 TREE_VEC_ELT (op1
, 2)
20089 = c_fully_fold (TREE_VEC_ELT (op1
, 2), false, NULL
);
20093 if (cclauses
!= NULL
20094 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
20097 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
20098 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
20099 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
20100 c
= &OMP_CLAUSE_CHAIN (*c
);
20103 for (i
= 0; i
< count
; i
++)
20104 if (TREE_VEC_ELT (declv
, i
) == OMP_CLAUSE_DECL (*c
))
20107 c
= &OMP_CLAUSE_CHAIN (*c
);
20108 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
20111 "iteration variable %qD should not be firstprivate",
20112 OMP_CLAUSE_DECL (*c
));
20113 *c
= OMP_CLAUSE_CHAIN (*c
);
20117 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
20119 *c
= OMP_CLAUSE_CHAIN (*c
);
20120 if (code
== OMP_SIMD
)
20122 OMP_CLAUSE_CHAIN (l
)
20123 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
20124 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
20128 OMP_CLAUSE_CHAIN (l
) = clauses
;
20134 OMP_FOR_CLAUSES (stmt
) = clauses
;
20139 while (!for_block
->is_empty ())
20141 /* FIXME diagnostics: LOC below should be the actual location of
20142 this particular for block. We need to build a list of
20143 locations to go along with FOR_BLOCK. */
20144 stmt
= c_end_compound_stmt (loc
, for_block
->pop (), true);
20147 release_tree_vector (for_block
);
20151 /* Helper function for OpenMP parsing, split clauses and call
20152 finish_omp_clauses on each of the set of clauses afterwards. */
20155 omp_split_clauses (location_t loc
, enum tree_code code
,
20156 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
20159 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
20160 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
20162 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
],
20163 i
== C_OMP_CLAUSE_SPLIT_TARGET
20164 ? C_ORT_OMP_TARGET
: C_ORT_OMP
);
20168 #pragma omp loop loop-clause[optseq] new-line
20171 LOC is the location of the #pragma token.
20174 #define OMP_LOOP_CLAUSE_MASK \
20175 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20176 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20177 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20178 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20179 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
20180 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20183 c_parser_omp_loop (location_t loc
, c_parser
*parser
,
20184 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20187 tree block
, clauses
, ret
;
20189 strcat (p_name
, " loop");
20190 mask
|= OMP_LOOP_CLAUSE_MASK
;
20192 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20195 omp_split_clauses (loc
, OMP_LOOP
, mask
, clauses
, cclauses
);
20196 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_LOOP
];
20199 block
= c_begin_compound_stmt (true);
20200 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_LOOP
, clauses
, cclauses
, if_p
);
20201 block
= c_end_compound_stmt (loc
, block
, true);
20208 #pragma omp simd simd-clause[optseq] new-line
20211 LOC is the location of the #pragma token.
20214 #define OMP_SIMD_CLAUSE_MASK \
20215 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
20216 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
20217 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
20218 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
20219 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20220 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20221 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20222 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20223 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20224 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
20225 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20228 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
20229 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20232 tree block
, clauses
, ret
;
20234 strcat (p_name
, " simd");
20235 mask
|= OMP_SIMD_CLAUSE_MASK
;
20237 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20240 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
20241 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
20244 block
= c_begin_compound_stmt (true);
20245 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
20246 block
= c_end_compound_stmt (loc
, block
, true);
20253 #pragma omp for for-clause[optseq] new-line
20257 #pragma omp for simd for-simd-clause[optseq] new-line
20260 LOC is the location of the #pragma token.
20263 #define OMP_FOR_CLAUSE_MASK \
20264 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20265 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20266 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20267 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
20268 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20269 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
20270 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
20271 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20272 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
20273 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20274 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20277 c_parser_omp_for (location_t loc
, c_parser
*parser
,
20278 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20281 tree block
, clauses
, ret
;
20283 strcat (p_name
, " for");
20284 mask
|= OMP_FOR_CLAUSE_MASK
;
20285 /* parallel for{, simd} disallows nowait clause, but for
20286 target {teams distribute ,}parallel for{, simd} it should be accepted. */
20287 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
20288 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
20289 /* Composite distribute parallel for{, simd} disallows ordered clause. */
20290 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
20291 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
20293 if (c_parser_next_token_is (parser
, CPP_NAME
))
20295 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20297 if (strcmp (p
, "simd") == 0)
20299 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20300 if (cclauses
== NULL
)
20301 cclauses
= cclauses_buf
;
20303 c_parser_consume_token (parser
);
20304 if (!flag_openmp
) /* flag_openmp_simd */
20305 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
20307 block
= c_begin_compound_stmt (true);
20308 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
20309 block
= c_end_compound_stmt (loc
, block
, true);
20310 if (ret
== NULL_TREE
)
20312 ret
= make_node (OMP_FOR
);
20313 TREE_TYPE (ret
) = void_type_node
;
20314 OMP_FOR_BODY (ret
) = block
;
20315 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
20316 SET_EXPR_LOCATION (ret
, loc
);
20321 if (!flag_openmp
) /* flag_openmp_simd */
20323 c_parser_skip_to_pragma_eol (parser
, false);
20327 /* Composite distribute parallel for disallows linear clause. */
20328 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
20329 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
20331 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20334 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
20335 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
20338 block
= c_begin_compound_stmt (true);
20339 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
20340 block
= c_end_compound_stmt (loc
, block
, true);
20346 static tree
c_parser_omp_taskloop (location_t
, c_parser
*, char *,
20347 omp_clause_mask
, tree
*, bool *);
20350 # pragma omp master new-line
20353 LOC is the location of the #pragma token.
20357 c_parser_omp_master (location_t loc
, c_parser
*parser
,
20358 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20361 tree block
, clauses
, ret
;
20363 strcat (p_name
, " master");
20365 if (c_parser_next_token_is (parser
, CPP_NAME
))
20367 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20369 if (strcmp (p
, "taskloop") == 0)
20371 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20372 if (cclauses
== NULL
)
20373 cclauses
= cclauses_buf
;
20375 c_parser_consume_token (parser
);
20376 if (!flag_openmp
) /* flag_openmp_simd */
20377 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
20379 block
= c_begin_compound_stmt (true);
20380 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
20382 block
= c_end_compound_stmt (loc
, block
, true);
20383 if (ret
== NULL_TREE
)
20385 ret
= c_finish_omp_master (loc
, block
);
20386 OMP_MASTER_COMBINED (ret
) = 1;
20390 if (!flag_openmp
) /* flag_openmp_simd */
20392 c_parser_skip_to_pragma_eol (parser
, false);
20398 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, false);
20399 omp_split_clauses (loc
, OMP_MASTER
, mask
, clauses
, cclauses
);
20402 c_parser_skip_to_pragma_eol (parser
);
20404 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
20409 # pragma omp masked masked-clauses new-line
20412 LOC is the location of the #pragma token.
20415 #define OMP_MASKED_CLAUSE_MASK \
20416 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
20419 c_parser_omp_masked (location_t loc
, c_parser
*parser
,
20420 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20423 tree block
, clauses
, ret
;
20425 strcat (p_name
, " masked");
20426 mask
|= OMP_MASKED_CLAUSE_MASK
;
20428 if (c_parser_next_token_is (parser
, CPP_NAME
))
20430 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20432 if (strcmp (p
, "taskloop") == 0)
20434 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20435 if (cclauses
== NULL
)
20436 cclauses
= cclauses_buf
;
20438 c_parser_consume_token (parser
);
20439 if (!flag_openmp
) /* flag_openmp_simd */
20440 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
20442 block
= c_begin_compound_stmt (true);
20443 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
20445 block
= c_end_compound_stmt (loc
, block
, true);
20446 if (ret
== NULL_TREE
)
20448 ret
= c_finish_omp_masked (loc
, block
,
20449 cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
]);
20450 OMP_MASKED_COMBINED (ret
) = 1;
20454 if (!flag_openmp
) /* flag_openmp_simd */
20456 c_parser_skip_to_pragma_eol (parser
, false);
20460 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20463 omp_split_clauses (loc
, OMP_MASKED
, mask
, clauses
, cclauses
);
20464 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
];
20467 return c_finish_omp_masked (loc
, c_parser_omp_structured_block (parser
,
20473 # pragma omp ordered new-line
20477 # pragma omp ordered ordered-clauses new-line
20480 # pragma omp ordered depend-clauses new-line
20483 # pragma omp ordered doacross-clauses new-line */
20485 #define OMP_ORDERED_CLAUSE_MASK \
20486 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
20487 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
20489 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
20490 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20491 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
20494 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
20497 location_t loc
= c_parser_peek_token (parser
)->location
;
20498 c_parser_consume_pragma (parser
);
20500 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
20502 c_parser_error (parser
, "expected declaration specifiers");
20503 c_parser_skip_to_pragma_eol (parser
, false);
20507 if (c_parser_next_token_is (parser
, CPP_NAME
))
20509 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20511 if (!strcmp ("depend", p
) || !strcmp ("doacross", p
))
20513 if (!flag_openmp
) /* flag_openmp_simd */
20515 c_parser_skip_to_pragma_eol (parser
, false);
20518 if (context
== pragma_stmt
)
20521 "%<#pragma omp ordered%> with %qs clause may "
20522 "only be used in compound statements", p
);
20523 c_parser_skip_to_pragma_eol (parser
, false);
20528 = c_parser_omp_all_clauses (parser
,
20529 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
20530 "#pragma omp ordered");
20531 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
20536 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
20537 "#pragma omp ordered");
20539 if (!flag_openmp
/* flag_openmp_simd */
20540 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
20543 c_finish_omp_ordered (loc
, clauses
,
20544 c_parser_omp_structured_block (parser
, if_p
));
20551 { section-sequence }
20554 section-directive[opt] structured-block
20555 section-sequence section-directive structured-block
20557 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20559 SECTIONS_LOC is the location of the #pragma omp sections. */
20562 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
20564 tree stmt
, substmt
;
20565 bool error_suppress
= false;
20568 loc
= c_parser_peek_token (parser
)->location
;
20569 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
20571 /* Avoid skipping until the end of the block. */
20572 parser
->error
= false;
20576 stmt
= push_stmt_list ();
20578 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
)
20580 substmt
= c_parser_omp_structured_block_sequence (parser
,
20581 PRAGMA_OMP_SECTION
);
20582 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
20583 SET_EXPR_LOCATION (substmt
, loc
);
20584 add_stmt (substmt
);
20589 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
20591 if (c_parser_next_token_is (parser
, CPP_EOF
))
20594 loc
= c_parser_peek_token (parser
)->location
;
20595 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
20597 c_parser_consume_pragma (parser
);
20598 c_parser_skip_to_pragma_eol (parser
);
20599 error_suppress
= false;
20601 else if (!error_suppress
)
20603 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
20604 error_suppress
= true;
20607 substmt
= c_parser_omp_structured_block_sequence (parser
,
20608 PRAGMA_OMP_SECTION
);
20609 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
20610 SET_EXPR_LOCATION (substmt
, loc
);
20611 add_stmt (substmt
);
20613 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
20614 "expected %<#pragma omp section%> or %<}%>");
20616 substmt
= pop_stmt_list (stmt
);
20618 stmt
= make_node (OMP_SECTIONS
);
20619 SET_EXPR_LOCATION (stmt
, sections_loc
);
20620 TREE_TYPE (stmt
) = void_type_node
;
20621 OMP_SECTIONS_BODY (stmt
) = substmt
;
20623 return add_stmt (stmt
);
20627 # pragma omp sections sections-clause[optseq] newline
20630 LOC is the location of the #pragma token.
20633 #define OMP_SECTIONS_CLAUSE_MASK \
20634 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20635 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
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_ALLOCATE) \
20639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20642 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
20643 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
20645 tree block
, clauses
, ret
;
20647 strcat (p_name
, " sections");
20648 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
20650 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
20652 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20655 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
20656 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
20659 block
= c_begin_compound_stmt (true);
20660 ret
= c_parser_omp_sections_scope (loc
, parser
);
20662 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
20663 block
= c_end_compound_stmt (loc
, block
, true);
20670 # pragma omp parallel parallel-clause[optseq] new-line
20672 # pragma omp parallel for parallel-for-clause[optseq] new-line
20674 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
20678 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
20681 LOC is the location of the #pragma token.
20684 #define OMP_PARALLEL_CLAUSE_MASK \
20685 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20686 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20687 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20688 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20689 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20690 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
20691 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20692 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
20693 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20694 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
20697 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
20698 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20701 tree stmt
, clauses
, block
;
20703 strcat (p_name
, " parallel");
20704 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
20705 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
20706 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
20707 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
20708 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
20710 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
20712 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20713 if (cclauses
== NULL
)
20714 cclauses
= cclauses_buf
;
20716 c_parser_consume_token (parser
);
20717 if (!flag_openmp
) /* flag_openmp_simd */
20718 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
20719 block
= c_begin_omp_parallel ();
20720 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
20722 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20724 if (ret
== NULL_TREE
)
20726 OMP_PARALLEL_COMBINED (stmt
) = 1;
20729 /* When combined with distribute, parallel has to be followed by for.
20730 #pragma omp target parallel is allowed though. */
20732 && (mask
& (OMP_CLAUSE_MASK_1
20733 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
20735 error_at (loc
, "expected %<for%> after %qs", p_name
);
20736 c_parser_skip_to_pragma_eol (parser
);
20739 else if (c_parser_next_token_is (parser
, CPP_NAME
))
20741 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20742 if (cclauses
== NULL
&& strcmp (p
, "masked") == 0)
20744 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20745 cclauses
= cclauses_buf
;
20747 c_parser_consume_token (parser
);
20748 if (!flag_openmp
) /* flag_openmp_simd */
20749 return c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
20751 block
= c_begin_omp_parallel ();
20752 tree ret
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
20754 stmt
= c_finish_omp_parallel (loc
,
20755 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20759 /* masked does have just filter clause, but during gimplification
20760 isn't represented by a gimplification omp context, so for
20761 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
20763 #pragma omp parallel masked
20764 #pragma omp taskloop simd lastprivate (x)
20765 isn't confused with
20766 #pragma omp parallel masked taskloop simd lastprivate (x) */
20767 if (OMP_MASKED_COMBINED (ret
))
20768 OMP_PARALLEL_COMBINED (stmt
) = 1;
20771 else if (cclauses
== NULL
&& strcmp (p
, "master") == 0)
20773 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20774 cclauses
= cclauses_buf
;
20776 c_parser_consume_token (parser
);
20777 if (!flag_openmp
) /* flag_openmp_simd */
20778 return c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
20780 block
= c_begin_omp_parallel ();
20781 tree ret
= c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
20783 stmt
= c_finish_omp_parallel (loc
,
20784 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20788 /* master doesn't have any clauses and during gimplification
20789 isn't represented by a gimplification omp context, so for
20790 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
20792 #pragma omp parallel master
20793 #pragma omp taskloop simd lastprivate (x)
20794 isn't confused with
20795 #pragma omp parallel master taskloop simd lastprivate (x) */
20796 if (OMP_MASTER_COMBINED (ret
))
20797 OMP_PARALLEL_COMBINED (stmt
) = 1;
20800 else if (strcmp (p
, "loop") == 0)
20802 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20803 if (cclauses
== NULL
)
20804 cclauses
= cclauses_buf
;
20806 c_parser_consume_token (parser
);
20807 if (!flag_openmp
) /* flag_openmp_simd */
20808 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
20810 block
= c_begin_omp_parallel ();
20811 tree ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
20814 = c_finish_omp_parallel (loc
,
20815 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20817 if (ret
== NULL_TREE
)
20819 OMP_PARALLEL_COMBINED (stmt
) = 1;
20822 else if (!flag_openmp
) /* flag_openmp_simd */
20824 c_parser_skip_to_pragma_eol (parser
, false);
20827 else if (cclauses
== NULL
&& strcmp (p
, "sections") == 0)
20829 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20830 cclauses
= cclauses_buf
;
20832 c_parser_consume_token (parser
);
20833 block
= c_begin_omp_parallel ();
20834 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
20835 stmt
= c_finish_omp_parallel (loc
,
20836 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20838 OMP_PARALLEL_COMBINED (stmt
) = 1;
20842 else if (!flag_openmp
) /* flag_openmp_simd */
20844 c_parser_skip_to_pragma_eol (parser
, false);
20848 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20851 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
20852 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
20855 block
= c_begin_omp_parallel ();
20856 c_parser_statement (parser
, if_p
);
20857 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
20863 # pragma omp single single-clause[optseq] new-line
20866 LOC is the location of the #pragma.
20869 #define OMP_SINGLE_CLAUSE_MASK \
20870 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20871 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20872 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
20873 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20874 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20877 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
20879 tree stmt
= make_node (OMP_SINGLE
);
20880 SET_EXPR_LOCATION (stmt
, loc
);
20881 TREE_TYPE (stmt
) = void_type_node
;
20883 OMP_SINGLE_CLAUSES (stmt
)
20884 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
20885 "#pragma omp single");
20886 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
20888 return add_stmt (stmt
);
20892 # pragma omp scope scope-clause[optseq] new-line
20895 LOC is the location of the #pragma.
20898 #define OMP_SCOPE_CLAUSE_MASK \
20899 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20900 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20901 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20902 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20906 c_parser_omp_scope (location_t loc
, c_parser
*parser
, bool *if_p
)
20908 tree stmt
= make_node (OMP_SCOPE
);
20909 SET_EXPR_LOCATION (stmt
, loc
);
20910 TREE_TYPE (stmt
) = void_type_node
;
20912 OMP_SCOPE_CLAUSES (stmt
)
20913 = c_parser_omp_all_clauses (parser
, OMP_SCOPE_CLAUSE_MASK
,
20914 "#pragma omp scope");
20915 OMP_SCOPE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
20917 return add_stmt (stmt
);
20921 # pragma omp task task-clause[optseq] new-line
20923 LOC is the location of the #pragma.
20926 #define OMP_TASK_CLAUSE_MASK \
20927 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20928 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
20929 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20930 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20931 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20932 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20933 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
20934 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
20935 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20936 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
20937 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20938 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
20939 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
20940 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
20943 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
20945 tree clauses
, block
;
20947 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
20948 "#pragma omp task");
20950 block
= c_begin_omp_task ();
20951 c_parser_statement (parser
, if_p
);
20952 return c_finish_omp_task (loc
, clauses
, block
);
20956 # pragma omp taskwait new-line
20959 # pragma omp taskwait taskwait-clause[optseq] new-line
20962 #define OMP_TASKWAIT_CLAUSE_MASK \
20963 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20964 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20967 c_parser_omp_taskwait (c_parser
*parser
)
20969 location_t loc
= c_parser_peek_token (parser
)->location
;
20970 c_parser_consume_pragma (parser
);
20973 = c_parser_omp_all_clauses (parser
, OMP_TASKWAIT_CLAUSE_MASK
,
20974 "#pragma omp taskwait");
20978 tree stmt
= make_node (OMP_TASK
);
20979 TREE_TYPE (stmt
) = void_node
;
20980 OMP_TASK_CLAUSES (stmt
) = clauses
;
20981 OMP_TASK_BODY (stmt
) = NULL_TREE
;
20982 SET_EXPR_LOCATION (stmt
, loc
);
20986 c_finish_omp_taskwait (loc
);
20990 # pragma omp taskyield new-line
20994 c_parser_omp_taskyield (c_parser
*parser
)
20996 location_t loc
= c_parser_peek_token (parser
)->location
;
20997 c_parser_consume_pragma (parser
);
20998 c_parser_skip_to_pragma_eol (parser
);
21000 c_finish_omp_taskyield (loc
);
21004 # pragma omp taskgroup new-line
21007 # pragma omp taskgroup taskgroup-clause[optseq] new-line
21010 #define OMP_TASKGROUP_CLAUSE_MASK \
21011 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21012 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
21015 c_parser_omp_taskgroup (location_t loc
, c_parser
*parser
, bool *if_p
)
21017 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_TASKGROUP_CLAUSE_MASK
,
21018 "#pragma omp taskgroup");
21020 tree body
= c_parser_omp_structured_block (parser
, if_p
);
21021 return c_finish_omp_taskgroup (loc
, body
, clauses
);
21025 # pragma omp cancel cancel-clause[optseq] new-line
21027 LOC is the location of the #pragma.
21030 #define OMP_CANCEL_CLAUSE_MASK \
21031 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
21032 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
21033 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
21034 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
21035 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
21038 c_parser_omp_cancel (c_parser
*parser
)
21040 location_t loc
= c_parser_peek_token (parser
)->location
;
21042 c_parser_consume_pragma (parser
);
21043 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
21044 "#pragma omp cancel");
21046 c_finish_omp_cancel (loc
, clauses
);
21050 # pragma omp cancellation point cancelpt-clause[optseq] new-line
21052 LOC is the location of the #pragma.
21055 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
21056 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
21057 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
21058 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
21059 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
21062 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
21064 location_t loc
= c_parser_peek_token (parser
)->location
;
21066 bool point_seen
= false;
21068 c_parser_consume_pragma (parser
);
21069 if (c_parser_next_token_is (parser
, CPP_NAME
))
21071 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21072 if (strcmp (p
, "point") == 0)
21074 c_parser_consume_token (parser
);
21080 c_parser_error (parser
, "expected %<point%>");
21081 c_parser_skip_to_pragma_eol (parser
);
21085 if (context
!= pragma_compound
)
21087 if (context
== pragma_stmt
)
21089 "%<#pragma %s%> may only be used in compound statements",
21090 "omp cancellation point");
21092 c_parser_error (parser
, "expected declaration specifiers");
21093 c_parser_skip_to_pragma_eol (parser
, false);
21098 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
21099 "#pragma omp cancellation point");
21101 c_finish_omp_cancellation_point (loc
, clauses
);
21106 #pragma omp distribute distribute-clause[optseq] new-line
21109 #define OMP_DISTRIBUTE_CLAUSE_MASK \
21110 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21111 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21112 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
21113 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
21114 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21115 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
21116 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
21119 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
21120 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
21123 tree clauses
, block
, ret
;
21125 strcat (p_name
, " distribute");
21126 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
21128 if (c_parser_next_token_is (parser
, CPP_NAME
))
21130 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21132 bool parallel
= false;
21134 if (strcmp (p
, "simd") == 0)
21137 parallel
= strcmp (p
, "parallel") == 0;
21138 if (parallel
|| simd
)
21140 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
21141 if (cclauses
== NULL
)
21142 cclauses
= cclauses_buf
;
21143 c_parser_consume_token (parser
);
21144 if (!flag_openmp
) /* flag_openmp_simd */
21147 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
21150 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
21153 block
= c_begin_compound_stmt (true);
21155 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
21158 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
21160 block
= c_end_compound_stmt (loc
, block
, true);
21163 ret
= make_node (OMP_DISTRIBUTE
);
21164 TREE_TYPE (ret
) = void_type_node
;
21165 OMP_FOR_BODY (ret
) = block
;
21166 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
21167 SET_EXPR_LOCATION (ret
, loc
);
21172 if (!flag_openmp
) /* flag_openmp_simd */
21174 c_parser_skip_to_pragma_eol (parser
, false);
21178 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
21181 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
21182 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
21185 block
= c_begin_compound_stmt (true);
21186 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
21188 block
= c_end_compound_stmt (loc
, block
, true);
21195 # pragma omp teams teams-clause[optseq] new-line
21196 structured-block */
21198 #define OMP_TEAMS_CLAUSE_MASK \
21199 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21200 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21201 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21202 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21203 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
21204 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21205 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21206 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
21209 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
21210 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
21213 tree clauses
, block
, ret
;
21215 strcat (p_name
, " teams");
21216 mask
|= OMP_TEAMS_CLAUSE_MASK
;
21218 if (c_parser_next_token_is (parser
, CPP_NAME
))
21220 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21221 if (strcmp (p
, "distribute") == 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_distribute (loc
, parser
, p_name
, mask
,
21231 block
= c_begin_omp_parallel ();
21232 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
21234 block
= c_end_compound_stmt (loc
, block
, true);
21237 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
21238 ret
= make_node (OMP_TEAMS
);
21239 TREE_TYPE (ret
) = void_type_node
;
21240 OMP_TEAMS_CLAUSES (ret
) = clauses
;
21241 OMP_TEAMS_BODY (ret
) = block
;
21242 OMP_TEAMS_COMBINED (ret
) = 1;
21243 SET_EXPR_LOCATION (ret
, loc
);
21244 return add_stmt (ret
);
21246 else if (strcmp (p
, "loop") == 0)
21248 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
21249 if (cclauses
== NULL
)
21250 cclauses
= cclauses_buf
;
21252 c_parser_consume_token (parser
);
21253 if (!flag_openmp
) /* flag_openmp_simd */
21254 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
21256 block
= c_begin_omp_parallel ();
21257 ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
21258 block
= c_end_compound_stmt (loc
, block
, true);
21261 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
21262 ret
= make_node (OMP_TEAMS
);
21263 TREE_TYPE (ret
) = void_type_node
;
21264 OMP_TEAMS_CLAUSES (ret
) = clauses
;
21265 OMP_TEAMS_BODY (ret
) = block
;
21266 OMP_TEAMS_COMBINED (ret
) = 1;
21267 SET_EXPR_LOCATION (ret
, loc
);
21268 return add_stmt (ret
);
21271 if (!flag_openmp
) /* flag_openmp_simd */
21273 c_parser_skip_to_pragma_eol (parser
, false);
21277 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
21280 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
21281 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
21284 tree stmt
= make_node (OMP_TEAMS
);
21285 TREE_TYPE (stmt
) = void_type_node
;
21286 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
21287 block
= c_begin_omp_parallel ();
21288 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
21289 OMP_TEAMS_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
21290 SET_EXPR_LOCATION (stmt
, loc
);
21292 return add_stmt (stmt
);
21296 # pragma omp target data target-data-clause[optseq] new-line
21297 structured-block */
21299 #define OMP_TARGET_DATA_CLAUSE_MASK \
21300 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21301 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21302 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21303 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
21304 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
21307 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
21311 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21314 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
21315 "#pragma omp target data");
21316 c_omp_adjust_map_clauses (clauses
, false);
21318 for (tree
*pc
= &clauses
; *pc
;)
21320 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21321 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21324 case GOMP_MAP_ALWAYS_TO
:
21325 case GOMP_MAP_FROM
:
21326 case GOMP_MAP_ALWAYS_FROM
:
21327 case GOMP_MAP_TOFROM
:
21328 case GOMP_MAP_ALWAYS_TOFROM
:
21329 case GOMP_MAP_ALLOC
:
21332 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
21333 case GOMP_MAP_ALWAYS_POINTER
:
21334 case GOMP_MAP_ATTACH_DETACH
:
21338 error_at (OMP_CLAUSE_LOCATION (*pc
),
21339 "%<#pragma omp target data%> with map-type other "
21340 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21341 "on %<map%> clause");
21342 *pc
= OMP_CLAUSE_CHAIN (*pc
);
21345 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
21346 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
21348 pc
= &OMP_CLAUSE_CHAIN (*pc
);
21355 "%<#pragma omp target data%> must contain at least "
21356 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
21361 tree stmt
= make_node (OMP_TARGET_DATA
);
21362 TREE_TYPE (stmt
) = void_type_node
;
21363 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
21364 keep_next_level ();
21365 tree block
= c_begin_compound_stmt (true);
21366 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
21367 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
21369 SET_EXPR_LOCATION (stmt
, loc
);
21370 return add_stmt (stmt
);
21374 # pragma omp target update target-update-clause[optseq] new-line */
21376 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
21377 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
21378 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
21379 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21380 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21381 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21382 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21385 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
21386 enum pragma_context context
)
21388 if (context
== pragma_stmt
)
21390 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
21391 "omp target update");
21392 c_parser_skip_to_pragma_eol (parser
, false);
21397 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
21398 "#pragma omp target update");
21399 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
21400 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
21403 "%<#pragma omp target update%> must contain at least one "
21404 "%<from%> or %<to%> clauses");
21410 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21412 tree stmt
= make_node (OMP_TARGET_UPDATE
);
21413 TREE_TYPE (stmt
) = void_type_node
;
21414 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
21415 SET_EXPR_LOCATION (stmt
, loc
);
21421 # pragma omp target enter data target-data-clause[optseq] new-line */
21423 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
21424 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21425 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21426 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21427 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21428 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21431 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
21432 enum pragma_context context
)
21434 bool data_seen
= false;
21435 if (c_parser_next_token_is (parser
, CPP_NAME
))
21437 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21438 if (strcmp (p
, "data") == 0)
21440 c_parser_consume_token (parser
);
21446 c_parser_error (parser
, "expected %<data%>");
21447 c_parser_skip_to_pragma_eol (parser
);
21451 if (context
== pragma_stmt
)
21453 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
21454 "omp target enter data");
21455 c_parser_skip_to_pragma_eol (parser
, false);
21461 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21464 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
21465 "#pragma omp target enter data");
21466 c_omp_adjust_map_clauses (clauses
, false);
21468 for (tree
*pc
= &clauses
; *pc
;)
21470 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21471 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21474 case GOMP_MAP_ALWAYS_TO
:
21475 case GOMP_MAP_ALLOC
:
21478 case GOMP_MAP_TOFROM
:
21479 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_TO
);
21482 case GOMP_MAP_ALWAYS_TOFROM
:
21483 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_TO
);
21486 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
21487 case GOMP_MAP_ALWAYS_POINTER
:
21488 case GOMP_MAP_ATTACH_DETACH
:
21492 error_at (OMP_CLAUSE_LOCATION (*pc
),
21493 "%<#pragma omp target enter data%> with map-type other "
21494 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
21495 *pc
= OMP_CLAUSE_CHAIN (*pc
);
21498 pc
= &OMP_CLAUSE_CHAIN (*pc
);
21505 "%<#pragma omp target enter data%> must contain at least "
21506 "one %<map%> clause");
21510 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
21511 TREE_TYPE (stmt
) = void_type_node
;
21512 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
21513 SET_EXPR_LOCATION (stmt
, loc
);
21519 # pragma omp target exit data target-data-clause[optseq] new-line */
21521 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
21522 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21523 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21524 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21525 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21526 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21529 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
21530 enum pragma_context context
)
21532 bool data_seen
= false;
21533 if (c_parser_next_token_is (parser
, CPP_NAME
))
21535 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21536 if (strcmp (p
, "data") == 0)
21538 c_parser_consume_token (parser
);
21544 c_parser_error (parser
, "expected %<data%>");
21545 c_parser_skip_to_pragma_eol (parser
);
21549 if (context
== pragma_stmt
)
21551 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
21552 "omp target exit data");
21553 c_parser_skip_to_pragma_eol (parser
, false);
21559 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21562 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
21563 "#pragma omp target exit data");
21564 c_omp_adjust_map_clauses (clauses
, false);
21566 for (tree
*pc
= &clauses
; *pc
;)
21568 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21569 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21571 case GOMP_MAP_FROM
:
21572 case GOMP_MAP_ALWAYS_FROM
:
21573 case GOMP_MAP_RELEASE
:
21574 case GOMP_MAP_DELETE
:
21577 case GOMP_MAP_TOFROM
:
21578 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_FROM
);
21581 case GOMP_MAP_ALWAYS_TOFROM
:
21582 OMP_CLAUSE_SET_MAP_KIND (*pc
, GOMP_MAP_ALWAYS_FROM
);
21585 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
21586 case GOMP_MAP_ALWAYS_POINTER
:
21587 case GOMP_MAP_ATTACH_DETACH
:
21591 error_at (OMP_CLAUSE_LOCATION (*pc
),
21592 "%<#pragma omp target exit data%> with map-type other "
21593 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
21594 "on %<map%> clause");
21595 *pc
= OMP_CLAUSE_CHAIN (*pc
);
21598 pc
= &OMP_CLAUSE_CHAIN (*pc
);
21605 "%<#pragma omp target exit data%> must contain at least one "
21610 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
21611 TREE_TYPE (stmt
) = void_type_node
;
21612 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
21613 SET_EXPR_LOCATION (stmt
, loc
);
21619 # pragma omp target target-clause[optseq] new-line
21620 structured-block */
21622 #define OMP_TARGET_CLAUSE_MASK \
21623 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21624 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21625 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21626 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21627 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
21628 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21629 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21630 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21631 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
21632 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
21633 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21634 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
21635 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
21638 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
21640 location_t loc
= c_parser_peek_token (parser
)->location
;
21641 c_parser_consume_pragma (parser
);
21642 tree
*pc
= NULL
, stmt
, block
;
21644 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
21646 c_parser_error (parser
, "expected declaration specifiers");
21647 c_parser_skip_to_pragma_eol (parser
);
21653 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21655 if (c_parser_next_token_is (parser
, CPP_NAME
))
21657 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21658 enum tree_code ccode
= ERROR_MARK
;
21660 if (strcmp (p
, "teams") == 0)
21662 else if (strcmp (p
, "parallel") == 0)
21663 ccode
= OMP_PARALLEL
;
21664 else if (strcmp (p
, "simd") == 0)
21666 if (ccode
!= ERROR_MARK
)
21668 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
21669 char p_name
[sizeof ("#pragma omp target teams distribute "
21670 "parallel for simd")];
21672 c_parser_consume_token (parser
);
21673 strcpy (p_name
, "#pragma omp target");
21674 if (!flag_openmp
) /* flag_openmp_simd */
21680 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
21681 OMP_TARGET_CLAUSE_MASK
,
21685 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
21686 OMP_TARGET_CLAUSE_MASK
,
21690 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
21691 OMP_TARGET_CLAUSE_MASK
,
21695 gcc_unreachable ();
21697 return stmt
!= NULL_TREE
;
21699 keep_next_level ();
21700 tree block
= c_begin_compound_stmt (true), ret
;
21704 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
21705 OMP_TARGET_CLAUSE_MASK
, cclauses
,
21709 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
21710 OMP_TARGET_CLAUSE_MASK
, cclauses
,
21714 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
21715 OMP_TARGET_CLAUSE_MASK
, cclauses
,
21719 gcc_unreachable ();
21721 block
= c_end_compound_stmt (loc
, block
, true);
21722 if (ret
== NULL_TREE
)
21724 if (ccode
== OMP_TEAMS
)
21725 /* For combined target teams, ensure the num_teams and
21726 thread_limit clause expressions are evaluated on the host,
21727 before entering the target construct. */
21728 for (tree c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
21729 c
; c
= OMP_CLAUSE_CHAIN (c
))
21730 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
21731 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
21733 i
<= (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
); ++i
)
21734 if (OMP_CLAUSE_OPERAND (c
, i
)
21735 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, i
)) != INTEGER_CST
)
21737 tree expr
= OMP_CLAUSE_OPERAND (c
, i
);
21738 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
21739 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
21740 expr
, NULL_TREE
, NULL_TREE
);
21742 OMP_CLAUSE_OPERAND (c
, i
) = expr
;
21743 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
21744 OMP_CLAUSE_FIRSTPRIVATE
);
21745 OMP_CLAUSE_DECL (tc
) = tmp
;
21746 OMP_CLAUSE_CHAIN (tc
)
21747 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
21748 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
21750 tree stmt
= make_node (OMP_TARGET
);
21751 TREE_TYPE (stmt
) = void_type_node
;
21752 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
21753 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
21754 OMP_TARGET_BODY (stmt
) = block
;
21755 OMP_TARGET_COMBINED (stmt
) = 1;
21756 SET_EXPR_LOCATION (stmt
, loc
);
21758 pc
= &OMP_TARGET_CLAUSES (stmt
);
21759 goto check_clauses
;
21761 else if (!flag_openmp
) /* flag_openmp_simd */
21763 c_parser_skip_to_pragma_eol (parser
, false);
21766 else if (strcmp (p
, "data") == 0)
21768 c_parser_consume_token (parser
);
21769 c_parser_omp_target_data (loc
, parser
, if_p
);
21772 else if (strcmp (p
, "enter") == 0)
21774 c_parser_consume_token (parser
);
21775 return c_parser_omp_target_enter_data (loc
, parser
, context
);
21777 else if (strcmp (p
, "exit") == 0)
21779 c_parser_consume_token (parser
);
21780 return c_parser_omp_target_exit_data (loc
, parser
, context
);
21782 else if (strcmp (p
, "update") == 0)
21784 c_parser_consume_token (parser
);
21785 return c_parser_omp_target_update (loc
, parser
, context
);
21788 if (!flag_openmp
) /* flag_openmp_simd */
21790 c_parser_skip_to_pragma_eol (parser
, false);
21794 stmt
= make_node (OMP_TARGET
);
21795 TREE_TYPE (stmt
) = void_type_node
;
21797 OMP_TARGET_CLAUSES (stmt
)
21798 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
21799 "#pragma omp target", false);
21800 for (tree c
= OMP_TARGET_CLAUSES (stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
21801 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
)
21803 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
21804 OMP_CLAUSE_DECL (nc
) = OMP_CLAUSE_DECL (c
);
21805 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_ALWAYS_TOFROM
);
21806 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
21807 OMP_CLAUSE_CHAIN (c
) = nc
;
21809 OMP_TARGET_CLAUSES (stmt
)
21810 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt
), C_ORT_OMP_TARGET
);
21811 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
21813 pc
= &OMP_TARGET_CLAUSES (stmt
);
21814 keep_next_level ();
21815 block
= c_begin_compound_stmt (true);
21816 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
21817 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
21819 SET_EXPR_LOCATION (stmt
, loc
);
21825 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21826 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21829 case GOMP_MAP_ALWAYS_TO
:
21830 case GOMP_MAP_FROM
:
21831 case GOMP_MAP_ALWAYS_FROM
:
21832 case GOMP_MAP_TOFROM
:
21833 case GOMP_MAP_ALWAYS_TOFROM
:
21834 case GOMP_MAP_ALLOC
:
21835 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
21836 case GOMP_MAP_ALWAYS_POINTER
:
21837 case GOMP_MAP_ATTACH_DETACH
:
21840 error_at (OMP_CLAUSE_LOCATION (*pc
),
21841 "%<#pragma omp target%> with map-type other "
21842 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21843 "on %<map%> clause");
21844 *pc
= OMP_CLAUSE_CHAIN (*pc
);
21847 pc
= &OMP_CLAUSE_CHAIN (*pc
);
21849 cfun
->has_omp_target
= true;
21854 # pragma omp declare simd declare-simd-clauses[optseq] new-line
21857 # pragma omp declare variant (identifier) match(context-selector) new-line
21860 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
21861 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
21862 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
21863 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
21864 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
21865 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
21866 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
21869 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
21871 c_token
*token
= c_parser_peek_token (parser
);
21872 gcc_assert (token
->type
== CPP_NAME
);
21873 tree kind
= token
->value
;
21874 gcc_assert (strcmp (IDENTIFIER_POINTER (kind
), "simd") == 0
21875 || strcmp (IDENTIFIER_POINTER (kind
), "variant") == 0);
21877 auto_vec
<c_token
> clauses
;
21878 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21880 c_token
*token
= c_parser_peek_token (parser
);
21881 if (token
->type
== CPP_EOF
)
21883 c_parser_skip_to_pragma_eol (parser
);
21886 clauses
.safe_push (*token
);
21887 c_parser_consume_token (parser
);
21889 clauses
.safe_push (*c_parser_peek_token (parser
));
21890 c_parser_skip_to_pragma_eol (parser
);
21892 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
21894 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_DECLARE
21895 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
21896 || c_parser_peek_2nd_token (parser
)->value
!= kind
)
21898 error ("%<#pragma omp declare %s%> must be followed by "
21899 "function declaration or definition or another "
21900 "%<#pragma omp declare %s%>",
21901 IDENTIFIER_POINTER (kind
), IDENTIFIER_POINTER (kind
));
21904 c_parser_consume_pragma (parser
);
21905 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21907 c_token
*token
= c_parser_peek_token (parser
);
21908 if (token
->type
== CPP_EOF
)
21910 c_parser_skip_to_pragma_eol (parser
);
21913 clauses
.safe_push (*token
);
21914 c_parser_consume_token (parser
);
21916 clauses
.safe_push (*c_parser_peek_token (parser
));
21917 c_parser_skip_to_pragma_eol (parser
);
21920 /* Make sure nothing tries to read past the end of the tokens. */
21922 memset (&eof_token
, 0, sizeof (eof_token
));
21923 eof_token
.type
= CPP_EOF
;
21924 clauses
.safe_push (eof_token
);
21925 clauses
.safe_push (eof_token
);
21929 case pragma_external
:
21930 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21931 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
21933 int ext
= disable_extension_diagnostics ();
21935 c_parser_consume_token (parser
);
21936 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21937 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
21938 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
21940 restore_extension_diagnostics (ext
);
21943 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
21946 case pragma_struct
:
21949 error ("%<#pragma omp declare %s%> must be followed by "
21950 "function declaration or definition",
21951 IDENTIFIER_POINTER (kind
));
21953 case pragma_compound
:
21954 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21955 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
21957 int ext
= disable_extension_diagnostics ();
21959 c_parser_consume_token (parser
);
21960 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21961 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
21962 if (c_parser_next_tokens_start_declaration (parser
))
21964 c_parser_declaration_or_fndef (parser
, true, true, true, true,
21965 true, NULL
, &clauses
);
21966 restore_extension_diagnostics (ext
);
21969 restore_extension_diagnostics (ext
);
21971 else if (c_parser_next_tokens_start_declaration (parser
))
21973 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
21977 error ("%<#pragma omp declare %s%> must be followed by "
21978 "function declaration or definition",
21979 IDENTIFIER_POINTER (kind
));
21982 gcc_unreachable ();
21986 static const char *const omp_construct_selectors
[] = {
21987 "simd", "target", "teams", "parallel", "for", NULL
};
21988 static const char *const omp_device_selectors
[] = {
21989 "kind", "isa", "arch", NULL
};
21990 static const char *const omp_implementation_selectors
[] = {
21991 "vendor", "extension", "atomic_default_mem_order", "unified_address",
21992 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL
};
21993 static const char *const omp_user_selectors
[] = {
21994 "condition", NULL
};
21999 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
22002 score(score-expression) */
22005 c_parser_omp_context_selector (c_parser
*parser
, tree set
, tree parms
)
22007 tree ret
= NULL_TREE
;
22011 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
22012 || c_parser_next_token_is (parser
, CPP_NAME
))
22013 selector
= c_parser_peek_token (parser
)->value
;
22016 c_parser_error (parser
, "expected trait selector name");
22017 return error_mark_node
;
22020 tree properties
= NULL_TREE
;
22021 const char *const *selectors
= NULL
;
22022 bool allow_score
= true;
22023 bool allow_user
= false;
22024 int property_limit
= 0;
22025 enum { CTX_PROPERTY_NONE
, CTX_PROPERTY_USER
, CTX_PROPERTY_NAME_LIST
,
22026 CTX_PROPERTY_ID
, CTX_PROPERTY_EXPR
,
22027 CTX_PROPERTY_SIMD
} property_kind
= CTX_PROPERTY_NONE
;
22028 switch (IDENTIFIER_POINTER (set
)[0])
22030 case 'c': /* construct */
22031 selectors
= omp_construct_selectors
;
22032 allow_score
= false;
22033 property_limit
= 1;
22034 property_kind
= CTX_PROPERTY_SIMD
;
22036 case 'd': /* device */
22037 selectors
= omp_device_selectors
;
22038 allow_score
= false;
22040 property_limit
= 3;
22041 property_kind
= CTX_PROPERTY_NAME_LIST
;
22043 case 'i': /* implementation */
22044 selectors
= omp_implementation_selectors
;
22046 property_limit
= 3;
22047 property_kind
= CTX_PROPERTY_NAME_LIST
;
22049 case 'u': /* user */
22050 selectors
= omp_user_selectors
;
22051 property_limit
= 1;
22052 property_kind
= CTX_PROPERTY_EXPR
;
22055 gcc_unreachable ();
22057 for (int i
= 0; ; i
++)
22059 if (selectors
[i
] == NULL
)
22063 property_kind
= CTX_PROPERTY_USER
;
22068 error_at (c_parser_peek_token (parser
)->location
,
22069 "selector %qs not allowed for context selector "
22070 "set %qs", IDENTIFIER_POINTER (selector
),
22071 IDENTIFIER_POINTER (set
));
22072 c_parser_consume_token (parser
);
22073 return error_mark_node
;
22076 if (i
== property_limit
)
22077 property_kind
= CTX_PROPERTY_NONE
;
22078 if (strcmp (selectors
[i
], IDENTIFIER_POINTER (selector
)) == 0)
22081 if (property_kind
== CTX_PROPERTY_NAME_LIST
22082 && IDENTIFIER_POINTER (set
)[0] == 'i'
22083 && strcmp (IDENTIFIER_POINTER (selector
),
22084 "atomic_default_mem_order") == 0)
22085 property_kind
= CTX_PROPERTY_ID
;
22087 c_parser_consume_token (parser
);
22089 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
22091 if (property_kind
== CTX_PROPERTY_NONE
)
22093 error_at (c_parser_peek_token (parser
)->location
,
22094 "selector %qs does not accept any properties",
22095 IDENTIFIER_POINTER (selector
));
22096 return error_mark_node
;
22099 matching_parens parens
;
22100 parens
.require_open (parser
);
22102 c_token
*token
= c_parser_peek_token (parser
);
22104 && c_parser_next_token_is (parser
, CPP_NAME
)
22105 && strcmp (IDENTIFIER_POINTER (token
->value
), "score") == 0
22106 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
22108 c_parser_consume_token (parser
);
22110 matching_parens parens2
;
22111 parens2
.require_open (parser
);
22112 tree score
= c_parser_expr_no_commas (parser
, NULL
).value
;
22113 parens2
.skip_until_found_close (parser
);
22114 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
22115 if (score
!= error_mark_node
)
22117 mark_exp_read (score
);
22118 score
= c_fully_fold (score
, false, NULL
);
22119 if (!INTEGRAL_TYPE_P (TREE_TYPE (score
))
22120 || TREE_CODE (score
) != INTEGER_CST
)
22121 error_at (token
->location
, "score argument must be "
22122 "constant integer expression");
22123 else if (tree_int_cst_sgn (score
) < 0)
22124 error_at (token
->location
, "score argument must be "
22127 properties
= tree_cons (get_identifier (" score"),
22128 score
, properties
);
22130 token
= c_parser_peek_token (parser
);
22133 switch (property_kind
)
22136 case CTX_PROPERTY_USER
:
22139 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
22140 if (TREE_CODE (t
) == STRING_CST
)
22141 properties
= tree_cons (NULL_TREE
, t
, properties
);
22142 else if (t
!= error_mark_node
)
22145 t
= c_fully_fold (t
, false, NULL
);
22146 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
22147 || !tree_fits_shwi_p (t
))
22148 error_at (token
->location
, "property must be "
22149 "constant integer expression or string "
22152 properties
= tree_cons (NULL_TREE
, t
, properties
);
22155 return error_mark_node
;
22157 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22158 c_parser_consume_token (parser
);
22164 case CTX_PROPERTY_ID
:
22165 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
22166 || c_parser_next_token_is (parser
, CPP_NAME
))
22168 tree prop
= c_parser_peek_token (parser
)->value
;
22169 c_parser_consume_token (parser
);
22170 properties
= tree_cons (prop
, NULL_TREE
, properties
);
22174 c_parser_error (parser
, "expected identifier");
22175 return error_mark_node
;
22178 case CTX_PROPERTY_NAME_LIST
:
22181 tree prop
= NULL_TREE
, value
= NULL_TREE
;
22182 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
22183 || c_parser_next_token_is (parser
, CPP_NAME
))
22185 prop
= c_parser_peek_token (parser
)->value
;
22186 c_parser_consume_token (parser
);
22188 else if (c_parser_next_token_is (parser
, CPP_STRING
))
22189 value
= c_parser_string_literal (parser
, false,
22193 c_parser_error (parser
, "expected identifier or "
22195 return error_mark_node
;
22198 properties
= tree_cons (prop
, value
, properties
);
22200 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22201 c_parser_consume_token (parser
);
22207 case CTX_PROPERTY_EXPR
:
22208 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
22209 if (t
!= error_mark_node
)
22212 t
= c_fully_fold (t
, false, NULL
);
22213 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
22214 || !tree_fits_shwi_p (t
))
22215 error_at (token
->location
, "property must be "
22216 "constant integer expression");
22218 properties
= tree_cons (NULL_TREE
, t
, properties
);
22221 return error_mark_node
;
22223 case CTX_PROPERTY_SIMD
:
22224 if (parms
== NULL_TREE
)
22226 error_at (token
->location
, "properties for %<simd%> "
22227 "selector may not be specified in "
22228 "%<metadirective%>");
22229 return error_mark_node
;
22232 c
= c_parser_omp_all_clauses (parser
,
22233 OMP_DECLARE_SIMD_CLAUSE_MASK
,
22235 c
= c_omp_declare_simd_clauses_to_numbers (parms
22237 ? NULL_TREE
: parms
,
22242 gcc_unreachable ();
22245 parens
.skip_until_found_close (parser
);
22246 properties
= nreverse (properties
);
22248 else if (property_kind
== CTX_PROPERTY_NAME_LIST
22249 || property_kind
== CTX_PROPERTY_ID
22250 || property_kind
== CTX_PROPERTY_EXPR
)
22252 c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>");
22253 return error_mark_node
;
22256 ret
= tree_cons (selector
, properties
, ret
);
22258 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22259 c_parser_consume_token (parser
);
22265 return nreverse (ret
);
22270 trait-set-selector[,trait-set-selector[,...]]
22272 trait-set-selector:
22273 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
22275 trait-set-selector-name:
22282 c_parser_omp_context_selector_specification (c_parser
*parser
, tree parms
)
22284 tree ret
= NULL_TREE
;
22287 const char *setp
= "";
22288 if (c_parser_next_token_is (parser
, CPP_NAME
))
22289 setp
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22293 if (strcmp (setp
, "construct") == 0)
22297 if (strcmp (setp
, "device") == 0)
22301 if (strcmp (setp
, "implementation") == 0)
22305 if (strcmp (setp
, "user") == 0)
22313 c_parser_error (parser
, "expected %<construct%>, %<device%>, "
22314 "%<implementation%> or %<user%>");
22315 return error_mark_node
;
22318 tree set
= c_parser_peek_token (parser
)->value
;
22319 c_parser_consume_token (parser
);
22321 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
22322 return error_mark_node
;
22324 matching_braces braces
;
22325 if (!braces
.require_open (parser
))
22326 return error_mark_node
;
22328 tree selectors
= c_parser_omp_context_selector (parser
, set
, parms
);
22329 if (selectors
== error_mark_node
)
22330 ret
= error_mark_node
;
22331 else if (ret
!= error_mark_node
)
22332 ret
= tree_cons (set
, selectors
, ret
);
22334 braces
.skip_until_found_close (parser
);
22336 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22337 c_parser_consume_token (parser
);
22343 if (ret
== error_mark_node
)
22345 return nreverse (ret
);
22348 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
22349 that into "omp declare variant base" attribute. */
22352 c_finish_omp_declare_variant (c_parser
*parser
, tree fndecl
, tree parms
)
22354 matching_parens parens
;
22355 if (!parens
.require_open (parser
))
22358 c_parser_skip_to_pragma_eol (parser
, false);
22362 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
22363 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
22365 c_parser_error (parser
, "expected identifier");
22369 c_token
*token
= c_parser_peek_token (parser
);
22370 tree variant
= lookup_name (token
->value
);
22372 if (variant
== NULL_TREE
)
22374 undeclared_variable (token
->location
, token
->value
);
22375 variant
= error_mark_node
;
22378 c_parser_consume_token (parser
);
22380 parens
.require_close (parser
);
22382 const char *clause
= "";
22383 location_t match_loc
= c_parser_peek_token (parser
)->location
;
22384 if (c_parser_next_token_is (parser
, CPP_NAME
))
22385 clause
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22386 if (strcmp (clause
, "match"))
22388 c_parser_error (parser
, "expected %<match%>");
22392 c_parser_consume_token (parser
);
22394 if (!parens
.require_open (parser
))
22397 if (parms
== NULL_TREE
)
22398 parms
= error_mark_node
;
22400 tree ctx
= c_parser_omp_context_selector_specification (parser
, parms
);
22401 if (ctx
== error_mark_node
)
22403 ctx
= omp_check_context_selector (match_loc
, ctx
);
22404 if (ctx
!= error_mark_node
&& variant
!= error_mark_node
)
22406 if (TREE_CODE (variant
) != FUNCTION_DECL
)
22408 error_at (token
->location
, "variant %qD is not a function", variant
);
22409 variant
= error_mark_node
;
22411 else if (omp_get_context_selector (ctx
, "construct", "simd") == NULL_TREE
22412 && !comptypes (TREE_TYPE (fndecl
), TREE_TYPE (variant
)))
22414 error_at (token
->location
, "variant %qD and base %qD have "
22415 "incompatible types", variant
, fndecl
);
22416 variant
= error_mark_node
;
22418 else if (fndecl_built_in_p (variant
)
22419 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
22420 "__builtin_", strlen ("__builtin_")) == 0
22421 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
22422 "__sync_", strlen ("__sync_")) == 0
22423 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
22424 "__atomic_", strlen ("__atomic_")) == 0))
22426 error_at (token
->location
, "variant %qD is a built-in", variant
);
22427 variant
= error_mark_node
;
22429 if (variant
!= error_mark_node
)
22431 C_DECL_USED (variant
) = 1;
22432 tree construct
= omp_get_context_selector (ctx
, "construct", NULL
);
22433 omp_mark_declare_variant (match_loc
, variant
, construct
);
22434 if (omp_context_selector_matches (ctx
))
22437 = tree_cons (get_identifier ("omp declare variant base"),
22438 build_tree_list (variant
, ctx
),
22439 DECL_ATTRIBUTES (fndecl
));
22440 DECL_ATTRIBUTES (fndecl
) = attr
;
22445 parens
.require_close (parser
);
22446 c_parser_skip_to_pragma_eol (parser
);
22449 /* Finalize #pragma omp declare simd or #pragma omp declare variant
22450 clauses after FNDECL has been parsed, and put that into "omp declare simd"
22451 or "omp declare variant base" attribute. */
22454 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
22455 vec
<c_token
> *pclauses
)
22457 vec
<c_token
> &clauses
= *pclauses
;
22459 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
22460 indicates error has been reported and CPP_PRAGMA that
22461 c_finish_omp_declare_simd has already processed the tokens. */
22462 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
22464 const char *kind
= "simd";
22465 if (clauses
.exists ()
22466 && (clauses
[0].type
== CPP_NAME
|| clauses
[0].type
== CPP_PRAGMA
))
22467 kind
= IDENTIFIER_POINTER (clauses
[0].value
);
22468 gcc_assert (strcmp (kind
, "simd") == 0 || strcmp (kind
, "variant") == 0);
22469 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
22471 error ("%<#pragma omp declare %s%> not immediately followed by "
22472 "a function declaration or definition", kind
);
22473 clauses
[0].type
= CPP_EOF
;
22476 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
22478 error_at (DECL_SOURCE_LOCATION (fndecl
),
22479 "%<#pragma omp declare %s%> not immediately followed by "
22480 "a single function declaration or definition", kind
);
22481 clauses
[0].type
= CPP_EOF
;
22485 if (parms
== NULL_TREE
)
22486 parms
= DECL_ARGUMENTS (fndecl
);
22488 unsigned int tokens_avail
= parser
->tokens_avail
;
22489 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
22491 parser
->tokens
= clauses
.address ();
22492 parser
->tokens_avail
= clauses
.length ();
22494 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
22495 while (parser
->tokens_avail
> 3)
22497 c_token
*token
= c_parser_peek_token (parser
);
22498 gcc_assert (token
->type
== CPP_NAME
22499 && strcmp (IDENTIFIER_POINTER (token
->value
), kind
) == 0);
22500 c_parser_consume_token (parser
);
22501 parser
->in_pragma
= true;
22503 if (strcmp (kind
, "simd") == 0)
22506 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
22507 "#pragma omp declare simd");
22508 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
22509 if (c
!= NULL_TREE
)
22510 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
22511 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
22512 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
22513 DECL_ATTRIBUTES (fndecl
) = c
;
22517 gcc_assert (strcmp (kind
, "variant") == 0);
22518 c_finish_omp_declare_variant (parser
, fndecl
, parms
);
22522 parser
->tokens
= &parser
->tokens_buf
[0];
22523 parser
->tokens_avail
= tokens_avail
;
22524 if (clauses
.exists ())
22525 clauses
[0].type
= CPP_PRAGMA
;
22530 # pragma omp declare target new-line
22531 declarations and definitions
22532 # pragma omp end declare target new-line
22535 # pragma omp declare target ( extended-list ) new-line
22537 # pragma omp declare target declare-target-clauses[seq] new-line */
22539 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
22540 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
22541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
22542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
22543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
22546 c_parser_omp_declare_target (c_parser
*parser
)
22548 tree clauses
= NULL_TREE
;
22549 int device_type
= 0;
22550 bool only_device_type
= true;
22551 if (c_parser_next_token_is (parser
, CPP_NAME
))
22552 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
22553 "#pragma omp declare target");
22554 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
22556 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ENTER
,
22558 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
22559 c_parser_skip_to_pragma_eol (parser
);
22563 c_parser_skip_to_pragma_eol (parser
);
22564 c_omp_declare_target_attr attr
= { -1 };
22565 vec_safe_push (current_omp_declare_target_attribute
, attr
);
22568 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
22569 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
22570 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
22571 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
22573 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
22575 tree t
= OMP_CLAUSE_DECL (c
), id
;
22576 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
22577 tree at2
= lookup_attribute ("omp declare target link",
22578 DECL_ATTRIBUTES (t
));
22579 only_device_type
= false;
22580 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
22582 id
= get_identifier ("omp declare target link");
22583 std::swap (at1
, at2
);
22586 id
= get_identifier ("omp declare target");
22589 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_ENTER
)
22590 error_at (OMP_CLAUSE_LOCATION (c
),
22591 "%qD specified both in declare target %<link%> and %qs"
22592 " clauses", t
, OMP_CLAUSE_ENTER_TO (c
) ? "to" : "enter");
22594 error_at (OMP_CLAUSE_LOCATION (c
),
22595 "%qD specified both in declare target %<link%> and "
22596 "%<to%> or %<enter%> clauses", t
);
22601 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
22602 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
22605 symtab_node
*node
= symtab_node::get (t
);
22608 node
->offloadable
= 1;
22609 if (ENABLE_OFFLOADING
)
22611 g
->have_offload
= true;
22612 if (is_a
<varpool_node
*> (node
))
22613 vec_safe_push (offload_vars
, t
);
22617 if (TREE_CODE (t
) != FUNCTION_DECL
)
22619 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_HOST
) != 0)
22621 tree at3
= lookup_attribute ("omp declare target host",
22622 DECL_ATTRIBUTES (t
));
22623 if (at3
== NULL_TREE
)
22625 id
= get_identifier ("omp declare target host");
22626 DECL_ATTRIBUTES (t
)
22627 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
22630 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_NOHOST
) != 0)
22632 tree at3
= lookup_attribute ("omp declare target nohost",
22633 DECL_ATTRIBUTES (t
));
22634 if (at3
== NULL_TREE
)
22636 id
= get_identifier ("omp declare target nohost");
22637 DECL_ATTRIBUTES (t
)
22638 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
22642 if (device_type
&& only_device_type
)
22643 error_at (OMP_CLAUSE_LOCATION (clauses
),
22644 "directive with only %<device_type%> clause");
22648 #pragma omp begin assumes clauses[optseq] new-line
22650 #pragma omp begin declare target clauses[optseq] new-line */
22652 #define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \
22653 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE)
22656 c_parser_omp_begin (c_parser
*parser
)
22658 const char *p
= "";
22659 c_parser_consume_pragma (parser
);
22660 if (c_parser_next_token_is (parser
, CPP_NAME
))
22661 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22662 if (strcmp (p
, "declare") == 0)
22664 c_parser_consume_token (parser
);
22666 if (c_parser_next_token_is (parser
, CPP_NAME
))
22667 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22668 if (strcmp (p
, "target") == 0)
22670 c_parser_consume_token (parser
);
22672 = c_parser_omp_all_clauses (parser
,
22673 OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK
,
22674 "#pragma omp begin declare target");
22675 int device_type
= 0;
22676 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
22677 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
22678 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
22679 c_omp_declare_target_attr attr
= { device_type
};
22680 vec_safe_push (current_omp_declare_target_attribute
, attr
);
22684 c_parser_error (parser
, "expected %<target%>");
22685 c_parser_skip_to_pragma_eol (parser
);
22688 else if (strcmp (p
, "assumes") == 0)
22690 c_parser_consume_token (parser
);
22691 c_parser_omp_assumption_clauses (parser
, false);
22692 current_omp_begin_assumes
++;
22696 c_parser_error (parser
, "expected %<declare target%> or %<assumes%>");
22697 c_parser_skip_to_pragma_eol (parser
);
22702 #pragma omp end declare target
22705 #pragma omp end assumes */
22708 c_parser_omp_end (c_parser
*parser
)
22710 location_t loc
= c_parser_peek_token (parser
)->location
;
22711 const char *p
= "";
22712 c_parser_consume_pragma (parser
);
22713 if (c_parser_next_token_is (parser
, CPP_NAME
))
22714 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22715 if (strcmp (p
, "declare") == 0)
22717 c_parser_consume_token (parser
);
22718 if (c_parser_next_token_is (parser
, CPP_NAME
)
22719 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
22721 c_parser_consume_token (parser
);
22724 c_parser_error (parser
, "expected %<target%>");
22725 c_parser_skip_to_pragma_eol (parser
);
22728 c_parser_skip_to_pragma_eol (parser
);
22729 if (!vec_safe_length (current_omp_declare_target_attribute
))
22730 error_at (loc
, "%<#pragma omp end declare target%> without "
22731 "corresponding %<#pragma omp declare target%> or "
22732 "%<#pragma omp begin declare target%>");
22734 current_omp_declare_target_attribute
->pop ();
22736 else if (strcmp (p
, "assumes") == 0)
22738 c_parser_consume_token (parser
);
22739 c_parser_skip_to_pragma_eol (parser
);
22740 if (!current_omp_begin_assumes
)
22741 error_at (loc
, "%qs without corresponding %qs",
22742 "#pragma omp end assumes", "#pragma omp begin assumes");
22744 current_omp_begin_assumes
--;
22748 c_parser_error (parser
, "expected %<declare%> or %<assumes%>");
22749 c_parser_skip_to_pragma_eol (parser
);
22754 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22755 initializer-clause[opt] new-line
22757 initializer-clause:
22758 initializer (omp_priv = initializer)
22759 initializer (function-name (argument-list)) */
22762 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
22764 unsigned int tokens_avail
= 0, i
;
22765 vec
<tree
> types
= vNULL
;
22766 vec
<c_token
> clauses
= vNULL
;
22767 enum tree_code reduc_code
= ERROR_MARK
;
22768 tree reduc_id
= NULL_TREE
;
22770 location_t rloc
= c_parser_peek_token (parser
)->location
;
22772 if (context
== pragma_struct
|| context
== pragma_param
)
22774 error ("%<#pragma omp declare reduction%> not at file or block scope");
22778 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
22781 switch (c_parser_peek_token (parser
)->type
)
22784 reduc_code
= PLUS_EXPR
;
22787 reduc_code
= MULT_EXPR
;
22790 reduc_code
= MINUS_EXPR
;
22793 reduc_code
= BIT_AND_EXPR
;
22796 reduc_code
= BIT_XOR_EXPR
;
22799 reduc_code
= BIT_IOR_EXPR
;
22802 reduc_code
= TRUTH_ANDIF_EXPR
;
22805 reduc_code
= TRUTH_ORIF_EXPR
;
22809 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22810 if (strcmp (p
, "min") == 0)
22812 reduc_code
= MIN_EXPR
;
22815 if (strcmp (p
, "max") == 0)
22817 reduc_code
= MAX_EXPR
;
22820 reduc_id
= c_parser_peek_token (parser
)->value
;
22823 c_parser_error (parser
,
22824 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
22825 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
22829 tree orig_reduc_id
, reduc_decl
;
22830 orig_reduc_id
= reduc_id
;
22831 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
22832 reduc_decl
= c_omp_reduction_decl (reduc_id
);
22833 c_parser_consume_token (parser
);
22835 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
22840 location_t loc
= c_parser_peek_token (parser
)->location
;
22841 struct c_type_name
*ctype
= c_parser_type_name (parser
);
22844 type
= groktypename (ctype
, NULL
, NULL
);
22845 if (type
== error_mark_node
)
22847 else if ((INTEGRAL_TYPE_P (type
)
22848 || TREE_CODE (type
) == REAL_TYPE
22849 || TREE_CODE (type
) == COMPLEX_TYPE
)
22850 && orig_reduc_id
== NULL_TREE
)
22851 error_at (loc
, "predeclared arithmetic type in "
22852 "%<#pragma omp declare reduction%>");
22853 else if (TREE_CODE (type
) == FUNCTION_TYPE
22854 || TREE_CODE (type
) == ARRAY_TYPE
)
22855 error_at (loc
, "function or array type in "
22856 "%<#pragma omp declare reduction%>");
22857 else if (TYPE_ATOMIC (type
))
22858 error_at (loc
, "%<_Atomic%> qualified type in "
22859 "%<#pragma omp declare reduction%>");
22860 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
22861 error_at (loc
, "const, volatile or restrict qualified type in "
22862 "%<#pragma omp declare reduction%>");
22866 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
22867 if (comptypes (TREE_PURPOSE (t
), type
))
22869 error_at (loc
, "redeclaration of %qs "
22870 "%<#pragma omp declare reduction%> for "
22872 IDENTIFIER_POINTER (reduc_id
)
22873 + sizeof ("omp declare reduction ") - 1,
22876 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
22878 error_at (ploc
, "previous %<#pragma omp declare "
22882 if (t
== NULL_TREE
)
22883 types
.safe_push (type
);
22885 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22886 c_parser_consume_token (parser
);
22894 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
22895 || types
.is_empty ())
22898 clauses
.release ();
22902 c_token
*token
= c_parser_peek_token (parser
);
22903 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
22905 c_parser_consume_token (parser
);
22907 c_parser_skip_to_pragma_eol (parser
);
22911 if (types
.length () > 1)
22913 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
22915 c_token
*token
= c_parser_peek_token (parser
);
22916 if (token
->type
== CPP_EOF
)
22918 clauses
.safe_push (*token
);
22919 c_parser_consume_token (parser
);
22921 clauses
.safe_push (*c_parser_peek_token (parser
));
22922 c_parser_skip_to_pragma_eol (parser
);
22924 /* Make sure nothing tries to read past the end of the tokens. */
22926 memset (&eof_token
, 0, sizeof (eof_token
));
22927 eof_token
.type
= CPP_EOF
;
22928 clauses
.safe_push (eof_token
);
22929 clauses
.safe_push (eof_token
);
22932 int errs
= errorcount
;
22933 FOR_EACH_VEC_ELT (types
, i
, type
)
22935 tokens_avail
= parser
->tokens_avail
;
22936 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
22937 if (!clauses
.is_empty ())
22939 parser
->tokens
= clauses
.address ();
22940 parser
->tokens_avail
= clauses
.length ();
22941 parser
->in_pragma
= true;
22944 bool nested
= current_function_decl
!= NULL_TREE
;
22946 c_push_function_context ();
22947 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
22948 reduc_id
, default_function_type
);
22949 current_function_decl
= fndecl
;
22950 allocate_struct_function (fndecl
, true);
22952 tree stmt
= push_stmt_list ();
22953 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
22954 warn about these. */
22955 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22956 get_identifier ("omp_out"), type
);
22957 DECL_ARTIFICIAL (omp_out
) = 1;
22958 DECL_CONTEXT (omp_out
) = fndecl
;
22959 pushdecl (omp_out
);
22960 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22961 get_identifier ("omp_in"), type
);
22962 DECL_ARTIFICIAL (omp_in
) = 1;
22963 DECL_CONTEXT (omp_in
) = fndecl
;
22965 struct c_expr combiner
= c_parser_expression (parser
);
22966 struct c_expr initializer
;
22967 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
22969 initializer
.set_error ();
22970 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
22972 else if (c_parser_next_token_is (parser
, CPP_NAME
)
22973 && strcmp (IDENTIFIER_POINTER
22974 (c_parser_peek_token (parser
)->value
),
22975 "initializer") == 0)
22977 c_parser_consume_token (parser
);
22980 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22981 get_identifier ("omp_priv"), type
);
22982 DECL_ARTIFICIAL (omp_priv
) = 1;
22983 DECL_INITIAL (omp_priv
) = error_mark_node
;
22984 DECL_CONTEXT (omp_priv
) = fndecl
;
22985 pushdecl (omp_priv
);
22986 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22987 get_identifier ("omp_orig"), type
);
22988 DECL_ARTIFICIAL (omp_orig
) = 1;
22989 DECL_CONTEXT (omp_orig
) = fndecl
;
22990 pushdecl (omp_orig
);
22991 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
22993 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
22995 c_parser_error (parser
, "expected %<omp_priv%> or "
22999 else if (strcmp (IDENTIFIER_POINTER
23000 (c_parser_peek_token (parser
)->value
),
23003 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
23004 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
23006 c_parser_error (parser
, "expected function-name %<(%>");
23010 initializer
= c_parser_postfix_expression (parser
);
23011 if (initializer
.value
23012 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
23015 tree c
= initializer
.value
;
23016 for (j
= 0; j
< call_expr_nargs (c
); j
++)
23018 tree a
= CALL_EXPR_ARG (c
, j
);
23020 if (TREE_CODE (a
) == ADDR_EXPR
23021 && TREE_OPERAND (a
, 0) == omp_priv
)
23024 if (j
== call_expr_nargs (c
))
23025 error ("one of the initializer call arguments should be "
23031 c_parser_consume_token (parser
);
23032 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
23036 tree st
= push_stmt_list ();
23037 location_t loc
= c_parser_peek_token (parser
)->location
;
23038 rich_location
richloc (line_table
, loc
);
23039 start_init (omp_priv
, NULL_TREE
, 0, &richloc
);
23040 struct c_expr init
= c_parser_initializer (parser
, omp_priv
);
23042 finish_decl (omp_priv
, loc
, init
.value
,
23043 init
.original_type
, NULL_TREE
);
23044 pop_stmt_list (st
);
23048 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
23054 c_parser_skip_to_pragma_eol (parser
);
23056 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
23057 DECL_INITIAL (reduc_decl
));
23058 DECL_INITIAL (reduc_decl
) = t
;
23059 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
23060 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
23061 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
23062 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
23063 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
23064 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
23067 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
23068 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
23069 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
23070 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
23071 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
23072 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
23073 walk_tree (&DECL_INITIAL (omp_priv
),
23074 c_check_omp_declare_reduction_r
,
23075 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
23079 pop_stmt_list (stmt
);
23081 if (cfun
->language
!= NULL
)
23083 ggc_free (cfun
->language
);
23084 cfun
->language
= NULL
;
23087 current_function_decl
= NULL_TREE
;
23089 c_pop_function_context ();
23091 if (!clauses
.is_empty ())
23093 parser
->tokens
= &parser
->tokens_buf
[0];
23094 parser
->tokens_avail
= tokens_avail
;
23098 if (errs
!= errorcount
)
23102 clauses
.release ();
23108 #pragma omp declare simd declare-simd-clauses[optseq] new-line
23109 #pragma omp declare reduction (reduction-id : typename-list : expression) \
23110 initializer-clause[opt] new-line
23111 #pragma omp declare target new-line
23114 #pragma omp declare variant (identifier) match (context-selector) */
23117 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
23119 c_parser_consume_pragma (parser
);
23120 if (c_parser_next_token_is (parser
, CPP_NAME
))
23122 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23123 if (strcmp (p
, "simd") == 0)
23125 /* c_parser_consume_token (parser); done in
23126 c_parser_omp_declare_simd. */
23127 c_parser_omp_declare_simd (parser
, context
);
23130 if (strcmp (p
, "reduction") == 0)
23132 c_parser_consume_token (parser
);
23133 c_parser_omp_declare_reduction (parser
, context
);
23136 if (!flag_openmp
) /* flag_openmp_simd */
23138 c_parser_skip_to_pragma_eol (parser
, false);
23141 if (strcmp (p
, "target") == 0)
23143 c_parser_consume_token (parser
);
23144 c_parser_omp_declare_target (parser
);
23147 if (strcmp (p
, "variant") == 0)
23149 /* c_parser_consume_token (parser); done in
23150 c_parser_omp_declare_simd. */
23151 c_parser_omp_declare_simd (parser
, context
);
23156 c_parser_error (parser
, "expected %<simd%>, %<reduction%>, "
23157 "%<target%> or %<variant%>");
23158 c_parser_skip_to_pragma_eol (parser
);
23163 #pragma omp requires clauses[optseq] new-line */
23166 c_parser_omp_requires (c_parser
*parser
)
23169 enum omp_requires new_req
= (enum omp_requires
) 0;
23171 c_parser_consume_pragma (parser
);
23173 location_t loc
= c_parser_peek_token (parser
)->location
;
23174 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
23177 && c_parser_next_token_is (parser
, CPP_COMMA
)
23178 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
23179 c_parser_consume_token (parser
);
23183 if (c_parser_next_token_is (parser
, CPP_NAME
))
23186 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23187 location_t cloc
= c_parser_peek_token (parser
)->location
;
23188 enum omp_requires this_req
= (enum omp_requires
) 0;
23190 if (!strcmp (p
, "unified_address"))
23191 this_req
= OMP_REQUIRES_UNIFIED_ADDRESS
;
23192 else if (!strcmp (p
, "unified_shared_memory"))
23193 this_req
= OMP_REQUIRES_UNIFIED_SHARED_MEMORY
;
23194 else if (!strcmp (p
, "dynamic_allocators"))
23195 this_req
= OMP_REQUIRES_DYNAMIC_ALLOCATORS
;
23196 else if (!strcmp (p
, "reverse_offload"))
23197 this_req
= OMP_REQUIRES_REVERSE_OFFLOAD
;
23198 else if (!strcmp (p
, "atomic_default_mem_order"))
23200 c_parser_consume_token (parser
);
23202 matching_parens parens
;
23203 if (parens
.require_open (parser
))
23205 if (c_parser_next_token_is (parser
, CPP_NAME
))
23207 tree v
= c_parser_peek_token (parser
)->value
;
23208 p
= IDENTIFIER_POINTER (v
);
23210 if (!strcmp (p
, "seq_cst"))
23212 = (enum omp_requires
) OMP_MEMORY_ORDER_SEQ_CST
;
23213 else if (!strcmp (p
, "relaxed"))
23215 = (enum omp_requires
) OMP_MEMORY_ORDER_RELAXED
;
23216 else if (!strcmp (p
, "acq_rel"))
23218 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQ_REL
;
23222 error_at (c_parser_peek_token (parser
)->location
,
23223 "expected %<seq_cst%>, %<relaxed%> or "
23225 switch (c_parser_peek_token (parser
)->type
)
23228 case CPP_PRAGMA_EOL
:
23229 case CPP_CLOSE_PAREN
:
23232 if (c_parser_peek_2nd_token (parser
)->type
23233 == CPP_CLOSE_PAREN
)
23234 c_parser_consume_token (parser
);
23239 c_parser_consume_token (parser
);
23241 parens
.skip_until_found_close (parser
);
23244 c_parser_skip_to_pragma_eol (parser
, false);
23252 error_at (cloc
, "expected %<unified_address%>, "
23253 "%<unified_shared_memory%>, "
23254 "%<dynamic_allocators%>, "
23255 "%<reverse_offload%> "
23256 "or %<atomic_default_mem_order%> clause");
23257 c_parser_skip_to_pragma_eol (parser
, false);
23261 c_parser_consume_token (parser
);
23264 if ((this_req
& ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
23266 if ((this_req
& new_req
) != 0)
23267 error_at (cloc
, "too many %qs clauses", p
);
23268 if (this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
23269 && (omp_requires_mask
& OMP_REQUIRES_TARGET_USED
) != 0)
23270 error_at (cloc
, "%qs clause used lexically after first "
23271 "target construct or offloading API", p
);
23273 else if ((new_req
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
23275 error_at (cloc
, "too many %qs clauses",
23276 "atomic_default_mem_order");
23277 this_req
= (enum omp_requires
) 0;
23279 else if ((omp_requires_mask
23280 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
23282 error_at (cloc
, "more than one %<atomic_default_mem_order%>"
23283 " clause in a single compilation unit");
23285 = (enum omp_requires
)
23287 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
);
23289 else if ((omp_requires_mask
23290 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
) != 0)
23291 error_at (cloc
, "%<atomic_default_mem_order%> clause used "
23292 "lexically after first %<atomic%> construct "
23293 "without memory order clause");
23294 new_req
= (enum omp_requires
) (new_req
| this_req
);
23296 = (enum omp_requires
) (omp_requires_mask
| this_req
);
23302 c_parser_skip_to_pragma_eol (parser
);
23305 error_at (loc
, "%<pragma omp requires%> requires at least one clause");
23308 /* Helper function for c_parser_omp_taskloop.
23309 Disallow zero sized or potentially zero sized task reductions. */
23312 c_finish_taskloop_clauses (tree clauses
)
23314 tree
*pc
= &clauses
;
23315 for (tree c
= clauses
; c
; c
= *pc
)
23317 bool remove
= false;
23318 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
23320 tree type
= strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
23321 if (integer_zerop (TYPE_SIZE_UNIT (type
)))
23323 error_at (OMP_CLAUSE_LOCATION (c
),
23324 "zero sized type %qT in %<reduction%> clause", type
);
23327 else if (TREE_CODE (TYPE_SIZE_UNIT (type
)) != INTEGER_CST
)
23329 error_at (OMP_CLAUSE_LOCATION (c
),
23330 "variable sized type %qT in %<reduction%> clause",
23336 *pc
= OMP_CLAUSE_CHAIN (c
);
23338 pc
= &OMP_CLAUSE_CHAIN (c
);
23344 #pragma omp taskloop taskloop-clause[optseq] new-line
23347 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
23350 #define OMP_TASKLOOP_CLAUSE_MASK \
23351 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23354 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23355 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23356 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
23357 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
23358 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23359 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
23360 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23361 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
23362 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
23363 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
23364 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
23365 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23366 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23367 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
23370 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
23371 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
23374 tree clauses
, block
, ret
;
23376 strcat (p_name
, " taskloop");
23377 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
23378 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
23380 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
)) != 0)
23381 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_IN_REDUCTION
);
23383 if (c_parser_next_token_is (parser
, CPP_NAME
))
23385 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23387 if (strcmp (p
, "simd") == 0)
23389 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
23390 if (cclauses
== NULL
)
23391 cclauses
= cclauses_buf
;
23392 c_parser_consume_token (parser
);
23393 if (!flag_openmp
) /* flag_openmp_simd */
23394 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
23396 block
= c_begin_compound_stmt (true);
23397 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
23398 block
= c_end_compound_stmt (loc
, block
, true);
23401 ret
= make_node (OMP_TASKLOOP
);
23402 TREE_TYPE (ret
) = void_type_node
;
23403 OMP_FOR_BODY (ret
) = block
;
23404 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
23405 OMP_FOR_CLAUSES (ret
)
23406 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret
));
23407 SET_EXPR_LOCATION (ret
, loc
);
23412 if (!flag_openmp
) /* flag_openmp_simd */
23414 c_parser_skip_to_pragma_eol (parser
, false);
23418 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
23421 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
23422 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
23425 clauses
= c_finish_taskloop_clauses (clauses
);
23426 block
= c_begin_compound_stmt (true);
23427 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
23428 block
= c_end_compound_stmt (loc
, block
, true);
23435 #pragma omp nothing new-line */
23438 c_parser_omp_nothing (c_parser
*parser
)
23440 c_parser_consume_pragma (parser
);
23441 c_parser_skip_to_pragma_eol (parser
);
23445 #pragma omp error clauses[optseq] new-line */
23448 c_parser_omp_error (c_parser
*parser
, enum pragma_context context
)
23450 int at_compilation
= -1;
23451 int severity_fatal
= -1;
23452 tree message
= NULL_TREE
;
23455 location_t loc
= c_parser_peek_token (parser
)->location
;
23457 c_parser_consume_pragma (parser
);
23459 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
23462 && c_parser_next_token_is (parser
, CPP_COMMA
)
23463 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
23464 c_parser_consume_token (parser
);
23468 if (!c_parser_next_token_is (parser
, CPP_NAME
))
23472 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23473 location_t cloc
= c_parser_peek_token (parser
)->location
;
23474 static const char *args
[] = {
23475 "execution", "compilation", "warning", "fatal"
23478 int idx
= 0, n
= -1;
23479 tree m
= NULL_TREE
;
23481 if (!strcmp (p
, "at"))
23482 v
= &at_compilation
;
23483 else if (!strcmp (p
, "severity"))
23485 v
= &severity_fatal
;
23488 else if (strcmp (p
, "message"))
23491 "expected %<at%>, %<severity%> or %<message%> clause");
23492 c_parser_skip_to_pragma_eol (parser
, false);
23496 c_parser_consume_token (parser
);
23498 matching_parens parens
;
23499 if (parens
.require_open (parser
))
23503 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
23504 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
23505 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
23506 m
= convert (const_string_type_node
, expr
.value
);
23507 m
= c_fully_fold (m
, false, NULL
);
23511 if (c_parser_next_token_is (parser
, CPP_NAME
))
23513 tree val
= c_parser_peek_token (parser
)->value
;
23514 const char *q
= IDENTIFIER_POINTER (val
);
23516 if (!strcmp (q
, args
[idx
]))
23518 else if (!strcmp (q
, args
[idx
+ 1]))
23523 error_at (c_parser_peek_token (parser
)->location
,
23524 "expected %qs or %qs", args
[idx
], args
[idx
+ 1]);
23526 switch (c_parser_peek_token (parser
)->type
)
23529 case CPP_PRAGMA_EOL
:
23530 case CPP_CLOSE_PAREN
:
23533 if (c_parser_peek_2nd_token (parser
)->type
23534 == CPP_CLOSE_PAREN
)
23535 c_parser_consume_token (parser
);
23540 c_parser_consume_token (parser
);
23543 parens
.skip_until_found_close (parser
);
23549 error_at (cloc
, "too many %qs clauses", p
);
23559 error_at (cloc
, "too many %qs clauses", p
);
23569 c_parser_skip_to_pragma_eol (parser
);
23573 if (at_compilation
== -1)
23574 at_compilation
= 1;
23575 if (severity_fatal
== -1)
23576 severity_fatal
= 1;
23577 if (!at_compilation
)
23579 if (context
!= pragma_compound
)
23581 error_at (loc
, "%<#pragma omp error%> with %<at(execution)%> clause "
23582 "may only be used in compound statements");
23586 = builtin_decl_explicit (severity_fatal
? BUILT_IN_GOMP_ERROR
23587 : BUILT_IN_GOMP_WARNING
);
23589 message
= build_zero_cst (const_string_type_node
);
23590 tree stmt
= build_call_expr_loc (loc
, fndecl
, 2, message
,
23591 build_all_ones_cst (size_type_node
));
23595 const char *msg
= NULL
;
23598 msg
= c_getstr (message
);
23600 msg
= _("<message unknown at compile time>");
23603 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
23604 "%<pragma omp error%> encountered: %s", msg
);
23606 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
23607 "%<pragma omp error%> encountered");
23611 /* Assumption clauses:
23613 absent (directive-name-list)
23614 contains (directive-name-list)
23621 c_parser_omp_assumption_clauses (c_parser
*parser
, bool is_assume
)
23624 bool no_openmp
= false;
23625 bool no_openmp_routines
= false;
23626 bool no_parallelism
= false;
23627 bitmap_head absent_head
, contains_head
;
23629 bitmap_obstack_initialize (NULL
);
23630 bitmap_initialize (&absent_head
, &bitmap_default_obstack
);
23631 bitmap_initialize (&contains_head
, &bitmap_default_obstack
);
23633 if (c_parser_next_token_is (parser
, CPP_PRAGMA_EOL
))
23634 error_at (c_parser_peek_token (parser
)->location
,
23635 "expected at least one assumption clause");
23637 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
23640 && c_parser_next_token_is (parser
, CPP_COMMA
)
23641 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
23642 c_parser_consume_token (parser
);
23646 if (!c_parser_next_token_is (parser
, CPP_NAME
))
23650 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
23651 location_t cloc
= c_parser_peek_token (parser
)->location
;
23653 if (!strcmp (p
, "no_openmp"))
23655 c_parser_consume_token (parser
);
23657 error_at (cloc
, "too many %qs clauses", "no_openmp");
23660 else if (!strcmp (p
, "no_openmp_routines"))
23662 c_parser_consume_token (parser
);
23663 if (no_openmp_routines
)
23664 error_at (cloc
, "too many %qs clauses", "no_openmp_routines");
23665 no_openmp_routines
= true;
23667 else if (!strcmp (p
, "no_parallelism"))
23669 c_parser_consume_token (parser
);
23670 if (no_parallelism
)
23671 error_at (cloc
, "too many %qs clauses", "no_parallelism");
23672 no_parallelism
= true;
23674 else if (!strcmp (p
, "holds"))
23676 c_parser_consume_token (parser
);
23677 matching_parens parens
;
23678 if (parens
.require_open (parser
))
23680 location_t eloc
= c_parser_peek_token (parser
)->location
;
23681 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
23682 tree t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
23683 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
23684 t
= c_fully_fold (t
, false, NULL
);
23685 if (is_assume
&& t
!= error_mark_node
)
23687 tree fn
= build_call_expr_internal_loc (eloc
, IFN_ASSUME
,
23692 parens
.skip_until_found_close (parser
);
23695 else if (!strcmp (p
, "absent") || !strcmp (p
, "contains"))
23697 c_parser_consume_token (parser
);
23698 matching_parens parens
;
23699 if (parens
.require_open (parser
))
23703 const char *directive
[3] = {};
23705 location_t dloc
= c_parser_peek_token (parser
)->location
;
23706 for (i
= 0; i
< 3; i
++)
23709 if (c_parser_peek_nth_token (parser
, i
+ 1)->type
23711 id
= c_parser_peek_nth_token (parser
, i
+ 1)->value
;
23712 else if (c_parser_peek_nth_token (parser
, i
+ 1)->keyword
23716 = c_parser_peek_nth_token (parser
, i
+ 1)->keyword
;
23717 id
= ridpointers
[rid
];
23721 directive
[i
] = IDENTIFIER_POINTER (id
);
23724 error_at (dloc
, "expected directive name");
23727 const struct c_omp_directive
*dir
23728 = c_omp_categorize_directive (directive
[0],
23732 || dir
->kind
== C_OMP_DIR_DECLARATIVE
23733 || dir
->kind
== C_OMP_DIR_INFORMATIONAL
23734 || dir
->id
== PRAGMA_OMP_END
23735 || (!dir
->second
&& directive
[1])
23736 || (!dir
->third
&& directive
[2]))
23737 error_at (dloc
, "unknown OpenMP directive name in "
23738 "%qs clause argument", p
);
23741 int id
= dir
- c_omp_directives
;
23742 if (bitmap_bit_p (p
[0] == 'a' ? &contains_head
23743 : &absent_head
, id
))
23744 error_at (dloc
, "%<%s%s%s%s%s%> directive "
23745 "mentioned in both %<absent%> and "
23746 "%<contains%> clauses",
23748 directive
[1] ? " " : "",
23749 directive
[1] ? directive
[1] : "",
23750 directive
[2] ? " " : "",
23751 directive
[2] ? directive
[2] : "");
23752 else if (!bitmap_set_bit (p
[0] == 'a'
23754 : &contains_head
, id
))
23755 error_at (dloc
, "%<%s%s%s%s%s%> directive "
23756 "mentioned multiple times in %qs "
23759 directive
[1] ? " " : "",
23760 directive
[1] ? directive
[1] : "",
23761 directive
[2] ? " " : "",
23762 directive
[2] ? directive
[2] : "", p
);
23765 c_parser_consume_token (parser
);
23767 if (c_parser_next_token_is (parser
, CPP_COMMA
))
23768 c_parser_consume_token (parser
);
23773 parens
.skip_until_found_close (parser
);
23776 else if (startswith (p
, "ext_"))
23778 warning_at (cloc
, 0, "unknown assumption clause %qs", p
);
23779 c_parser_consume_token (parser
);
23780 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
23782 matching_parens parens
;
23783 parens
.consume_open (parser
);
23784 c_parser_balanced_token_sequence (parser
);
23785 parens
.require_close (parser
);
23790 c_parser_consume_token (parser
);
23791 error_at (cloc
, "expected assumption clause");
23795 c_parser_skip_to_pragma_eol (parser
);
23799 #pragma omp assume clauses[optseq] new-line */
23802 c_parser_omp_assume (c_parser
*parser
, bool *if_p
)
23804 c_parser_omp_assumption_clauses (parser
, true);
23805 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
23809 #pragma omp assumes clauses[optseq] new-line */
23812 c_parser_omp_assumes (c_parser
*parser
)
23814 c_parser_consume_pragma (parser
);
23815 c_parser_omp_assumption_clauses (parser
, false);
23818 /* Main entry point to parsing most OpenMP pragmas. */
23821 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
23823 enum pragma_kind p_kind
;
23826 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
23827 omp_clause_mask
mask (0);
23829 loc
= c_parser_peek_token (parser
)->location
;
23830 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
23831 c_parser_consume_pragma (parser
);
23835 case PRAGMA_OACC_ATOMIC
:
23836 c_parser_omp_atomic (loc
, parser
, true);
23838 case PRAGMA_OACC_CACHE
:
23839 strcpy (p_name
, "#pragma acc");
23840 stmt
= c_parser_oacc_cache (loc
, parser
);
23842 case PRAGMA_OACC_DATA
:
23843 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
23845 case PRAGMA_OACC_HOST_DATA
:
23846 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
23848 case PRAGMA_OACC_KERNELS
:
23849 case PRAGMA_OACC_PARALLEL
:
23850 case PRAGMA_OACC_SERIAL
:
23851 strcpy (p_name
, "#pragma acc");
23852 stmt
= c_parser_oacc_compute (loc
, parser
, p_kind
, p_name
, if_p
);
23854 case PRAGMA_OACC_LOOP
:
23855 strcpy (p_name
, "#pragma acc");
23856 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23858 case PRAGMA_OACC_WAIT
:
23859 strcpy (p_name
, "#pragma wait");
23860 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
23862 case PRAGMA_OMP_ALLOCATE
:
23863 c_parser_omp_allocate (loc
, parser
);
23865 case PRAGMA_OMP_ATOMIC
:
23866 c_parser_omp_atomic (loc
, parser
, false);
23868 case PRAGMA_OMP_CRITICAL
:
23869 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
23871 case PRAGMA_OMP_DISTRIBUTE
:
23872 strcpy (p_name
, "#pragma omp");
23873 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23875 case PRAGMA_OMP_FOR
:
23876 strcpy (p_name
, "#pragma omp");
23877 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23879 case PRAGMA_OMP_LOOP
:
23880 strcpy (p_name
, "#pragma omp");
23881 stmt
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23883 case PRAGMA_OMP_MASKED
:
23884 strcpy (p_name
, "#pragma omp");
23885 stmt
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23887 case PRAGMA_OMP_MASTER
:
23888 strcpy (p_name
, "#pragma omp");
23889 stmt
= c_parser_omp_master (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23891 case PRAGMA_OMP_PARALLEL
:
23892 strcpy (p_name
, "#pragma omp");
23893 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23895 case PRAGMA_OMP_SCOPE
:
23896 stmt
= c_parser_omp_scope (loc
, parser
, if_p
);
23898 case PRAGMA_OMP_SECTIONS
:
23899 strcpy (p_name
, "#pragma omp");
23900 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
23902 case PRAGMA_OMP_SIMD
:
23903 strcpy (p_name
, "#pragma omp");
23904 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23906 case PRAGMA_OMP_SINGLE
:
23907 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
23909 case PRAGMA_OMP_TASK
:
23910 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
23912 case PRAGMA_OMP_TASKGROUP
:
23913 stmt
= c_parser_omp_taskgroup (loc
, parser
, if_p
);
23915 case PRAGMA_OMP_TASKLOOP
:
23916 strcpy (p_name
, "#pragma omp");
23917 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23919 case PRAGMA_OMP_TEAMS
:
23920 strcpy (p_name
, "#pragma omp");
23921 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23923 case PRAGMA_OMP_ASSUME
:
23924 c_parser_omp_assume (parser
, if_p
);
23927 gcc_unreachable ();
23930 if (stmt
&& stmt
!= error_mark_node
)
23931 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
23936 # pragma omp threadprivate (variable-list) */
23939 c_parser_omp_threadprivate (c_parser
*parser
)
23944 c_parser_consume_pragma (parser
);
23945 loc
= c_parser_peek_token (parser
)->location
;
23946 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
23948 /* Mark every variable in VARS to be assigned thread local storage. */
23949 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
23951 tree v
= TREE_PURPOSE (t
);
23953 /* FIXME diagnostics: Ideally we should keep individual
23954 locations for all the variables in the var list to make the
23955 following errors more precise. Perhaps
23956 c_parser_omp_var_list_parens() should construct a list of
23957 locations to go along with the var list. */
23959 /* If V had already been marked threadprivate, it doesn't matter
23960 whether it had been used prior to this point. */
23962 error_at (loc
, "%qD is not a variable", v
);
23963 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
23964 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
23965 else if (! is_global_var (v
))
23966 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
23967 else if (TREE_TYPE (v
) == error_mark_node
)
23969 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
23970 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
23973 if (! DECL_THREAD_LOCAL_P (v
))
23975 set_decl_tls_model (v
, decl_default_tls_model (v
));
23976 /* If rtl has been already set for this var, call
23977 make_decl_rtl once again, so that encode_section_info
23978 has a chance to look at the new decl flags. */
23979 if (DECL_RTL_SET_P (v
))
23982 C_DECL_THREADPRIVATE_P (v
) = 1;
23986 c_parser_skip_to_pragma_eol (parser
);
23989 /* Parse a transaction attribute (GCC Extension).
23991 transaction-attribute:
23993 attribute-specifier
23997 c_parser_transaction_attributes (c_parser
*parser
)
23999 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
24000 return c_parser_gnu_attributes (parser
);
24002 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
24004 return c_parser_std_attribute_specifier (parser
, true);
24007 /* Parse a __transaction_atomic or __transaction_relaxed statement
24010 transaction-statement:
24011 __transaction_atomic transaction-attribute[opt] compound-statement
24012 __transaction_relaxed compound-statement
24014 Note that the only valid attribute is: "outer".
24018 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
24020 unsigned int old_in
= parser
->in_transaction
;
24021 unsigned int this_in
= 1, new_in
;
24022 location_t loc
= c_parser_peek_token (parser
)->location
;
24025 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
24026 || keyword
== RID_TRANSACTION_RELAXED
)
24027 && c_parser_next_token_is_keyword (parser
, keyword
));
24028 c_parser_consume_token (parser
);
24030 if (keyword
== RID_TRANSACTION_RELAXED
)
24031 this_in
|= TM_STMT_ATTR_RELAXED
;
24034 attrs
= c_parser_transaction_attributes (parser
);
24036 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
24039 /* Keep track if we're in the lexical scope of an outer transaction. */
24040 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
24042 parser
->in_transaction
= new_in
;
24043 stmt
= c_parser_compound_statement (parser
);
24044 parser
->in_transaction
= old_in
;
24047 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
24049 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
24050 "%<__transaction_atomic%> without transactional memory support enabled"
24051 : "%<__transaction_relaxed %> "
24052 "without transactional memory support enabled"));
24057 /* Parse a __transaction_atomic or __transaction_relaxed expression
24060 transaction-expression:
24061 __transaction_atomic ( expression )
24062 __transaction_relaxed ( expression )
24065 static struct c_expr
24066 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
24069 unsigned int old_in
= parser
->in_transaction
;
24070 unsigned int this_in
= 1;
24071 location_t loc
= c_parser_peek_token (parser
)->location
;
24074 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
24075 || keyword
== RID_TRANSACTION_RELAXED
)
24076 && c_parser_next_token_is_keyword (parser
, keyword
));
24077 c_parser_consume_token (parser
);
24079 if (keyword
== RID_TRANSACTION_RELAXED
)
24080 this_in
|= TM_STMT_ATTR_RELAXED
;
24083 attrs
= c_parser_transaction_attributes (parser
);
24085 this_in
|= parse_tm_stmt_attr (attrs
, 0);
24088 parser
->in_transaction
= this_in
;
24089 matching_parens parens
;
24090 if (parens
.require_open (parser
))
24092 tree expr
= c_parser_expression (parser
).value
;
24093 ret
.original_type
= TREE_TYPE (expr
);
24094 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
24095 if (this_in
& TM_STMT_ATTR_RELAXED
)
24096 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
24097 SET_EXPR_LOCATION (ret
.value
, loc
);
24098 ret
.original_code
= TRANSACTION_EXPR
;
24100 if (!parens
.require_close (parser
))
24102 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
24110 ret
.original_code
= ERROR_MARK
;
24111 ret
.original_type
= NULL
;
24113 parser
->in_transaction
= old_in
;
24116 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
24117 "%<__transaction_atomic%> without transactional memory support enabled"
24118 : "%<__transaction_relaxed %> "
24119 "without transactional memory support enabled"));
24121 set_c_expr_source_range (&ret
, loc
, loc
);
24126 /* Parse a __transaction_cancel statement (GCC Extension).
24128 transaction-cancel-statement:
24129 __transaction_cancel transaction-attribute[opt] ;
24131 Note that the only valid attribute is "outer".
24135 c_parser_transaction_cancel (c_parser
*parser
)
24137 location_t loc
= c_parser_peek_token (parser
)->location
;
24139 bool is_outer
= false;
24141 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
24142 c_parser_consume_token (parser
);
24144 attrs
= c_parser_transaction_attributes (parser
);
24146 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
24150 error_at (loc
, "%<__transaction_cancel%> without "
24151 "transactional memory support enabled");
24154 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
24156 error_at (loc
, "%<__transaction_cancel%> within a "
24157 "%<__transaction_relaxed%>");
24162 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
24163 && !is_tm_may_cancel_outer (current_function_decl
))
24165 error_at (loc
, "outer %<__transaction_cancel%> not "
24166 "within outer %<__transaction_atomic%> or "
24167 "a %<transaction_may_cancel_outer%> function");
24171 else if (parser
->in_transaction
== 0)
24173 error_at (loc
, "%<__transaction_cancel%> not within "
24174 "%<__transaction_atomic%>");
24178 return add_stmt (build_tm_abort_call (loc
, is_outer
));
24181 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
24184 /* Parse a single source file. */
24187 c_parse_file (void)
24189 /* Use local storage to begin. If the first token is a pragma, parse it.
24190 If it is #pragma GCC pch_preprocess, then this will load a PCH file
24191 which will cause garbage collection. */
24194 memset (&tparser
, 0, sizeof tparser
);
24195 tparser
.translate_strings_p
= true;
24196 tparser
.tokens
= &tparser
.tokens_buf
[0];
24197 the_parser
= &tparser
;
24199 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
24200 c_parser_pragma_pch_preprocess (&tparser
);
24202 c_common_no_more_pch ();
24204 the_parser
= ggc_alloc
<c_parser
> ();
24205 *the_parser
= tparser
;
24206 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
24207 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
24209 /* Initialize EH, if we've been told to do so. */
24210 if (flag_exceptions
)
24211 using_eh_for_cleanups ();
24213 c_parser_translation_unit (the_parser
);
24217 /* Parse the body of a function declaration marked with "__RTL".
24219 The RTL parser works on the level of characters read from a
24220 FILE *, whereas c_parser works at the level of tokens.
24221 Square this circle by consuming all of the tokens up to and
24222 including the closing brace, recording the start/end of the RTL
24223 fragment, and reopening the file and re-reading the relevant
24224 lines within the RTL parser.
24226 This requires the opening and closing braces of the C function
24227 to be on separate lines from the RTL they wrap.
24229 Take ownership of START_WITH_PASS, if non-NULL. */
24232 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
24234 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
24236 free (start_with_pass
);
24237 return c_parser_peek_token (parser
)->location
;
24240 location_t start_loc
= c_parser_peek_token (parser
)->location
;
24242 /* Consume all tokens, up to the closing brace, handling
24243 matching pairs of braces in the rtl dump. */
24244 int num_open_braces
= 1;
24247 switch (c_parser_peek_token (parser
)->type
)
24249 case CPP_OPEN_BRACE
:
24252 case CPP_CLOSE_BRACE
:
24253 if (--num_open_braces
== 0)
24254 goto found_closing_brace
;
24257 error_at (start_loc
, "no closing brace");
24258 free (start_with_pass
);
24259 return c_parser_peek_token (parser
)->location
;
24263 c_parser_consume_token (parser
);
24266 found_closing_brace
:
24267 /* At the closing brace; record its location. */
24268 location_t end_loc
= c_parser_peek_token (parser
)->location
;
24270 /* Consume the closing brace. */
24271 c_parser_consume_token (parser
);
24273 /* Invoke the RTL parser. */
24274 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
24276 free (start_with_pass
);
24280 /* Run the backend on the cfun created above, transferring ownership of
24281 START_WITH_PASS. */
24282 run_rtl_passes (start_with_pass
);
24286 #include "gt-c-c-parser.h"