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"
75 /* We need to walk over decls with incomplete struct/union/enum types
76 after parsing the whole translation unit.
77 In finish_decl(), if the decl is static, has incomplete
78 struct/union/enum type, it is appended to incomplete_record_decls.
79 In c_parser_translation_unit(), we iterate over incomplete_record_decls
80 and report error if any of the decls are still incomplete. */
82 vec
<tree
> incomplete_record_decls
;
85 set_c_expr_source_range (c_expr
*expr
,
86 location_t start
, location_t finish
)
88 expr
->src_range
.m_start
= start
;
89 expr
->src_range
.m_finish
= finish
;
91 set_source_range (expr
->value
, start
, finish
);
95 set_c_expr_source_range (c_expr
*expr
,
96 source_range src_range
)
98 expr
->src_range
= src_range
;
100 set_source_range (expr
->value
, src_range
);
104 /* Initialization routine for this file. */
109 /* The only initialization required is of the reserved word
115 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
116 the c_token structure. */
117 gcc_assert (RID_MAX
<= 255);
124 mask
|= D_ASM
| D_EXT
;
128 if (!c_dialect_objc ())
129 mask
|= D_OBJC
| D_CXX_OBJC
;
131 ridpointers
= ggc_cleared_vec_alloc
<tree
> ((int) RID_MAX
);
132 for (i
= 0; i
< num_c_common_reswords
; i
++)
134 /* If a keyword is disabled, do not enter it into the table
135 and so create a canonical spelling that isn't a keyword. */
136 if (c_common_reswords
[i
].disable
& mask
)
139 && (c_common_reswords
[i
].disable
& D_CXXWARN
))
141 id
= get_identifier (c_common_reswords
[i
].word
);
142 C_SET_RID_CODE (id
, RID_CXX_COMPAT_WARN
);
143 C_IS_RESERVED_WORD (id
) = 1;
148 id
= get_identifier (c_common_reswords
[i
].word
);
149 C_SET_RID_CODE (id
, c_common_reswords
[i
].rid
);
150 C_IS_RESERVED_WORD (id
) = 1;
151 ridpointers
[(int) c_common_reswords
[i
].rid
] = id
;
154 for (i
= 0; i
< NUM_INT_N_ENTS
; i
++)
156 /* We always create the symbols but they aren't always supported. */
158 sprintf (name
, "__int%d", int_n_data
[i
].bitsize
);
159 id
= get_identifier (name
);
160 C_SET_RID_CODE (id
, RID_FIRST_INT_N
+ i
);
161 C_IS_RESERVED_WORD (id
) = 1;
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;
170 /* A parser structure recording information about the state and
171 context of parsing. Includes lexer information with up to two
172 tokens of look-ahead; more are not needed for C. */
173 struct GTY(()) c_parser
{
174 /* The look-ahead tokens. */
175 c_token
* GTY((skip
)) tokens
;
176 /* Buffer for look-ahead tokens. */
177 c_token tokens_buf
[4];
178 /* How many look-ahead tokens are available (0 - 4, or
179 more if parsing from pre-lexed tokens). */
180 unsigned int tokens_avail
;
181 /* Raw look-ahead tokens, used only for checking in Objective-C
182 whether '[[' starts attributes. */
183 vec
<c_token
, va_gc
> *raw_tokens
;
184 /* The number of raw look-ahead tokens that have since been fully
186 unsigned int raw_tokens_used
;
187 /* True if a syntax error is being recovered from; false otherwise.
188 c_parser_error sets this flag. It should clear this flag when
189 enough tokens have been consumed to recover from the error. */
190 BOOL_BITFIELD error
: 1;
191 /* True if we're processing a pragma, and shouldn't automatically
192 consume CPP_PRAGMA_EOL. */
193 BOOL_BITFIELD in_pragma
: 1;
194 /* True if we're parsing the outermost block of an if statement. */
195 BOOL_BITFIELD in_if_block
: 1;
196 /* True if we want to lex a translated, joined string (for an
197 initial #pragma pch_preprocess). Otherwise the parser is
198 responsible for concatenating strings and translating to the
199 execution character set as needed. */
200 BOOL_BITFIELD lex_joined_string
: 1;
201 /* True if, when the parser is concatenating string literals, it
202 should translate them to the execution character set (false
203 inside attributes). */
204 BOOL_BITFIELD translate_strings_p
: 1;
206 /* Objective-C specific parser/lexer information. */
208 /* True if we are in a context where the Objective-C "PQ" keywords
209 are considered keywords. */
210 BOOL_BITFIELD objc_pq_context
: 1;
211 /* True if we are parsing a (potential) Objective-C foreach
212 statement. This is set to true after we parsed 'for (' and while
213 we wait for 'in' or ';' to decide if it's a standard C for loop or an
214 Objective-C foreach loop. */
215 BOOL_BITFIELD objc_could_be_foreach_context
: 1;
216 /* The following flag is needed to contextualize Objective-C lexical
217 analysis. In some cases (e.g., 'int NSObject;'), it is
218 undesirable to bind an identifier to an Objective-C class, even
219 if a class with that name exists. */
220 BOOL_BITFIELD objc_need_raw_identifier
: 1;
221 /* Nonzero if we're processing a __transaction statement. The value
222 is 1 | TM_STMT_ATTR_*. */
223 unsigned int in_transaction
: 4;
224 /* True if we are in a context where the Objective-C "Property attribute"
225 keywords are valid. */
226 BOOL_BITFIELD objc_property_attr_context
: 1;
228 /* Whether we have just seen/constructed a string-literal. Set when
229 returning a string-literal from c_parser_string_literal. Reset
230 in consume_token. Useful when we get a parse error and see an
231 unknown token, which could have been a string-literal constant
233 BOOL_BITFIELD seen_string_literal
: 1;
235 /* Location of the last consumed token. */
236 location_t last_token_location
;
239 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
242 c_parser_tokens_buf (c_parser
*parser
, unsigned n
)
244 return &parser
->tokens_buf
[n
];
247 /* Return the error state of PARSER. */
250 c_parser_error (c_parser
*parser
)
252 return parser
->error
;
255 /* Set the error state of PARSER to ERR. */
258 c_parser_set_error (c_parser
*parser
, bool err
)
264 /* The actual parser and external interface. ??? Does this need to be
265 garbage-collected? */
267 static GTY (()) c_parser
*the_parser
;
269 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
270 context-sensitive postprocessing of the token is not done. */
273 c_lex_one_token (c_parser
*parser
, c_token
*token
, bool raw
= false)
275 timevar_push (TV_LEX
);
277 if (raw
|| vec_safe_length (parser
->raw_tokens
) == 0)
279 token
->type
= c_lex_with_flags (&token
->value
, &token
->location
,
281 (parser
->lex_joined_string
282 ? 0 : C_LEX_STRING_NO_JOIN
));
283 token
->id_kind
= C_ID_NONE
;
284 token
->keyword
= RID_MAX
;
285 token
->pragma_kind
= PRAGMA_NONE
;
289 /* Use a token previously lexed as a raw look-ahead token, and
290 complete the processing on it. */
291 *token
= (*parser
->raw_tokens
)[parser
->raw_tokens_used
];
292 ++parser
->raw_tokens_used
;
293 if (parser
->raw_tokens_used
== vec_safe_length (parser
->raw_tokens
))
295 vec_free (parser
->raw_tokens
);
296 parser
->raw_tokens_used
= 0;
309 bool objc_force_identifier
= parser
->objc_need_raw_identifier
;
310 if (c_dialect_objc ())
311 parser
->objc_need_raw_identifier
= false;
313 if (C_IS_RESERVED_WORD (token
->value
))
315 enum rid rid_code
= C_RID_CODE (token
->value
);
317 if (rid_code
== RID_CXX_COMPAT_WARN
)
319 warning_at (token
->location
,
321 "identifier %qE conflicts with C++ keyword",
324 else if (rid_code
>= RID_FIRST_ADDR_SPACE
325 && rid_code
<= RID_LAST_ADDR_SPACE
)
328 as
= (addr_space_t
) (rid_code
- RID_FIRST_ADDR_SPACE
);
329 targetm
.addr_space
.diagnose_usage (as
, token
->location
);
330 token
->id_kind
= C_ID_ADDRSPACE
;
331 token
->keyword
= rid_code
;
334 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code
))
336 /* We found an Objective-C "pq" keyword (in, out,
337 inout, bycopy, byref, oneway). They need special
338 care because the interpretation depends on the
340 if (parser
->objc_pq_context
)
342 token
->type
= CPP_KEYWORD
;
343 token
->keyword
= rid_code
;
346 else if (parser
->objc_could_be_foreach_context
347 && rid_code
== RID_IN
)
349 /* We are in Objective-C, inside a (potential)
350 foreach context (which means after having
351 parsed 'for (', but before having parsed ';'),
352 and we found 'in'. We consider it the keyword
353 which terminates the declaration at the
354 beginning of a foreach-statement. Note that
355 this means you can't use 'in' for anything else
356 in that context; in particular, in Objective-C
357 you can't use 'in' as the name of the running
358 variable in a C for loop. We could potentially
359 try to add code here to disambiguate, but it
360 seems a reasonable limitation. */
361 token
->type
= CPP_KEYWORD
;
362 token
->keyword
= rid_code
;
365 /* Else, "pq" keywords outside of the "pq" context are
366 not keywords, and we fall through to the code for
369 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code
))
371 /* We found an Objective-C "property attribute"
372 keyword (getter, setter, readonly, etc). These are
373 only valid in the property context. */
374 if (parser
->objc_property_attr_context
)
376 token
->type
= CPP_KEYWORD
;
377 token
->keyword
= rid_code
;
380 /* Else they are not special keywords.
383 else if (c_dialect_objc ()
384 && (OBJC_IS_AT_KEYWORD (rid_code
)
385 || OBJC_IS_CXX_KEYWORD (rid_code
)))
387 /* We found one of the Objective-C "@" keywords (defs,
388 selector, synchronized, etc) or one of the
389 Objective-C "cxx" keywords (class, private,
390 protected, public, try, catch, throw) without a
391 preceding '@' sign. Do nothing and fall through to
392 the code for normal tokens (in C++ we would still
393 consider the CXX ones keywords, but not in C). */
398 token
->type
= CPP_KEYWORD
;
399 token
->keyword
= rid_code
;
404 decl
= lookup_name (token
->value
);
407 if (TREE_CODE (decl
) == TYPE_DECL
)
409 token
->id_kind
= C_ID_TYPENAME
;
413 else if (c_dialect_objc ())
415 tree objc_interface_decl
= objc_is_class_name (token
->value
);
416 /* Objective-C class names are in the same namespace as
417 variables and typedefs, and hence are shadowed by local
419 if (objc_interface_decl
420 && (!objc_force_identifier
|| global_bindings_p ()))
422 token
->value
= objc_interface_decl
;
423 token
->id_kind
= C_ID_CLASSNAME
;
427 token
->id_kind
= C_ID_ID
;
431 /* This only happens in Objective-C; it must be a keyword. */
432 token
->type
= CPP_KEYWORD
;
433 switch (C_RID_CODE (token
->value
))
435 /* Replace 'class' with '@class', 'private' with '@private',
436 etc. This prevents confusion with the C++ keyword
437 'class', and makes the tokens consistent with other
438 Objective-C 'AT' keywords. For example '@class' is
439 reported as RID_AT_CLASS which is consistent with
440 '@synchronized', which is reported as
443 case RID_CLASS
: token
->keyword
= RID_AT_CLASS
; break;
444 case RID_PRIVATE
: token
->keyword
= RID_AT_PRIVATE
; break;
445 case RID_PROTECTED
: token
->keyword
= RID_AT_PROTECTED
; break;
446 case RID_PUBLIC
: token
->keyword
= RID_AT_PUBLIC
; break;
447 case RID_THROW
: token
->keyword
= RID_AT_THROW
; break;
448 case RID_TRY
: token
->keyword
= RID_AT_TRY
; break;
449 case RID_CATCH
: token
->keyword
= RID_AT_CATCH
; break;
450 case RID_SYNCHRONIZED
: token
->keyword
= RID_AT_SYNCHRONIZED
; break;
451 default: token
->keyword
= C_RID_CODE (token
->value
);
456 case CPP_CLOSE_PAREN
:
458 /* These tokens may affect the interpretation of any identifiers
459 following, if doing Objective-C. */
460 if (c_dialect_objc ())
461 parser
->objc_need_raw_identifier
= false;
464 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
465 token
->pragma_kind
= (enum pragma_kind
) TREE_INT_CST_LOW (token
->value
);
472 timevar_pop (TV_LEX
);
475 /* Return a pointer to the next token from PARSER, reading it in if
479 c_parser_peek_token (c_parser
*parser
)
481 if (parser
->tokens_avail
== 0)
483 c_lex_one_token (parser
, &parser
->tokens
[0]);
484 parser
->tokens_avail
= 1;
486 return &parser
->tokens
[0];
489 /* Return a pointer to the next-but-one token from PARSER, reading it
490 in if necessary. The next token is already read in. */
493 c_parser_peek_2nd_token (c_parser
*parser
)
495 if (parser
->tokens_avail
>= 2)
496 return &parser
->tokens
[1];
497 gcc_assert (parser
->tokens_avail
== 1);
498 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
499 gcc_assert (parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
500 c_lex_one_token (parser
, &parser
->tokens
[1]);
501 parser
->tokens_avail
= 2;
502 return &parser
->tokens
[1];
505 /* Return a pointer to the Nth token from PARSER, reading it
506 in if necessary. The N-1th token is already read in. */
509 c_parser_peek_nth_token (c_parser
*parser
, unsigned int n
)
511 /* N is 1-based, not zero-based. */
514 if (parser
->tokens_avail
>= n
)
515 return &parser
->tokens
[n
- 1];
516 gcc_assert (parser
->tokens_avail
== n
- 1);
517 c_lex_one_token (parser
, &parser
->tokens
[n
- 1]);
518 parser
->tokens_avail
= n
;
519 return &parser
->tokens
[n
- 1];
522 /* Return a pointer to the Nth token from PARSER, reading it in as a
523 raw look-ahead token if necessary. The N-1th token is already read
524 in. Raw look-ahead tokens remain available for when the non-raw
525 functions above are called. */
528 c_parser_peek_nth_token_raw (c_parser
*parser
, unsigned int n
)
530 /* N is 1-based, not zero-based. */
533 if (parser
->tokens_avail
>= n
)
534 return &parser
->tokens
[n
- 1];
535 unsigned int raw_len
= vec_safe_length (parser
->raw_tokens
);
536 unsigned int raw_avail
537 = parser
->tokens_avail
+ raw_len
- parser
->raw_tokens_used
;
538 gcc_assert (raw_avail
>= n
- 1);
540 return &(*parser
->raw_tokens
)[parser
->raw_tokens_used
541 + n
- 1 - parser
->tokens_avail
];
542 vec_safe_reserve (parser
->raw_tokens
, 1);
543 parser
->raw_tokens
->quick_grow (raw_len
+ 1);
544 c_lex_one_token (parser
, &(*parser
->raw_tokens
)[raw_len
], true);
545 return &(*parser
->raw_tokens
)[raw_len
];
549 c_keyword_starts_typename (enum rid keyword
)
584 if (keyword
>= RID_FIRST_INT_N
585 && keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
586 && int_n_enabled_p
[keyword
- RID_FIRST_INT_N
])
592 /* Return true if TOKEN can start a type name,
595 c_token_starts_typename (c_token
*token
)
600 switch (token
->id_kind
)
609 gcc_assert (c_dialect_objc ());
615 return c_keyword_starts_typename (token
->keyword
);
617 if (c_dialect_objc ())
625 /* Return true if the next token from PARSER can start a type name,
626 false otherwise. LA specifies how to do lookahead in order to
627 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
630 c_parser_next_tokens_start_typename (c_parser
*parser
, enum c_lookahead_kind la
)
632 c_token
*token
= c_parser_peek_token (parser
);
633 if (c_token_starts_typename (token
))
636 /* Try a bit harder to detect an unknown typename. */
637 if (la
!= cla_prefer_id
638 && token
->type
== CPP_NAME
639 && token
->id_kind
== C_ID_ID
641 /* Do not try too hard when we could have "object in array". */
642 && !parser
->objc_could_be_foreach_context
644 && (la
== cla_prefer_type
645 || c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
646 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
648 /* Only unknown identifiers. */
649 && !lookup_name (token
->value
))
655 /* Return true if TOKEN is a type qualifier, false otherwise. */
657 c_token_is_qualifier (c_token
*token
)
662 switch (token
->id_kind
)
670 switch (token
->keyword
)
688 /* Return true if the next token from PARSER is a type qualifier,
691 c_parser_next_token_is_qualifier (c_parser
*parser
)
693 c_token
*token
= c_parser_peek_token (parser
);
694 return c_token_is_qualifier (token
);
697 /* Return true if TOKEN can start declaration specifiers (not
698 including standard attributes), false otherwise. */
700 c_token_starts_declspecs (c_token
*token
)
705 switch (token
->id_kind
)
714 gcc_assert (c_dialect_objc ());
720 switch (token
->keyword
)
761 if (token
->keyword
>= RID_FIRST_INT_N
762 && token
->keyword
< RID_FIRST_INT_N
+ NUM_INT_N_ENTS
763 && int_n_enabled_p
[token
->keyword
- RID_FIRST_INT_N
])
768 if (c_dialect_objc ())
777 /* Return true if TOKEN can start declaration specifiers (not
778 including standard attributes) or a static assertion, false
781 c_token_starts_declaration (c_token
*token
)
783 if (c_token_starts_declspecs (token
)
784 || token
->keyword
== RID_STATIC_ASSERT
)
790 /* Return true if the next token from PARSER can start declaration
791 specifiers (not including standard attributes), false
794 c_parser_next_token_starts_declspecs (c_parser
*parser
)
796 c_token
*token
= c_parser_peek_token (parser
);
798 /* In Objective-C, a classname normally starts a declspecs unless it
799 is immediately followed by a dot. In that case, it is the
800 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
801 setter/getter on the class. c_token_starts_declspecs() can't
802 differentiate between the two cases because it only checks the
803 current token, so we have a special check here. */
804 if (c_dialect_objc ()
805 && token
->type
== CPP_NAME
806 && token
->id_kind
== C_ID_CLASSNAME
807 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
810 return c_token_starts_declspecs (token
);
813 /* Return true if the next tokens from PARSER can start declaration
814 specifiers (not including standard attributes) or a static
815 assertion, false otherwise. */
817 c_parser_next_tokens_start_declaration (c_parser
*parser
)
819 c_token
*token
= c_parser_peek_token (parser
);
822 if (c_dialect_objc ()
823 && token
->type
== CPP_NAME
824 && token
->id_kind
== C_ID_CLASSNAME
825 && c_parser_peek_2nd_token (parser
)->type
== CPP_DOT
)
828 /* Labels do not start declarations. */
829 if (token
->type
== CPP_NAME
830 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
833 if (c_token_starts_declaration (token
))
836 if (c_parser_next_tokens_start_typename (parser
, cla_nonabstract_decl
))
842 /* Consume the next token from PARSER. */
845 c_parser_consume_token (c_parser
*parser
)
847 gcc_assert (parser
->tokens_avail
>= 1);
848 gcc_assert (parser
->tokens
[0].type
!= CPP_EOF
);
849 gcc_assert (!parser
->in_pragma
|| parser
->tokens
[0].type
!= CPP_PRAGMA_EOL
);
850 gcc_assert (parser
->error
|| parser
->tokens
[0].type
!= CPP_PRAGMA
);
851 parser
->last_token_location
= parser
->tokens
[0].location
;
852 if (parser
->tokens
!= &parser
->tokens_buf
[0])
854 else if (parser
->tokens_avail
>= 2)
856 parser
->tokens
[0] = parser
->tokens
[1];
857 if (parser
->tokens_avail
>= 3)
859 parser
->tokens
[1] = parser
->tokens
[2];
860 if (parser
->tokens_avail
>= 4)
861 parser
->tokens
[2] = parser
->tokens
[3];
864 parser
->tokens_avail
--;
865 parser
->seen_string_literal
= false;
868 /* Expect the current token to be a #pragma. Consume it and remember
869 that we've begun parsing a pragma. */
872 c_parser_consume_pragma (c_parser
*parser
)
874 gcc_assert (!parser
->in_pragma
);
875 gcc_assert (parser
->tokens_avail
>= 1);
876 gcc_assert (parser
->tokens
[0].type
== CPP_PRAGMA
);
877 if (parser
->tokens
!= &parser
->tokens_buf
[0])
879 else if (parser
->tokens_avail
>= 2)
881 parser
->tokens
[0] = parser
->tokens
[1];
882 if (parser
->tokens_avail
>= 3)
883 parser
->tokens
[1] = parser
->tokens
[2];
885 parser
->tokens_avail
--;
886 parser
->in_pragma
= true;
889 /* Update the global input_location from TOKEN. */
891 c_parser_set_source_position_from_token (c_token
*token
)
893 if (token
->type
!= CPP_EOF
)
895 input_location
= token
->location
;
899 /* Helper function for c_parser_error.
900 Having peeked a token of kind TOK1_KIND that might signify
901 a conflict marker, peek successor tokens to determine
902 if we actually do have a conflict marker.
903 Specifically, we consider a run of 7 '<', '=' or '>' characters
904 at the start of a line as a conflict marker.
905 These come through the lexer as three pairs and a single,
906 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
907 If it returns true, *OUT_LOC is written to with the location/range
911 c_parser_peek_conflict_marker (c_parser
*parser
, enum cpp_ttype tok1_kind
,
914 c_token
*token2
= c_parser_peek_2nd_token (parser
);
915 if (token2
->type
!= tok1_kind
)
917 c_token
*token3
= c_parser_peek_nth_token (parser
, 3);
918 if (token3
->type
!= tok1_kind
)
920 c_token
*token4
= c_parser_peek_nth_token (parser
, 4);
921 if (token4
->type
!= conflict_marker_get_final_tok_kind (tok1_kind
))
924 /* It must be at the start of the line. */
925 location_t start_loc
= c_parser_peek_token (parser
)->location
;
926 if (LOCATION_COLUMN (start_loc
) != 1)
929 /* We have a conflict marker. Construct a location of the form:
932 with start == caret, finishing at the end of the marker. */
933 location_t finish_loc
= get_finish (token4
->location
);
934 *out_loc
= make_location (start_loc
, start_loc
, finish_loc
);
939 /* Issue a diagnostic of the form
940 FILE:LINE: MESSAGE before TOKEN
941 where TOKEN is the next token in the input stream of PARSER.
942 MESSAGE (specified by the caller) is usually of the form "expected
945 Use RICHLOC as the location of the diagnostic.
947 Do not issue a diagnostic if still recovering from an error.
949 Return true iff an error was actually emitted.
951 ??? This is taken from the C++ parser, but building up messages in
952 this way is not i18n-friendly and some other approach should be
956 c_parser_error_richloc (c_parser
*parser
, const char *gmsgid
,
957 rich_location
*richloc
)
959 c_token
*token
= c_parser_peek_token (parser
);
962 parser
->error
= true;
966 /* If this is actually a conflict marker, report it as such. */
967 if (token
->type
== CPP_LSHIFT
968 || token
->type
== CPP_RSHIFT
969 || token
->type
== CPP_EQ_EQ
)
972 if (c_parser_peek_conflict_marker (parser
, token
->type
, &loc
))
974 error_at (loc
, "version control conflict marker in file");
979 /* If we were parsing a string-literal and there is an unknown name
980 token right after, then check to see if that could also have been
981 a literal string by checking the name against a list of known
982 standard string literal constants defined in header files. If
983 there is one, then add that as an hint to the error message. */
984 auto_diagnostic_group d
;
986 if (parser
->seen_string_literal
&& token
->type
== CPP_NAME
)
988 tree name
= token
->value
;
989 const char *token_name
= IDENTIFIER_POINTER (name
);
990 const char *header_hint
991 = get_c_stdlib_header_for_string_macro_name (token_name
);
992 if (header_hint
!= NULL
)
993 h
= name_hint (NULL
, new suggest_missing_header (token
->location
,
998 c_parse_error (gmsgid
,
999 /* Because c_parse_error does not understand
1000 CPP_KEYWORD, keywords are treated like
1002 (token
->type
== CPP_KEYWORD
? CPP_NAME
: token
->type
),
1003 /* ??? The C parser does not save the cpp flags of a
1004 token, we need to pass 0 here and we will not get
1005 the source spelling of some tokens but rather the
1006 canonical spelling. */
1007 token
->value
, /*flags=*/0, richloc
);
1011 /* As c_parser_error_richloc, but issue the message at the
1012 location of PARSER's next token, or at input_location
1013 if the next token is EOF. */
1016 c_parser_error (c_parser
*parser
, const char *gmsgid
)
1018 c_token
*token
= c_parser_peek_token (parser
);
1019 c_parser_set_source_position_from_token (token
);
1020 rich_location
richloc (line_table
, input_location
);
1021 return c_parser_error_richloc (parser
, gmsgid
, &richloc
);
1024 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1025 This class is for tracking such a matching pair of symbols.
1026 In particular, it tracks the location of the first token,
1027 so that if the second token is missing, we can highlight the
1028 location of the first token when notifying the user about the
1031 template <typename traits_t
>
1035 /* token_pair's ctor. */
1036 token_pair () : m_open_loc (UNKNOWN_LOCATION
) {}
1038 /* If the next token is the opening symbol for this pair, consume it and
1040 Otherwise, issue an error and return false.
1041 In either case, record the location of the opening token. */
1043 bool require_open (c_parser
*parser
)
1045 c_token
*token
= c_parser_peek_token (parser
);
1047 m_open_loc
= token
->location
;
1049 return c_parser_require (parser
, traits_t::open_token_type
,
1050 traits_t::open_gmsgid
);
1053 /* Consume the next token from PARSER, recording its location as
1054 that of the opening token within the pair. */
1056 void consume_open (c_parser
*parser
)
1058 c_token
*token
= c_parser_peek_token (parser
);
1059 gcc_assert (token
->type
== traits_t::open_token_type
);
1060 m_open_loc
= token
->location
;
1061 c_parser_consume_token (parser
);
1064 /* If the next token is the closing symbol for this pair, consume it
1066 Otherwise, issue an error, highlighting the location of the
1067 corresponding opening token, and return false. */
1069 bool require_close (c_parser
*parser
) const
1071 return c_parser_require (parser
, traits_t::close_token_type
,
1072 traits_t::close_gmsgid
, m_open_loc
);
1075 /* Like token_pair::require_close, except that tokens will be skipped
1076 until the desired token is found. An error message is still produced
1077 if the next token is not as expected. */
1079 void skip_until_found_close (c_parser
*parser
) const
1081 c_parser_skip_until_found (parser
, traits_t::close_token_type
,
1082 traits_t::close_gmsgid
, m_open_loc
);
1086 location_t m_open_loc
;
1089 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1091 struct matching_paren_traits
1093 static const enum cpp_ttype open_token_type
= CPP_OPEN_PAREN
;
1094 static const char * const open_gmsgid
;
1095 static const enum cpp_ttype close_token_type
= CPP_CLOSE_PAREN
;
1096 static const char * const close_gmsgid
;
1099 const char * const matching_paren_traits::open_gmsgid
= "expected %<(%>";
1100 const char * const matching_paren_traits::close_gmsgid
= "expected %<)%>";
1102 /* "matching_parens" is a token_pair<T> class for tracking matching
1103 pairs of parentheses. */
1105 typedef token_pair
<matching_paren_traits
> matching_parens
;
1107 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1109 struct matching_brace_traits
1111 static const enum cpp_ttype open_token_type
= CPP_OPEN_BRACE
;
1112 static const char * const open_gmsgid
;
1113 static const enum cpp_ttype close_token_type
= CPP_CLOSE_BRACE
;
1114 static const char * const close_gmsgid
;
1117 const char * const matching_brace_traits::open_gmsgid
= "expected %<{%>";
1118 const char * const matching_brace_traits::close_gmsgid
= "expected %<}%>";
1120 /* "matching_braces" is a token_pair<T> class for tracking matching
1123 typedef token_pair
<matching_brace_traits
> matching_braces
;
1125 /* Get a description of the matching symbol to TYPE e.g. "(" for
1129 get_matching_symbol (enum cpp_ttype type
)
1135 case CPP_CLOSE_PAREN
:
1137 case CPP_CLOSE_BRACE
:
1142 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1143 issue the error MSGID. If MSGID is NULL then a message has already
1144 been produced and no message will be produced this time. Returns
1145 true if found, false otherwise.
1147 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1148 within any error as the location of an "opening" token matching
1149 the close token TYPE (e.g. the location of the '(' when TYPE is
1152 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1153 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1154 attempt to generate a fix-it hint for the problem.
1155 Otherwise msgid describes multiple token types (e.g.
1156 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1157 generate a fix-it hint. */
1160 c_parser_require (c_parser
*parser
,
1161 enum cpp_ttype type
,
1163 location_t matching_location
,
1164 bool type_is_unique
)
1166 if (c_parser_next_token_is (parser
, type
))
1168 c_parser_consume_token (parser
);
1173 location_t next_token_loc
= c_parser_peek_token (parser
)->location
;
1174 gcc_rich_location
richloc (next_token_loc
);
1176 /* Potentially supply a fix-it hint, suggesting to add the
1177 missing token immediately after the *previous* token.
1178 This may move the primary location within richloc. */
1179 if (!parser
->error
&& type_is_unique
)
1180 maybe_suggest_missing_token_insertion (&richloc
, type
,
1181 parser
->last_token_location
);
1183 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1184 Attempt to consolidate diagnostics by printing it as a
1185 secondary range within the main diagnostic. */
1186 bool added_matching_location
= false;
1187 if (matching_location
!= UNKNOWN_LOCATION
)
1188 added_matching_location
1189 = richloc
.add_location_if_nearby (matching_location
);
1191 if (c_parser_error_richloc (parser
, msgid
, &richloc
))
1192 /* If we weren't able to consolidate matching_location, then
1193 print it as a secondary diagnostic. */
1194 if (matching_location
!= UNKNOWN_LOCATION
&& !added_matching_location
)
1195 inform (matching_location
, "to match this %qs",
1196 get_matching_symbol (type
));
1202 /* If the next token is the indicated keyword, consume it. Otherwise,
1203 issue the error MSGID. Returns true if found, false otherwise. */
1206 c_parser_require_keyword (c_parser
*parser
,
1210 if (c_parser_next_token_is_keyword (parser
, keyword
))
1212 c_parser_consume_token (parser
);
1217 c_parser_error (parser
, msgid
);
1222 /* Like c_parser_require, except that tokens will be skipped until the
1223 desired token is found. An error message is still produced if the
1224 next token is not as expected. If MSGID is NULL then a message has
1225 already been produced and no message will be produced this
1228 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1229 within any error as the location of an "opening" token matching
1230 the close token TYPE (e.g. the location of the '(' when TYPE is
1231 CPP_CLOSE_PAREN). */
1234 c_parser_skip_until_found (c_parser
*parser
,
1235 enum cpp_ttype type
,
1237 location_t matching_location
)
1239 unsigned nesting_depth
= 0;
1241 if (c_parser_require (parser
, type
, msgid
, matching_location
))
1244 /* Skip tokens until the desired token is found. */
1247 /* Peek at the next token. */
1248 c_token
*token
= c_parser_peek_token (parser
);
1249 /* If we've reached the token we want, consume it and stop. */
1250 if (token
->type
== type
&& !nesting_depth
)
1252 c_parser_consume_token (parser
);
1256 /* If we've run out of tokens, stop. */
1257 if (token
->type
== CPP_EOF
)
1259 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1261 if (token
->type
== CPP_OPEN_BRACE
1262 || token
->type
== CPP_OPEN_PAREN
1263 || token
->type
== CPP_OPEN_SQUARE
)
1265 else if (token
->type
== CPP_CLOSE_BRACE
1266 || token
->type
== CPP_CLOSE_PAREN
1267 || token
->type
== CPP_CLOSE_SQUARE
)
1269 if (nesting_depth
-- == 0)
1272 /* Consume this token. */
1273 c_parser_consume_token (parser
);
1275 parser
->error
= false;
1278 /* Skip tokens until the end of a parameter is found, but do not
1279 consume the comma, semicolon or closing delimiter. */
1282 c_parser_skip_to_end_of_parameter (c_parser
*parser
)
1284 unsigned nesting_depth
= 0;
1288 c_token
*token
= c_parser_peek_token (parser
);
1289 if ((token
->type
== CPP_COMMA
|| token
->type
== CPP_SEMICOLON
)
1292 /* If we've run out of tokens, stop. */
1293 if (token
->type
== CPP_EOF
)
1295 if (token
->type
== CPP_PRAGMA_EOL
&& parser
->in_pragma
)
1297 if (token
->type
== CPP_OPEN_BRACE
1298 || token
->type
== CPP_OPEN_PAREN
1299 || token
->type
== CPP_OPEN_SQUARE
)
1301 else if (token
->type
== CPP_CLOSE_BRACE
1302 || token
->type
== CPP_CLOSE_PAREN
1303 || token
->type
== CPP_CLOSE_SQUARE
)
1305 if (nesting_depth
-- == 0)
1308 /* Consume this token. */
1309 c_parser_consume_token (parser
);
1311 parser
->error
= false;
1314 /* Expect to be at the end of the pragma directive and consume an
1315 end of line marker. */
1318 c_parser_skip_to_pragma_eol (c_parser
*parser
, bool error_if_not_eol
= true)
1320 gcc_assert (parser
->in_pragma
);
1321 parser
->in_pragma
= false;
1323 if (error_if_not_eol
&& c_parser_peek_token (parser
)->type
!= CPP_PRAGMA_EOL
)
1324 c_parser_error (parser
, "expected end of line");
1326 cpp_ttype token_type
;
1329 c_token
*token
= c_parser_peek_token (parser
);
1330 token_type
= token
->type
;
1331 if (token_type
== CPP_EOF
)
1333 c_parser_consume_token (parser
);
1335 while (token_type
!= CPP_PRAGMA_EOL
);
1337 parser
->error
= false;
1340 /* Skip tokens until we have consumed an entire block, or until we
1341 have consumed a non-nested ';'. */
1344 c_parser_skip_to_end_of_block_or_statement (c_parser
*parser
)
1346 unsigned nesting_depth
= 0;
1347 bool save_error
= parser
->error
;
1353 /* Peek at the next token. */
1354 token
= c_parser_peek_token (parser
);
1356 switch (token
->type
)
1361 case CPP_PRAGMA_EOL
:
1362 if (parser
->in_pragma
)
1367 /* If the next token is a ';', we have reached the
1368 end of the statement. */
1371 /* Consume the ';'. */
1372 c_parser_consume_token (parser
);
1377 case CPP_CLOSE_BRACE
:
1378 /* If the next token is a non-nested '}', then we have
1379 reached the end of the current block. */
1380 if (nesting_depth
== 0 || --nesting_depth
== 0)
1382 c_parser_consume_token (parser
);
1387 case CPP_OPEN_BRACE
:
1388 /* If it the next token is a '{', then we are entering a new
1389 block. Consume the entire block. */
1394 /* If we see a pragma, consume the whole thing at once. We
1395 have some safeguards against consuming pragmas willy-nilly.
1396 Normally, we'd expect to be here with parser->error set,
1397 which disables these safeguards. But it's possible to get
1398 here for secondary error recovery, after parser->error has
1400 c_parser_consume_pragma (parser
);
1401 c_parser_skip_to_pragma_eol (parser
);
1402 parser
->error
= save_error
;
1409 c_parser_consume_token (parser
);
1413 parser
->error
= false;
1416 /* CPP's options (initialized by c-opts.cc). */
1417 extern cpp_options
*cpp_opts
;
1419 /* Save the warning flags which are controlled by __extension__. */
1422 disable_extension_diagnostics (void)
1425 | (warn_pointer_arith
<< 1)
1426 | (warn_traditional
<< 2)
1428 | (warn_long_long
<< 4)
1429 | (warn_cxx_compat
<< 5)
1430 | (warn_overlength_strings
<< 6)
1431 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1432 play tricks to properly restore it. */
1433 | ((warn_c90_c99_compat
== 1) << 7)
1434 | ((warn_c90_c99_compat
== -1) << 8)
1435 /* Similarly for warn_c99_c11_compat. */
1436 | ((warn_c99_c11_compat
== 1) << 9)
1437 | ((warn_c99_c11_compat
== -1) << 10)
1438 /* Similarly for warn_c11_c2x_compat. */
1439 | ((warn_c11_c2x_compat
== 1) << 11)
1440 | ((warn_c11_c2x_compat
== -1) << 12)
1442 cpp_opts
->cpp_pedantic
= pedantic
= 0;
1443 warn_pointer_arith
= 0;
1444 cpp_opts
->cpp_warn_traditional
= warn_traditional
= 0;
1446 cpp_opts
->cpp_warn_long_long
= warn_long_long
= 0;
1447 warn_cxx_compat
= 0;
1448 warn_overlength_strings
= 0;
1449 warn_c90_c99_compat
= 0;
1450 warn_c99_c11_compat
= 0;
1451 warn_c11_c2x_compat
= 0;
1455 /* Restore the warning flags which are controlled by __extension__.
1456 FLAGS is the return value from disable_extension_diagnostics. */
1459 restore_extension_diagnostics (int flags
)
1461 cpp_opts
->cpp_pedantic
= pedantic
= flags
& 1;
1462 warn_pointer_arith
= (flags
>> 1) & 1;
1463 cpp_opts
->cpp_warn_traditional
= warn_traditional
= (flags
>> 2) & 1;
1464 flag_iso
= (flags
>> 3) & 1;
1465 cpp_opts
->cpp_warn_long_long
= warn_long_long
= (flags
>> 4) & 1;
1466 warn_cxx_compat
= (flags
>> 5) & 1;
1467 warn_overlength_strings
= (flags
>> 6) & 1;
1468 /* See above for why is this needed. */
1469 warn_c90_c99_compat
= (flags
>> 7) & 1 ? 1 : ((flags
>> 8) & 1 ? -1 : 0);
1470 warn_c99_c11_compat
= (flags
>> 9) & 1 ? 1 : ((flags
>> 10) & 1 ? -1 : 0);
1471 warn_c11_c2x_compat
= (flags
>> 11) & 1 ? 1 : ((flags
>> 12) & 1 ? -1 : 0);
1474 /* Helper data structure for parsing #pragma acc routine. */
1475 struct oacc_routine_data
{
1476 bool error_seen
; /* Set if error has been reported. */
1477 bool fndecl_seen
; /* Set if one fn decl/definition has been seen already. */
1482 /* Used for parsing objc foreach statements. */
1483 static tree objc_foreach_break_label
, objc_foreach_continue_label
;
1485 static bool c_parser_nth_token_starts_std_attributes (c_parser
*,
1487 static tree
c_parser_std_attribute_specifier_sequence (c_parser
*);
1488 static void c_parser_external_declaration (c_parser
*);
1489 static void c_parser_asm_definition (c_parser
*);
1490 static void c_parser_declaration_or_fndef (c_parser
*, bool, bool, bool,
1491 bool, bool, tree
* = NULL
,
1492 vec
<c_token
> * = NULL
,
1493 bool have_attrs
= false,
1495 struct oacc_routine_data
* = NULL
,
1497 static void c_parser_static_assert_declaration_no_semi (c_parser
*);
1498 static void c_parser_static_assert_declaration (c_parser
*);
1499 static struct c_typespec
c_parser_enum_specifier (c_parser
*);
1500 static struct c_typespec
c_parser_struct_or_union_specifier (c_parser
*);
1501 static tree
c_parser_struct_declaration (c_parser
*);
1502 static struct c_typespec
c_parser_typeof_specifier (c_parser
*);
1503 static tree
c_parser_alignas_specifier (c_parser
*);
1504 static struct c_declarator
*c_parser_direct_declarator (c_parser
*, bool,
1506 static struct c_declarator
*c_parser_direct_declarator_inner (c_parser
*,
1508 struct c_declarator
*);
1509 static struct c_arg_info
*c_parser_parms_declarator (c_parser
*, bool, tree
,
1511 static struct c_arg_info
*c_parser_parms_list_declarator (c_parser
*, tree
,
1513 static struct c_parm
*c_parser_parameter_declaration (c_parser
*, tree
, bool);
1514 static tree
c_parser_simple_asm_expr (c_parser
*);
1515 static tree
c_parser_gnu_attributes (c_parser
*);
1516 static struct c_expr
c_parser_initializer (c_parser
*);
1517 static struct c_expr
c_parser_braced_init (c_parser
*, tree
, bool,
1519 static void c_parser_initelt (c_parser
*, struct obstack
*);
1520 static void c_parser_initval (c_parser
*, struct c_expr
*,
1522 static tree
c_parser_compound_statement (c_parser
*, location_t
* = NULL
);
1523 static location_t
c_parser_compound_statement_nostart (c_parser
*);
1524 static void c_parser_label (c_parser
*, tree
);
1525 static void c_parser_statement (c_parser
*, bool *, location_t
* = NULL
);
1526 static void c_parser_statement_after_labels (c_parser
*, bool *,
1527 vec
<tree
> * = NULL
);
1528 static tree
c_parser_c99_block_statement (c_parser
*, bool *,
1529 location_t
* = NULL
);
1530 static void c_parser_if_statement (c_parser
*, bool *, vec
<tree
> *);
1531 static void c_parser_switch_statement (c_parser
*, bool *);
1532 static void c_parser_while_statement (c_parser
*, bool, unsigned short, bool *);
1533 static void c_parser_do_statement (c_parser
*, bool, unsigned short);
1534 static void c_parser_for_statement (c_parser
*, bool, unsigned short, bool *);
1535 static tree
c_parser_asm_statement (c_parser
*);
1536 static tree
c_parser_asm_operands (c_parser
*);
1537 static tree
c_parser_asm_goto_operands (c_parser
*);
1538 static tree
c_parser_asm_clobbers (c_parser
*);
1539 static struct c_expr
c_parser_expr_no_commas (c_parser
*, struct c_expr
*,
1541 static struct c_expr
c_parser_conditional_expression (c_parser
*,
1542 struct c_expr
*, tree
);
1543 static struct c_expr
c_parser_binary_expression (c_parser
*, struct c_expr
*,
1545 static struct c_expr
c_parser_cast_expression (c_parser
*, struct c_expr
*);
1546 static struct c_expr
c_parser_unary_expression (c_parser
*);
1547 static struct c_expr
c_parser_sizeof_expression (c_parser
*);
1548 static struct c_expr
c_parser_alignof_expression (c_parser
*);
1549 static struct c_expr
c_parser_postfix_expression (c_parser
*);
1550 static struct c_expr
c_parser_postfix_expression_after_paren_type (c_parser
*,
1551 struct c_type_name
*,
1553 static struct c_expr
c_parser_postfix_expression_after_primary (c_parser
*,
1556 static tree
c_parser_transaction (c_parser
*, enum rid
);
1557 static struct c_expr
c_parser_transaction_expression (c_parser
*, enum rid
);
1558 static tree
c_parser_transaction_cancel (c_parser
*);
1559 static struct c_expr
c_parser_expression (c_parser
*);
1560 static struct c_expr
c_parser_expression_conv (c_parser
*);
1561 static vec
<tree
, va_gc
> *c_parser_expr_list (c_parser
*, bool, bool,
1562 vec
<tree
, va_gc
> **, location_t
*,
1563 tree
*, vec
<location_t
> *,
1564 unsigned int * = NULL
);
1565 static struct c_expr
c_parser_has_attribute_expression (c_parser
*);
1567 static void c_parser_oacc_declare (c_parser
*);
1568 static void c_parser_oacc_enter_exit_data (c_parser
*, bool);
1569 static void c_parser_oacc_update (c_parser
*);
1570 static void c_parser_omp_construct (c_parser
*, bool *);
1571 static void c_parser_omp_threadprivate (c_parser
*);
1572 static void c_parser_omp_barrier (c_parser
*);
1573 static void c_parser_omp_depobj (c_parser
*);
1574 static void c_parser_omp_flush (c_parser
*);
1575 static tree
c_parser_omp_for_loop (location_t
, c_parser
*, enum tree_code
,
1576 tree
, tree
*, bool *);
1577 static void c_parser_omp_taskwait (c_parser
*);
1578 static void c_parser_omp_taskyield (c_parser
*);
1579 static void c_parser_omp_cancel (c_parser
*);
1580 static void c_parser_omp_nothing (c_parser
*);
1582 enum pragma_context
{ pragma_external
, pragma_struct
, pragma_param
,
1583 pragma_stmt
, pragma_compound
};
1584 static bool c_parser_pragma (c_parser
*, enum pragma_context
, bool *);
1585 static bool c_parser_omp_cancellation_point (c_parser
*, enum pragma_context
);
1586 static bool c_parser_omp_target (c_parser
*, enum pragma_context
, bool *);
1587 static void c_parser_omp_end_declare_target (c_parser
*);
1588 static bool c_parser_omp_declare (c_parser
*, enum pragma_context
);
1589 static void c_parser_omp_requires (c_parser
*);
1590 static bool c_parser_omp_error (c_parser
*, enum pragma_context
);
1591 static bool c_parser_omp_ordered (c_parser
*, enum pragma_context
, bool *);
1592 static void c_parser_oacc_routine (c_parser
*, enum pragma_context
);
1594 /* These Objective-C parser functions are only ever called when
1595 compiling Objective-C. */
1596 static void c_parser_objc_class_definition (c_parser
*, tree
);
1597 static void c_parser_objc_class_instance_variables (c_parser
*);
1598 static void c_parser_objc_class_declaration (c_parser
*);
1599 static void c_parser_objc_alias_declaration (c_parser
*);
1600 static void c_parser_objc_protocol_definition (c_parser
*, tree
);
1601 static bool c_parser_objc_method_type (c_parser
*);
1602 static void c_parser_objc_method_definition (c_parser
*);
1603 static void c_parser_objc_methodprotolist (c_parser
*);
1604 static void c_parser_objc_methodproto (c_parser
*);
1605 static tree
c_parser_objc_method_decl (c_parser
*, bool, tree
*, tree
*);
1606 static tree
c_parser_objc_type_name (c_parser
*);
1607 static tree
c_parser_objc_protocol_refs (c_parser
*);
1608 static void c_parser_objc_try_catch_finally_statement (c_parser
*);
1609 static void c_parser_objc_synchronized_statement (c_parser
*);
1610 static tree
c_parser_objc_selector (c_parser
*);
1611 static tree
c_parser_objc_selector_arg (c_parser
*);
1612 static tree
c_parser_objc_receiver (c_parser
*);
1613 static tree
c_parser_objc_message_args (c_parser
*);
1614 static tree
c_parser_objc_keywordexpr (c_parser
*);
1615 static void c_parser_objc_at_property_declaration (c_parser
*);
1616 static void c_parser_objc_at_synthesize_declaration (c_parser
*);
1617 static void c_parser_objc_at_dynamic_declaration (c_parser
*);
1618 static bool c_parser_objc_diagnose_bad_element_prefix
1619 (c_parser
*, struct c_declspecs
*);
1620 static location_t
c_parser_parse_rtl_body (c_parser
*, char *);
1622 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1625 external-declarations
1627 external-declarations:
1628 external-declaration
1629 external-declarations external-declaration
1638 c_parser_translation_unit (c_parser
*parser
)
1640 if (c_parser_next_token_is (parser
, CPP_EOF
))
1642 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1643 "ISO C forbids an empty translation unit");
1647 void *obstack_position
= obstack_alloc (&parser_obstack
, 0);
1648 mark_valid_location_for_stdc_pragma (false);
1652 c_parser_external_declaration (parser
);
1653 obstack_free (&parser_obstack
, obstack_position
);
1655 while (c_parser_next_token_is_not (parser
, CPP_EOF
));
1660 FOR_EACH_VEC_ELT (incomplete_record_decls
, i
, decl
)
1661 if (DECL_SIZE (decl
) == NULL_TREE
&& TREE_TYPE (decl
) != error_mark_node
)
1662 error ("storage size of %q+D isn%'t known", decl
);
1664 if (current_omp_declare_target_attribute
)
1667 error ("%<#pragma omp declare target%> without corresponding "
1668 "%<#pragma omp end declare target%>");
1669 current_omp_declare_target_attribute
= 0;
1673 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1675 external-declaration:
1681 external-declaration:
1684 __extension__ external-declaration
1688 external-declaration:
1689 objc-class-definition
1690 objc-class-declaration
1691 objc-alias-declaration
1692 objc-protocol-definition
1693 objc-method-definition
1698 c_parser_external_declaration (c_parser
*parser
)
1701 switch (c_parser_peek_token (parser
)->type
)
1704 switch (c_parser_peek_token (parser
)->keyword
)
1707 ext
= disable_extension_diagnostics ();
1708 c_parser_consume_token (parser
);
1709 c_parser_external_declaration (parser
);
1710 restore_extension_diagnostics (ext
);
1713 c_parser_asm_definition (parser
);
1715 case RID_AT_INTERFACE
:
1716 case RID_AT_IMPLEMENTATION
:
1717 gcc_assert (c_dialect_objc ());
1718 c_parser_objc_class_definition (parser
, NULL_TREE
);
1721 gcc_assert (c_dialect_objc ());
1722 c_parser_objc_class_declaration (parser
);
1725 gcc_assert (c_dialect_objc ());
1726 c_parser_objc_alias_declaration (parser
);
1728 case RID_AT_PROTOCOL
:
1729 gcc_assert (c_dialect_objc ());
1730 c_parser_objc_protocol_definition (parser
, NULL_TREE
);
1732 case RID_AT_PROPERTY
:
1733 gcc_assert (c_dialect_objc ());
1734 c_parser_objc_at_property_declaration (parser
);
1736 case RID_AT_SYNTHESIZE
:
1737 gcc_assert (c_dialect_objc ());
1738 c_parser_objc_at_synthesize_declaration (parser
);
1740 case RID_AT_DYNAMIC
:
1741 gcc_assert (c_dialect_objc ());
1742 c_parser_objc_at_dynamic_declaration (parser
);
1745 gcc_assert (c_dialect_objc ());
1746 c_parser_consume_token (parser
);
1747 objc_finish_implementation ();
1754 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
1755 "ISO C does not allow extra %<;%> outside of a function");
1756 c_parser_consume_token (parser
);
1759 mark_valid_location_for_stdc_pragma (true);
1760 c_parser_pragma (parser
, pragma_external
, NULL
);
1761 mark_valid_location_for_stdc_pragma (false);
1765 if (c_dialect_objc ())
1767 c_parser_objc_method_definition (parser
);
1770 /* Else fall through, and yield a syntax error trying to parse
1771 as a declaration or function definition. */
1775 /* A declaration or a function definition (or, in Objective-C,
1776 an @interface or @protocol with prefix attributes). We can
1777 only tell which after parsing the declaration specifiers, if
1778 any, and the first declarator. */
1779 c_parser_declaration_or_fndef (parser
, true, true, true, false, true);
1784 static void c_finish_omp_declare_simd (c_parser
*, tree
, tree
, vec
<c_token
> *);
1785 static void c_finish_oacc_routine (struct oacc_routine_data
*, tree
, bool);
1787 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1790 add_debug_begin_stmt (location_t loc
)
1792 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1793 if (!MAY_HAVE_DEBUG_MARKER_STMTS
|| !building_stmt_list_p ())
1796 tree stmt
= build0 (DEBUG_BEGIN_STMT
, void_type_node
);
1797 SET_EXPR_LOCATION (stmt
, loc
);
1801 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1802 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1803 is accepted; otherwise (old-style parameter declarations) only other
1804 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1805 assertion is accepted; otherwise (old-style parameter declarations)
1806 it is not. If NESTED is true, we are inside a function or parsing
1807 old-style parameter declarations; any functions encountered are
1808 nested functions and declaration specifiers are required; otherwise
1809 we are at top level and functions are normal functions and
1810 declaration specifiers may be optional. If EMPTY_OK is true, empty
1811 declarations are OK (subject to all other constraints); otherwise
1812 (old-style parameter declarations) they are diagnosed. If
1813 START_ATTR_OK is true, the declaration specifiers may start with
1814 attributes (GNU or standard); otherwise they may not.
1815 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1816 declaration when parsing an Objective-C foreach statement.
1817 FALLTHRU_ATTR_P is used to signal whether this function parsed
1818 "__attribute__((fallthrough));". ATTRS are any standard attributes
1819 parsed in the caller (in contexts where such attributes had to be
1820 parsed to determine whether what follows is a declaration or a
1821 statement); HAVE_ATTRS says whether there were any such attributes
1825 declaration-specifiers init-declarator-list[opt] ;
1826 static_assert-declaration
1828 function-definition:
1829 declaration-specifiers[opt] declarator declaration-list[opt]
1834 declaration-list declaration
1836 init-declarator-list:
1838 init-declarator-list , init-declarator
1841 declarator simple-asm-expr[opt] gnu-attributes[opt]
1842 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1846 nested-function-definition:
1847 declaration-specifiers declarator declaration-list[opt]
1853 gnu-attributes objc-class-definition
1854 gnu-attributes objc-category-definition
1855 gnu-attributes objc-protocol-definition
1857 The simple-asm-expr and gnu-attributes are GNU extensions.
1859 This function does not handle __extension__; that is handled in its
1860 callers. ??? Following the old parser, __extension__ may start
1861 external declarations, declarations in functions and declarations
1862 at the start of "for" loops, but not old-style parameter
1865 C99 requires declaration specifiers in a function definition; the
1866 absence is diagnosed through the diagnosis of implicit int. In GNU
1867 C we also allow but diagnose declarations without declaration
1868 specifiers, but only at top level (elsewhere they conflict with
1871 In Objective-C, declarations of the looping variable in a foreach
1872 statement are exceptionally terminated by 'in' (for example, 'for
1873 (NSObject *object in array) { ... }').
1878 threadprivate-directive
1882 gimple-function-definition:
1883 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1884 declaration-list[opt] compound-statement
1886 rtl-function-definition:
1887 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1888 declaration-list[opt] compound-statement */
1891 c_parser_declaration_or_fndef (c_parser
*parser
, bool fndef_ok
,
1892 bool static_assert_ok
, bool empty_ok
,
1893 bool nested
, bool start_attr_ok
,
1894 tree
*objc_foreach_object_declaration
1896 vec
<c_token
> *omp_declare_simd_clauses
1898 bool have_attrs
/* = false */,
1899 tree attrs
/* = NULL_TREE */,
1900 struct oacc_routine_data
*oacc_routine_data
1902 bool *fallthru_attr_p
/* = NULL */)
1904 struct c_declspecs
*specs
;
1906 tree all_prefix_attrs
;
1907 bool diagnosed_no_specs
= false;
1908 location_t here
= c_parser_peek_token (parser
)->location
;
1910 add_debug_begin_stmt (c_parser_peek_token (parser
)->location
);
1912 if (static_assert_ok
1913 && c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
1915 c_parser_static_assert_declaration (parser
);
1918 specs
= build_null_declspecs ();
1920 /* Handle any standard attributes parsed in the caller. */
1923 declspecs_add_attrs (here
, specs
, attrs
);
1924 specs
->non_std_attrs_seen_p
= false;
1927 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1928 if (c_parser_peek_token (parser
)->type
== CPP_NAME
1929 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
1930 && (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
1931 || c_parser_peek_2nd_token (parser
)->type
== CPP_MULT
)
1932 && (!nested
|| !lookup_name (c_parser_peek_token (parser
)->value
)))
1934 tree name
= c_parser_peek_token (parser
)->value
;
1936 /* Issue a warning about NAME being an unknown type name, perhaps
1937 with some kind of hint.
1938 If the user forgot a "struct" etc, suggest inserting
1939 it. Otherwise, attempt to look for misspellings. */
1940 gcc_rich_location
richloc (here
);
1941 if (tag_exists_p (RECORD_TYPE
, name
))
1943 /* This is not C++ with its implicit typedef. */
1944 richloc
.add_fixit_insert_before ("struct ");
1946 "unknown type name %qE;"
1947 " use %<struct%> keyword to refer to the type",
1950 else if (tag_exists_p (UNION_TYPE
, name
))
1952 richloc
.add_fixit_insert_before ("union ");
1954 "unknown type name %qE;"
1955 " use %<union%> keyword to refer to the type",
1958 else if (tag_exists_p (ENUMERAL_TYPE
, name
))
1960 richloc
.add_fixit_insert_before ("enum ");
1962 "unknown type name %qE;"
1963 " use %<enum%> keyword to refer to the type",
1968 auto_diagnostic_group d
;
1969 name_hint hint
= lookup_name_fuzzy (name
, FUZZY_LOOKUP_TYPENAME
,
1971 if (const char *suggestion
= hint
.suggestion ())
1973 richloc
.add_fixit_replace (suggestion
);
1975 "unknown type name %qE; did you mean %qs?",
1979 error_at (here
, "unknown type name %qE", name
);
1982 /* Parse declspecs normally to get a correct pointer type, but avoid
1983 a further "fails to be a type name" error. Refuse nested functions
1984 since it is not how the user likely wants us to recover. */
1985 c_parser_peek_token (parser
)->type
= CPP_KEYWORD
;
1986 c_parser_peek_token (parser
)->keyword
= RID_VOID
;
1987 c_parser_peek_token (parser
)->value
= error_mark_node
;
1991 /* When there are standard attributes at the start of the
1992 declaration (to apply to the entity being declared), an
1993 init-declarator-list or function definition must be present. */
1994 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
1997 c_parser_declspecs (parser
, specs
, true, true, start_attr_ok
,
1998 true, true, start_attr_ok
, true, cla_nonabstract_decl
);
2001 c_parser_skip_to_end_of_block_or_statement (parser
);
2004 if (nested
&& !specs
->declspecs_seen_p
)
2006 c_parser_error (parser
, "expected declaration specifiers");
2007 c_parser_skip_to_end_of_block_or_statement (parser
);
2011 finish_declspecs (specs
);
2012 bool auto_type_p
= specs
->typespec_word
== cts_auto_type
;
2013 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2016 error_at (here
, "%<__auto_type%> in empty declaration");
2017 else if (specs
->typespec_kind
== ctsk_none
2018 && attribute_fallthrough_p (specs
->attrs
))
2020 if (fallthru_attr_p
!= NULL
)
2021 *fallthru_attr_p
= true;
2024 tree fn
= build_call_expr_internal_loc (here
, IFN_FALLTHROUGH
,
2029 pedwarn (here
, OPT_Wattributes
,
2030 "%<fallthrough%> attribute at top level");
2032 else if (empty_ok
&& !(have_attrs
2033 && specs
->non_std_attrs_seen_p
))
2037 shadow_tag_warned (specs
, 1);
2038 pedwarn (here
, 0, "empty declaration");
2040 c_parser_consume_token (parser
);
2041 if (oacc_routine_data
)
2042 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2046 /* Provide better error recovery. Note that a type name here is usually
2047 better diagnosed as a redeclaration. */
2049 && specs
->typespec_kind
== ctsk_tagdef
2050 && c_parser_next_token_starts_declspecs (parser
)
2051 && !c_parser_next_token_is (parser
, CPP_NAME
))
2053 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
2054 parser
->error
= false;
2055 shadow_tag_warned (specs
, 1);
2058 else if (c_dialect_objc () && !auto_type_p
)
2060 /* Prefix attributes are an error on method decls. */
2061 switch (c_parser_peek_token (parser
)->type
)
2065 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2069 warning_at (c_parser_peek_token (parser
)->location
,
2071 "prefix attributes are ignored for methods");
2072 specs
->attrs
= NULL_TREE
;
2075 c_parser_objc_method_definition (parser
);
2077 c_parser_objc_methodproto (parser
);
2083 /* This is where we parse 'attributes @interface ...',
2084 'attributes @implementation ...', 'attributes @protocol ...'
2085 (where attributes could be, for example, __attribute__
2088 switch (c_parser_peek_token (parser
)->keyword
)
2090 case RID_AT_INTERFACE
:
2092 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2094 c_parser_objc_class_definition (parser
, specs
->attrs
);
2098 case RID_AT_IMPLEMENTATION
:
2100 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2104 warning_at (c_parser_peek_token (parser
)->location
,
2106 "prefix attributes are ignored for implementations");
2107 specs
->attrs
= NULL_TREE
;
2109 c_parser_objc_class_definition (parser
, NULL_TREE
);
2113 case RID_AT_PROTOCOL
:
2115 if (c_parser_objc_diagnose_bad_element_prefix (parser
, specs
))
2117 c_parser_objc_protocol_definition (parser
, specs
->attrs
);
2124 case RID_AT_PROPERTY
:
2127 c_parser_error (parser
, "unexpected attribute");
2128 specs
->attrs
= NULL
;
2135 else if (attribute_fallthrough_p (specs
->attrs
))
2136 warning_at (here
, OPT_Wattributes
,
2137 "%<fallthrough%> attribute not followed by %<;%>");
2139 pending_xref_error ();
2140 prefix_attrs
= specs
->attrs
;
2141 all_prefix_attrs
= prefix_attrs
;
2142 specs
->attrs
= NULL_TREE
;
2145 struct c_declarator
*declarator
;
2148 tree fnbody
= NULL_TREE
;
2149 /* Declaring either one or more declarators (in which case we
2150 should diagnose if there were no declaration specifiers) or a
2151 function definition (in which case the diagnostic for
2152 implicit int suffices). */
2153 declarator
= c_parser_declarator (parser
,
2154 specs
->typespec_kind
!= ctsk_none
,
2155 C_DTR_NORMAL
, &dummy
);
2156 if (declarator
== NULL
)
2158 if (omp_declare_simd_clauses
)
2159 c_finish_omp_declare_simd (parser
, NULL_TREE
, NULL_TREE
,
2160 omp_declare_simd_clauses
);
2161 if (oacc_routine_data
)
2162 c_finish_oacc_routine (oacc_routine_data
, NULL_TREE
, false);
2163 c_parser_skip_to_end_of_block_or_statement (parser
);
2166 if (auto_type_p
&& declarator
->kind
!= cdk_id
)
2169 "%<__auto_type%> requires a plain identifier"
2171 c_parser_skip_to_end_of_block_or_statement (parser
);
2174 if (c_parser_next_token_is (parser
, CPP_EQ
)
2175 || c_parser_next_token_is (parser
, CPP_COMMA
)
2176 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
2177 || c_parser_next_token_is_keyword (parser
, RID_ASM
)
2178 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
)
2179 || c_parser_next_token_is_keyword (parser
, RID_IN
))
2181 tree asm_name
= NULL_TREE
;
2182 tree postfix_attrs
= NULL_TREE
;
2183 if (!diagnosed_no_specs
&& !specs
->declspecs_seen_p
)
2185 diagnosed_no_specs
= true;
2186 pedwarn (here
, 0, "data definition has no type or storage class");
2188 /* Having seen a data definition, there cannot now be a
2189 function definition. */
2191 if (c_parser_next_token_is_keyword (parser
, RID_ASM
))
2192 asm_name
= c_parser_simple_asm_expr (parser
);
2193 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2195 postfix_attrs
= c_parser_gnu_attributes (parser
);
2196 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
2198 /* This means there is an attribute specifier after
2199 the declarator in a function definition. Provide
2200 some more information for the user. */
2201 error_at (here
, "attributes should be specified before the "
2202 "declarator in a function definition");
2203 c_parser_skip_to_end_of_block_or_statement (parser
);
2207 if (c_parser_next_token_is (parser
, CPP_EQ
))
2211 location_t init_loc
;
2212 c_parser_consume_token (parser
);
2215 init_loc
= c_parser_peek_token (parser
)->location
;
2216 rich_location
richloc (line_table
, init_loc
);
2217 start_init (NULL_TREE
, asm_name
, global_bindings_p (), &richloc
);
2218 /* A parameter is initialized, which is invalid. Don't
2219 attempt to instrument the initializer. */
2220 int flag_sanitize_save
= flag_sanitize
;
2221 if (nested
&& !empty_ok
)
2223 init
= c_parser_expr_no_commas (parser
, NULL
);
2224 flag_sanitize
= flag_sanitize_save
;
2225 if (TREE_CODE (init
.value
) == COMPONENT_REF
2226 && DECL_C_BIT_FIELD (TREE_OPERAND (init
.value
, 1)))
2228 "%<__auto_type%> used with a bit-field"
2230 init
= convert_lvalue_to_rvalue (init_loc
, init
, true, true);
2231 tree init_type
= TREE_TYPE (init
.value
);
2232 bool vm_type
= variably_modified_type_p (init_type
,
2235 init
.value
= save_expr (init
.value
);
2237 specs
->typespec_kind
= ctsk_typeof
;
2238 specs
->locations
[cdw_typedef
] = init_loc
;
2239 specs
->typedef_p
= true;
2240 specs
->type
= init_type
;
2243 bool maybe_const
= true;
2244 tree type_expr
= c_fully_fold (init
.value
, false,
2246 specs
->expr_const_operands
&= maybe_const
;
2248 specs
->expr
= build2 (COMPOUND_EXPR
,
2249 TREE_TYPE (type_expr
),
2250 specs
->expr
, type_expr
);
2252 specs
->expr
= type_expr
;
2254 d
= start_decl (declarator
, specs
, true,
2255 chainon (postfix_attrs
, all_prefix_attrs
));
2257 d
= error_mark_node
;
2258 if (omp_declare_simd_clauses
)
2259 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2260 omp_declare_simd_clauses
);
2264 /* The declaration of the variable is in effect while
2265 its initializer is parsed. */
2266 d
= start_decl (declarator
, specs
, true,
2267 chainon (postfix_attrs
, all_prefix_attrs
));
2269 d
= error_mark_node
;
2270 if (omp_declare_simd_clauses
)
2271 c_finish_omp_declare_simd (parser
, d
, NULL_TREE
,
2272 omp_declare_simd_clauses
);
2273 init_loc
= c_parser_peek_token (parser
)->location
;
2274 rich_location
richloc (line_table
, init_loc
);
2275 start_init (d
, asm_name
, global_bindings_p (), &richloc
);
2276 /* A parameter is initialized, which is invalid. Don't
2277 attempt to instrument the initializer. */
2278 int flag_sanitize_save
= flag_sanitize
;
2279 if (TREE_CODE (d
) == PARM_DECL
)
2281 init
= c_parser_initializer (parser
);
2282 flag_sanitize
= flag_sanitize_save
;
2285 if (oacc_routine_data
)
2286 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2287 if (d
!= error_mark_node
)
2289 maybe_warn_string_init (init_loc
, TREE_TYPE (d
), init
);
2290 finish_decl (d
, init_loc
, init
.value
,
2291 init
.original_type
, asm_name
);
2299 "%<__auto_type%> requires an initialized "
2300 "data declaration");
2301 c_parser_skip_to_end_of_block_or_statement (parser
);
2305 location_t lastloc
= UNKNOWN_LOCATION
;
2306 tree attrs
= chainon (postfix_attrs
, all_prefix_attrs
);
2307 tree d
= start_decl (declarator
, specs
, false, attrs
, &lastloc
);
2308 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2310 /* Find the innermost declarator that is neither cdk_id
2312 const struct c_declarator
*decl
= declarator
;
2313 const struct c_declarator
*last_non_id_attrs
= NULL
;
2321 last_non_id_attrs
= decl
;
2322 decl
= decl
->declarator
;
2326 decl
= decl
->declarator
;
2337 /* If it exists and is cdk_function declaration whose
2338 arguments have not been set yet, use its arguments. */
2339 if (last_non_id_attrs
2340 && last_non_id_attrs
->kind
== cdk_function
)
2342 tree parms
= last_non_id_attrs
->u
.arg_info
->parms
;
2343 if (DECL_ARGUMENTS (d
) == NULL_TREE
2344 && DECL_INITIAL (d
) == NULL_TREE
)
2345 DECL_ARGUMENTS (d
) = parms
;
2347 warn_parm_array_mismatch (lastloc
, d
, parms
);
2350 if (omp_declare_simd_clauses
)
2352 tree parms
= NULL_TREE
;
2353 if (d
&& TREE_CODE (d
) == FUNCTION_DECL
)
2355 struct c_declarator
*ce
= declarator
;
2357 if (ce
->kind
== cdk_function
)
2359 parms
= ce
->u
.arg_info
->parms
;
2363 ce
= ce
->declarator
;
2366 temp_store_parm_decls (d
, parms
);
2367 c_finish_omp_declare_simd (parser
, d
, parms
,
2368 omp_declare_simd_clauses
);
2370 temp_pop_parm_decls ();
2372 if (oacc_routine_data
)
2373 c_finish_oacc_routine (oacc_routine_data
, d
, false);
2375 finish_decl (d
, UNKNOWN_LOCATION
, NULL_TREE
,
2376 NULL_TREE
, asm_name
);
2378 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2381 *objc_foreach_object_declaration
= d
;
2383 *objc_foreach_object_declaration
= error_mark_node
;
2386 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2391 "%<__auto_type%> may only be used with"
2392 " a single declarator");
2393 c_parser_skip_to_end_of_block_or_statement (parser
);
2396 c_parser_consume_token (parser
);
2397 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
2398 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
2401 all_prefix_attrs
= prefix_attrs
;
2404 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
2406 c_parser_consume_token (parser
);
2409 else if (c_parser_next_token_is_keyword (parser
, RID_IN
))
2411 /* This can only happen in Objective-C: we found the
2412 'in' that terminates the declaration inside an
2413 Objective-C foreach statement. Do not consume the
2414 token, so that the caller can use it to determine
2415 that this indeed is a foreach context. */
2420 c_parser_error (parser
, "expected %<,%> or %<;%>");
2421 c_parser_skip_to_end_of_block_or_statement (parser
);
2425 else if (auto_type_p
)
2428 "%<__auto_type%> requires an initialized data declaration");
2429 c_parser_skip_to_end_of_block_or_statement (parser
);
2434 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, "
2435 "%<asm%> or %<__attribute__%>");
2436 c_parser_skip_to_end_of_block_or_statement (parser
);
2439 /* Function definition (nested or otherwise). */
2442 pedwarn (here
, OPT_Wpedantic
, "ISO C forbids nested functions");
2443 c_push_function_context ();
2445 if (!start_function (specs
, declarator
, all_prefix_attrs
))
2447 /* At this point we've consumed:
2448 declaration-specifiers declarator
2449 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2450 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2452 declaration-specifiers declarator
2453 aren't grokkable as a function definition, so we have
2455 gcc_assert (!c_parser_next_token_is (parser
, CPP_SEMICOLON
));
2456 if (c_parser_next_token_starts_declspecs (parser
))
2459 declaration-specifiers declarator decl-specs
2460 then assume we have a missing semicolon, which would
2462 declaration-specifiers declarator decl-specs
2465 <~~~~~~~~~ declaration ~~~~~~~~~~>
2466 Use c_parser_require to get an error with a fix-it hint. */
2467 c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>");
2468 parser
->error
= false;
2472 /* This can appear in many cases looking nothing like a
2473 function definition, so we don't give a more specific
2474 error suggesting there was one. */
2475 c_parser_error (parser
, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2476 "or %<__attribute__%>");
2479 c_pop_function_context ();
2483 if (DECL_DECLARED_INLINE_P (current_function_decl
))
2484 tv
= TV_PARSE_INLINE
;
2487 auto_timevar
at (g_timer
, tv
);
2489 /* Parse old-style parameter declarations. ??? Attributes are
2490 not allowed to start declaration specifiers here because of a
2491 syntax conflict between a function declaration with attribute
2492 suffix and a function definition with an attribute prefix on
2493 first old-style parameter declaration. Following the old
2494 parser, they are not accepted on subsequent old-style
2495 parameter declarations either. However, there is no
2496 ambiguity after the first declaration, nor indeed on the
2497 first as long as we don't allow postfix attributes after a
2498 declarator with a nonempty identifier list in a definition;
2499 and postfix attributes have never been accepted here in
2500 function definitions either. */
2501 while (c_parser_next_token_is_not (parser
, CPP_EOF
)
2502 && c_parser_next_token_is_not (parser
, CPP_OPEN_BRACE
))
2503 c_parser_declaration_or_fndef (parser
, false, false, false,
2505 store_parm_decls ();
2506 if (omp_declare_simd_clauses
)
2507 c_finish_omp_declare_simd (parser
, current_function_decl
, NULL_TREE
,
2508 omp_declare_simd_clauses
);
2509 if (oacc_routine_data
)
2510 c_finish_oacc_routine (oacc_routine_data
, current_function_decl
, true);
2511 location_t startloc
= c_parser_peek_token (parser
)->location
;
2512 DECL_STRUCT_FUNCTION (current_function_decl
)->function_start_locus
2514 location_t endloc
= startloc
;
2516 /* If the definition was marked with __RTL, use the RTL parser now,
2517 consuming the function body. */
2518 if (specs
->declspec_il
== cdil_rtl
)
2520 endloc
= c_parser_parse_rtl_body (parser
, specs
->gimple_or_rtl_pass
);
2522 /* Normally, store_parm_decls sets next_is_function_body,
2523 anticipating a function body. We need a push_scope/pop_scope
2524 pair to flush out this state, or subsequent function parsing
2529 finish_function (endloc
);
2532 /* If the definition was marked with __GIMPLE then parse the
2533 function body as GIMPLE. */
2534 else if (specs
->declspec_il
!= cdil_none
)
2536 bool saved
= in_late_binary_op
;
2537 in_late_binary_op
= true;
2538 c_parser_parse_gimple_body (parser
, specs
->gimple_or_rtl_pass
,
2540 specs
->entry_bb_count
);
2541 in_late_binary_op
= saved
;
2544 fnbody
= c_parser_compound_statement (parser
, &endloc
);
2545 tree fndecl
= current_function_decl
;
2548 tree decl
= current_function_decl
;
2549 /* Mark nested functions as needing static-chain initially.
2550 lower_nested_functions will recompute it but the
2551 DECL_STATIC_CHAIN flag is also used before that happens,
2552 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2553 DECL_STATIC_CHAIN (decl
) = 1;
2555 finish_function (endloc
);
2556 c_pop_function_context ();
2557 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl
), DECL_EXPR
, decl
));
2563 finish_function (endloc
);
2565 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2566 if (specs
->declspec_il
!= cdil_none
)
2567 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
2573 /* Parse an asm-definition (asm() outside a function body). This is a
2581 c_parser_asm_definition (c_parser
*parser
)
2583 tree asm_str
= c_parser_simple_asm_expr (parser
);
2585 symtab
->finalize_toplevel_asm (asm_str
);
2586 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
2589 /* Parse a static assertion (C11 6.7.10).
2591 static_assert-declaration:
2592 static_assert-declaration-no-semi ;
2596 c_parser_static_assert_declaration (c_parser
*parser
)
2598 c_parser_static_assert_declaration_no_semi (parser
);
2600 || !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
2601 c_parser_skip_to_end_of_block_or_statement (parser
);
2604 /* Parse a static assertion (C11 6.7.10), without the trailing
2607 static_assert-declaration-no-semi:
2608 _Static_assert ( constant-expression , string-literal )
2611 static_assert-declaration-no-semi:
2612 _Static_assert ( constant-expression )
2616 c_parser_static_assert_declaration_no_semi (c_parser
*parser
)
2618 location_t assert_loc
, value_loc
;
2620 tree string
= NULL_TREE
;
2622 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
));
2623 assert_loc
= c_parser_peek_token (parser
)->location
;
2625 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2626 "ISO C99 does not support %<_Static_assert%>");
2628 pedwarn_c99 (assert_loc
, OPT_Wpedantic
,
2629 "ISO C90 does not support %<_Static_assert%>");
2630 c_parser_consume_token (parser
);
2631 matching_parens parens
;
2632 if (!parens
.require_open (parser
))
2634 location_t value_tok_loc
= c_parser_peek_token (parser
)->location
;
2635 value
= c_parser_expr_no_commas (parser
, NULL
).value
;
2636 value_loc
= EXPR_LOC_OR_LOC (value
, value_tok_loc
);
2637 if (c_parser_next_token_is (parser
, CPP_COMMA
))
2639 c_parser_consume_token (parser
);
2640 switch (c_parser_peek_token (parser
)->type
)
2646 case CPP_UTF8STRING
:
2647 string
= c_parser_string_literal (parser
, false, true).value
;
2650 c_parser_error (parser
, "expected string literal");
2654 else if (flag_isoc11
)
2655 /* If pedantic for pre-C11, the use of _Static_assert itself will
2656 have been diagnosed, so do not also diagnose the use of this
2657 new C2X feature of _Static_assert. */
2658 pedwarn_c11 (assert_loc
, OPT_Wpedantic
,
2659 "ISO C11 does not support omitting the string in "
2660 "%<_Static_assert%>");
2661 parens
.require_close (parser
);
2663 if (!INTEGRAL_TYPE_P (TREE_TYPE (value
)))
2665 error_at (value_loc
, "expression in static assertion is not an integer");
2668 if (TREE_CODE (value
) != INTEGER_CST
)
2670 value
= c_fully_fold (value
, false, NULL
);
2671 /* Strip no-op conversions. */
2672 STRIP_TYPE_NOPS (value
);
2673 if (TREE_CODE (value
) == INTEGER_CST
)
2674 pedwarn (value_loc
, OPT_Wpedantic
, "expression in static assertion "
2675 "is not an integer constant expression");
2677 if (TREE_CODE (value
) != INTEGER_CST
)
2679 error_at (value_loc
, "expression in static assertion is not constant");
2682 constant_expression_warning (value
);
2683 if (integer_zerop (value
))
2686 error_at (assert_loc
, "static assertion failed: %E", string
);
2688 error_at (assert_loc
, "static assertion failed");
2692 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2693 6.7, C11 6.7), adding them to SPECS (which may already include some).
2694 Storage class specifiers are accepted iff SCSPEC_OK; type
2695 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2696 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2697 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2698 addition to the syntax shown, standard attributes are accepted at
2699 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2700 unlike gnu-attributes, they are not accepted in the middle of the
2701 list. (This combines various different syntax productions in the C
2702 standard, and in some cases gnu-attributes and standard attributes
2703 at the start may already have been parsed before this function is
2706 declaration-specifiers:
2707 storage-class-specifier declaration-specifiers[opt]
2708 type-specifier declaration-specifiers[opt]
2709 type-qualifier declaration-specifiers[opt]
2710 function-specifier declaration-specifiers[opt]
2711 alignment-specifier declaration-specifiers[opt]
2713 Function specifiers (inline) are from C99, and are currently
2714 handled as storage class specifiers, as is __thread. Alignment
2715 specifiers are from C11.
2717 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2718 storage-class-specifier:
2726 (_Thread_local is new in C11.)
2728 C99 6.7.4, C11 6.7.4:
2733 (_Noreturn is new in C11.)
2735 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2748 [_Imaginary removed in C99 TC2]
2749 struct-or-union-specifier
2752 atomic-type-specifier
2754 (_Bool and _Complex are new in C99.)
2755 (atomic-type-specifier is new in C11.)
2757 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2763 address-space-qualifier
2766 (restrict is new in C99.)
2767 (_Atomic is new in C11.)
2771 declaration-specifiers:
2772 gnu-attributes declaration-specifiers[opt]
2778 identifier recognized by the target
2780 storage-class-specifier:
2794 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2795 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2797 atomic-type-specifier
2798 _Atomic ( type-name )
2803 class-name objc-protocol-refs[opt]
2804 typedef-name objc-protocol-refs
2809 c_parser_declspecs (c_parser
*parser
, struct c_declspecs
*specs
,
2810 bool scspec_ok
, bool typespec_ok
, bool start_attr_ok
,
2811 bool alignspec_ok
, bool auto_type_ok
,
2812 bool start_std_attr_ok
, bool end_std_attr_ok
,
2813 enum c_lookahead_kind la
)
2815 bool attrs_ok
= start_attr_ok
;
2816 bool seen_type
= specs
->typespec_kind
!= ctsk_none
;
2819 gcc_assert (la
== cla_prefer_id
);
2821 if (start_std_attr_ok
2822 && c_parser_nth_token_starts_std_attributes (parser
, 1))
2824 gcc_assert (!specs
->non_std_attrs_seen_p
);
2825 location_t loc
= c_parser_peek_token (parser
)->location
;
2826 tree attrs
= c_parser_std_attribute_specifier_sequence (parser
);
2827 declspecs_add_attrs (loc
, specs
, attrs
);
2828 specs
->non_std_attrs_seen_p
= false;
2831 while (c_parser_next_token_is (parser
, CPP_NAME
)
2832 || c_parser_next_token_is (parser
, CPP_KEYWORD
)
2833 || (c_dialect_objc () && c_parser_next_token_is (parser
, CPP_LESS
)))
2835 struct c_typespec t
;
2838 location_t loc
= c_parser_peek_token (parser
)->location
;
2840 /* If we cannot accept a type, exit if the next token must start
2841 one. Also, if we already have seen a tagged definition,
2842 a typename would be an error anyway and likely the user
2843 has simply forgotten a semicolon, so we exit. */
2844 if ((!typespec_ok
|| specs
->typespec_kind
== ctsk_tagdef
)
2845 && c_parser_next_tokens_start_typename (parser
, la
)
2846 && !c_parser_next_token_is_qualifier (parser
)
2847 && !c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
))
2850 if (c_parser_next_token_is (parser
, CPP_NAME
))
2852 c_token
*name_token
= c_parser_peek_token (parser
);
2853 tree value
= name_token
->value
;
2854 c_id_kind kind
= name_token
->id_kind
;
2856 if (kind
== C_ID_ADDRSPACE
)
2859 = name_token
->keyword
- RID_FIRST_ADDR_SPACE
;
2860 declspecs_add_addrspace (name_token
->location
, specs
, as
);
2861 c_parser_consume_token (parser
);
2866 gcc_assert (!c_parser_next_token_is_qualifier (parser
));
2868 /* If we cannot accept a type, and the next token must start one,
2869 exit. Do the same if we already have seen a tagged definition,
2870 since it would be an error anyway and likely the user has simply
2871 forgotten a semicolon. */
2872 if (seen_type
|| !c_parser_next_tokens_start_typename (parser
, la
))
2875 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2876 a C_ID_CLASSNAME. */
2877 c_parser_consume_token (parser
);
2880 if (kind
== C_ID_ID
)
2882 error_at (loc
, "unknown type name %qE", value
);
2883 t
.kind
= ctsk_typedef
;
2884 t
.spec
= error_mark_node
;
2886 else if (kind
== C_ID_TYPENAME
2887 && (!c_dialect_objc ()
2888 || c_parser_next_token_is_not (parser
, CPP_LESS
)))
2890 t
.kind
= ctsk_typedef
;
2891 /* For a typedef name, record the meaning, not the name.
2892 In case of 'foo foo, bar;'. */
2893 t
.spec
= lookup_name (value
);
2897 tree proto
= NULL_TREE
;
2898 gcc_assert (c_dialect_objc ());
2900 if (c_parser_next_token_is (parser
, CPP_LESS
))
2901 proto
= c_parser_objc_protocol_refs (parser
);
2902 t
.spec
= objc_get_protocol_qualified_type (value
, proto
);
2905 t
.expr_const_operands
= true;
2906 declspecs_add_type (name_token
->location
, specs
, t
);
2909 if (c_parser_next_token_is (parser
, CPP_LESS
))
2911 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2912 nisse@lysator.liu.se. */
2914 gcc_assert (c_dialect_objc ());
2915 if (!typespec_ok
|| seen_type
)
2917 proto
= c_parser_objc_protocol_refs (parser
);
2919 t
.spec
= objc_get_protocol_qualified_type (NULL_TREE
, proto
);
2921 t
.expr_const_operands
= true;
2922 declspecs_add_type (loc
, specs
, t
);
2925 gcc_assert (c_parser_next_token_is (parser
, CPP_KEYWORD
));
2926 switch (c_parser_peek_token (parser
)->keyword
)
2939 /* TODO: Distinguish between function specifiers (inline, noreturn)
2940 and storage class specifiers, either here or in
2941 declspecs_add_scspec. */
2942 declspecs_add_scspec (loc
, specs
,
2943 c_parser_peek_token (parser
)->value
);
2944 c_parser_consume_token (parser
);
2976 if (c_dialect_objc ())
2977 parser
->objc_need_raw_identifier
= true;
2978 t
.kind
= ctsk_resword
;
2979 t
.spec
= c_parser_peek_token (parser
)->value
;
2981 t
.expr_const_operands
= true;
2982 declspecs_add_type (loc
, specs
, t
);
2983 c_parser_consume_token (parser
);
2990 t
= c_parser_enum_specifier (parser
);
2991 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
2992 declspecs_add_type (loc
, specs
, t
);
3000 t
= c_parser_struct_or_union_specifier (parser
);
3001 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE
, t
.spec
);
3002 declspecs_add_type (loc
, specs
, t
);
3005 /* ??? The old parser rejected typeof after other type
3006 specifiers, but is a syntax error the best way of
3008 if (!typespec_ok
|| seen_type
)
3012 t
= c_parser_typeof_specifier (parser
);
3013 declspecs_add_type (loc
, specs
, t
);
3016 /* C parser handling of Objective-C constructs needs
3017 checking for correct lvalue-to-rvalue conversions, and
3018 the code in build_modify_expr handling various
3019 Objective-C cases, and that in build_unary_op handling
3020 Objective-C cases for increment / decrement, also needs
3021 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3022 and objc_types_are_equivalent may also need updates. */
3023 if (c_dialect_objc ())
3024 sorry ("%<_Atomic%> in Objective-C");
3026 pedwarn_c99 (loc
, OPT_Wpedantic
,
3027 "ISO C99 does not support the %<_Atomic%> qualifier");
3029 pedwarn_c99 (loc
, OPT_Wpedantic
,
3030 "ISO C90 does not support the %<_Atomic%> qualifier");
3033 value
= c_parser_peek_token (parser
)->value
;
3034 c_parser_consume_token (parser
);
3035 if (typespec_ok
&& c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3037 /* _Atomic ( type-name ). */
3039 c_parser_consume_token (parser
);
3040 struct c_type_name
*type
= c_parser_type_name (parser
);
3041 t
.kind
= ctsk_typeof
;
3042 t
.spec
= error_mark_node
;
3044 t
.expr_const_operands
= true;
3046 t
.spec
= groktypename (type
, &t
.expr
,
3047 &t
.expr_const_operands
);
3048 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
3050 if (t
.spec
!= error_mark_node
)
3052 if (TREE_CODE (t
.spec
) == ARRAY_TYPE
)
3053 error_at (loc
, "%<_Atomic%>-qualified array type");
3054 else if (TREE_CODE (t
.spec
) == FUNCTION_TYPE
)
3055 error_at (loc
, "%<_Atomic%>-qualified function type");
3056 else if (TYPE_QUALS (t
.spec
) != TYPE_UNQUALIFIED
)
3057 error_at (loc
, "%<_Atomic%> applied to a qualified type");
3059 t
.spec
= c_build_qualified_type (t
.spec
, TYPE_QUAL_ATOMIC
);
3061 declspecs_add_type (loc
, specs
, t
);
3064 declspecs_add_qual (loc
, specs
, value
);
3070 declspecs_add_qual (loc
, specs
, c_parser_peek_token (parser
)->value
);
3071 c_parser_consume_token (parser
);
3076 attrs
= c_parser_gnu_attributes (parser
);
3077 declspecs_add_attrs (loc
, specs
, attrs
);
3082 align
= c_parser_alignas_specifier (parser
);
3083 declspecs_add_alignas (loc
, specs
, align
);
3087 error_at (loc
, "%<__GIMPLE%> only valid with %<-fgimple%>");
3088 c_parser_consume_token (parser
);
3089 specs
->declspec_il
= cdil_gimple
;
3090 specs
->locations
[cdw_gimple
] = loc
;
3091 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3094 c_parser_consume_token (parser
);
3095 specs
->declspec_il
= cdil_rtl
;
3096 specs
->locations
[cdw_rtl
] = loc
;
3097 c_parser_gimple_or_rtl_pass_list (parser
, specs
);
3105 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3106 specs
->postfix_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3109 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3112 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3114 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3116 enum gnu-attributes[opt] identifier
3118 The form with trailing comma is new in C99. The forms with
3119 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3120 without commas in the syntax (assignment expressions, not just
3121 conditional expressions); assignment expressions will be diagnosed
3126 enumerator-list , enumerator
3129 enumeration-constant attribute-specifier-sequence[opt]
3130 enumeration-constant attribute-specifier-sequence[opt]
3131 = constant-expression
3136 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3137 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3138 = constant-expression
3142 static struct c_typespec
3143 c_parser_enum_specifier (c_parser
*parser
)
3145 struct c_typespec ret
;
3146 bool have_std_attrs
;
3147 tree std_attrs
= NULL_TREE
;
3149 tree ident
= NULL_TREE
;
3150 location_t enum_loc
;
3151 location_t ident_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3152 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ENUM
));
3153 c_parser_consume_token (parser
);
3154 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3156 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3157 attrs
= c_parser_gnu_attributes (parser
);
3158 enum_loc
= c_parser_peek_token (parser
)->location
;
3159 /* Set the location in case we create a decl now. */
3160 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3161 if (c_parser_next_token_is (parser
, CPP_NAME
))
3163 ident
= c_parser_peek_token (parser
)->value
;
3164 ident_loc
= c_parser_peek_token (parser
)->location
;
3165 enum_loc
= ident_loc
;
3166 c_parser_consume_token (parser
);
3168 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3170 /* Parse an enum definition. */
3171 struct c_enum_contents the_enum
;
3174 /* We chain the enumerators in reverse order, then put them in
3175 forward order at the end. */
3177 timevar_push (TV_PARSE_ENUM
);
3178 type
= start_enum (enum_loc
, &the_enum
, ident
);
3180 c_parser_consume_token (parser
);
3188 location_t comma_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
3189 location_t decl_loc
, value_loc
;
3190 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
3192 /* Give a nicer error for "enum {}". */
3193 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3196 error_at (c_parser_peek_token (parser
)->location
,
3197 "empty enum is invalid");
3198 parser
->error
= true;
3201 c_parser_error (parser
, "expected identifier");
3202 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3203 values
= error_mark_node
;
3206 token
= c_parser_peek_token (parser
);
3207 enum_id
= token
->value
;
3208 /* Set the location in case we create a decl now. */
3209 c_parser_set_source_position_from_token (token
);
3210 decl_loc
= value_loc
= token
->location
;
3211 c_parser_consume_token (parser
);
3212 /* Parse any specified attributes. */
3213 tree std_attrs
= NULL_TREE
;
3214 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3215 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3216 tree enum_attrs
= chainon (std_attrs
,
3217 c_parser_gnu_attributes (parser
));
3218 if (c_parser_next_token_is (parser
, CPP_EQ
))
3220 c_parser_consume_token (parser
);
3221 value_loc
= c_parser_peek_token (parser
)->location
;
3222 enum_value
= c_parser_expr_no_commas (parser
, NULL
).value
;
3225 enum_value
= NULL_TREE
;
3226 enum_decl
= build_enumerator (decl_loc
, value_loc
,
3227 &the_enum
, enum_id
, enum_value
);
3229 decl_attributes (&TREE_PURPOSE (enum_decl
), enum_attrs
, 0);
3230 TREE_CHAIN (enum_decl
) = values
;
3233 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3235 comma_loc
= c_parser_peek_token (parser
)->location
;
3237 c_parser_consume_token (parser
);
3239 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3242 pedwarn_c90 (comma_loc
, OPT_Wpedantic
,
3243 "comma at end of enumerator list");
3244 c_parser_consume_token (parser
);
3249 c_parser_error (parser
, "expected %<,%> or %<}%>");
3250 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3251 values
= error_mark_node
;
3255 postfix_attrs
= c_parser_gnu_attributes (parser
);
3256 ret
.spec
= finish_enum (type
, nreverse (values
),
3258 chainon (attrs
, postfix_attrs
)));
3259 ret
.kind
= ctsk_tagdef
;
3260 ret
.expr
= NULL_TREE
;
3261 ret
.expr_const_operands
= true;
3262 timevar_pop (TV_PARSE_ENUM
);
3267 c_parser_error (parser
, "expected %<{%>");
3268 ret
.spec
= error_mark_node
;
3269 ret
.kind
= ctsk_tagref
;
3270 ret
.expr
= NULL_TREE
;
3271 ret
.expr_const_operands
= true;
3274 /* Attributes may only appear when the members are defined or in
3275 certain forward declarations (treat enum forward declarations in
3276 GNU C analogously to struct and union forward declarations in
3278 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3279 c_parser_error (parser
, "expected %<;%>");
3280 ret
= parser_xref_tag (ident_loc
, ENUMERAL_TYPE
, ident
, have_std_attrs
,
3282 /* In ISO C, enumerated types can be referred to only if already
3284 if (pedantic
&& !COMPLETE_TYPE_P (ret
.spec
))
3287 pedwarn (enum_loc
, OPT_Wpedantic
,
3288 "ISO C forbids forward references to %<enum%> types");
3293 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3295 struct-or-union-specifier:
3296 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3297 identifier[opt] { struct-contents } gnu-attributes[opt]
3298 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3302 struct-declaration-list
3304 struct-declaration-list:
3305 struct-declaration ;
3306 struct-declaration-list struct-declaration ;
3313 struct-declaration-list struct-declaration
3315 struct-declaration-list:
3316 struct-declaration-list ;
3319 (Note that in the syntax here, unlike that in ISO C, the semicolons
3320 are included here rather than in struct-declaration, in order to
3321 describe the syntax with extra semicolons and missing semicolon at
3326 struct-declaration-list:
3327 @defs ( class-name )
3329 (Note this does not include a trailing semicolon, but can be
3330 followed by further declarations, and gets a pedwarn-if-pedantic
3331 when followed by a semicolon.) */
3333 static struct c_typespec
3334 c_parser_struct_or_union_specifier (c_parser
*parser
)
3336 struct c_typespec ret
;
3337 bool have_std_attrs
;
3338 tree std_attrs
= NULL_TREE
;
3340 tree ident
= NULL_TREE
;
3341 location_t struct_loc
;
3342 location_t ident_loc
= UNKNOWN_LOCATION
;
3343 enum tree_code code
;
3344 switch (c_parser_peek_token (parser
)->keyword
)
3355 struct_loc
= c_parser_peek_token (parser
)->location
;
3356 c_parser_consume_token (parser
);
3357 have_std_attrs
= c_parser_nth_token_starts_std_attributes (parser
, 1);
3359 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3360 attrs
= c_parser_gnu_attributes (parser
);
3362 /* Set the location in case we create a decl now. */
3363 c_parser_set_source_position_from_token (c_parser_peek_token (parser
));
3365 if (c_parser_next_token_is (parser
, CPP_NAME
))
3367 ident
= c_parser_peek_token (parser
)->value
;
3368 ident_loc
= c_parser_peek_token (parser
)->location
;
3369 struct_loc
= ident_loc
;
3370 c_parser_consume_token (parser
);
3372 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
3374 /* Parse a struct or union definition. Start the scope of the
3375 tag before parsing components. */
3376 class c_struct_parse_info
*struct_info
;
3377 tree type
= start_struct (struct_loc
, code
, ident
, &struct_info
);
3379 /* We chain the components in reverse order, then put them in
3380 forward order at the end. Each struct-declaration may
3381 declare multiple components (comma-separated), so we must use
3382 chainon to join them, although when parsing each
3383 struct-declaration we can use TREE_CHAIN directly.
3385 The theory behind all this is that there will be more
3386 semicolon separated fields than comma separated fields, and
3387 so we'll be minimizing the number of node traversals required
3390 timevar_push (TV_PARSE_STRUCT
);
3391 contents
= NULL_TREE
;
3392 c_parser_consume_token (parser
);
3393 /* Handle the Objective-C @defs construct,
3394 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3395 if (c_parser_next_token_is_keyword (parser
, RID_AT_DEFS
))
3398 gcc_assert (c_dialect_objc ());
3399 c_parser_consume_token (parser
);
3400 matching_parens parens
;
3401 if (!parens
.require_open (parser
))
3403 if (c_parser_next_token_is (parser
, CPP_NAME
)
3404 && c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
)
3406 name
= c_parser_peek_token (parser
)->value
;
3407 c_parser_consume_token (parser
);
3411 c_parser_error (parser
, "expected class name");
3412 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
3415 parens
.skip_until_found_close (parser
);
3416 contents
= nreverse (objc_get_class_ivars (name
));
3419 /* Parse the struct-declarations and semicolons. Problems with
3420 semicolons are diagnosed here; empty structures are diagnosed
3425 /* Parse any stray semicolon. */
3426 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3428 location_t semicolon_loc
3429 = c_parser_peek_token (parser
)->location
;
3430 gcc_rich_location
richloc (semicolon_loc
);
3431 richloc
.add_fixit_remove ();
3432 pedwarn (&richloc
, OPT_Wpedantic
,
3433 "extra semicolon in struct or union specified");
3434 c_parser_consume_token (parser
);
3437 /* Stop if at the end of the struct or union contents. */
3438 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3440 c_parser_consume_token (parser
);
3443 /* Accept #pragmas at struct scope. */
3444 if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
3446 c_parser_pragma (parser
, pragma_struct
, NULL
);
3449 /* Parse some comma-separated declarations, but not the
3450 trailing semicolon if any. */
3451 decls
= c_parser_struct_declaration (parser
);
3452 contents
= chainon (decls
, contents
);
3453 /* If no semicolon follows, either we have a parse error or
3454 are at the end of the struct or union and should
3456 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
3457 c_parser_consume_token (parser
);
3460 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3461 pedwarn (c_parser_peek_token (parser
)->location
, 0,
3462 "no semicolon at end of struct or union");
3463 else if (parser
->error
3464 || !c_parser_next_token_starts_declspecs (parser
))
3466 c_parser_error (parser
, "expected %<;%>");
3467 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
3471 /* If we come here, we have already emitted an error
3472 for an expected `;', identifier or `(', and we also
3473 recovered already. Go on with the next field. */
3476 postfix_attrs
= c_parser_gnu_attributes (parser
);
3477 ret
.spec
= finish_struct (struct_loc
, type
, nreverse (contents
),
3479 chainon (attrs
, postfix_attrs
)),
3481 ret
.kind
= ctsk_tagdef
;
3482 ret
.expr
= NULL_TREE
;
3483 ret
.expr_const_operands
= true;
3484 timevar_pop (TV_PARSE_STRUCT
);
3489 c_parser_error (parser
, "expected %<{%>");
3490 ret
.spec
= error_mark_node
;
3491 ret
.kind
= ctsk_tagref
;
3492 ret
.expr
= NULL_TREE
;
3493 ret
.expr_const_operands
= true;
3496 /* Attributes may only appear when the members are defined or in
3497 certain forward declarations. */
3498 if (have_std_attrs
&& c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
3499 c_parser_error (parser
, "expected %<;%>");
3500 /* ??? Existing practice is that GNU attributes are ignored after
3501 the struct or union keyword when not defining the members. */
3502 ret
= parser_xref_tag (ident_loc
, code
, ident
, have_std_attrs
, std_attrs
);
3506 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3507 *without* the trailing semicolon.
3510 attribute-specifier-sequence[opt] specifier-qualifier-list
3511 attribute-specifier-sequence[opt] struct-declarator-list
3512 static_assert-declaration-no-semi
3514 specifier-qualifier-list:
3515 type-specifier specifier-qualifier-list[opt]
3516 type-qualifier specifier-qualifier-list[opt]
3517 alignment-specifier specifier-qualifier-list[opt]
3518 gnu-attributes specifier-qualifier-list[opt]
3520 struct-declarator-list:
3522 struct-declarator-list , gnu-attributes[opt] struct-declarator
3525 declarator gnu-attributes[opt]
3526 declarator[opt] : constant-expression gnu-attributes[opt]
3531 __extension__ struct-declaration
3532 specifier-qualifier-list
3534 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3535 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3536 any expression without commas in the syntax (assignment
3537 expressions, not just conditional expressions); assignment
3538 expressions will be diagnosed as non-constant. */
3541 c_parser_struct_declaration (c_parser
*parser
)
3543 struct c_declspecs
*specs
;
3545 tree all_prefix_attrs
;
3547 location_t decl_loc
;
3548 if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
3552 ext
= disable_extension_diagnostics ();
3553 c_parser_consume_token (parser
);
3554 decl
= c_parser_struct_declaration (parser
);
3555 restore_extension_diagnostics (ext
);
3558 if (c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
3560 c_parser_static_assert_declaration_no_semi (parser
);
3563 specs
= build_null_declspecs ();
3564 decl_loc
= c_parser_peek_token (parser
)->location
;
3565 /* Strictly by the standard, we shouldn't allow _Alignas here,
3566 but it appears to have been intended to allow it there, so
3567 we're keeping it as it is until WG14 reaches a conclusion
3569 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3570 c_parser_declspecs (parser
, specs
, false, true, true,
3571 true, false, true, true, cla_nonabstract_decl
);
3574 if (!specs
->declspecs_seen_p
)
3576 c_parser_error (parser
, "expected specifier-qualifier-list");
3579 finish_declspecs (specs
);
3580 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3581 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3584 if (specs
->typespec_kind
== ctsk_none
)
3586 pedwarn (decl_loc
, OPT_Wpedantic
,
3587 "ISO C forbids member declarations with no members");
3588 shadow_tag_warned (specs
, pedantic
);
3593 /* Support for unnamed structs or unions as members of
3594 structs or unions (which is [a] useful and [b] supports
3598 ret
= grokfield (c_parser_peek_token (parser
)->location
,
3599 build_id_declarator (NULL_TREE
), specs
,
3602 decl_attributes (&ret
, attrs
, 0);
3607 /* Provide better error recovery. Note that a type name here is valid,
3608 and will be treated as a field name. */
3609 if (specs
->typespec_kind
== ctsk_tagdef
3610 && TREE_CODE (specs
->type
) != ENUMERAL_TYPE
3611 && c_parser_next_token_starts_declspecs (parser
)
3612 && !c_parser_next_token_is (parser
, CPP_NAME
))
3614 c_parser_error (parser
, "expected %<;%>, identifier or %<(%>");
3615 parser
->error
= false;
3619 pending_xref_error ();
3620 prefix_attrs
= specs
->attrs
;
3621 all_prefix_attrs
= prefix_attrs
;
3622 specs
->attrs
= NULL_TREE
;
3626 /* Declaring one or more declarators or un-named bit-fields. */
3627 struct c_declarator
*declarator
;
3629 if (c_parser_next_token_is (parser
, CPP_COLON
))
3630 declarator
= build_id_declarator (NULL_TREE
);
3632 declarator
= c_parser_declarator (parser
,
3633 specs
->typespec_kind
!= ctsk_none
,
3634 C_DTR_NORMAL
, &dummy
);
3635 if (declarator
== NULL
)
3637 c_parser_skip_to_end_of_block_or_statement (parser
);
3640 if (c_parser_next_token_is (parser
, CPP_COLON
)
3641 || c_parser_next_token_is (parser
, CPP_COMMA
)
3642 || c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3643 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
)
3644 || c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3646 tree postfix_attrs
= NULL_TREE
;
3647 tree width
= NULL_TREE
;
3649 if (c_parser_next_token_is (parser
, CPP_COLON
))
3651 c_parser_consume_token (parser
);
3652 width
= c_parser_expr_no_commas (parser
, NULL
).value
;
3654 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3655 postfix_attrs
= c_parser_gnu_attributes (parser
);
3656 d
= grokfield (c_parser_peek_token (parser
)->location
,
3657 declarator
, specs
, width
, &all_prefix_attrs
);
3658 decl_attributes (&d
, chainon (postfix_attrs
,
3659 all_prefix_attrs
), 0);
3660 DECL_CHAIN (d
) = decls
;
3662 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
3663 all_prefix_attrs
= chainon (c_parser_gnu_attributes (parser
),
3666 all_prefix_attrs
= prefix_attrs
;
3667 if (c_parser_next_token_is (parser
, CPP_COMMA
))
3668 c_parser_consume_token (parser
);
3669 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
3670 || c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
3672 /* Semicolon consumed in caller. */
3677 c_parser_error (parser
, "expected %<,%>, %<;%> or %<}%>");
3683 c_parser_error (parser
,
3684 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3685 "%<__attribute__%>");
3692 /* Parse a typeof specifier (a GNU extension).
3695 typeof ( expression )
3696 typeof ( type-name )
3699 static struct c_typespec
3700 c_parser_typeof_specifier (c_parser
*parser
)
3702 struct c_typespec ret
;
3703 ret
.kind
= ctsk_typeof
;
3704 ret
.spec
= error_mark_node
;
3705 ret
.expr
= NULL_TREE
;
3706 ret
.expr_const_operands
= true;
3707 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TYPEOF
));
3708 c_parser_consume_token (parser
);
3709 c_inhibit_evaluation_warnings
++;
3711 matching_parens parens
;
3712 if (!parens
.require_open (parser
))
3714 c_inhibit_evaluation_warnings
--;
3718 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3720 struct c_type_name
*type
= c_parser_type_name (parser
);
3721 c_inhibit_evaluation_warnings
--;
3725 ret
.spec
= groktypename (type
, &ret
.expr
, &ret
.expr_const_operands
);
3726 pop_maybe_used (variably_modified_type_p (ret
.spec
, NULL_TREE
));
3732 location_t here
= c_parser_peek_token (parser
)->location
;
3733 struct c_expr expr
= c_parser_expression (parser
);
3734 c_inhibit_evaluation_warnings
--;
3736 if (TREE_CODE (expr
.value
) == COMPONENT_REF
3737 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
3738 error_at (here
, "%<typeof%> applied to a bit-field");
3739 mark_exp_read (expr
.value
);
3740 ret
.spec
= TREE_TYPE (expr
.value
);
3741 was_vm
= variably_modified_type_p (ret
.spec
, NULL_TREE
);
3742 /* This is returned with the type so that when the type is
3743 evaluated, this can be evaluated. */
3745 ret
.expr
= c_fully_fold (expr
.value
, false, &ret
.expr_const_operands
);
3746 pop_maybe_used (was_vm
);
3748 parens
.skip_until_found_close (parser
);
3752 /* Parse an alignment-specifier.
3756 alignment-specifier:
3757 _Alignas ( type-name )
3758 _Alignas ( constant-expression )
3762 c_parser_alignas_specifier (c_parser
* parser
)
3764 tree ret
= error_mark_node
;
3765 location_t loc
= c_parser_peek_token (parser
)->location
;
3766 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNAS
));
3767 c_parser_consume_token (parser
);
3769 pedwarn_c99 (loc
, OPT_Wpedantic
,
3770 "ISO C99 does not support %<_Alignas%>");
3772 pedwarn_c99 (loc
, OPT_Wpedantic
,
3773 "ISO C90 does not support %<_Alignas%>");
3774 matching_parens parens
;
3775 if (!parens
.require_open (parser
))
3777 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
3779 struct c_type_name
*type
= c_parser_type_name (parser
);
3781 ret
= c_sizeof_or_alignof_type (loc
, groktypename (type
, NULL
, NULL
),
3785 ret
= c_parser_expr_no_commas (parser
, NULL
).value
;
3786 parens
.skip_until_found_close (parser
);
3790 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3791 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3792 a typedef name may be redeclared; otherwise it may not. KIND
3793 indicates which kind of declarator is wanted. Returns a valid
3794 declarator except in the case of a syntax error in which case NULL is
3795 returned. *SEEN_ID is set to true if an identifier being declared is
3796 seen; this is used to diagnose bad forms of abstract array declarators
3797 and to determine whether an identifier list is syntactically permitted.
3800 pointer[opt] direct-declarator
3804 ( gnu-attributes[opt] declarator )
3805 direct-declarator array-declarator
3806 direct-declarator ( parameter-type-list )
3807 direct-declarator ( identifier-list[opt] )
3810 * type-qualifier-list[opt]
3811 * type-qualifier-list[opt] pointer
3813 type-qualifier-list:
3816 type-qualifier-list type-qualifier
3817 type-qualifier-list gnu-attributes
3820 [ type-qualifier-list[opt] assignment-expression[opt] ]
3821 [ static type-qualifier-list[opt] assignment-expression ]
3822 [ type-qualifier-list static assignment-expression ]
3823 [ type-qualifier-list[opt] * ]
3825 parameter-type-list:
3827 parameter-list , ...
3830 parameter-declaration
3831 parameter-list , parameter-declaration
3833 parameter-declaration:
3834 declaration-specifiers declarator gnu-attributes[opt]
3835 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3839 identifier-list , identifier
3841 abstract-declarator:
3843 pointer[opt] direct-abstract-declarator
3845 direct-abstract-declarator:
3846 ( gnu-attributes[opt] abstract-declarator )
3847 direct-abstract-declarator[opt] array-declarator
3848 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3853 direct-declarator ( parameter-forward-declarations
3854 parameter-type-list[opt] )
3856 direct-abstract-declarator:
3857 direct-abstract-declarator[opt] ( parameter-forward-declarations
3858 parameter-type-list[opt] )
3860 parameter-forward-declarations:
3862 parameter-forward-declarations parameter-list ;
3864 The uses of gnu-attributes shown above are GNU extensions.
3866 Some forms of array declarator are not included in C99 in the
3867 syntax for abstract declarators; these are disallowed elsewhere.
3868 This may be a defect (DR#289).
3870 This function also accepts an omitted abstract declarator as being
3871 an abstract declarator, although not part of the formal syntax. */
3873 struct c_declarator
*
3874 c_parser_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3877 /* Parse any initial pointer part. */
3878 if (c_parser_next_token_is (parser
, CPP_MULT
))
3880 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
3881 struct c_declarator
*inner
;
3882 c_parser_consume_token (parser
);
3883 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
3884 false, false, true, false, cla_prefer_id
);
3885 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
3889 return make_pointer_declarator (quals_attrs
, inner
);
3891 /* Now we have a direct declarator, direct abstract declarator or
3892 nothing (which counts as a direct abstract declarator here). */
3893 return c_parser_direct_declarator (parser
, type_seen_p
, kind
, seen_id
);
3896 /* Parse a direct declarator or direct abstract declarator; arguments
3897 as c_parser_declarator. */
3899 static struct c_declarator
*
3900 c_parser_direct_declarator (c_parser
*parser
, bool type_seen_p
, c_dtr_syn kind
,
3903 /* The direct declarator must start with an identifier (possibly
3904 omitted) or a parenthesized declarator (possibly abstract). In
3905 an ordinary declarator, initial parentheses must start a
3906 parenthesized declarator. In an abstract declarator or parameter
3907 declarator, they could start a parenthesized declarator or a
3908 parameter list. To tell which, the open parenthesis and any
3909 following gnu-attributes must be read. If a declaration
3910 specifier or standard attributes follow, then it is a parameter
3911 list; if the specifier is a typedef name, there might be an
3912 ambiguity about redeclaring it, which is resolved in the
3913 direction of treating it as a typedef name. If a close
3914 parenthesis follows, it is also an empty parameter list, as the
3915 syntax does not permit empty abstract declarators. Otherwise, it
3916 is a parenthesized declarator (in which case the analysis may be
3917 repeated inside it, recursively).
3919 ??? There is an ambiguity in a parameter declaration "int
3920 (__attribute__((foo)) x)", where x is not a typedef name: it
3921 could be an abstract declarator for a function, or declare x with
3922 parentheses. The proper resolution of this ambiguity needs
3923 documenting. At present we follow an accident of the old
3924 parser's implementation, whereby the first parameter must have
3925 some declaration specifiers other than just gnu-attributes. Thus as
3926 a parameter declaration it is treated as a parenthesized
3927 parameter named x, and as an abstract declarator it is
3930 ??? Also following the old parser, gnu-attributes inside an empty
3931 parameter list are ignored, making it a list not yielding a
3932 prototype, rather than giving an error or making it have one
3933 parameter with implicit type int.
3935 ??? Also following the old parser, typedef names may be
3936 redeclared in declarators, but not Objective-C class names. */
3938 if (kind
!= C_DTR_ABSTRACT
3939 && c_parser_next_token_is (parser
, CPP_NAME
)
3941 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
3942 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
3943 || c_parser_peek_token (parser
)->id_kind
== C_ID_ID
))
3945 struct c_declarator
*inner
3946 = build_id_declarator (c_parser_peek_token (parser
)->value
);
3948 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3949 c_parser_consume_token (parser
);
3950 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
3951 inner
->u
.id
.attrs
= c_parser_std_attribute_specifier_sequence (parser
);
3952 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3955 if (kind
!= C_DTR_NORMAL
3956 && c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
3957 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
3959 struct c_declarator
*inner
= build_id_declarator (NULL_TREE
);
3960 inner
->id_loc
= c_parser_peek_token (parser
)->location
;
3961 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
3964 /* Either we are at the end of an abstract declarator, or we have
3967 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
3970 struct c_declarator
*inner
;
3971 c_parser_consume_token (parser
);
3972 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
3974 attrs
= c_parser_gnu_attributes (parser
);
3975 if (kind
!= C_DTR_NORMAL
3976 && (c_parser_next_token_starts_declspecs (parser
)
3978 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3979 || c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
)))
3981 struct c_arg_info
*args
3982 = c_parser_parms_declarator (parser
, kind
== C_DTR_NORMAL
,
3983 attrs
, have_gnu_attrs
);
3988 inner
= build_id_declarator (NULL_TREE
);
3990 && args
->types
!= error_mark_node
3991 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
3992 && c_parser_nth_token_starts_std_attributes (parser
, 1))
3995 = c_parser_std_attribute_specifier_sequence (parser
);
3997 inner
= build_attrs_declarator (std_attrs
, inner
);
3999 inner
= build_function_declarator (args
, inner
);
4000 return c_parser_direct_declarator_inner (parser
, *seen_id
,
4004 /* A parenthesized declarator. */
4005 inner
= c_parser_declarator (parser
, type_seen_p
, kind
, seen_id
);
4006 if (inner
!= NULL
&& attrs
!= NULL
)
4007 inner
= build_attrs_declarator (attrs
, inner
);
4008 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4010 c_parser_consume_token (parser
);
4014 return c_parser_direct_declarator_inner (parser
, *seen_id
, inner
);
4018 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4025 if (kind
== C_DTR_NORMAL
)
4027 c_parser_error (parser
, "expected identifier or %<(%>");
4031 return build_id_declarator (NULL_TREE
);
4035 /* Parse part of a direct declarator or direct abstract declarator,
4036 given that some (in INNER) has already been parsed; ID_PRESENT is
4037 true if an identifier is present, false for an abstract
4040 static struct c_declarator
*
4041 c_parser_direct_declarator_inner (c_parser
*parser
, bool id_present
,
4042 struct c_declarator
*inner
)
4044 /* Parse a sequence of array declarators and parameter lists. */
4045 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
4046 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4048 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
4049 struct c_declarator
*declarator
;
4050 struct c_declspecs
*quals_attrs
= build_null_declspecs ();
4053 struct c_expr dimen
;
4054 dimen
.value
= NULL_TREE
;
4055 dimen
.original_code
= ERROR_MARK
;
4056 dimen
.original_type
= NULL_TREE
;
4057 c_parser_consume_token (parser
);
4058 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4059 false, false, false, false, cla_prefer_id
);
4060 static_seen
= c_parser_next_token_is_keyword (parser
, RID_STATIC
);
4062 c_parser_consume_token (parser
);
4063 if (static_seen
&& !quals_attrs
->declspecs_seen_p
)
4064 c_parser_declspecs (parser
, quals_attrs
, false, false, true,
4065 false, false, false, false, cla_prefer_id
);
4066 if (!quals_attrs
->declspecs_seen_p
)
4068 /* If "static" is present, there must be an array dimension.
4069 Otherwise, there may be a dimension, "*", or no
4074 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4078 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4080 dimen
.value
= NULL_TREE
;
4083 else if (c_parser_next_token_is (parser
, CPP_MULT
))
4085 if (c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_SQUARE
)
4087 dimen
.value
= NULL_TREE
;
4089 c_parser_consume_token (parser
);
4094 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4100 dimen
= c_parser_expr_no_commas (parser
, NULL
);
4103 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
4104 c_parser_consume_token (parser
);
4107 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
4112 dimen
= convert_lvalue_to_rvalue (brace_loc
, dimen
, true, true);
4113 declarator
= build_array_declarator (brace_loc
, dimen
.value
, quals_attrs
,
4114 static_seen
, star_seen
);
4115 if (declarator
== NULL
)
4117 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
4120 = c_parser_std_attribute_specifier_sequence (parser
);
4122 inner
= build_attrs_declarator (std_attrs
, inner
);
4124 inner
= set_array_declarator_inner (declarator
, inner
);
4125 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4127 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
4130 struct c_arg_info
*args
;
4131 c_parser_consume_token (parser
);
4132 bool have_gnu_attrs
= c_parser_next_token_is_keyword (parser
,
4134 attrs
= c_parser_gnu_attributes (parser
);
4135 args
= c_parser_parms_declarator (parser
, id_present
, attrs
,
4142 && args
->types
!= error_mark_node
4143 && TREE_CODE (TREE_VALUE (args
->types
)) == IDENTIFIER_NODE
)
4144 && c_parser_nth_token_starts_std_attributes (parser
, 1))
4147 = c_parser_std_attribute_specifier_sequence (parser
);
4149 inner
= build_attrs_declarator (std_attrs
, inner
);
4151 inner
= build_function_declarator (args
, inner
);
4152 return c_parser_direct_declarator_inner (parser
, id_present
, inner
);
4158 /* Parse a parameter list or identifier list, including the closing
4159 parenthesis but not the opening one. ATTRS are the gnu-attributes
4160 at the start of the list. ID_LIST_OK is true if an identifier list
4161 is acceptable; such a list must not have attributes at the start.
4162 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4163 attributes) were present (in which case standard attributes cannot
4166 static struct c_arg_info
*
4167 c_parser_parms_declarator (c_parser
*parser
, bool id_list_ok
, tree attrs
,
4168 bool have_gnu_attrs
)
4171 declare_parm_level ();
4172 /* If the list starts with an identifier, it is an identifier list.
4173 Otherwise, it is either a prototype list or an empty list. */
4176 && c_parser_next_token_is (parser
, CPP_NAME
)
4177 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4179 /* Look ahead to detect typos in type names. */
4180 && c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
4181 && c_parser_peek_2nd_token (parser
)->type
!= CPP_MULT
4182 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
4183 && c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_SQUARE
4184 && c_parser_peek_2nd_token (parser
)->type
!= CPP_KEYWORD
)
4186 tree list
= NULL_TREE
, *nextp
= &list
;
4187 while (c_parser_next_token_is (parser
, CPP_NAME
)
4188 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
4190 *nextp
= build_tree_list (NULL_TREE
,
4191 c_parser_peek_token (parser
)->value
);
4192 nextp
= & TREE_CHAIN (*nextp
);
4193 c_parser_consume_token (parser
);
4194 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
4196 c_parser_consume_token (parser
);
4197 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4199 c_parser_error (parser
, "expected identifier");
4203 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4205 struct c_arg_info
*ret
= build_arg_info ();
4207 c_parser_consume_token (parser
);
4213 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4221 struct c_arg_info
*ret
4222 = c_parser_parms_list_declarator (parser
, attrs
, NULL
, have_gnu_attrs
);
4228 /* Parse a parameter list (possibly empty), including the closing
4229 parenthesis but not the opening one. ATTRS are the gnu-attributes
4230 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4231 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4232 which means standard attributes cannot start the list. EXPR is
4233 NULL or an expression that needs to be evaluated for the side
4234 effects of array size expressions in the parameters. */
4236 static struct c_arg_info
*
4237 c_parser_parms_list_declarator (c_parser
*parser
, tree attrs
, tree expr
,
4238 bool have_gnu_attrs
)
4240 bool bad_parm
= false;
4242 /* ??? Following the old parser, forward parameter declarations may
4243 use abstract declarators, and if no real parameter declarations
4244 follow the forward declarations then this is not diagnosed. Also
4245 note as above that gnu-attributes are ignored as the only contents of
4246 the parentheses, or as the only contents after forward
4248 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4250 struct c_arg_info
*ret
= build_arg_info ();
4251 c_parser_consume_token (parser
);
4254 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4256 struct c_arg_info
*ret
= build_arg_info ();
4258 if (flag_allow_parameterless_variadic_functions
)
4260 /* F (...) is allowed. */
4261 ret
->types
= NULL_TREE
;
4265 /* Suppress -Wold-style-definition for this case. */
4266 ret
->types
= error_mark_node
;
4267 error_at (c_parser_peek_token (parser
)->location
,
4268 "ISO C requires a named argument before %<...%>");
4270 c_parser_consume_token (parser
);
4271 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4273 c_parser_consume_token (parser
);
4278 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4283 /* Nonempty list of parameters, either terminated with semicolon
4284 (forward declarations; recurse) or with close parenthesis (normal
4285 function) or with ", ... )" (variadic function). */
4288 /* Parse a parameter. */
4289 struct c_parm
*parm
= c_parser_parameter_declaration (parser
, attrs
,
4292 have_gnu_attrs
= false;
4296 push_parm_decl (parm
, &expr
);
4297 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
4300 c_parser_consume_token (parser
);
4301 mark_forward_parm_decls ();
4302 bool new_have_gnu_attrs
4303 = c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
);
4304 new_attrs
= c_parser_gnu_attributes (parser
);
4305 return c_parser_parms_list_declarator (parser
, new_attrs
, expr
,
4306 new_have_gnu_attrs
);
4308 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4310 c_parser_consume_token (parser
);
4314 return get_parm_info (false, expr
);
4316 if (!c_parser_require (parser
, CPP_COMMA
,
4317 "expected %<;%>, %<,%> or %<)%>",
4318 UNKNOWN_LOCATION
, false))
4320 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4323 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
4325 c_parser_consume_token (parser
);
4326 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4328 c_parser_consume_token (parser
);
4332 return get_parm_info (true, expr
);
4336 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4344 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4345 start of the declaration if it is the first parameter;
4346 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4349 static struct c_parm
*
4350 c_parser_parameter_declaration (c_parser
*parser
, tree attrs
,
4351 bool have_gnu_attrs
)
4353 struct c_declspecs
*specs
;
4354 struct c_declarator
*declarator
;
4356 tree postfix_attrs
= NULL_TREE
;
4359 /* Accept #pragmas between parameter declarations. */
4360 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
4361 c_parser_pragma (parser
, pragma_param
, NULL
);
4363 if (!c_parser_next_token_starts_declspecs (parser
)
4364 && !c_parser_nth_token_starts_std_attributes (parser
, 1))
4366 c_token
*token
= c_parser_peek_token (parser
);
4369 c_parser_set_source_position_from_token (token
);
4370 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
4372 auto_diagnostic_group d
;
4373 name_hint hint
= lookup_name_fuzzy (token
->value
,
4374 FUZZY_LOOKUP_TYPENAME
,
4376 if (const char *suggestion
= hint
.suggestion ())
4378 gcc_rich_location
richloc (token
->location
);
4379 richloc
.add_fixit_replace (suggestion
);
4381 "unknown type name %qE; did you mean %qs?",
4382 token
->value
, suggestion
);
4385 error_at (token
->location
, "unknown type name %qE", token
->value
);
4386 parser
->error
= true;
4388 /* ??? In some Objective-C cases '...' isn't applicable so there
4389 should be a different message. */
4391 c_parser_error (parser
,
4392 "expected declaration specifiers or %<...%>");
4393 c_parser_skip_to_end_of_parameter (parser
);
4397 location_t start_loc
= c_parser_peek_token (parser
)->location
;
4399 specs
= build_null_declspecs ();
4402 declspecs_add_attrs (input_location
, specs
, attrs
);
4405 c_parser_declspecs (parser
, specs
, true, true, true, true, false,
4406 !have_gnu_attrs
, true, cla_nonabstract_decl
);
4407 finish_declspecs (specs
);
4408 pending_xref_error ();
4409 prefix_attrs
= specs
->attrs
;
4410 specs
->attrs
= NULL_TREE
;
4411 declarator
= c_parser_declarator (parser
,
4412 specs
->typespec_kind
!= ctsk_none
,
4413 C_DTR_PARM
, &dummy
);
4414 if (declarator
== NULL
)
4416 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
4419 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4420 postfix_attrs
= c_parser_gnu_attributes (parser
);
4422 /* Generate a location for the parameter, ranging from the start of the
4423 initial token to the end of the final token.
4425 If we have a identifier, then use it for the caret location, e.g.
4427 extern int callee (int one, int (*two)(int, int), float three);
4428 ~~~~~~^~~~~~~~~~~~~~
4430 otherwise, reuse the start location for the caret location e.g.:
4432 extern int callee (int one, int (*)(int, int), float three);
4435 location_t end_loc
= parser
->last_token_location
;
4437 /* Find any cdk_id declarator; determine if we have an identifier. */
4438 c_declarator
*id_declarator
= declarator
;
4439 while (id_declarator
&& id_declarator
->kind
!= cdk_id
)
4440 id_declarator
= id_declarator
->declarator
;
4441 location_t caret_loc
= (id_declarator
->u
.id
.id
4442 ? id_declarator
->id_loc
4444 location_t param_loc
= make_location (caret_loc
, start_loc
, end_loc
);
4446 return build_c_parm (specs
, chainon (postfix_attrs
, prefix_attrs
),
4447 declarator
, param_loc
);
4450 /* Parse a string literal in an asm expression. It should not be
4451 translated, and wide string literals are an error although
4452 permitted by the syntax. This is a GNU extension.
4459 c_parser_asm_string_literal (c_parser
*parser
)
4462 int save_flag
= warn_overlength_strings
;
4463 warn_overlength_strings
= 0;
4464 str
= c_parser_string_literal (parser
, false, false).value
;
4465 warn_overlength_strings
= save_flag
;
4469 /* Parse a simple asm expression. This is used in restricted
4470 contexts, where a full expression with inputs and outputs does not
4471 make sense. This is a GNU extension.
4474 asm ( asm-string-literal )
4478 c_parser_simple_asm_expr (c_parser
*parser
)
4481 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
4482 c_parser_consume_token (parser
);
4483 matching_parens parens
;
4484 if (!parens
.require_open (parser
))
4486 str
= c_parser_asm_string_literal (parser
);
4487 if (!parens
.require_close (parser
))
4489 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4496 c_parser_gnu_attribute_any_word (c_parser
*parser
)
4498 tree attr_name
= NULL_TREE
;
4500 if (c_parser_next_token_is (parser
, CPP_KEYWORD
))
4502 /* ??? See comment above about what keywords are accepted here. */
4504 switch (c_parser_peek_token (parser
)->keyword
)
4535 case RID_TRANSACTION_ATOMIC
:
4536 case RID_TRANSACTION_CANCEL
:
4552 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4553 attr_name
= ridpointers
[(int) c_parser_peek_token (parser
)->keyword
];
4555 else if (c_parser_next_token_is (parser
, CPP_NAME
))
4556 attr_name
= c_parser_peek_token (parser
)->value
;
4561 /* Parse attribute arguments. This is a common form of syntax
4562 covering all currently valid GNU and standard attributes.
4564 gnu-attribute-arguments:
4566 identifier , nonempty-expr-list
4569 where the "identifier" must not be declared as a type. ??? Why not
4570 allow identifiers declared as types to start the arguments? */
4573 c_parser_attribute_arguments (c_parser
*parser
, bool takes_identifier
,
4574 bool require_string
, bool allow_empty_args
)
4576 vec
<tree
, va_gc
> *expr_list
;
4578 /* Parse the attribute contents. If they start with an
4579 identifier which is followed by a comma or close
4580 parenthesis, then the arguments start with that
4581 identifier; otherwise they are an expression list.
4582 In objective-c the identifier may be a classname. */
4583 if (c_parser_next_token_is (parser
, CPP_NAME
)
4584 && (c_parser_peek_token (parser
)->id_kind
== C_ID_ID
4585 || (c_dialect_objc ()
4586 && c_parser_peek_token (parser
)->id_kind
4588 && ((c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
4589 || (c_parser_peek_2nd_token (parser
)->type
4590 == CPP_CLOSE_PAREN
))
4591 && (takes_identifier
4592 || (c_dialect_objc ()
4593 && c_parser_peek_token (parser
)->id_kind
4594 == C_ID_CLASSNAME
)))
4596 tree arg1
= c_parser_peek_token (parser
)->value
;
4597 c_parser_consume_token (parser
);
4598 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4599 attr_args
= build_tree_list (NULL_TREE
, arg1
);
4603 c_parser_consume_token (parser
);
4604 expr_list
= c_parser_expr_list (parser
, false, true,
4605 NULL
, NULL
, NULL
, NULL
);
4606 tree_list
= build_tree_list_vec (expr_list
);
4607 attr_args
= tree_cons (NULL_TREE
, arg1
, tree_list
);
4608 release_tree_vector (expr_list
);
4613 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4615 if (!allow_empty_args
)
4616 error_at (c_parser_peek_token (parser
)->location
,
4617 "parentheses must be omitted if "
4618 "attribute argument list is empty");
4619 attr_args
= NULL_TREE
;
4621 else if (require_string
)
4623 /* The only valid argument for this attribute is a string
4624 literal. Handle this specially here to avoid accepting
4625 string literals with excess parentheses. */
4626 tree string
= c_parser_string_literal (parser
, false, true).value
;
4627 attr_args
= build_tree_list (NULL_TREE
, string
);
4631 expr_list
= c_parser_expr_list (parser
, false, true,
4632 NULL
, NULL
, NULL
, NULL
);
4633 attr_args
= build_tree_list_vec (expr_list
);
4634 release_tree_vector (expr_list
);
4640 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4644 gnu-attributes gnu-attribute
4647 __attribute__ ( ( gnu-attribute-list ) )
4651 gnu-attribute_list , gnu-attrib
4656 any-word ( gnu-attribute-arguments )
4658 where "any-word" may be any identifier (including one declared as a
4659 type), a reserved word storage class specifier, type specifier or
4660 type qualifier. ??? This still leaves out most reserved keywords
4661 (following the old parser), shouldn't we include them?
4662 When EXPECT_COMMA is true, expect the attribute to be preceded
4663 by a comma and fail if it isn't.
4664 When EMPTY_OK is true, allow and consume any number of consecutive
4665 commas with no attributes in between. */
4668 c_parser_gnu_attribute (c_parser
*parser
, tree attrs
,
4669 bool expect_comma
= false, bool empty_ok
= true)
4671 bool comma_first
= c_parser_next_token_is (parser
, CPP_COMMA
);
4673 && !c_parser_next_token_is (parser
, CPP_NAME
)
4674 && !c_parser_next_token_is (parser
, CPP_KEYWORD
))
4677 while (c_parser_next_token_is (parser
, CPP_COMMA
))
4679 c_parser_consume_token (parser
);
4684 tree attr_name
= c_parser_gnu_attribute_any_word (parser
);
4685 if (attr_name
== NULL_TREE
)
4688 attr_name
= canonicalize_attr_name (attr_name
);
4689 c_parser_consume_token (parser
);
4692 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4694 if (expect_comma
&& !comma_first
)
4696 /* A comma is missing between the last attribute on the chain
4698 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4700 return error_mark_node
;
4702 attr
= build_tree_list (attr_name
, NULL_TREE
);
4703 /* Add this attribute to the list. */
4704 attrs
= chainon (attrs
, attr
);
4707 c_parser_consume_token (parser
);
4710 = c_parser_attribute_arguments (parser
,
4711 attribute_takes_identifier_p (attr_name
),
4714 attr
= build_tree_list (attr_name
, attr_args
);
4715 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4716 c_parser_consume_token (parser
);
4719 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4721 return error_mark_node
;
4724 if (expect_comma
&& !comma_first
)
4726 /* A comma is missing between the last attribute on the chain
4728 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4730 return error_mark_node
;
4733 /* Add this attribute to the list. */
4734 attrs
= chainon (attrs
, attr
);
4739 c_parser_gnu_attributes (c_parser
*parser
)
4741 tree attrs
= NULL_TREE
;
4742 while (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
4744 bool save_translate_strings_p
= parser
->translate_strings_p
;
4745 parser
->translate_strings_p
= false;
4746 /* Consume the `__attribute__' keyword. */
4747 c_parser_consume_token (parser
);
4748 /* Look for the two `(' tokens. */
4749 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4751 parser
->translate_strings_p
= save_translate_strings_p
;
4754 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
4756 parser
->translate_strings_p
= save_translate_strings_p
;
4757 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
4760 /* Parse the attribute list. Require a comma between successive
4761 (possibly empty) attributes. */
4762 for (bool expect_comma
= false; ; expect_comma
= true)
4764 /* Parse a single attribute. */
4765 tree attr
= c_parser_gnu_attribute (parser
, attrs
, expect_comma
);
4766 if (attr
== error_mark_node
)
4773 /* Look for the two `)' tokens. */
4774 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4775 c_parser_consume_token (parser
);
4778 parser
->translate_strings_p
= save_translate_strings_p
;
4779 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4783 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
4784 c_parser_consume_token (parser
);
4787 parser
->translate_strings_p
= save_translate_strings_p
;
4788 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
4792 parser
->translate_strings_p
= save_translate_strings_p
;
4798 /* Parse an optional balanced token sequence.
4800 balanced-token-sequence:
4802 balanced-token-sequence balanced-token
4805 ( balanced-token-sequence[opt] )
4806 [ balanced-token-sequence[opt] ]
4807 { balanced-token-sequence[opt] }
4808 any token other than ()[]{}
4812 c_parser_balanced_token_sequence (c_parser
*parser
)
4816 c_token
*token
= c_parser_peek_token (parser
);
4817 switch (token
->type
)
4819 case CPP_OPEN_BRACE
:
4821 matching_braces braces
;
4822 braces
.consume_open (parser
);
4823 c_parser_balanced_token_sequence (parser
);
4824 braces
.require_close (parser
);
4828 case CPP_OPEN_PAREN
:
4830 matching_parens parens
;
4831 parens
.consume_open (parser
);
4832 c_parser_balanced_token_sequence (parser
);
4833 parens
.require_close (parser
);
4837 case CPP_OPEN_SQUARE
:
4838 c_parser_consume_token (parser
);
4839 c_parser_balanced_token_sequence (parser
);
4840 c_parser_require (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
4843 case CPP_CLOSE_BRACE
:
4844 case CPP_CLOSE_PAREN
:
4845 case CPP_CLOSE_SQUARE
:
4850 c_parser_consume_pragma (parser
);
4851 c_parser_skip_to_pragma_eol (parser
, false);
4855 c_parser_consume_token (parser
);
4861 /* Parse standard (C2X) attributes (including GNU attributes in the
4864 attribute-specifier-sequence:
4865 attribute-specifier-sequence[opt] attribute-specifier
4867 attribute-specifier:
4868 [ [ attribute-list ] ]
4872 attribute-list, attribute[opt]
4875 attribute-token attribute-argument-clause[opt]
4879 attribute-prefixed-token
4884 attribute-prefixed-token:
4885 attribute-prefix :: identifier
4890 attribute-argument-clause:
4891 ( balanced-token-sequence[opt] )
4893 Keywords are accepted as identifiers for this purpose.
4897 c_parser_std_attribute (c_parser
*parser
, bool for_tm
)
4899 c_token
*token
= c_parser_peek_token (parser
);
4900 tree ns
, name
, attribute
;
4902 /* Parse the attribute-token. */
4903 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
4905 c_parser_error (parser
, "expected identifier");
4906 return error_mark_node
;
4908 name
= canonicalize_attr_name (token
->value
);
4909 c_parser_consume_token (parser
);
4910 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
4913 c_parser_consume_token (parser
);
4914 token
= c_parser_peek_token (parser
);
4915 if (token
->type
!= CPP_NAME
&& token
->type
!= CPP_KEYWORD
)
4917 c_parser_error (parser
, "expected identifier");
4918 return error_mark_node
;
4920 name
= canonicalize_attr_name (token
->value
);
4921 c_parser_consume_token (parser
);
4925 attribute
= build_tree_list (build_tree_list (ns
, name
), NULL_TREE
);
4927 /* Parse the arguments, if any. */
4928 const attribute_spec
*as
= lookup_attribute_spec (TREE_PURPOSE (attribute
));
4929 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
4932 location_t open_loc
= c_parser_peek_token (parser
)->location
;
4933 matching_parens parens
;
4934 parens
.consume_open (parser
);
4935 if ((as
&& as
->max_length
== 0)
4936 /* Special-case the transactional-memory attribute "outer",
4937 which is specially handled but not registered as an
4938 attribute, to avoid allowing arbitrary balanced token
4939 sequences as arguments. */
4940 || is_attribute_p ("outer", name
))
4942 error_at (open_loc
, "%qE attribute does not take any arguments", name
);
4943 parens
.skip_until_found_close (parser
);
4944 return error_mark_node
;
4946 /* If this is a fake attribute created to handle -Wno-attributes,
4947 we must skip parsing the arguments. */
4948 if (as
&& !attribute_ignored_p (as
))
4950 bool takes_identifier
4952 && strcmp (IDENTIFIER_POINTER (ns
), "gnu") == 0
4953 && attribute_takes_identifier_p (name
));
4956 && (strcmp (IDENTIFIER_POINTER (name
), "deprecated") == 0
4957 || strcmp (IDENTIFIER_POINTER (name
), "nodiscard") == 0));
4958 TREE_VALUE (attribute
)
4959 = c_parser_attribute_arguments (parser
, takes_identifier
,
4960 require_string
, false);
4963 c_parser_balanced_token_sequence (parser
);
4964 parens
.require_close (parser
);
4967 if (ns
== NULL_TREE
&& !for_tm
&& !as
)
4969 /* An attribute with standard syntax and no namespace specified
4970 is a constraint violation if it is not one of the known
4971 standard attributes. Diagnose it here with a pedwarn and
4972 then discard it to prevent a duplicate warning later. */
4973 pedwarn (input_location
, OPT_Wattributes
, "%qE attribute ignored",
4975 return error_mark_node
;
4981 c_parser_std_attribute_specifier (c_parser
*parser
, bool for_tm
)
4983 location_t loc
= c_parser_peek_token (parser
)->location
;
4984 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
4986 if (!c_parser_require (parser
, CPP_OPEN_SQUARE
, "expected %<[%>"))
4988 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
4992 pedwarn_c11 (loc
, OPT_Wpedantic
,
4993 "ISO C does not support %<[[]]%> attributes before C2X");
4994 tree attributes
= NULL_TREE
;
4997 c_token
*token
= c_parser_peek_token (parser
);
4998 if (token
->type
== CPP_CLOSE_SQUARE
)
5000 if (token
->type
== CPP_COMMA
)
5002 c_parser_consume_token (parser
);
5005 tree attribute
= c_parser_std_attribute (parser
, for_tm
);
5006 if (attribute
!= error_mark_node
)
5008 TREE_CHAIN (attribute
) = attributes
;
5009 attributes
= attribute
;
5011 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
5014 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5015 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, "expected %<]%>");
5016 return nreverse (attributes
);
5019 /* Look past an optional balanced token sequence of raw look-ahead
5020 tokens starting with the *Nth token. *N is updated to point to the
5021 following token. Return true if such a sequence was found, false
5022 if the tokens parsed were not balanced. */
5025 c_parser_check_balanced_raw_token_sequence (c_parser
*parser
, unsigned int *n
)
5029 c_token
*token
= c_parser_peek_nth_token_raw (parser
, *n
);
5030 switch (token
->type
)
5032 case CPP_OPEN_BRACE
:
5035 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5037 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5038 if (token
->type
== CPP_CLOSE_BRACE
)
5048 case CPP_OPEN_PAREN
:
5051 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5053 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5054 if (token
->type
== CPP_CLOSE_PAREN
)
5064 case CPP_OPEN_SQUARE
:
5067 if (c_parser_check_balanced_raw_token_sequence (parser
, n
))
5069 token
= c_parser_peek_nth_token_raw (parser
, *n
);
5070 if (token
->type
== CPP_CLOSE_SQUARE
)
5080 case CPP_CLOSE_BRACE
:
5081 case CPP_CLOSE_PAREN
:
5082 case CPP_CLOSE_SQUARE
:
5093 /* Return whether standard attributes start with the Nth token. */
5096 c_parser_nth_token_starts_std_attributes (c_parser
*parser
, unsigned int n
)
5098 if (!(c_parser_peek_nth_token (parser
, n
)->type
== CPP_OPEN_SQUARE
5099 && c_parser_peek_nth_token (parser
, n
+ 1)->type
== CPP_OPEN_SQUARE
))
5101 /* In C, '[[' must start attributes. In Objective-C, we need to
5102 check whether '[[' is matched by ']]'. */
5103 if (!c_dialect_objc ())
5106 if (!c_parser_check_balanced_raw_token_sequence (parser
, &n
))
5108 c_token
*token
= c_parser_peek_nth_token_raw (parser
, n
);
5109 if (token
->type
!= CPP_CLOSE_SQUARE
)
5111 token
= c_parser_peek_nth_token_raw (parser
, n
+ 1);
5112 return token
->type
== CPP_CLOSE_SQUARE
;
5116 c_parser_std_attribute_specifier_sequence (c_parser
*parser
)
5118 tree attributes
= NULL_TREE
;
5121 tree attrs
= c_parser_std_attribute_specifier (parser
, false);
5122 attributes
= chainon (attributes
, attrs
);
5124 while (c_parser_nth_token_starts_std_attributes (parser
, 1));
5128 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5129 says whether alignment specifiers are OK (only in cases that might
5130 be the type name of a compound literal).
5133 specifier-qualifier-list abstract-declarator[opt]
5136 struct c_type_name
*
5137 c_parser_type_name (c_parser
*parser
, bool alignas_ok
)
5139 struct c_declspecs
*specs
= build_null_declspecs ();
5140 struct c_declarator
*declarator
;
5141 struct c_type_name
*ret
;
5143 c_parser_declspecs (parser
, specs
, false, true, true, alignas_ok
, false,
5144 false, true, cla_prefer_type
);
5145 if (!specs
->declspecs_seen_p
)
5147 c_parser_error (parser
, "expected specifier-qualifier-list");
5150 if (specs
->type
!= error_mark_node
)
5152 pending_xref_error ();
5153 finish_declspecs (specs
);
5155 declarator
= c_parser_declarator (parser
,
5156 specs
->typespec_kind
!= ctsk_none
,
5157 C_DTR_ABSTRACT
, &dummy
);
5158 if (declarator
== NULL
)
5160 ret
= XOBNEW (&parser_obstack
, struct c_type_name
);
5162 ret
->declarator
= declarator
;
5166 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5169 assignment-expression
5170 { initializer-list }
5171 { initializer-list , }
5174 designation[opt] initializer
5175 initializer-list , designation[opt] initializer
5182 designator-list designator
5189 [ constant-expression ]
5201 [ constant-expression ... constant-expression ]
5203 Any expression without commas is accepted in the syntax for the
5204 constant-expressions, with non-constant expressions rejected later.
5206 This function is only used for top-level initializers; for nested
5207 ones, see c_parser_initval. */
5209 static struct c_expr
5210 c_parser_initializer (c_parser
*parser
)
5212 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
5213 return c_parser_braced_init (parser
, NULL_TREE
, false, NULL
);
5217 location_t loc
= c_parser_peek_token (parser
)->location
;
5218 ret
= c_parser_expr_no_commas (parser
, NULL
);
5219 if (TREE_CODE (ret
.value
) != STRING_CST
5220 && TREE_CODE (ret
.value
) != COMPOUND_LITERAL_EXPR
)
5221 ret
= convert_lvalue_to_rvalue (loc
, ret
, true, true);
5226 /* The location of the last comma within the current initializer list,
5227 or UNKNOWN_LOCATION if not within one. */
5229 location_t last_init_list_comma
;
5231 /* Parse a braced initializer list. TYPE is the type specified for a
5232 compound literal, and NULL_TREE for other initializers and for
5233 nested braced lists. NESTED_P is true for nested braced lists,
5234 false for the list of a compound literal or the list that is the
5235 top-level initializer in a declaration. */
5237 static struct c_expr
5238 c_parser_braced_init (c_parser
*parser
, tree type
, bool nested_p
,
5239 struct obstack
*outer_obstack
)
5242 struct obstack braced_init_obstack
;
5243 location_t brace_loc
= c_parser_peek_token (parser
)->location
;
5244 gcc_obstack_init (&braced_init_obstack
);
5245 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
5246 matching_braces braces
;
5247 braces
.consume_open (parser
);
5250 finish_implicit_inits (brace_loc
, outer_obstack
);
5251 push_init_level (brace_loc
, 0, &braced_init_obstack
);
5254 really_start_incremental_init (type
);
5255 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5257 pedwarn (brace_loc
, OPT_Wpedantic
, "ISO C forbids empty initializer braces");
5261 /* Parse a non-empty initializer list, possibly with a trailing
5265 c_parser_initelt (parser
, &braced_init_obstack
);
5268 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5270 last_init_list_comma
= c_parser_peek_token (parser
)->location
;
5271 c_parser_consume_token (parser
);
5275 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5279 c_token
*next_tok
= c_parser_peek_token (parser
);
5280 if (next_tok
->type
!= CPP_CLOSE_BRACE
)
5283 ret
.original_code
= ERROR_MARK
;
5284 ret
.original_type
= NULL
;
5285 braces
.skip_until_found_close (parser
);
5286 pop_init_level (brace_loc
, 0, &braced_init_obstack
, last_init_list_comma
);
5287 obstack_free (&braced_init_obstack
, NULL
);
5290 location_t close_loc
= next_tok
->location
;
5291 c_parser_consume_token (parser
);
5292 ret
= pop_init_level (brace_loc
, 0, &braced_init_obstack
, close_loc
);
5293 obstack_free (&braced_init_obstack
, NULL
);
5294 set_c_expr_source_range (&ret
, brace_loc
, close_loc
);
5298 /* Parse a nested initializer, including designators. */
5301 c_parser_initelt (c_parser
*parser
, struct obstack
* braced_init_obstack
)
5303 /* Parse any designator or designator list. A single array
5304 designator may have the subsequent "=" omitted in GNU C, but a
5305 longer list or a structure member designator may not. */
5306 if (c_parser_next_token_is (parser
, CPP_NAME
)
5307 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
5309 /* Old-style structure member designator. */
5310 set_init_label (c_parser_peek_token (parser
)->location
,
5311 c_parser_peek_token (parser
)->value
,
5312 c_parser_peek_token (parser
)->location
,
5313 braced_init_obstack
);
5314 /* Use the colon as the error location. */
5315 pedwarn (c_parser_peek_2nd_token (parser
)->location
, OPT_Wpedantic
,
5316 "obsolete use of designated initializer with %<:%>");
5317 c_parser_consume_token (parser
);
5318 c_parser_consume_token (parser
);
5322 /* des_seen is 0 if there have been no designators, 1 if there
5323 has been a single array designator and 2 otherwise. */
5325 /* Location of a designator. */
5326 location_t des_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5327 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
)
5328 || c_parser_next_token_is (parser
, CPP_DOT
))
5330 int des_prev
= des_seen
;
5332 des_loc
= c_parser_peek_token (parser
)->location
;
5335 if (c_parser_next_token_is (parser
, CPP_DOT
))
5338 c_parser_consume_token (parser
);
5339 if (c_parser_next_token_is (parser
, CPP_NAME
))
5341 set_init_label (des_loc
, c_parser_peek_token (parser
)->value
,
5342 c_parser_peek_token (parser
)->location
,
5343 braced_init_obstack
);
5344 c_parser_consume_token (parser
);
5350 init
.original_code
= ERROR_MARK
;
5351 init
.original_type
= NULL
;
5352 c_parser_error (parser
, "expected identifier");
5353 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5354 process_init_element (input_location
, init
, false,
5355 braced_init_obstack
);
5362 location_t ellipsis_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5363 location_t array_index_loc
= UNKNOWN_LOCATION
;
5364 /* ??? Following the old parser, [ objc-receiver
5365 objc-message-args ] is accepted as an initializer,
5366 being distinguished from a designator by what follows
5367 the first assignment expression inside the square
5368 brackets, but after a first array designator a
5369 subsequent square bracket is for Objective-C taken to
5370 start an expression, using the obsolete form of
5371 designated initializer without '=', rather than
5372 possibly being a second level of designation: in LALR
5373 terms, the '[' is shifted rather than reducing
5374 designator to designator-list. */
5375 if (des_prev
== 1 && c_dialect_objc ())
5377 des_seen
= des_prev
;
5380 if (des_prev
== 0 && c_dialect_objc ())
5382 /* This might be an array designator or an
5383 Objective-C message expression. If the former,
5384 continue parsing here; if the latter, parse the
5385 remainder of the initializer given the starting
5386 primary-expression. ??? It might make sense to
5387 distinguish when des_prev == 1 as well; see
5388 previous comment. */
5390 struct c_expr mexpr
;
5391 c_parser_consume_token (parser
);
5392 if (c_parser_peek_token (parser
)->type
== CPP_NAME
5393 && ((c_parser_peek_token (parser
)->id_kind
5395 || (c_parser_peek_token (parser
)->id_kind
5396 == C_ID_CLASSNAME
)))
5398 /* Type name receiver. */
5399 tree id
= c_parser_peek_token (parser
)->value
;
5400 c_parser_consume_token (parser
);
5401 rec
= objc_get_class_reference (id
);
5402 goto parse_message_args
;
5404 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
5405 mark_exp_read (first
);
5406 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
)
5407 || c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5408 goto array_desig_after_first
;
5409 /* Expression receiver. So far only one part
5410 without commas has been parsed; there might be
5411 more of the expression. */
5413 while (c_parser_next_token_is (parser
, CPP_COMMA
))
5416 location_t comma_loc
, exp_loc
;
5417 comma_loc
= c_parser_peek_token (parser
)->location
;
5418 c_parser_consume_token (parser
);
5419 exp_loc
= c_parser_peek_token (parser
)->location
;
5420 next
= c_parser_expr_no_commas (parser
, NULL
);
5421 next
= convert_lvalue_to_rvalue (exp_loc
, next
,
5423 rec
= build_compound_expr (comma_loc
, rec
, next
.value
);
5426 /* Now parse the objc-message-args. */
5427 args
= c_parser_objc_message_args (parser
);
5428 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5431 = objc_build_message_expr (rec
, args
);
5432 mexpr
.original_code
= ERROR_MARK
;
5433 mexpr
.original_type
= NULL
;
5434 /* Now parse and process the remainder of the
5435 initializer, starting with this message
5436 expression as a primary-expression. */
5437 c_parser_initval (parser
, &mexpr
, braced_init_obstack
);
5440 c_parser_consume_token (parser
);
5441 array_index_loc
= c_parser_peek_token (parser
)->location
;
5442 first
= c_parser_expr_no_commas (parser
, NULL
).value
;
5443 mark_exp_read (first
);
5444 array_desig_after_first
:
5445 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5447 ellipsis_loc
= c_parser_peek_token (parser
)->location
;
5448 c_parser_consume_token (parser
);
5449 second
= c_parser_expr_no_commas (parser
, NULL
).value
;
5450 mark_exp_read (second
);
5454 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
5456 c_parser_consume_token (parser
);
5457 set_init_index (array_index_loc
, first
, second
,
5458 braced_init_obstack
);
5460 pedwarn (ellipsis_loc
, OPT_Wpedantic
,
5461 "ISO C forbids specifying range of elements to initialize");
5464 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
5470 if (c_parser_next_token_is (parser
, CPP_EQ
))
5472 pedwarn_c90 (des_loc
, OPT_Wpedantic
,
5473 "ISO C90 forbids specifying subobject "
5475 c_parser_consume_token (parser
);
5480 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
5481 "obsolete use of designated initializer without %<=%>");
5486 init
.original_code
= ERROR_MARK
;
5487 init
.original_type
= NULL
;
5488 c_parser_error (parser
, "expected %<=%>");
5489 c_parser_skip_until_found (parser
, CPP_COMMA
, NULL
);
5490 process_init_element (input_location
, init
, false,
5491 braced_init_obstack
);
5497 c_parser_initval (parser
, NULL
, braced_init_obstack
);
5500 /* Parse a nested initializer; as c_parser_initializer but parses
5501 initializers within braced lists, after any designators have been
5502 applied. If AFTER is not NULL then it is an Objective-C message
5503 expression which is the primary-expression starting the
5507 c_parser_initval (c_parser
*parser
, struct c_expr
*after
,
5508 struct obstack
* braced_init_obstack
)
5511 gcc_assert (!after
|| c_dialect_objc ());
5512 location_t loc
= c_parser_peek_token (parser
)->location
;
5514 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
) && !after
)
5515 init
= c_parser_braced_init (parser
, NULL_TREE
, true,
5516 braced_init_obstack
);
5519 init
= c_parser_expr_no_commas (parser
, after
);
5520 if (init
.value
!= NULL_TREE
5521 && TREE_CODE (init
.value
) != STRING_CST
5522 && TREE_CODE (init
.value
) != COMPOUND_LITERAL_EXPR
)
5523 init
= convert_lvalue_to_rvalue (loc
, init
, true, true);
5525 process_init_element (loc
, init
, false, braced_init_obstack
);
5528 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5529 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5532 { block-item-list[opt] }
5533 { label-declarations block-item-list }
5537 block-item-list block-item
5550 { label-declarations block-item-list }
5553 __extension__ nested-declaration
5554 nested-function-definition
5558 label-declarations label-declaration
5561 __label__ identifier-list ;
5563 Allowing the mixing of declarations and code is new in C99. The
5564 GNU syntax also permits (not shown above) labels at the end of
5565 compound statements, which yield an error. We don't allow labels
5566 on declarations; this might seem like a natural extension, but
5567 there would be a conflict between gnu-attributes on the label and
5568 prefix gnu-attributes on the declaration. ??? The syntax follows the
5569 old parser in requiring something after label declarations.
5570 Although they are erroneous if the labels declared aren't defined,
5571 is it useful for the syntax to be this way?
5592 cancellation-point-directive */
5595 c_parser_compound_statement (c_parser
*parser
, location_t
*endlocp
)
5598 location_t brace_loc
;
5599 brace_loc
= c_parser_peek_token (parser
)->location
;
5600 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
5602 /* Ensure a scope is entered and left anyway to avoid confusion
5603 if we have just prepared to enter a function body. */
5604 stmt
= c_begin_compound_stmt (true);
5605 c_end_compound_stmt (brace_loc
, stmt
, true);
5606 return error_mark_node
;
5608 stmt
= c_begin_compound_stmt (true);
5609 location_t end_loc
= c_parser_compound_statement_nostart (parser
);
5613 return c_end_compound_stmt (brace_loc
, stmt
, true);
5616 /* Parse a compound statement except for the opening brace. This is
5617 used for parsing both compound statements and statement expressions
5618 (which follow different paths to handling the opening). */
5621 c_parser_compound_statement_nostart (c_parser
*parser
)
5623 bool last_stmt
= false;
5624 bool last_label
= false;
5625 bool save_valid_for_pragma
= valid_location_for_stdc_pragma_p ();
5626 location_t label_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
5627 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5629 location_t endloc
= c_parser_peek_token (parser
)->location
;
5630 add_debug_begin_stmt (endloc
);
5631 c_parser_consume_token (parser
);
5634 mark_valid_location_for_stdc_pragma (true);
5635 if (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5637 /* Read zero or more forward-declarations for labels that nested
5638 functions can jump to. */
5639 mark_valid_location_for_stdc_pragma (false);
5640 while (c_parser_next_token_is_keyword (parser
, RID_LABEL
))
5642 label_loc
= c_parser_peek_token (parser
)->location
;
5643 c_parser_consume_token (parser
);
5644 /* Any identifiers, including those declared as type names,
5649 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
5651 c_parser_error (parser
, "expected identifier");
5655 = declare_label (c_parser_peek_token (parser
)->value
);
5656 C_DECLARED_LABEL_FLAG (label
) = 1;
5657 add_stmt (build_stmt (label_loc
, DECL_EXPR
, label
));
5658 c_parser_consume_token (parser
);
5659 if (c_parser_next_token_is (parser
, CPP_COMMA
))
5660 c_parser_consume_token (parser
);
5664 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
5666 pedwarn (label_loc
, OPT_Wpedantic
, "ISO C forbids label declarations");
5668 /* We must now have at least one statement, label or declaration. */
5669 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
5671 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5672 c_parser_error (parser
, "expected declaration or statement");
5673 location_t endloc
= c_parser_peek_token (parser
)->location
;
5674 c_parser_consume_token (parser
);
5677 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_BRACE
))
5679 location_t loc
= c_parser_peek_token (parser
)->location
;
5680 loc
= expansion_point_location_if_in_system_header (loc
);
5681 /* Standard attributes may start a label, statement or declaration. */
5683 = c_parser_nth_token_starts_std_attributes (parser
, 1);
5684 tree std_attrs
= NULL_TREE
;
5686 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5687 if (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5688 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5689 || (c_parser_next_token_is (parser
, CPP_NAME
)
5690 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5692 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5693 label_loc
= c_parser_peek_2nd_token (parser
)->location
;
5695 label_loc
= c_parser_peek_token (parser
)->location
;
5698 mark_valid_location_for_stdc_pragma (false);
5699 c_parser_label (parser
, std_attrs
);
5701 else if (c_parser_next_tokens_start_declaration (parser
)
5703 && c_parser_next_token_is (parser
, CPP_SEMICOLON
)))
5706 pedwarn_c11 (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
5707 "a label can only be part of a statement and "
5708 "a declaration is not a statement");
5710 mark_valid_location_for_stdc_pragma (false);
5711 bool fallthru_attr_p
= false;
5712 c_parser_declaration_or_fndef (parser
, true, !have_std_attrs
,
5713 true, true, true, NULL
,
5714 NULL
, have_std_attrs
, std_attrs
,
5715 NULL
, &fallthru_attr_p
);
5717 if (last_stmt
&& !fallthru_attr_p
)
5718 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5719 "ISO C90 forbids mixed declarations and code");
5720 last_stmt
= fallthru_attr_p
;
5723 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
5725 /* __extension__ can start a declaration, but is also an
5726 unary operator that can start an expression. Consume all
5727 but the last of a possible series of __extension__ to
5728 determine which. If standard attributes have already
5729 been seen, it must start a statement, not a declaration,
5730 but standard attributes starting a declaration may appear
5731 after __extension__. */
5732 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
5733 && (c_parser_peek_2nd_token (parser
)->keyword
5735 c_parser_consume_token (parser
);
5737 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
5738 || c_parser_nth_token_starts_std_attributes (parser
, 2)))
5741 ext
= disable_extension_diagnostics ();
5742 c_parser_consume_token (parser
);
5744 mark_valid_location_for_stdc_pragma (false);
5745 c_parser_declaration_or_fndef (parser
, true, true, true, true,
5747 /* Following the old parser, __extension__ does not
5748 disable this diagnostic. */
5749 restore_extension_diagnostics (ext
);
5751 pedwarn_c90 (loc
, OPT_Wdeclaration_after_statement
,
5752 "ISO C90 forbids mixed declarations and code");
5758 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
5761 c_parser_error (parser
, "expected declaration or statement");
5762 /* External pragmas, and some omp pragmas, are not associated
5763 with regular c code, and so are not to be considered statements
5764 syntactically. This ensures that the user doesn't put them
5765 places that would turn into syntax errors if the directive
5767 if (c_parser_pragma (parser
,
5768 last_label
? pragma_stmt
: pragma_compound
,
5770 last_label
= false, last_stmt
= true;
5772 else if (c_parser_next_token_is (parser
, CPP_EOF
))
5774 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5775 c_parser_error (parser
, "expected declaration or statement");
5776 return c_parser_peek_token (parser
)->location
;
5778 else if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
5780 if (parser
->in_if_block
)
5782 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5783 error_at (loc
, "expected %<}%> before %<else%>");
5784 return c_parser_peek_token (parser
)->location
;
5788 error_at (loc
, "%<else%> without a previous %<if%>");
5789 c_parser_consume_token (parser
);
5796 c_warn_unused_attributes (std_attrs
);
5799 mark_valid_location_for_stdc_pragma (false);
5800 c_parser_statement_after_labels (parser
, NULL
);
5803 parser
->error
= false;
5806 pedwarn_c11 (label_loc
, OPT_Wpedantic
, "label at end of compound statement");
5807 location_t endloc
= c_parser_peek_token (parser
)->location
;
5808 c_parser_consume_token (parser
);
5809 /* Restore the value we started with. */
5810 mark_valid_location_for_stdc_pragma (save_valid_for_pragma
);
5814 /* Parse all consecutive labels, possibly preceded by standard
5815 attributes. In this context, a statement is required, not a
5816 declaration, so attributes must be followed by a statement that is
5817 not just a semicolon. */
5820 c_parser_all_labels (c_parser
*parser
)
5822 tree std_attrs
= NULL
;
5823 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
5825 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5826 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5827 c_parser_error (parser
, "expected statement");
5829 while (c_parser_next_token_is_keyword (parser
, RID_CASE
)
5830 || c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
5831 || (c_parser_next_token_is (parser
, CPP_NAME
)
5832 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
))
5834 c_parser_label (parser
, std_attrs
);
5836 if (c_parser_nth_token_starts_std_attributes (parser
, 1))
5838 std_attrs
= c_parser_std_attribute_specifier_sequence (parser
);
5839 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
5840 c_parser_error (parser
, "expected statement");
5844 c_warn_unused_attributes (std_attrs
);
5847 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5850 identifier : gnu-attributes[opt]
5851 case constant-expression :
5857 case constant-expression ... constant-expression :
5859 The use of gnu-attributes on labels is a GNU extension. The syntax in
5860 GNU C accepts any expressions without commas, non-constant
5861 expressions being rejected later. Any standard
5862 attribute-specifier-sequence before the first label has been parsed
5863 in the caller, to distinguish statements from declarations. Any
5864 attribute-specifier-sequence after the label is parsed in this
5867 c_parser_label (c_parser
*parser
, tree std_attrs
)
5869 location_t loc1
= c_parser_peek_token (parser
)->location
;
5870 tree label
= NULL_TREE
;
5872 /* Remember whether this case or a user-defined label is allowed to fall
5874 bool fallthrough_p
= c_parser_peek_token (parser
)->flags
& PREV_FALLTHROUGH
;
5876 if (c_parser_next_token_is_keyword (parser
, RID_CASE
))
5879 c_parser_consume_token (parser
);
5880 exp1
= c_parser_expr_no_commas (parser
, NULL
).value
;
5881 if (c_parser_next_token_is (parser
, CPP_COLON
))
5883 c_parser_consume_token (parser
);
5884 label
= do_case (loc1
, exp1
, NULL_TREE
);
5886 else if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
5888 c_parser_consume_token (parser
);
5889 exp2
= c_parser_expr_no_commas (parser
, NULL
).value
;
5890 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5891 label
= do_case (loc1
, exp1
, exp2
);
5894 c_parser_error (parser
, "expected %<:%> or %<...%>");
5896 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
5898 c_parser_consume_token (parser
);
5899 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
5900 label
= do_case (loc1
, NULL_TREE
, NULL_TREE
);
5904 tree name
= c_parser_peek_token (parser
)->value
;
5907 location_t loc2
= c_parser_peek_token (parser
)->location
;
5908 gcc_assert (c_parser_next_token_is (parser
, CPP_NAME
));
5909 c_parser_consume_token (parser
);
5910 gcc_assert (c_parser_next_token_is (parser
, CPP_COLON
));
5911 c_parser_consume_token (parser
);
5912 attrs
= c_parser_gnu_attributes (parser
);
5913 tlab
= define_label (loc2
, name
);
5916 decl_attributes (&tlab
, attrs
, 0);
5917 decl_attributes (&tlab
, std_attrs
, 0);
5918 label
= add_stmt (build_stmt (loc1
, LABEL_EXPR
, tlab
));
5921 && c_parser_next_tokens_start_declaration (parser
))
5922 warning_at (loc2
, OPT_Wattributes
, "GNU-style attribute between"
5923 " label and declaration appertains to the label");
5927 if (TREE_CODE (label
) == LABEL_EXPR
)
5928 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label
)) = fallthrough_p
;
5930 FALLTHROUGH_LABEL_P (CASE_LABEL (label
)) = fallthrough_p
;
5934 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5938 attribute-specifier-sequence[opt] compound-statement
5939 expression-statement
5940 attribute-specifier-sequence[opt] selection-statement
5941 attribute-specifier-sequence[opt] iteration-statement
5942 attribute-specifier-sequence[opt] jump-statement
5945 attribute-specifier-sequence[opt] label statement
5947 expression-statement:
5949 attribute-specifier-sequence expression ;
5951 selection-statement:
5955 iteration-statement:
5964 return expression[opt] ;
5969 attribute-specifier-sequence[opt] asm-statement
5974 expression-statement:
5980 attribute-specifier-sequence[opt] objc-throw-statement
5981 attribute-specifier-sequence[opt] objc-try-catch-statement
5982 attribute-specifier-sequence[opt] objc-synchronized-statement
5984 objc-throw-statement:
5991 attribute-specifier-sequence[opt] openacc-construct
6000 parallel-directive structured-block
6003 kernels-directive structured-block
6006 data-directive structured-block
6009 loop-directive structured-block
6014 attribute-specifier-sequence[opt] openmp-construct
6023 parallel-for-construct
6024 parallel-for-simd-construct
6025 parallel-sections-construct
6032 parallel-directive structured-block
6035 for-directive iteration-statement
6038 simd-directive iteration-statements
6041 for-simd-directive iteration-statements
6044 sections-directive section-scope
6047 single-directive structured-block
6049 parallel-for-construct:
6050 parallel-for-directive iteration-statement
6052 parallel-for-simd-construct:
6053 parallel-for-simd-directive iteration-statement
6055 parallel-sections-construct:
6056 parallel-sections-directive section-scope
6059 master-directive structured-block
6062 critical-directive structured-block
6065 atomic-directive expression-statement
6068 ordered-directive structured-block
6070 Transactional Memory:
6073 attribute-specifier-sequence[opt] transaction-statement
6074 attribute-specifier-sequence[opt] transaction-cancel-statement
6076 IF_P is used to track whether there's a (possibly labeled) if statement
6077 which is not enclosed in braces and has an else clause. This is used to
6078 implement -Wparentheses. */
6081 c_parser_statement (c_parser
*parser
, bool *if_p
, location_t
*loc_after_labels
)
6083 c_parser_all_labels (parser
);
6084 if (loc_after_labels
)
6085 *loc_after_labels
= c_parser_peek_token (parser
)->location
;
6086 c_parser_statement_after_labels (parser
, if_p
, NULL
);
6089 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6090 of if-else-if conditions. All labels and standard attributes have
6091 been parsed in the caller.
6093 IF_P is used to track whether there's a (possibly labeled) if statement
6094 which is not enclosed in braces and has an else clause. This is used to
6095 implement -Wparentheses. */
6098 c_parser_statement_after_labels (c_parser
*parser
, bool *if_p
,
6101 location_t loc
= c_parser_peek_token (parser
)->location
;
6102 tree stmt
= NULL_TREE
;
6103 bool in_if_block
= parser
->in_if_block
;
6104 parser
->in_if_block
= false;
6108 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_BRACE
)
6109 add_debug_begin_stmt (loc
);
6112 switch (c_parser_peek_token (parser
)->type
)
6114 case CPP_OPEN_BRACE
:
6115 add_stmt (c_parser_compound_statement (parser
));
6118 switch (c_parser_peek_token (parser
)->keyword
)
6121 c_parser_if_statement (parser
, if_p
, chain
);
6124 c_parser_switch_statement (parser
, if_p
);
6127 c_parser_while_statement (parser
, false, 0, if_p
);
6130 c_parser_do_statement (parser
, false, 0);
6133 c_parser_for_statement (parser
, false, 0, if_p
);
6136 c_parser_consume_token (parser
);
6137 if (c_parser_next_token_is (parser
, CPP_NAME
))
6139 stmt
= c_finish_goto_label (loc
,
6140 c_parser_peek_token (parser
)->value
);
6141 c_parser_consume_token (parser
);
6143 else if (c_parser_next_token_is (parser
, CPP_MULT
))
6147 c_parser_consume_token (parser
);
6148 val
= c_parser_expression (parser
);
6149 val
= convert_lvalue_to_rvalue (loc
, val
, false, true);
6150 stmt
= c_finish_goto_ptr (loc
, val
);
6153 c_parser_error (parser
, "expected identifier or %<*%>");
6154 goto expect_semicolon
;
6156 c_parser_consume_token (parser
);
6157 stmt
= c_finish_bc_stmt (loc
, objc_foreach_continue_label
, false);
6158 goto expect_semicolon
;
6160 c_parser_consume_token (parser
);
6161 stmt
= c_finish_bc_stmt (loc
, objc_foreach_break_label
, true);
6162 goto expect_semicolon
;
6164 c_parser_consume_token (parser
);
6165 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6167 stmt
= c_finish_return (loc
, NULL_TREE
, NULL_TREE
);
6168 c_parser_consume_token (parser
);
6172 location_t xloc
= c_parser_peek_token (parser
)->location
;
6173 struct c_expr expr
= c_parser_expression_conv (parser
);
6174 mark_exp_read (expr
.value
);
6175 stmt
= c_finish_return (EXPR_LOC_OR_LOC (expr
.value
, xloc
),
6176 expr
.value
, expr
.original_type
);
6177 goto expect_semicolon
;
6181 stmt
= c_parser_asm_statement (parser
);
6183 case RID_TRANSACTION_ATOMIC
:
6184 case RID_TRANSACTION_RELAXED
:
6185 stmt
= c_parser_transaction (parser
,
6186 c_parser_peek_token (parser
)->keyword
);
6188 case RID_TRANSACTION_CANCEL
:
6189 stmt
= c_parser_transaction_cancel (parser
);
6190 goto expect_semicolon
;
6192 gcc_assert (c_dialect_objc ());
6193 c_parser_consume_token (parser
);
6194 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6196 stmt
= objc_build_throw_stmt (loc
, NULL_TREE
);
6197 c_parser_consume_token (parser
);
6201 struct c_expr expr
= c_parser_expression (parser
);
6202 expr
= convert_lvalue_to_rvalue (loc
, expr
, false, false);
6203 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
6204 stmt
= objc_build_throw_stmt (loc
, expr
.value
);
6205 goto expect_semicolon
;
6209 gcc_assert (c_dialect_objc ());
6210 c_parser_objc_try_catch_finally_statement (parser
);
6212 case RID_AT_SYNCHRONIZED
:
6213 gcc_assert (c_dialect_objc ());
6214 c_parser_objc_synchronized_statement (parser
);
6218 /* Allow '__attribute__((fallthrough));'. */
6219 tree attrs
= c_parser_gnu_attributes (parser
);
6220 if (attribute_fallthrough_p (attrs
))
6222 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6224 tree fn
= build_call_expr_internal_loc (loc
,
6229 c_parser_consume_token (parser
);
6232 warning_at (loc
, OPT_Wattributes
,
6233 "%<fallthrough%> attribute not followed "
6236 else if (attrs
!= NULL_TREE
)
6237 warning_at (loc
, OPT_Wattributes
, "only attribute %<fallthrough%>"
6238 " can be applied to a null statement");
6246 c_parser_consume_token (parser
);
6248 case CPP_CLOSE_PAREN
:
6249 case CPP_CLOSE_SQUARE
:
6250 /* Avoid infinite loop in error recovery:
6251 c_parser_skip_until_found stops at a closing nesting
6252 delimiter without consuming it, but here we need to consume
6253 it to proceed further. */
6254 c_parser_error (parser
, "expected statement");
6255 c_parser_consume_token (parser
);
6258 if (!c_parser_pragma (parser
, pragma_stmt
, if_p
))
6263 stmt
= c_finish_expr_stmt (loc
, c_parser_expression_conv (parser
).value
);
6265 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
6268 /* Two cases cannot and do not have line numbers associated: If stmt
6269 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6270 cannot hold line numbers. But that's OK because the statement
6271 will either be changed to a MODIFY_EXPR during gimplification of
6272 the statement expr, or discarded. If stmt was compound, but
6273 without new variables, we will have skipped the creation of a
6274 BIND and will have a bare STATEMENT_LIST. But that's OK because
6275 (recursively) all of the component statements should already have
6276 line numbers assigned. ??? Can we discard no-op statements
6278 if (EXPR_LOCATION (stmt
) == UNKNOWN_LOCATION
)
6279 protected_set_expr_location (stmt
, loc
);
6281 parser
->in_if_block
= in_if_block
;
6284 /* Parse the condition from an if, do, while or for statements. */
6287 c_parser_condition (c_parser
*parser
)
6289 location_t loc
= c_parser_peek_token (parser
)->location
;
6291 cond
= c_parser_expression_conv (parser
).value
;
6292 cond
= c_objc_common_truthvalue_conversion (loc
, cond
);
6293 cond
= c_fully_fold (cond
, false, NULL
);
6294 if (warn_sequence_point
)
6295 verify_sequence_points (cond
);
6299 /* Parse a parenthesized condition from an if, do or while statement.
6305 c_parser_paren_condition (c_parser
*parser
)
6308 matching_parens parens
;
6309 if (!parens
.require_open (parser
))
6310 return error_mark_node
;
6311 cond
= c_parser_condition (parser
);
6312 parens
.skip_until_found_close (parser
);
6316 /* Parse a statement which is a block in C99.
6318 IF_P is used to track whether there's a (possibly labeled) if statement
6319 which is not enclosed in braces and has an else clause. This is used to
6320 implement -Wparentheses. */
6323 c_parser_c99_block_statement (c_parser
*parser
, bool *if_p
,
6324 location_t
*loc_after_labels
)
6326 tree block
= c_begin_compound_stmt (flag_isoc99
);
6327 location_t loc
= c_parser_peek_token (parser
)->location
;
6328 c_parser_statement (parser
, if_p
, loc_after_labels
);
6329 return c_end_compound_stmt (loc
, block
, flag_isoc99
);
6332 /* Parse the body of an if statement. This is just parsing a
6333 statement but (a) it is a block in C99, (b) we track whether the
6334 body is an if statement for the sake of -Wparentheses warnings, (c)
6335 we handle an empty body specially for the sake of -Wempty-body
6336 warnings, and (d) we call parser_compound_statement directly
6337 because c_parser_statement_after_labels resets
6338 parser->in_if_block.
6340 IF_P is used to track whether there's a (possibly labeled) if statement
6341 which is not enclosed in braces and has an else clause. This is used to
6342 implement -Wparentheses. */
6345 c_parser_if_body (c_parser
*parser
, bool *if_p
,
6346 const token_indent_info
&if_tinfo
)
6348 tree block
= c_begin_compound_stmt (flag_isoc99
);
6349 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6350 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6351 token_indent_info body_tinfo
6352 = get_token_indent_info (c_parser_peek_token (parser
));
6354 c_parser_all_labels (parser
);
6355 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6357 location_t loc
= c_parser_peek_token (parser
)->location
;
6358 add_stmt (build_empty_stmt (loc
));
6359 c_parser_consume_token (parser
);
6360 if (!c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6361 warning_at (loc
, OPT_Wempty_body
,
6362 "suggest braces around empty body in an %<if%> statement");
6364 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6365 add_stmt (c_parser_compound_statement (parser
));
6368 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6369 c_parser_statement_after_labels (parser
, if_p
);
6372 token_indent_info next_tinfo
6373 = get_token_indent_info (c_parser_peek_token (parser
));
6374 warn_for_misleading_indentation (if_tinfo
, body_tinfo
, next_tinfo
);
6375 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6376 && next_tinfo
.type
!= CPP_SEMICOLON
)
6377 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6378 if_tinfo
.location
, RID_IF
);
6380 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6383 /* Parse the else body of an if statement. This is just parsing a
6384 statement but (a) it is a block in C99, (b) we handle an empty body
6385 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6386 of if-else-if conditions. */
6389 c_parser_else_body (c_parser
*parser
, const token_indent_info
&else_tinfo
,
6392 location_t body_loc
= c_parser_peek_token (parser
)->location
;
6393 tree block
= c_begin_compound_stmt (flag_isoc99
);
6394 token_indent_info body_tinfo
6395 = get_token_indent_info (c_parser_peek_token (parser
));
6396 location_t body_loc_after_labels
= UNKNOWN_LOCATION
;
6398 c_parser_all_labels (parser
);
6399 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6401 location_t loc
= c_parser_peek_token (parser
)->location
;
6404 "suggest braces around empty body in an %<else%> statement");
6405 add_stmt (build_empty_stmt (loc
));
6406 c_parser_consume_token (parser
);
6410 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
6411 body_loc_after_labels
= c_parser_peek_token (parser
)->location
;
6412 c_parser_statement_after_labels (parser
, NULL
, chain
);
6415 token_indent_info next_tinfo
6416 = get_token_indent_info (c_parser_peek_token (parser
));
6417 warn_for_misleading_indentation (else_tinfo
, body_tinfo
, next_tinfo
);
6418 if (body_loc_after_labels
!= UNKNOWN_LOCATION
6419 && next_tinfo
.type
!= CPP_SEMICOLON
)
6420 warn_for_multistatement_macros (body_loc_after_labels
, next_tinfo
.location
,
6421 else_tinfo
.location
, RID_ELSE
);
6423 return c_end_compound_stmt (body_loc
, block
, flag_isoc99
);
6426 /* We might need to reclassify any previously-lexed identifier, e.g.
6427 when we've left a for loop with an if-statement without else in the
6428 body - we might have used a wrong scope for the token. See PR67784. */
6431 c_parser_maybe_reclassify_token (c_parser
*parser
)
6433 if (c_parser_next_token_is (parser
, CPP_NAME
))
6435 c_token
*token
= c_parser_peek_token (parser
);
6437 if (token
->id_kind
!= C_ID_CLASSNAME
)
6439 tree decl
= lookup_name (token
->value
);
6441 token
->id_kind
= C_ID_ID
;
6444 if (TREE_CODE (decl
) == TYPE_DECL
)
6445 token
->id_kind
= C_ID_TYPENAME
;
6447 else if (c_dialect_objc ())
6449 tree objc_interface_decl
= objc_is_class_name (token
->value
);
6450 /* Objective-C class names are in the same namespace as
6451 variables and typedefs, and hence are shadowed by local
6453 if (objc_interface_decl
)
6455 token
->value
= objc_interface_decl
;
6456 token
->id_kind
= C_ID_CLASSNAME
;
6463 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6466 if ( expression ) statement
6467 if ( expression ) statement else statement
6469 CHAIN is a vector of if-else-if conditions.
6470 IF_P is used to track whether there's a (possibly labeled) if statement
6471 which is not enclosed in braces and has an else clause. This is used to
6472 implement -Wparentheses. */
6475 c_parser_if_statement (c_parser
*parser
, bool *if_p
, vec
<tree
> *chain
)
6480 bool nested_if
= false;
6481 tree first_body
, second_body
;
6484 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_IF
));
6485 token_indent_info if_tinfo
6486 = get_token_indent_info (c_parser_peek_token (parser
));
6487 c_parser_consume_token (parser
);
6488 block
= c_begin_compound_stmt (flag_isoc99
);
6489 loc
= c_parser_peek_token (parser
)->location
;
6490 cond
= c_parser_paren_condition (parser
);
6491 in_if_block
= parser
->in_if_block
;
6492 parser
->in_if_block
= true;
6493 first_body
= c_parser_if_body (parser
, &nested_if
, if_tinfo
);
6494 parser
->in_if_block
= in_if_block
;
6496 if (warn_duplicated_cond
)
6497 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond
), cond
, &chain
);
6499 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
6501 token_indent_info else_tinfo
6502 = get_token_indent_info (c_parser_peek_token (parser
));
6503 c_parser_consume_token (parser
);
6504 if (warn_duplicated_cond
)
6506 if (c_parser_next_token_is_keyword (parser
, RID_IF
)
6509 /* We've got "if (COND) else if (COND2)". Start the
6510 condition chain and add COND as the first element. */
6511 chain
= new vec
<tree
> ();
6512 if (!CONSTANT_CLASS_P (cond
) && !TREE_SIDE_EFFECTS (cond
))
6513 chain
->safe_push (cond
);
6515 else if (!c_parser_next_token_is_keyword (parser
, RID_IF
))
6516 /* This is if-else without subsequent if. Zap the condition
6517 chain; we would have already warned at this point. */
6520 second_body
= c_parser_else_body (parser
, else_tinfo
, chain
);
6521 /* Set IF_P to true to indicate that this if statement has an
6522 else clause. This may trigger the Wparentheses warning
6523 below when we get back up to the parent if statement. */
6529 second_body
= NULL_TREE
;
6531 /* Diagnose an ambiguous else if if-then-else is nested inside
6534 warning_at (loc
, OPT_Wdangling_else
,
6535 "suggest explicit braces to avoid ambiguous %<else%>");
6537 if (warn_duplicated_cond
)
6538 /* This if statement does not have an else clause. We don't
6539 need the condition chain anymore. */
6542 c_finish_if_stmt (loc
, cond
, first_body
, second_body
);
6543 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6545 c_parser_maybe_reclassify_token (parser
);
6548 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6551 switch (expression) statement
6555 c_parser_switch_statement (c_parser
*parser
, bool *if_p
)
6558 tree block
, expr
, body
;
6559 unsigned char save_in_statement
;
6560 location_t switch_loc
= c_parser_peek_token (parser
)->location
;
6561 location_t switch_cond_loc
;
6562 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SWITCH
));
6563 c_parser_consume_token (parser
);
6564 block
= c_begin_compound_stmt (flag_isoc99
);
6565 bool explicit_cast_p
= false;
6566 matching_parens parens
;
6567 if (parens
.require_open (parser
))
6569 switch_cond_loc
= c_parser_peek_token (parser
)->location
;
6570 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
6571 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
6572 explicit_cast_p
= true;
6573 ce
= c_parser_expression (parser
);
6574 ce
= convert_lvalue_to_rvalue (switch_cond_loc
, ce
, true, true);
6576 /* ??? expr has no valid location? */
6577 parens
.skip_until_found_close (parser
);
6581 switch_cond_loc
= UNKNOWN_LOCATION
;
6582 expr
= error_mark_node
;
6583 ce
.original_type
= error_mark_node
;
6585 c_start_switch (switch_loc
, switch_cond_loc
, expr
, explicit_cast_p
);
6586 save_in_statement
= in_statement
;
6587 in_statement
|= IN_SWITCH_STMT
;
6588 location_t loc_after_labels
;
6589 bool open_brace_p
= c_parser_peek_token (parser
)->type
== CPP_OPEN_BRACE
;
6590 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6591 location_t next_loc
= c_parser_peek_token (parser
)->location
;
6592 if (!open_brace_p
&& c_parser_peek_token (parser
)->type
!= CPP_SEMICOLON
)
6593 warn_for_multistatement_macros (loc_after_labels
, next_loc
, switch_loc
,
6595 c_finish_switch (body
, ce
.original_type
);
6596 in_statement
= save_in_statement
;
6597 add_stmt (c_end_compound_stmt (switch_loc
, block
, flag_isoc99
));
6598 c_parser_maybe_reclassify_token (parser
);
6601 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6604 while (expression) statement
6606 IF_P is used to track whether there's a (possibly labeled) if statement
6607 which is not enclosed in braces and has an else clause. This is used to
6608 implement -Wparentheses. */
6611 c_parser_while_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6614 tree block
, cond
, body
;
6615 unsigned char save_in_statement
;
6617 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_WHILE
));
6618 token_indent_info while_tinfo
6619 = get_token_indent_info (c_parser_peek_token (parser
));
6620 c_parser_consume_token (parser
);
6621 block
= c_begin_compound_stmt (flag_isoc99
);
6622 loc
= c_parser_peek_token (parser
)->location
;
6623 cond
= c_parser_paren_condition (parser
);
6624 if (ivdep
&& cond
!= error_mark_node
)
6625 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6626 build_int_cst (integer_type_node
,
6627 annot_expr_ivdep_kind
),
6629 if (unroll
&& cond
!= error_mark_node
)
6630 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6631 build_int_cst (integer_type_node
,
6632 annot_expr_unroll_kind
),
6633 build_int_cst (integer_type_node
, unroll
));
6634 save_in_statement
= in_statement
;
6635 in_statement
= IN_ITERATION_STMT
;
6637 token_indent_info body_tinfo
6638 = get_token_indent_info (c_parser_peek_token (parser
));
6640 location_t loc_after_labels
;
6641 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
6642 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6643 add_stmt (build_stmt (loc
, WHILE_STMT
, cond
, body
));
6644 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6645 c_parser_maybe_reclassify_token (parser
);
6647 token_indent_info next_tinfo
6648 = get_token_indent_info (c_parser_peek_token (parser
));
6649 warn_for_misleading_indentation (while_tinfo
, body_tinfo
, next_tinfo
);
6651 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
6652 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
6653 while_tinfo
.location
, RID_WHILE
);
6655 in_statement
= save_in_statement
;
6658 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6661 do statement while ( expression ) ;
6665 c_parser_do_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
)
6667 tree block
, cond
, body
;
6668 unsigned char save_in_statement
;
6670 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_DO
));
6671 c_parser_consume_token (parser
);
6672 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6673 warning_at (c_parser_peek_token (parser
)->location
,
6675 "suggest braces around empty body in %<do%> statement");
6676 block
= c_begin_compound_stmt (flag_isoc99
);
6677 loc
= c_parser_peek_token (parser
)->location
;
6678 save_in_statement
= in_statement
;
6679 in_statement
= IN_ITERATION_STMT
;
6680 body
= c_parser_c99_block_statement (parser
, NULL
);
6681 c_parser_require_keyword (parser
, RID_WHILE
, "expected %<while%>");
6682 in_statement
= save_in_statement
;
6683 cond
= c_parser_paren_condition (parser
);
6684 if (ivdep
&& cond
!= error_mark_node
)
6685 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6686 build_int_cst (integer_type_node
,
6687 annot_expr_ivdep_kind
),
6689 if (unroll
&& cond
!= error_mark_node
)
6690 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6691 build_int_cst (integer_type_node
,
6692 annot_expr_unroll_kind
),
6693 build_int_cst (integer_type_node
, unroll
));
6694 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
6695 c_parser_skip_to_end_of_block_or_statement (parser
);
6697 add_stmt (build_stmt (loc
, DO_STMT
, cond
, body
));
6698 add_stmt (c_end_compound_stmt (loc
, block
, flag_isoc99
));
6701 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6704 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6705 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6707 The form with a declaration is new in C99.
6709 ??? In accordance with the old parser, the declaration may be a
6710 nested function, which is then rejected in check_for_loop_decls,
6711 but does it make any sense for this to be included in the grammar?
6712 Note in particular that the nested function does not include a
6713 trailing ';', whereas the "declaration" production includes one.
6714 Also, can we reject bad declarations earlier and cheaper than
6715 check_for_loop_decls?
6717 In Objective-C, there are two additional variants:
6720 for ( expression in expresssion ) statement
6721 for ( declaration in expression ) statement
6723 This is inconsistent with C, because the second variant is allowed
6724 even if c99 is not enabled.
6726 The rest of the comment documents these Objective-C foreach-statement.
6728 Here is the canonical example of the first variant:
6729 for (object in array) { do something with object }
6730 we call the first expression ("object") the "object_expression" and
6731 the second expression ("array") the "collection_expression".
6732 object_expression must be an lvalue of type "id" (a generic Objective-C
6733 object) because the loop works by assigning to object_expression the
6734 various objects from the collection_expression. collection_expression
6735 must evaluate to something of type "id" which responds to the method
6736 countByEnumeratingWithState:objects:count:.
6738 The canonical example of the second variant is:
6739 for (id object in array) { do something with object }
6740 which is completely equivalent to
6743 for (object in array) { do something with object }
6745 Note that initizializing 'object' in some way (eg, "for ((object =
6746 xxx) in array) { do something with object }") is possibly
6747 technically valid, but completely pointless as 'object' will be
6748 assigned to something else as soon as the loop starts. We should
6749 most likely reject it (TODO).
6751 The beginning of the Objective-C foreach-statement looks exactly
6752 like the beginning of the for-statement, and we can tell it is a
6753 foreach-statement only because the initial declaration or
6754 expression is terminated by 'in' instead of ';'.
6756 IF_P is used to track whether there's a (possibly labeled) if statement
6757 which is not enclosed in braces and has an else clause. This is used to
6758 implement -Wparentheses. */
6761 c_parser_for_statement (c_parser
*parser
, bool ivdep
, unsigned short unroll
,
6764 tree block
, cond
, incr
, body
;
6765 unsigned char save_in_statement
;
6766 tree save_objc_foreach_break_label
, save_objc_foreach_continue_label
;
6767 /* The following are only used when parsing an ObjC foreach statement. */
6768 tree object_expression
;
6769 /* Silence the bogus uninitialized warning. */
6770 tree collection_expression
= NULL
;
6771 location_t loc
= c_parser_peek_token (parser
)->location
;
6772 location_t for_loc
= loc
;
6773 bool is_foreach_statement
= false;
6774 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_FOR
));
6775 token_indent_info for_tinfo
6776 = get_token_indent_info (c_parser_peek_token (parser
));
6777 c_parser_consume_token (parser
);
6778 /* Open a compound statement in Objective-C as well, just in case this is
6779 as foreach expression. */
6780 block
= c_begin_compound_stmt (flag_isoc99
|| c_dialect_objc ());
6781 cond
= error_mark_node
;
6782 incr
= error_mark_node
;
6783 matching_parens parens
;
6784 if (parens
.require_open (parser
))
6786 /* Parse the initialization declaration or expression. */
6787 object_expression
= error_mark_node
;
6788 parser
->objc_could_be_foreach_context
= c_dialect_objc ();
6789 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6791 parser
->objc_could_be_foreach_context
= false;
6792 c_parser_consume_token (parser
);
6793 c_finish_expr_stmt (loc
, NULL_TREE
);
6795 else if (c_parser_next_tokens_start_declaration (parser
)
6796 || c_parser_nth_token_starts_std_attributes (parser
, 1))
6798 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
6799 &object_expression
);
6800 parser
->objc_could_be_foreach_context
= false;
6802 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6804 c_parser_consume_token (parser
);
6805 is_foreach_statement
= true;
6806 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6807 c_parser_error (parser
, "multiple iterating variables in "
6808 "fast enumeration");
6811 check_for_loop_decls (for_loc
, flag_isoc99
);
6813 else if (c_parser_next_token_is_keyword (parser
, RID_EXTENSION
))
6815 /* __extension__ can start a declaration, but is also an
6816 unary operator that can start an expression. Consume all
6817 but the last of a possible series of __extension__ to
6819 while (c_parser_peek_2nd_token (parser
)->type
== CPP_KEYWORD
6820 && (c_parser_peek_2nd_token (parser
)->keyword
6822 c_parser_consume_token (parser
);
6823 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser
))
6824 || c_parser_nth_token_starts_std_attributes (parser
, 2))
6827 ext
= disable_extension_diagnostics ();
6828 c_parser_consume_token (parser
);
6829 c_parser_declaration_or_fndef (parser
, true, true, true, true,
6830 true, &object_expression
);
6831 parser
->objc_could_be_foreach_context
= false;
6833 restore_extension_diagnostics (ext
);
6834 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6836 c_parser_consume_token (parser
);
6837 is_foreach_statement
= true;
6838 if (check_for_loop_decls (for_loc
, true) == NULL_TREE
)
6839 c_parser_error (parser
, "multiple iterating variables in "
6840 "fast enumeration");
6843 check_for_loop_decls (for_loc
, flag_isoc99
);
6853 tree init_expression
;
6854 ce
= c_parser_expression (parser
);
6855 init_expression
= ce
.value
;
6856 parser
->objc_could_be_foreach_context
= false;
6857 if (c_parser_next_token_is_keyword (parser
, RID_IN
))
6859 c_parser_consume_token (parser
);
6860 is_foreach_statement
= true;
6861 if (! lvalue_p (init_expression
))
6862 c_parser_error (parser
, "invalid iterating variable in "
6863 "fast enumeration");
6865 = c_fully_fold (init_expression
, false, NULL
);
6869 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6870 init_expression
= ce
.value
;
6871 c_finish_expr_stmt (loc
, init_expression
);
6872 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6877 /* Parse the loop condition. In the case of a foreach
6878 statement, there is no loop condition. */
6879 gcc_assert (!parser
->objc_could_be_foreach_context
);
6880 if (!is_foreach_statement
)
6882 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
6886 c_parser_error (parser
, "missing loop condition in loop "
6887 "with %<GCC ivdep%> pragma");
6888 cond
= error_mark_node
;
6892 c_parser_error (parser
, "missing loop condition in loop "
6893 "with %<GCC unroll%> pragma");
6894 cond
= error_mark_node
;
6898 c_parser_consume_token (parser
);
6904 cond
= c_parser_condition (parser
);
6905 c_parser_skip_until_found (parser
, CPP_SEMICOLON
,
6908 if (ivdep
&& cond
!= error_mark_node
)
6909 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6910 build_int_cst (integer_type_node
,
6911 annot_expr_ivdep_kind
),
6913 if (unroll
&& cond
!= error_mark_node
)
6914 cond
= build3 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
6915 build_int_cst (integer_type_node
,
6916 annot_expr_unroll_kind
),
6917 build_int_cst (integer_type_node
, unroll
));
6919 /* Parse the increment expression (the third expression in a
6920 for-statement). In the case of a foreach-statement, this is
6921 the expression that follows the 'in'. */
6922 loc
= c_parser_peek_token (parser
)->location
;
6923 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
6925 if (is_foreach_statement
)
6927 c_parser_error (parser
,
6928 "missing collection in fast enumeration");
6929 collection_expression
= error_mark_node
;
6932 incr
= c_process_expr_stmt (loc
, NULL_TREE
);
6936 if (is_foreach_statement
)
6937 collection_expression
6938 = c_fully_fold (c_parser_expression (parser
).value
, false, NULL
);
6941 struct c_expr ce
= c_parser_expression (parser
);
6942 ce
= convert_lvalue_to_rvalue (loc
, ce
, true, false);
6943 incr
= c_process_expr_stmt (loc
, ce
.value
);
6946 parens
.skip_until_found_close (parser
);
6948 save_in_statement
= in_statement
;
6949 if (is_foreach_statement
)
6951 in_statement
= IN_OBJC_FOREACH
;
6952 save_objc_foreach_break_label
= objc_foreach_break_label
;
6953 save_objc_foreach_continue_label
= objc_foreach_continue_label
;
6954 objc_foreach_break_label
= create_artificial_label (loc
);
6955 objc_foreach_continue_label
= create_artificial_label (loc
);
6958 in_statement
= IN_ITERATION_STMT
;
6960 token_indent_info body_tinfo
6961 = get_token_indent_info (c_parser_peek_token (parser
));
6963 location_t loc_after_labels
;
6964 bool open_brace
= c_parser_next_token_is (parser
, CPP_OPEN_BRACE
);
6965 body
= c_parser_c99_block_statement (parser
, if_p
, &loc_after_labels
);
6967 if (is_foreach_statement
)
6968 objc_finish_foreach_loop (for_loc
, object_expression
,
6969 collection_expression
, body
,
6970 objc_foreach_break_label
,
6971 objc_foreach_continue_label
);
6973 add_stmt (build_stmt (for_loc
, FOR_STMT
, NULL_TREE
, cond
, incr
,
6975 add_stmt (c_end_compound_stmt (for_loc
, block
,
6976 flag_isoc99
|| c_dialect_objc ()));
6977 c_parser_maybe_reclassify_token (parser
);
6979 token_indent_info next_tinfo
6980 = get_token_indent_info (c_parser_peek_token (parser
));
6981 warn_for_misleading_indentation (for_tinfo
, body_tinfo
, next_tinfo
);
6983 if (next_tinfo
.type
!= CPP_SEMICOLON
&& !open_brace
)
6984 warn_for_multistatement_macros (loc_after_labels
, next_tinfo
.location
,
6985 for_tinfo
.location
, RID_FOR
);
6987 in_statement
= save_in_statement
;
6988 if (is_foreach_statement
)
6990 objc_foreach_break_label
= save_objc_foreach_break_label
;
6991 objc_foreach_continue_label
= save_objc_foreach_continue_label
;
6995 /* Parse an asm statement, a GNU extension. This is a full-blown asm
6996 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7005 asm-qualifier-list asm-qualifier
7009 asm asm-qualifier-list[opt] ( asm-argument ) ;
7013 asm-string-literal : asm-operands[opt]
7014 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7015 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7017 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7020 The form with asm-goto-operands is valid if and only if the
7021 asm-qualifier-list contains goto, and is the only allowed form in that case.
7022 Duplicate asm-qualifiers are not allowed.
7024 The :: token is considered equivalent to two consecutive : tokens. */
7027 c_parser_asm_statement (c_parser
*parser
)
7029 tree str
, outputs
, inputs
, clobbers
, labels
, ret
;
7031 location_t asm_loc
= c_parser_peek_token (parser
)->location
;
7032 int section
, nsections
;
7034 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ASM
));
7035 c_parser_consume_token (parser
);
7037 /* Handle the asm-qualifier-list. */
7038 location_t volatile_loc
= UNKNOWN_LOCATION
;
7039 location_t inline_loc
= UNKNOWN_LOCATION
;
7040 location_t goto_loc
= UNKNOWN_LOCATION
;
7043 c_token
*token
= c_parser_peek_token (parser
);
7044 location_t loc
= token
->location
;
7045 switch (token
->keyword
)
7050 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7051 inform (volatile_loc
, "first seen here");
7055 c_parser_consume_token (parser
);
7061 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7062 inform (inline_loc
, "first seen here");
7066 c_parser_consume_token (parser
);
7072 error_at (loc
, "duplicate %<asm%> qualifier %qE", token
->value
);
7073 inform (goto_loc
, "first seen here");
7077 c_parser_consume_token (parser
);
7082 error_at (loc
, "%qE is not a valid %<asm%> qualifier", token
->value
);
7083 c_parser_consume_token (parser
);
7092 bool is_volatile
= (volatile_loc
!= UNKNOWN_LOCATION
);
7093 bool is_inline
= (inline_loc
!= UNKNOWN_LOCATION
);
7094 bool is_goto
= (goto_loc
!= UNKNOWN_LOCATION
);
7098 matching_parens parens
;
7099 if (!parens
.require_open (parser
))
7102 str
= c_parser_asm_string_literal (parser
);
7103 if (str
== NULL_TREE
)
7104 goto error_close_paren
;
7107 outputs
= NULL_TREE
;
7109 clobbers
= NULL_TREE
;
7112 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7115 /* Parse each colon-delimited section of operands. */
7116 nsections
= 3 + is_goto
;
7117 for (section
= 0; section
< nsections
; ++section
)
7119 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
7122 if (section
== nsections
)
7124 c_parser_error (parser
, "expected %<)%>");
7125 goto error_close_paren
;
7127 c_parser_consume_token (parser
);
7129 else if (!c_parser_require (parser
, CPP_COLON
,
7131 ? G_("expected %<:%>")
7132 : G_("expected %<:%> or %<)%>"),
7133 UNKNOWN_LOCATION
, is_goto
))
7134 goto error_close_paren
;
7136 /* Once past any colon, we're no longer a simple asm. */
7139 if ((!c_parser_next_token_is (parser
, CPP_COLON
)
7140 && !c_parser_next_token_is (parser
, CPP_SCOPE
)
7141 && !c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
7146 outputs
= c_parser_asm_operands (parser
);
7149 inputs
= c_parser_asm_operands (parser
);
7152 clobbers
= c_parser_asm_clobbers (parser
);
7155 labels
= c_parser_asm_goto_operands (parser
);
7161 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
) && !is_goto
)
7166 if (!parens
.require_close (parser
))
7168 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7172 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
7173 c_parser_skip_to_end_of_block_or_statement (parser
);
7175 ret
= build_asm_stmt (is_volatile
,
7176 build_asm_expr (asm_loc
, str
, outputs
, inputs
,
7177 clobbers
, labels
, simple
, is_inline
));
7183 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7187 /* Parse asm operands, a GNU extension.
7191 asm-operands , asm-operand
7194 asm-string-literal ( expression )
7195 [ identifier ] asm-string-literal ( expression )
7199 c_parser_asm_operands (c_parser
*parser
)
7201 tree list
= NULL_TREE
;
7206 if (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
7208 c_parser_consume_token (parser
);
7209 if (c_parser_next_token_is (parser
, CPP_NAME
))
7211 tree id
= c_parser_peek_token (parser
)->value
;
7212 c_parser_consume_token (parser
);
7213 name
= build_string (IDENTIFIER_LENGTH (id
),
7214 IDENTIFIER_POINTER (id
));
7218 c_parser_error (parser
, "expected identifier");
7219 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
, NULL
);
7222 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
7227 str
= c_parser_asm_string_literal (parser
);
7228 if (str
== NULL_TREE
)
7230 matching_parens parens
;
7231 if (!parens
.require_open (parser
))
7233 expr
= c_parser_expression (parser
);
7234 mark_exp_read (expr
.value
);
7235 if (!parens
.require_close (parser
))
7237 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
7240 list
= chainon (list
, build_tree_list (build_tree_list (name
, str
),
7242 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7243 c_parser_consume_token (parser
);
7250 /* Parse asm clobbers, a GNU extension.
7254 asm-clobbers , asm-string-literal
7258 c_parser_asm_clobbers (c_parser
*parser
)
7260 tree list
= NULL_TREE
;
7263 tree str
= c_parser_asm_string_literal (parser
);
7265 list
= tree_cons (NULL_TREE
, str
, list
);
7268 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7269 c_parser_consume_token (parser
);
7276 /* Parse asm goto labels, a GNU extension.
7280 asm-goto-operands , identifier
7284 c_parser_asm_goto_operands (c_parser
*parser
)
7286 tree list
= NULL_TREE
;
7291 if (c_parser_next_token_is (parser
, CPP_NAME
))
7293 c_token
*tok
= c_parser_peek_token (parser
);
7295 label
= lookup_label_for_goto (tok
->location
, name
);
7296 c_parser_consume_token (parser
);
7297 TREE_USED (label
) = 1;
7301 c_parser_error (parser
, "expected identifier");
7305 name
= build_string (IDENTIFIER_LENGTH (name
),
7306 IDENTIFIER_POINTER (name
));
7307 list
= tree_cons (name
, label
, list
);
7308 if (c_parser_next_token_is (parser
, CPP_COMMA
))
7309 c_parser_consume_token (parser
);
7311 return nreverse (list
);
7315 /* Parse a possibly concatenated sequence of string literals.
7316 TRANSLATE says whether to translate them to the execution character
7317 set; WIDE_OK says whether any kind of prefixed string literal is
7318 permitted in this context. This code is based on that in
7322 c_parser_string_literal (c_parser
*parser
, bool translate
, bool wide_ok
)
7326 struct obstack str_ob
;
7327 struct obstack loc_ob
;
7328 cpp_string str
, istr
, *strs
;
7330 location_t loc
, last_tok_loc
;
7331 enum cpp_ttype type
;
7332 tree value
, string_tree
;
7334 tok
= c_parser_peek_token (parser
);
7335 loc
= tok
->location
;
7336 last_tok_loc
= linemap_resolve_location (line_table
, loc
,
7337 LRK_MACRO_DEFINITION_LOCATION
,
7346 case CPP_UTF8STRING
:
7347 string_tree
= tok
->value
;
7351 c_parser_error (parser
, "expected string literal");
7353 ret
.value
= NULL_TREE
;
7354 ret
.original_code
= ERROR_MARK
;
7355 ret
.original_type
= NULL_TREE
;
7359 /* Try to avoid the overhead of creating and destroying an obstack
7360 for the common case of just one string. */
7361 switch (c_parser_peek_2nd_token (parser
)->type
)
7364 c_parser_consume_token (parser
);
7365 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7366 str
.len
= TREE_STRING_LENGTH (string_tree
);
7375 case CPP_UTF8STRING
:
7376 gcc_obstack_init (&str_ob
);
7377 gcc_obstack_init (&loc_ob
);
7381 c_parser_consume_token (parser
);
7383 str
.text
= (const unsigned char *) TREE_STRING_POINTER (string_tree
);
7384 str
.len
= TREE_STRING_LENGTH (string_tree
);
7385 if (type
!= tok
->type
)
7387 if (type
== CPP_STRING
)
7389 else if (tok
->type
!= CPP_STRING
)
7390 error ("unsupported non-standard concatenation "
7391 "of string literals");
7393 obstack_grow (&str_ob
, &str
, sizeof (cpp_string
));
7394 obstack_grow (&loc_ob
, &last_tok_loc
, sizeof (location_t
));
7395 tok
= c_parser_peek_token (parser
);
7396 string_tree
= tok
->value
;
7398 = linemap_resolve_location (line_table
, tok
->location
,
7399 LRK_MACRO_DEFINITION_LOCATION
, NULL
);
7401 while (tok
->type
== CPP_STRING
7402 || tok
->type
== CPP_WSTRING
7403 || tok
->type
== CPP_STRING16
7404 || tok
->type
== CPP_STRING32
7405 || tok
->type
== CPP_UTF8STRING
);
7406 strs
= (cpp_string
*) obstack_finish (&str_ob
);
7409 if (count
> 1 && !in_system_header_at (input_location
))
7410 warning (OPT_Wtraditional
,
7411 "traditional C rejects string constant concatenation");
7413 if ((type
== CPP_STRING
|| wide_ok
)
7415 ? cpp_interpret_string
: cpp_interpret_string_notranslate
)
7416 (parse_in
, strs
, count
, &istr
, type
)))
7418 value
= build_string (istr
.len
, (const char *) istr
.text
);
7419 free (CONST_CAST (unsigned char *, istr
.text
));
7422 location_t
*locs
= (location_t
*) obstack_finish (&loc_ob
);
7423 gcc_assert (g_string_concat_db
);
7424 g_string_concat_db
->record_string_concatenation (count
, locs
);
7429 if (type
!= CPP_STRING
&& !wide_ok
)
7431 error_at (loc
, "a wide string is invalid in this context");
7434 /* Callers cannot generally handle error_mark_node in this
7435 context, so return the empty string instead. An error has
7436 been issued, either above or from cpp_interpret_string. */
7441 case CPP_UTF8STRING
:
7442 value
= build_string (1, "");
7445 value
= build_string (TYPE_PRECISION (char16_type_node
)
7446 / TYPE_PRECISION (char_type_node
),
7447 "\0"); /* char16_t is 16 bits */
7450 value
= build_string (TYPE_PRECISION (char32_type_node
)
7451 / TYPE_PRECISION (char_type_node
),
7452 "\0\0\0"); /* char32_t is 32 bits */
7455 value
= build_string (TYPE_PRECISION (wchar_type_node
)
7456 / TYPE_PRECISION (char_type_node
),
7457 "\0\0\0"); /* widest supported wchar_t
7467 case CPP_UTF8STRING
:
7468 TREE_TYPE (value
) = char_array_type_node
;
7471 TREE_TYPE (value
) = char16_array_type_node
;
7474 TREE_TYPE (value
) = char32_array_type_node
;
7477 TREE_TYPE (value
) = wchar_array_type_node
;
7479 value
= fix_string_type (value
);
7483 obstack_free (&str_ob
, 0);
7484 obstack_free (&loc_ob
, 0);
7488 ret
.original_code
= STRING_CST
;
7489 ret
.original_type
= NULL_TREE
;
7490 set_c_expr_source_range (&ret
, get_range_from_loc (line_table
, loc
));
7491 parser
->seen_string_literal
= true;
7495 /* Parse an expression other than a compound expression; that is, an
7496 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7497 AFTER is not NULL then it is an Objective-C message expression which
7498 is the primary-expression starting the expression as an initializer.
7500 assignment-expression:
7501 conditional-expression
7502 unary-expression assignment-operator assignment-expression
7504 assignment-operator: one of
7505 = *= /= %= += -= <<= >>= &= ^= |=
7507 In GNU C we accept any conditional expression on the LHS and
7508 diagnose the invalid lvalue rather than producing a syntax
7511 static struct c_expr
7512 c_parser_expr_no_commas (c_parser
*parser
, struct c_expr
*after
,
7513 tree omp_atomic_lhs
)
7515 struct c_expr lhs
, rhs
, ret
;
7516 enum tree_code code
;
7517 location_t op_location
, exp_location
;
7518 bool save_in_omp_for
= c_in_omp_for
;
7519 c_in_omp_for
= false;
7520 gcc_assert (!after
|| c_dialect_objc ());
7521 lhs
= c_parser_conditional_expression (parser
, after
, omp_atomic_lhs
);
7522 op_location
= c_parser_peek_token (parser
)->location
;
7523 switch (c_parser_peek_token (parser
)->type
)
7532 code
= TRUNC_DIV_EXPR
;
7535 code
= TRUNC_MOD_EXPR
;
7550 code
= BIT_AND_EXPR
;
7553 code
= BIT_XOR_EXPR
;
7556 code
= BIT_IOR_EXPR
;
7559 c_in_omp_for
= save_in_omp_for
;
7562 c_parser_consume_token (parser
);
7563 exp_location
= c_parser_peek_token (parser
)->location
;
7564 rhs
= c_parser_expr_no_commas (parser
, NULL
);
7565 rhs
= convert_lvalue_to_rvalue (exp_location
, rhs
, true, true);
7567 ret
.value
= build_modify_expr (op_location
, lhs
.value
, lhs
.original_type
,
7568 code
, exp_location
, rhs
.value
,
7570 set_c_expr_source_range (&ret
, lhs
.get_start (), rhs
.get_finish ());
7571 if (code
== NOP_EXPR
)
7572 ret
.original_code
= MODIFY_EXPR
;
7575 suppress_warning (ret
.value
, OPT_Wparentheses
);
7576 ret
.original_code
= ERROR_MARK
;
7578 ret
.original_type
= NULL
;
7579 c_in_omp_for
= save_in_omp_for
;
7583 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7584 AFTER is not NULL then it is an Objective-C message expression which is
7585 the primary-expression starting the expression as an initializer.
7587 conditional-expression:
7588 logical-OR-expression
7589 logical-OR-expression ? expression : conditional-expression
7593 conditional-expression:
7594 logical-OR-expression ? : conditional-expression
7597 static struct c_expr
7598 c_parser_conditional_expression (c_parser
*parser
, struct c_expr
*after
,
7599 tree omp_atomic_lhs
)
7601 struct c_expr cond
, exp1
, exp2
, ret
;
7602 location_t start
, cond_loc
, colon_loc
;
7604 gcc_assert (!after
|| c_dialect_objc ());
7606 cond
= c_parser_binary_expression (parser
, after
, omp_atomic_lhs
);
7608 if (c_parser_next_token_is_not (parser
, CPP_QUERY
))
7610 if (cond
.value
!= error_mark_node
)
7611 start
= cond
.get_start ();
7613 start
= UNKNOWN_LOCATION
;
7614 cond_loc
= c_parser_peek_token (parser
)->location
;
7615 cond
= convert_lvalue_to_rvalue (cond_loc
, cond
, true, true);
7616 c_parser_consume_token (parser
);
7617 if (c_parser_next_token_is (parser
, CPP_COLON
))
7619 tree eptype
= NULL_TREE
;
7621 location_t middle_loc
= c_parser_peek_token (parser
)->location
;
7622 pedwarn (middle_loc
, OPT_Wpedantic
,
7623 "ISO C forbids omitting the middle term of a %<?:%> expression");
7624 if (TREE_CODE (cond
.value
) == EXCESS_PRECISION_EXPR
)
7626 eptype
= TREE_TYPE (cond
.value
);
7627 cond
.value
= TREE_OPERAND (cond
.value
, 0);
7629 tree e
= cond
.value
;
7630 while (TREE_CODE (e
) == COMPOUND_EXPR
)
7631 e
= TREE_OPERAND (e
, 1);
7632 warn_for_omitted_condop (middle_loc
, e
);
7633 /* Make sure first operand is calculated only once. */
7634 exp1
.value
= save_expr (default_conversion (cond
.value
));
7636 exp1
.value
= build1 (EXCESS_PRECISION_EXPR
, eptype
, exp1
.value
);
7637 exp1
.original_type
= NULL
;
7638 exp1
.src_range
= cond
.src_range
;
7639 cond
.value
= c_objc_common_truthvalue_conversion (cond_loc
, exp1
.value
);
7640 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_true_node
;
7645 = c_objc_common_truthvalue_conversion
7646 (cond_loc
, default_conversion (cond
.value
));
7647 c_inhibit_evaluation_warnings
+= cond
.value
== truthvalue_false_node
;
7648 exp1
= c_parser_expression_conv (parser
);
7649 mark_exp_read (exp1
.value
);
7650 c_inhibit_evaluation_warnings
+=
7651 ((cond
.value
== truthvalue_true_node
)
7652 - (cond
.value
== truthvalue_false_node
));
7655 colon_loc
= c_parser_peek_token (parser
)->location
;
7656 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
7658 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7660 ret
.original_code
= ERROR_MARK
;
7661 ret
.original_type
= NULL
;
7665 location_t exp2_loc
= c_parser_peek_token (parser
)->location
;
7666 exp2
= c_parser_conditional_expression (parser
, NULL
, NULL_TREE
);
7667 exp2
= convert_lvalue_to_rvalue (exp2_loc
, exp2
, true, true);
7669 c_inhibit_evaluation_warnings
-= cond
.value
== truthvalue_true_node
;
7670 location_t loc1
= make_location (exp1
.get_start (), exp1
.src_range
);
7671 location_t loc2
= make_location (exp2
.get_start (), exp2
.src_range
);
7672 if (__builtin_expect (omp_atomic_lhs
!= NULL
, 0)
7673 && (TREE_CODE (cond
.value
) == GT_EXPR
7674 || TREE_CODE (cond
.value
) == LT_EXPR
7675 || TREE_CODE (cond
.value
) == EQ_EXPR
)
7676 && c_tree_equal (exp2
.value
, omp_atomic_lhs
)
7677 && (c_tree_equal (TREE_OPERAND (cond
.value
, 0), omp_atomic_lhs
)
7678 || c_tree_equal (TREE_OPERAND (cond
.value
, 1), omp_atomic_lhs
)))
7679 ret
.value
= build3_loc (colon_loc
, COND_EXPR
, TREE_TYPE (omp_atomic_lhs
),
7680 cond
.value
, exp1
.value
, exp2
.value
);
7683 = build_conditional_expr (colon_loc
, cond
.value
,
7684 cond
.original_code
== C_MAYBE_CONST_EXPR
,
7685 exp1
.value
, exp1
.original_type
, loc1
,
7686 exp2
.value
, exp2
.original_type
, loc2
);
7687 ret
.original_code
= ERROR_MARK
;
7688 if (exp1
.value
== error_mark_node
|| exp2
.value
== error_mark_node
)
7689 ret
.original_type
= NULL
;
7694 /* If both sides are enum type, the default conversion will have
7695 made the type of the result be an integer type. We want to
7696 remember the enum types we started with. */
7697 t1
= exp1
.original_type
? exp1
.original_type
: TREE_TYPE (exp1
.value
);
7698 t2
= exp2
.original_type
? exp2
.original_type
: TREE_TYPE (exp2
.value
);
7699 ret
.original_type
= ((t1
!= error_mark_node
7700 && t2
!= error_mark_node
7701 && (TYPE_MAIN_VARIANT (t1
)
7702 == TYPE_MAIN_VARIANT (t2
)))
7706 set_c_expr_source_range (&ret
, start
, exp2
.get_finish ());
7710 /* Parse a binary expression; that is, a logical-OR-expression (C90
7711 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7712 NULL then it is an Objective-C message expression which is the
7713 primary-expression starting the expression as an initializer.
7715 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7716 when it should be the unfolded lhs. In a valid OpenMP source,
7717 one of the operands of the toplevel binary expression must be equal
7718 to it. In that case, just return a build2 created binary operation
7719 rather than result of parser_build_binary_op.
7721 multiplicative-expression:
7723 multiplicative-expression * cast-expression
7724 multiplicative-expression / cast-expression
7725 multiplicative-expression % cast-expression
7727 additive-expression:
7728 multiplicative-expression
7729 additive-expression + multiplicative-expression
7730 additive-expression - multiplicative-expression
7734 shift-expression << additive-expression
7735 shift-expression >> additive-expression
7737 relational-expression:
7739 relational-expression < shift-expression
7740 relational-expression > shift-expression
7741 relational-expression <= shift-expression
7742 relational-expression >= shift-expression
7744 equality-expression:
7745 relational-expression
7746 equality-expression == relational-expression
7747 equality-expression != relational-expression
7751 AND-expression & equality-expression
7753 exclusive-OR-expression:
7755 exclusive-OR-expression ^ AND-expression
7757 inclusive-OR-expression:
7758 exclusive-OR-expression
7759 inclusive-OR-expression | exclusive-OR-expression
7761 logical-AND-expression:
7762 inclusive-OR-expression
7763 logical-AND-expression && inclusive-OR-expression
7765 logical-OR-expression:
7766 logical-AND-expression
7767 logical-OR-expression || logical-AND-expression
7770 static struct c_expr
7771 c_parser_binary_expression (c_parser
*parser
, struct c_expr
*after
,
7772 tree omp_atomic_lhs
)
7774 /* A binary expression is parsed using operator-precedence parsing,
7775 with the operands being cast expressions. All the binary
7776 operators are left-associative. Thus a binary expression is of
7779 E0 op1 E1 op2 E2 ...
7781 which we represent on a stack. On the stack, the precedence
7782 levels are strictly increasing. When a new operator is
7783 encountered of higher precedence than that at the top of the
7784 stack, it is pushed; its LHS is the top expression, and its RHS
7785 is everything parsed until it is popped. When a new operator is
7786 encountered with precedence less than or equal to that at the top
7787 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7788 by the result of the operation until the operator at the top of
7789 the stack has lower precedence than the new operator or there is
7790 only one element on the stack; then the top expression is the LHS
7791 of the new operator. In the case of logical AND and OR
7792 expressions, we also need to adjust c_inhibit_evaluation_warnings
7793 as appropriate when the operators are pushed and popped. */
7796 /* The expression at this stack level. */
7798 /* The precedence of the operator on its left, PREC_NONE at the
7799 bottom of the stack. */
7800 enum c_parser_prec prec
;
7801 /* The operation on its left. */
7803 /* The source location of this operation. */
7805 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
7809 /* Location of the binary operator. */
7810 location_t binary_loc
= UNKNOWN_LOCATION
; /* Quiet warning. */
7813 switch (stack[sp].op) \
7815 case TRUTH_ANDIF_EXPR: \
7816 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7817 == truthvalue_false_node); \
7819 case TRUTH_ORIF_EXPR: \
7820 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7821 == truthvalue_true_node); \
7823 case TRUNC_DIV_EXPR: \
7824 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7825 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
7826 && (stack[sp].expr.original_code == SIZEOF_EXPR \
7827 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
7829 tree type0 = stack[sp - 1].sizeof_arg; \
7830 tree type1 = stack[sp].sizeof_arg; \
7831 tree first_arg = type0; \
7832 if (!TYPE_P (type0)) \
7833 type0 = TREE_TYPE (type0); \
7834 if (!TYPE_P (type1)) \
7835 type1 = TREE_TYPE (type1); \
7836 if (POINTER_TYPE_P (type0) \
7837 && comptypes (TREE_TYPE (type0), type1) \
7838 && !(TREE_CODE (first_arg) == PARM_DECL \
7839 && C_ARRAY_PARAMETER (first_arg) \
7840 && warn_sizeof_array_argument)) \
7842 auto_diagnostic_group d; \
7843 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7844 "division %<sizeof (%T) / sizeof (%T)%> " \
7845 "does not compute the number of array " \
7848 if (DECL_P (first_arg)) \
7849 inform (DECL_SOURCE_LOCATION (first_arg), \
7850 "first %<sizeof%> operand was declared here"); \
7852 else if (TREE_CODE (type0) == ARRAY_TYPE \
7853 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
7854 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
7855 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
7856 stack[sp].sizeof_arg, type1); \
7862 stack[sp - 1].expr \
7863 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7864 stack[sp - 1].expr, true, true); \
7866 = convert_lvalue_to_rvalue (stack[sp].loc, \
7867 stack[sp].expr, true, true); \
7868 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
7869 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
7870 && ((1 << stack[sp].prec) \
7871 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
7872 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
7873 | (1 << PREC_ADD) | (1 << PREC_MULT) \
7874 | (1 << PREC_EQ)))) \
7875 || ((c_parser_next_token_is (parser, CPP_QUERY) \
7876 || (omp_atomic_lhs == void_list_node \
7877 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
7878 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
7879 && stack[sp].op != TRUNC_MOD_EXPR \
7880 && stack[sp].op != GE_EXPR \
7881 && stack[sp].op != LE_EXPR \
7882 && stack[sp].op != NE_EXPR \
7883 && stack[0].expr.value != error_mark_node \
7884 && stack[1].expr.value != error_mark_node \
7885 && (omp_atomic_lhs == void_list_node \
7886 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7887 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
7888 || (stack[sp].op == EQ_EXPR \
7889 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
7891 tree t = make_node (stack[1].op); \
7892 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
7893 TREE_OPERAND (t, 0) = stack[0].expr.value; \
7894 TREE_OPERAND (t, 1) = stack[1].expr.value; \
7895 stack[0].expr.value = t; \
7898 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7900 stack[sp - 1].expr, \
7904 gcc_assert (!after
|| c_dialect_objc ());
7905 stack
[0].loc
= c_parser_peek_token (parser
)->location
;
7906 stack
[0].expr
= c_parser_cast_expression (parser
, after
);
7907 stack
[0].prec
= PREC_NONE
;
7908 stack
[0].sizeof_arg
= c_last_sizeof_arg
;
7912 enum c_parser_prec oprec
;
7913 enum tree_code ocode
;
7914 source_range src_range
;
7917 switch (c_parser_peek_token (parser
)->type
)
7925 ocode
= TRUNC_DIV_EXPR
;
7929 ocode
= TRUNC_MOD_EXPR
;
7941 ocode
= LSHIFT_EXPR
;
7945 ocode
= RSHIFT_EXPR
;
7959 case CPP_GREATER_EQ
:
7972 oprec
= PREC_BITAND
;
7973 ocode
= BIT_AND_EXPR
;
7976 oprec
= PREC_BITXOR
;
7977 ocode
= BIT_XOR_EXPR
;
7981 ocode
= BIT_IOR_EXPR
;
7984 oprec
= PREC_LOGAND
;
7985 ocode
= TRUTH_ANDIF_EXPR
;
7989 ocode
= TRUTH_ORIF_EXPR
;
7992 /* Not a binary operator, so end of the binary
7996 binary_loc
= c_parser_peek_token (parser
)->location
;
7997 while (oprec
<= stack
[sp
].prec
)
7999 c_parser_consume_token (parser
);
8002 case TRUTH_ANDIF_EXPR
:
8003 src_range
= stack
[sp
].expr
.src_range
;
8005 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
8006 stack
[sp
].expr
, true, true);
8007 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
8008 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
8009 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
8010 == truthvalue_false_node
);
8011 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
8013 case TRUTH_ORIF_EXPR
:
8014 src_range
= stack
[sp
].expr
.src_range
;
8016 = convert_lvalue_to_rvalue (stack
[sp
].loc
,
8017 stack
[sp
].expr
, true, true);
8018 stack
[sp
].expr
.value
= c_objc_common_truthvalue_conversion
8019 (stack
[sp
].loc
, default_conversion (stack
[sp
].expr
.value
));
8020 c_inhibit_evaluation_warnings
+= (stack
[sp
].expr
.value
8021 == truthvalue_true_node
);
8022 set_c_expr_source_range (&stack
[sp
].expr
, src_range
);
8028 stack
[sp
].loc
= binary_loc
;
8029 stack
[sp
].expr
= c_parser_cast_expression (parser
, NULL
);
8030 stack
[sp
].prec
= oprec
;
8031 stack
[sp
].op
= ocode
;
8032 stack
[sp
].sizeof_arg
= c_last_sizeof_arg
;
8037 return stack
[0].expr
;
8041 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8042 is not NULL then it is an Objective-C message expression which is the
8043 primary-expression starting the expression as an initializer.
8047 ( type-name ) unary-expression
8050 static struct c_expr
8051 c_parser_cast_expression (c_parser
*parser
, struct c_expr
*after
)
8053 location_t cast_loc
= c_parser_peek_token (parser
)->location
;
8054 gcc_assert (!after
|| c_dialect_objc ());
8056 return c_parser_postfix_expression_after_primary (parser
,
8058 /* If the expression begins with a parenthesized type name, it may
8059 be either a cast or a compound literal; we need to see whether
8060 the next character is '{' to tell the difference. If not, it is
8061 an unary expression. Full detection of unknown typenames here
8062 would require a 3-token lookahead. */
8063 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8064 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8066 struct c_type_name
*type_name
;
8069 matching_parens parens
;
8070 parens
.consume_open (parser
);
8071 type_name
= c_parser_type_name (parser
, true);
8072 parens
.skip_until_found_close (parser
);
8073 if (type_name
== NULL
)
8076 ret
.original_code
= ERROR_MARK
;
8077 ret
.original_type
= NULL
;
8081 /* Save casted types in the function's used types hash table. */
8082 used_types_insert (type_name
->specs
->type
);
8084 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8085 return c_parser_postfix_expression_after_paren_type (parser
, type_name
,
8087 if (type_name
->specs
->alignas_p
)
8088 error_at (type_name
->specs
->locations
[cdw_alignas
],
8089 "alignment specified for type name in cast");
8091 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
8092 expr
= c_parser_cast_expression (parser
, NULL
);
8093 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
8095 ret
.value
= c_cast_expr (cast_loc
, type_name
, expr
.value
);
8096 if (ret
.value
&& expr
.value
)
8097 set_c_expr_source_range (&ret
, cast_loc
, expr
.get_finish ());
8098 ret
.original_code
= ERROR_MARK
;
8099 ret
.original_type
= NULL
;
8103 return c_parser_unary_expression (parser
);
8106 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8112 unary-operator cast-expression
8113 sizeof unary-expression
8114 sizeof ( type-name )
8116 unary-operator: one of
8122 __alignof__ unary-expression
8123 __alignof__ ( type-name )
8126 (C11 permits _Alignof with type names only.)
8128 unary-operator: one of
8129 __extension__ __real__ __imag__
8131 Transactional Memory:
8134 transaction-expression
8136 In addition, the GNU syntax treats ++ and -- as unary operators, so
8137 they may be applied to cast expressions with errors for non-lvalues
8140 static struct c_expr
8141 c_parser_unary_expression (c_parser
*parser
)
8144 struct c_expr ret
, op
;
8145 location_t op_loc
= c_parser_peek_token (parser
)->location
;
8148 ret
.original_code
= ERROR_MARK
;
8149 ret
.original_type
= NULL
;
8150 switch (c_parser_peek_token (parser
)->type
)
8153 c_parser_consume_token (parser
);
8154 exp_loc
= c_parser_peek_token (parser
)->location
;
8155 op
= c_parser_cast_expression (parser
, NULL
);
8157 op
= default_function_array_read_conversion (exp_loc
, op
);
8158 return parser_build_unary_op (op_loc
, PREINCREMENT_EXPR
, op
);
8159 case CPP_MINUS_MINUS
:
8160 c_parser_consume_token (parser
);
8161 exp_loc
= c_parser_peek_token (parser
)->location
;
8162 op
= c_parser_cast_expression (parser
, NULL
);
8164 op
= default_function_array_read_conversion (exp_loc
, op
);
8165 return parser_build_unary_op (op_loc
, PREDECREMENT_EXPR
, op
);
8167 c_parser_consume_token (parser
);
8168 op
= c_parser_cast_expression (parser
, NULL
);
8169 mark_exp_read (op
.value
);
8170 return parser_build_unary_op (op_loc
, ADDR_EXPR
, op
);
8173 c_parser_consume_token (parser
);
8174 exp_loc
= c_parser_peek_token (parser
)->location
;
8175 op
= c_parser_cast_expression (parser
, NULL
);
8176 finish
= op
.get_finish ();
8177 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8178 location_t combined_loc
= make_location (op_loc
, op_loc
, finish
);
8179 ret
.value
= build_indirect_ref (combined_loc
, op
.value
, RO_UNARY_STAR
);
8180 ret
.src_range
.m_start
= op_loc
;
8181 ret
.src_range
.m_finish
= finish
;
8185 if (!c_dialect_objc () && !in_system_header_at (input_location
))
8188 "traditional C rejects the unary plus operator");
8189 c_parser_consume_token (parser
);
8190 exp_loc
= c_parser_peek_token (parser
)->location
;
8191 op
= c_parser_cast_expression (parser
, NULL
);
8192 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8193 return parser_build_unary_op (op_loc
, CONVERT_EXPR
, op
);
8195 c_parser_consume_token (parser
);
8196 exp_loc
= c_parser_peek_token (parser
)->location
;
8197 op
= c_parser_cast_expression (parser
, NULL
);
8198 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8199 return parser_build_unary_op (op_loc
, NEGATE_EXPR
, op
);
8201 c_parser_consume_token (parser
);
8202 exp_loc
= c_parser_peek_token (parser
)->location
;
8203 op
= c_parser_cast_expression (parser
, NULL
);
8204 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8205 return parser_build_unary_op (op_loc
, BIT_NOT_EXPR
, op
);
8207 c_parser_consume_token (parser
);
8208 exp_loc
= c_parser_peek_token (parser
)->location
;
8209 op
= c_parser_cast_expression (parser
, NULL
);
8210 op
= convert_lvalue_to_rvalue (exp_loc
, op
, true, true);
8211 return parser_build_unary_op (op_loc
, TRUTH_NOT_EXPR
, op
);
8213 /* Refer to the address of a label as a pointer. */
8214 c_parser_consume_token (parser
);
8215 if (c_parser_next_token_is (parser
, CPP_NAME
))
8217 ret
.value
= finish_label_address_expr
8218 (c_parser_peek_token (parser
)->value
, op_loc
);
8219 set_c_expr_source_range (&ret
, op_loc
,
8220 c_parser_peek_token (parser
)->get_finish ());
8221 c_parser_consume_token (parser
);
8225 c_parser_error (parser
, "expected identifier");
8230 switch (c_parser_peek_token (parser
)->keyword
)
8233 return c_parser_sizeof_expression (parser
);
8235 return c_parser_alignof_expression (parser
);
8236 case RID_BUILTIN_HAS_ATTRIBUTE
:
8237 return c_parser_has_attribute_expression (parser
);
8239 c_parser_consume_token (parser
);
8240 ext
= disable_extension_diagnostics ();
8241 ret
= c_parser_cast_expression (parser
, NULL
);
8242 restore_extension_diagnostics (ext
);
8245 c_parser_consume_token (parser
);
8246 exp_loc
= c_parser_peek_token (parser
)->location
;
8247 op
= c_parser_cast_expression (parser
, NULL
);
8248 op
= default_function_array_conversion (exp_loc
, op
);
8249 return parser_build_unary_op (op_loc
, REALPART_EXPR
, op
);
8251 c_parser_consume_token (parser
);
8252 exp_loc
= c_parser_peek_token (parser
)->location
;
8253 op
= c_parser_cast_expression (parser
, NULL
);
8254 op
= default_function_array_conversion (exp_loc
, op
);
8255 return parser_build_unary_op (op_loc
, IMAGPART_EXPR
, op
);
8256 case RID_TRANSACTION_ATOMIC
:
8257 case RID_TRANSACTION_RELAXED
:
8258 return c_parser_transaction_expression (parser
,
8259 c_parser_peek_token (parser
)->keyword
);
8261 return c_parser_postfix_expression (parser
);
8264 return c_parser_postfix_expression (parser
);
8268 /* Parse a sizeof expression. */
8270 static struct c_expr
8271 c_parser_sizeof_expression (c_parser
*parser
)
8274 struct c_expr result
;
8275 location_t expr_loc
;
8276 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_SIZEOF
));
8279 location_t finish
= UNKNOWN_LOCATION
;
8281 start
= c_parser_peek_token (parser
)->location
;
8283 c_parser_consume_token (parser
);
8284 c_inhibit_evaluation_warnings
++;
8286 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8287 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8289 /* Either sizeof ( type-name ) or sizeof unary-expression
8290 starting with a compound literal. */
8291 struct c_type_name
*type_name
;
8292 matching_parens parens
;
8293 parens
.consume_open (parser
);
8294 expr_loc
= c_parser_peek_token (parser
)->location
;
8295 type_name
= c_parser_type_name (parser
, true);
8296 parens
.skip_until_found_close (parser
);
8297 finish
= parser
->tokens_buf
[0].location
;
8298 if (type_name
== NULL
)
8301 c_inhibit_evaluation_warnings
--;
8304 ret
.original_code
= ERROR_MARK
;
8305 ret
.original_type
= NULL
;
8308 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8310 expr
= c_parser_postfix_expression_after_paren_type (parser
,
8313 finish
= expr
.get_finish ();
8316 /* sizeof ( type-name ). */
8317 if (type_name
->specs
->alignas_p
)
8318 error_at (type_name
->specs
->locations
[cdw_alignas
],
8319 "alignment specified for type name in %<sizeof%>");
8320 c_inhibit_evaluation_warnings
--;
8322 result
= c_expr_sizeof_type (expr_loc
, type_name
);
8326 expr_loc
= c_parser_peek_token (parser
)->location
;
8327 expr
= c_parser_unary_expression (parser
);
8328 finish
= expr
.get_finish ();
8330 c_inhibit_evaluation_warnings
--;
8332 mark_exp_read (expr
.value
);
8333 if (TREE_CODE (expr
.value
) == COMPONENT_REF
8334 && DECL_C_BIT_FIELD (TREE_OPERAND (expr
.value
, 1)))
8335 error_at (expr_loc
, "%<sizeof%> applied to a bit-field");
8336 result
= c_expr_sizeof_expr (expr_loc
, expr
);
8338 if (finish
== UNKNOWN_LOCATION
)
8340 set_c_expr_source_range (&result
, start
, finish
);
8344 /* Parse an alignof expression. */
8346 static struct c_expr
8347 c_parser_alignof_expression (c_parser
*parser
)
8350 location_t start_loc
= c_parser_peek_token (parser
)->location
;
8352 tree alignof_spelling
= c_parser_peek_token (parser
)->value
;
8353 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_ALIGNOF
));
8354 bool is_c11_alignof
= strcmp (IDENTIFIER_POINTER (alignof_spelling
),
8356 /* A diagnostic is not required for the use of this identifier in
8357 the implementation namespace; only diagnose it for the C11
8358 spelling because of existing code using the other spellings. */
8362 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C99 does not support %qE",
8365 pedwarn_c99 (start_loc
, OPT_Wpedantic
, "ISO C90 does not support %qE",
8368 c_parser_consume_token (parser
);
8369 c_inhibit_evaluation_warnings
++;
8371 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
)
8372 && c_token_starts_typename (c_parser_peek_2nd_token (parser
)))
8374 /* Either __alignof__ ( type-name ) or __alignof__
8375 unary-expression starting with a compound literal. */
8377 struct c_type_name
*type_name
;
8379 matching_parens parens
;
8380 parens
.consume_open (parser
);
8381 loc
= c_parser_peek_token (parser
)->location
;
8382 type_name
= c_parser_type_name (parser
, true);
8383 end_loc
= c_parser_peek_token (parser
)->location
;
8384 parens
.skip_until_found_close (parser
);
8385 if (type_name
== NULL
)
8388 c_inhibit_evaluation_warnings
--;
8391 ret
.original_code
= ERROR_MARK
;
8392 ret
.original_type
= NULL
;
8395 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
8397 expr
= c_parser_postfix_expression_after_paren_type (parser
,
8402 /* alignof ( type-name ). */
8403 if (type_name
->specs
->alignas_p
)
8404 error_at (type_name
->specs
->locations
[cdw_alignas
],
8405 "alignment specified for type name in %qE",
8407 c_inhibit_evaluation_warnings
--;
8409 ret
.value
= c_sizeof_or_alignof_type (loc
, groktypename (type_name
,
8411 false, is_c11_alignof
, 1);
8412 ret
.original_code
= ERROR_MARK
;
8413 ret
.original_type
= NULL
;
8414 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
8420 expr
= c_parser_unary_expression (parser
);
8421 end_loc
= expr
.src_range
.m_finish
;
8423 mark_exp_read (expr
.value
);
8424 c_inhibit_evaluation_warnings
--;
8428 OPT_Wpedantic
, "ISO C does not allow %<%E (expression)%>",
8430 ret
.value
= c_alignof_expr (start_loc
, expr
.value
);
8431 ret
.original_code
= ERROR_MARK
;
8432 ret
.original_type
= NULL
;
8433 set_c_expr_source_range (&ret
, start_loc
, end_loc
);
8438 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8441 static struct c_expr
8442 c_parser_has_attribute_expression (c_parser
*parser
)
8444 gcc_assert (c_parser_next_token_is_keyword (parser
,
8445 RID_BUILTIN_HAS_ATTRIBUTE
));
8446 location_t start
= c_parser_peek_token (parser
)->location
;
8447 c_parser_consume_token (parser
);
8449 c_inhibit_evaluation_warnings
++;
8451 matching_parens parens
;
8452 if (!parens
.require_open (parser
))
8454 c_inhibit_evaluation_warnings
--;
8457 struct c_expr result
;
8458 result
.set_error ();
8459 result
.original_code
= ERROR_MARK
;
8460 result
.original_type
= NULL
;
8464 /* Treat the type argument the same way as in typeof for the purposes
8465 of warnings. FIXME: Generalize this so the warning refers to
8466 __builtin_has_attribute rather than typeof. */
8469 /* The first operand: one of DECL, EXPR, or TYPE. */
8470 tree oper
= NULL_TREE
;
8471 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
8473 struct c_type_name
*tname
= c_parser_type_name (parser
);
8477 oper
= groktypename (tname
, NULL
, NULL
);
8478 pop_maybe_used (variably_modified_type_p (oper
, NULL_TREE
));
8483 struct c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
8484 c_inhibit_evaluation_warnings
--;
8486 if (cexpr
.value
!= error_mark_node
)
8488 mark_exp_read (cexpr
.value
);
8490 tree etype
= TREE_TYPE (oper
);
8491 bool was_vm
= variably_modified_type_p (etype
, NULL_TREE
);
8492 /* This is returned with the type so that when the type is
8493 evaluated, this can be evaluated. */
8495 oper
= c_fully_fold (oper
, false, NULL
);
8496 pop_maybe_used (was_vm
);
8500 struct c_expr result
;
8501 result
.original_code
= ERROR_MARK
;
8502 result
.original_type
= NULL
;
8504 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8506 /* Consume the closing parenthesis if that's the next token
8507 in the likely case the built-in was invoked with fewer
8508 than two arguments. */
8509 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8510 c_parser_consume_token (parser
);
8511 c_inhibit_evaluation_warnings
--;
8512 result
.set_error ();
8516 bool save_translate_strings_p
= parser
->translate_strings_p
;
8518 location_t atloc
= c_parser_peek_token (parser
)->location
;
8519 /* Parse a single attribute. Require no leading comma and do not
8520 allow empty attributes. */
8521 tree attr
= c_parser_gnu_attribute (parser
, NULL_TREE
, false, false);
8523 parser
->translate_strings_p
= save_translate_strings_p
;
8525 location_t finish
= c_parser_peek_token (parser
)->location
;
8526 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8527 c_parser_consume_token (parser
);
8530 c_parser_error (parser
, "expected identifier");
8531 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8533 result
.set_error ();
8539 error_at (atloc
, "expected identifier");
8540 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
8542 result
.set_error ();
8546 result
.original_code
= INTEGER_CST
;
8547 result
.original_type
= boolean_type_node
;
8549 if (has_attribute (atloc
, oper
, attr
, default_conversion
))
8550 result
.value
= boolean_true_node
;
8552 result
.value
= boolean_false_node
;
8554 set_c_expr_source_range (&result
, start
, finish
);
8558 /* Helper function to read arguments of builtins which are interfaces
8559 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8560 others. The name of the builtin is passed using BNAME parameter.
8561 Function returns true if there were no errors while parsing and
8562 stores the arguments in CEXPR_LIST. If it returns true,
8563 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8566 c_parser_get_builtin_args (c_parser
*parser
, const char *bname
,
8567 vec
<c_expr_t
, va_gc
> **ret_cexpr_list
,
8569 location_t
*out_close_paren_loc
)
8571 location_t loc
= c_parser_peek_token (parser
)->location
;
8572 vec
<c_expr_t
, va_gc
> *cexpr_list
;
8574 bool saved_force_folding_builtin_constant_p
;
8576 *ret_cexpr_list
= NULL
;
8577 if (c_parser_next_token_is_not (parser
, CPP_OPEN_PAREN
))
8579 error_at (loc
, "cannot take address of %qs", bname
);
8583 c_parser_consume_token (parser
);
8585 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
8587 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
8588 c_parser_consume_token (parser
);
8592 saved_force_folding_builtin_constant_p
8593 = force_folding_builtin_constant_p
;
8594 force_folding_builtin_constant_p
|= choose_expr_p
;
8595 expr
= c_parser_expr_no_commas (parser
, NULL
);
8596 force_folding_builtin_constant_p
8597 = saved_force_folding_builtin_constant_p
;
8598 vec_alloc (cexpr_list
, 1);
8599 vec_safe_push (cexpr_list
, expr
);
8600 while (c_parser_next_token_is (parser
, CPP_COMMA
))
8602 c_parser_consume_token (parser
);
8603 expr
= c_parser_expr_no_commas (parser
, NULL
);
8604 vec_safe_push (cexpr_list
, expr
);
8607 *out_close_paren_loc
= c_parser_peek_token (parser
)->location
;
8608 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
8611 *ret_cexpr_list
= cexpr_list
;
8615 /* This represents a single generic-association. */
8617 struct c_generic_association
8619 /* The location of the starting token of the type. */
8620 location_t type_location
;
8621 /* The association's type, or NULL_TREE for 'default'. */
8623 /* The association's expression. */
8624 struct c_expr expression
;
8627 /* Parse a generic-selection. (C11 6.5.1.1).
8630 _Generic ( assignment-expression , generic-assoc-list )
8634 generic-assoc-list , generic-association
8636 generic-association:
8637 type-name : assignment-expression
8638 default : assignment-expression
8641 static struct c_expr
8642 c_parser_generic_selection (c_parser
*parser
)
8644 struct c_expr selector
, error_expr
;
8646 struct c_generic_association matched_assoc
;
8647 int match_found
= -1;
8648 location_t generic_loc
, selector_loc
;
8650 error_expr
.original_code
= ERROR_MARK
;
8651 error_expr
.original_type
= NULL
;
8652 error_expr
.set_error ();
8653 matched_assoc
.type_location
= UNKNOWN_LOCATION
;
8654 matched_assoc
.type
= NULL_TREE
;
8655 matched_assoc
.expression
= error_expr
;
8657 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_GENERIC
));
8658 generic_loc
= c_parser_peek_token (parser
)->location
;
8659 c_parser_consume_token (parser
);
8661 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
8662 "ISO C99 does not support %<_Generic%>");
8664 pedwarn_c99 (generic_loc
, OPT_Wpedantic
,
8665 "ISO C90 does not support %<_Generic%>");
8667 matching_parens parens
;
8668 if (!parens
.require_open (parser
))
8671 c_inhibit_evaluation_warnings
++;
8672 selector_loc
= c_parser_peek_token (parser
)->location
;
8673 selector
= c_parser_expr_no_commas (parser
, NULL
);
8674 selector
= default_function_array_conversion (selector_loc
, selector
);
8675 c_inhibit_evaluation_warnings
--;
8677 if (selector
.value
== error_mark_node
)
8679 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8682 mark_exp_read (selector
.value
);
8683 selector_type
= TREE_TYPE (selector
.value
);
8684 /* In ISO C terms, rvalues (including the controlling expression of
8685 _Generic) do not have qualified types. */
8686 if (TREE_CODE (selector_type
) != ARRAY_TYPE
)
8687 selector_type
= TYPE_MAIN_VARIANT (selector_type
);
8688 /* In ISO C terms, _Noreturn is not part of the type of expressions
8689 such as &abort, but in GCC it is represented internally as a type
8691 if (FUNCTION_POINTER_TYPE_P (selector_type
)
8692 && TYPE_QUALS (TREE_TYPE (selector_type
)) != TYPE_UNQUALIFIED
)
8694 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type
)));
8696 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
8698 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8702 auto_vec
<c_generic_association
> associations
;
8705 struct c_generic_association assoc
, *iter
;
8707 c_token
*token
= c_parser_peek_token (parser
);
8709 assoc
.type_location
= token
->location
;
8710 if (token
->type
== CPP_KEYWORD
&& token
->keyword
== RID_DEFAULT
)
8712 c_parser_consume_token (parser
);
8713 assoc
.type
= NULL_TREE
;
8717 struct c_type_name
*type_name
;
8719 type_name
= c_parser_type_name (parser
);
8720 if (type_name
== NULL
)
8722 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8725 assoc
.type
= groktypename (type_name
, NULL
, NULL
);
8726 if (assoc
.type
== error_mark_node
)
8728 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8732 if (TREE_CODE (assoc
.type
) == FUNCTION_TYPE
)
8733 error_at (assoc
.type_location
,
8734 "%<_Generic%> association has function type");
8735 else if (!COMPLETE_TYPE_P (assoc
.type
))
8736 error_at (assoc
.type_location
,
8737 "%<_Generic%> association has incomplete type");
8739 if (variably_modified_type_p (assoc
.type
, NULL_TREE
))
8740 error_at (assoc
.type_location
,
8741 "%<_Generic%> association has "
8742 "variable length type");
8745 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
8747 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8751 assoc
.expression
= c_parser_expr_no_commas (parser
, NULL
);
8752 if (assoc
.expression
.value
== error_mark_node
)
8754 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8758 for (ix
= 0; associations
.iterate (ix
, &iter
); ++ix
)
8760 if (assoc
.type
== NULL_TREE
)
8762 if (iter
->type
== NULL_TREE
)
8764 error_at (assoc
.type_location
,
8765 "duplicate %<default%> case in %<_Generic%>");
8766 inform (iter
->type_location
, "original %<default%> is here");
8769 else if (iter
->type
!= NULL_TREE
)
8771 if (comptypes (assoc
.type
, iter
->type
))
8773 error_at (assoc
.type_location
,
8774 "%<_Generic%> specifies two compatible types");
8775 inform (iter
->type_location
, "compatible type is here");
8780 if (assoc
.type
== NULL_TREE
)
8782 if (match_found
< 0)
8784 matched_assoc
= assoc
;
8785 match_found
= associations
.length ();
8788 else if (comptypes (assoc
.type
, selector_type
))
8790 if (match_found
< 0 || matched_assoc
.type
== NULL_TREE
)
8792 matched_assoc
= assoc
;
8793 match_found
= associations
.length ();
8797 error_at (assoc
.type_location
,
8798 "%<_Generic%> selector matches multiple associations");
8799 inform (matched_assoc
.type_location
,
8800 "other match is here");
8804 associations
.safe_push (assoc
);
8806 if (c_parser_peek_token (parser
)->type
!= CPP_COMMA
)
8808 c_parser_consume_token (parser
);
8812 struct c_generic_association
*iter
;
8813 FOR_EACH_VEC_ELT (associations
, ix
, iter
)
8814 if (ix
!= (unsigned) match_found
)
8815 mark_exp_read (iter
->expression
.value
);
8817 if (!parens
.require_close (parser
))
8819 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
8823 if (match_found
< 0)
8825 error_at (selector_loc
, "%<_Generic%> selector of type %qT is not "
8826 "compatible with any association",
8831 return matched_assoc
.expression
;
8834 /* Check the validity of a function pointer argument *EXPR (argument
8835 position POS) to __builtin_tgmath. Return the number of function
8836 arguments if possibly valid; return 0 having reported an error if
8840 check_tgmath_function (c_expr
*expr
, unsigned int pos
)
8842 tree type
= TREE_TYPE (expr
->value
);
8843 if (!FUNCTION_POINTER_TYPE_P (type
))
8845 error_at (expr
->get_location (),
8846 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8850 type
= TREE_TYPE (type
);
8851 if (!prototype_p (type
))
8853 error_at (expr
->get_location (),
8854 "argument %u of %<__builtin_tgmath%> is unprototyped", pos
);
8857 if (stdarg_p (type
))
8859 error_at (expr
->get_location (),
8860 "argument %u of %<__builtin_tgmath%> has variable arguments",
8864 unsigned int nargs
= 0;
8865 function_args_iterator iter
;
8867 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
8869 if (t
== void_type_node
)
8875 error_at (expr
->get_location (),
8876 "argument %u of %<__builtin_tgmath%> has no arguments", pos
);
8882 /* Ways in which a parameter or return value of a type-generic macro
8883 may vary between the different functions the macro may call. */
8884 enum tgmath_parm_kind
8886 tgmath_fixed
, tgmath_real
, tgmath_complex
8889 /* Helper function for c_parser_postfix_expression. Parse predefined
8892 static struct c_expr
8893 c_parser_predefined_identifier (c_parser
*parser
)
8895 location_t loc
= c_parser_peek_token (parser
)->location
;
8896 switch (c_parser_peek_token (parser
)->keyword
)
8898 case RID_FUNCTION_NAME
:
8899 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
8900 "identifier", "__FUNCTION__");
8902 case RID_PRETTY_FUNCTION_NAME
:
8903 pedwarn (loc
, OPT_Wpedantic
, "ISO C does not support %qs predefined "
8904 "identifier", "__PRETTY_FUNCTION__");
8906 case RID_C99_FUNCTION_NAME
:
8907 pedwarn_c90 (loc
, OPT_Wpedantic
, "ISO C90 does not support "
8908 "%<__func__%> predefined identifier");
8915 expr
.original_code
= ERROR_MARK
;
8916 expr
.original_type
= NULL
;
8917 expr
.value
= fname_decl (loc
, c_parser_peek_token (parser
)->keyword
,
8918 c_parser_peek_token (parser
)->value
);
8919 set_c_expr_source_range (&expr
, loc
, loc
);
8920 c_parser_consume_token (parser
);
8924 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8925 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8926 call c_parser_postfix_expression_after_paren_type on encountering them.
8930 postfix-expression [ expression ]
8931 postfix-expression ( argument-expression-list[opt] )
8932 postfix-expression . identifier
8933 postfix-expression -> identifier
8934 postfix-expression ++
8935 postfix-expression --
8936 ( type-name ) { initializer-list }
8937 ( type-name ) { initializer-list , }
8939 argument-expression-list:
8941 argument-expression-list , argument-expression
8954 (treated as a keyword in GNU C)
8957 ( compound-statement )
8958 __builtin_va_arg ( assignment-expression , type-name )
8959 __builtin_offsetof ( type-name , offsetof-member-designator )
8960 __builtin_choose_expr ( assignment-expression ,
8961 assignment-expression ,
8962 assignment-expression )
8963 __builtin_types_compatible_p ( type-name , type-name )
8964 __builtin_tgmath ( expr-list )
8965 __builtin_complex ( assignment-expression , assignment-expression )
8966 __builtin_shuffle ( assignment-expression , assignment-expression )
8967 __builtin_shuffle ( assignment-expression ,
8968 assignment-expression ,
8969 assignment-expression, )
8970 __builtin_convertvector ( assignment-expression , type-name )
8971 __builtin_assoc_barrier ( assignment-expression )
8973 offsetof-member-designator:
8975 offsetof-member-designator . identifier
8976 offsetof-member-designator [ expression ]
8981 [ objc-receiver objc-message-args ]
8982 @selector ( objc-selector-arg )
8983 @protocol ( identifier )
8984 @encode ( type-name )
8986 Classname . identifier
8989 static struct c_expr
8990 c_parser_postfix_expression (c_parser
*parser
)
8992 struct c_expr expr
, e1
;
8993 struct c_type_name
*t1
, *t2
;
8994 location_t loc
= c_parser_peek_token (parser
)->location
;
8995 source_range tok_range
= c_parser_peek_token (parser
)->get_range ();
8996 expr
.original_code
= ERROR_MARK
;
8997 expr
.original_type
= NULL
;
8998 switch (c_parser_peek_token (parser
)->type
)
9001 expr
.value
= c_parser_peek_token (parser
)->value
;
9002 set_c_expr_source_range (&expr
, tok_range
);
9003 loc
= c_parser_peek_token (parser
)->location
;
9004 c_parser_consume_token (parser
);
9005 if (TREE_CODE (expr
.value
) == FIXED_CST
9006 && !targetm
.fixed_point_supported_p ())
9008 error_at (loc
, "fixed-point types not supported for this target");
9017 expr
.value
= c_parser_peek_token (parser
)->value
;
9018 /* For the purpose of warning when a pointer is compared with
9019 a zero character constant. */
9020 expr
.original_type
= char_type_node
;
9021 set_c_expr_source_range (&expr
, tok_range
);
9022 c_parser_consume_token (parser
);
9028 case CPP_UTF8STRING
:
9029 expr
= c_parser_string_literal (parser
, parser
->translate_strings_p
,
9032 case CPP_OBJC_STRING
:
9033 gcc_assert (c_dialect_objc ());
9035 = objc_build_string_object (c_parser_peek_token (parser
)->value
);
9036 set_c_expr_source_range (&expr
, tok_range
);
9037 c_parser_consume_token (parser
);
9040 switch (c_parser_peek_token (parser
)->id_kind
)
9044 tree id
= c_parser_peek_token (parser
)->value
;
9045 c_parser_consume_token (parser
);
9046 expr
.value
= build_external_ref (loc
, id
,
9047 (c_parser_peek_token (parser
)->type
9049 &expr
.original_type
);
9050 set_c_expr_source_range (&expr
, tok_range
);
9053 case C_ID_CLASSNAME
:
9055 /* Here we parse the Objective-C 2.0 Class.name dot
9057 tree class_name
= c_parser_peek_token (parser
)->value
;
9059 c_parser_consume_token (parser
);
9060 gcc_assert (c_dialect_objc ());
9061 if (!c_parser_require (parser
, CPP_DOT
, "expected %<.%>"))
9066 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
9068 c_parser_error (parser
, "expected identifier");
9072 c_token
*component_tok
= c_parser_peek_token (parser
);
9073 component
= component_tok
->value
;
9074 location_t end_loc
= component_tok
->get_finish ();
9075 c_parser_consume_token (parser
);
9076 expr
.value
= objc_build_class_component_ref (class_name
,
9078 set_c_expr_source_range (&expr
, loc
, end_loc
);
9082 c_parser_error (parser
, "expected expression");
9087 case CPP_OPEN_PAREN
:
9088 /* A parenthesized expression, statement expression or compound
9090 if (c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_BRACE
)
9092 /* A statement expression. */
9094 location_t brace_loc
;
9095 c_parser_consume_token (parser
);
9096 brace_loc
= c_parser_peek_token (parser
)->location
;
9097 c_parser_consume_token (parser
);
9098 /* If we've not yet started the current function's statement list,
9099 or we're in the parameter scope of an old-style function
9100 declaration, statement expressions are not allowed. */
9101 if (!building_stmt_list_p () || old_style_parameter_scope ())
9103 error_at (loc
, "braced-group within expression allowed "
9104 "only inside a function");
9105 parser
->error
= true;
9106 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
, NULL
);
9107 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9111 stmt
= c_begin_stmt_expr ();
9112 c_parser_compound_statement_nostart (parser
);
9113 location_t close_loc
= c_parser_peek_token (parser
)->location
;
9114 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9116 pedwarn (loc
, OPT_Wpedantic
,
9117 "ISO C forbids braced-groups within expressions");
9118 expr
.value
= c_finish_stmt_expr (brace_loc
, stmt
);
9119 set_c_expr_source_range (&expr
, loc
, close_loc
);
9120 mark_exp_read (expr
.value
);
9124 /* A parenthesized expression. */
9125 location_t loc_open_paren
= c_parser_peek_token (parser
)->location
;
9126 c_parser_consume_token (parser
);
9127 expr
= c_parser_expression (parser
);
9128 if (TREE_CODE (expr
.value
) == MODIFY_EXPR
)
9129 suppress_warning (expr
.value
, OPT_Wparentheses
);
9130 if (expr
.original_code
!= C_MAYBE_CONST_EXPR
9131 && expr
.original_code
!= SIZEOF_EXPR
)
9132 expr
.original_code
= ERROR_MARK
;
9133 /* Remember that we saw ( ) around the sizeof. */
9134 if (expr
.original_code
== SIZEOF_EXPR
)
9135 expr
.original_code
= PAREN_SIZEOF_EXPR
;
9136 /* Don't change EXPR.ORIGINAL_TYPE. */
9137 location_t loc_close_paren
= c_parser_peek_token (parser
)->location
;
9138 set_c_expr_source_range (&expr
, loc_open_paren
, loc_close_paren
);
9139 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9140 "expected %<)%>", loc_open_paren
);
9144 switch (c_parser_peek_token (parser
)->keyword
)
9146 case RID_FUNCTION_NAME
:
9147 case RID_PRETTY_FUNCTION_NAME
:
9148 case RID_C99_FUNCTION_NAME
:
9149 expr
= c_parser_predefined_identifier (parser
);
9153 location_t start_loc
= loc
;
9154 c_parser_consume_token (parser
);
9155 matching_parens parens
;
9156 if (!parens
.require_open (parser
))
9161 e1
= c_parser_expr_no_commas (parser
, NULL
);
9162 mark_exp_read (e1
.value
);
9163 e1
.value
= c_fully_fold (e1
.value
, false, NULL
);
9164 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9166 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9170 loc
= c_parser_peek_token (parser
)->location
;
9171 t1
= c_parser_type_name (parser
);
9172 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9173 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9181 tree type_expr
= NULL_TREE
;
9182 expr
.value
= c_build_va_arg (start_loc
, e1
.value
, loc
,
9183 groktypename (t1
, &type_expr
, NULL
));
9186 expr
.value
= build2 (C_MAYBE_CONST_EXPR
,
9187 TREE_TYPE (expr
.value
), type_expr
,
9189 C_MAYBE_CONST_EXPR_NON_CONST (expr
.value
) = true;
9191 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
9197 c_parser_consume_token (parser
);
9198 matching_parens parens
;
9199 if (!parens
.require_open (parser
))
9204 t1
= c_parser_type_name (parser
);
9206 parser
->error
= true;
9207 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9208 gcc_assert (parser
->error
);
9211 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9215 tree type
= groktypename (t1
, NULL
, NULL
);
9217 if (type
== error_mark_node
)
9218 offsetof_ref
= error_mark_node
;
9221 offsetof_ref
= build1 (INDIRECT_REF
, type
, null_pointer_node
);
9222 SET_EXPR_LOCATION (offsetof_ref
, loc
);
9224 /* Parse the second argument to __builtin_offsetof. We
9225 must have one identifier, and beyond that we want to
9226 accept sub structure and sub array references. */
9227 if (c_parser_next_token_is (parser
, CPP_NAME
))
9229 c_token
*comp_tok
= c_parser_peek_token (parser
);
9230 offsetof_ref
= build_component_ref
9231 (loc
, offsetof_ref
, comp_tok
->value
, comp_tok
->location
);
9232 c_parser_consume_token (parser
);
9233 while (c_parser_next_token_is (parser
, CPP_DOT
)
9234 || c_parser_next_token_is (parser
,
9236 || c_parser_next_token_is (parser
,
9239 if (c_parser_next_token_is (parser
, CPP_DEREF
))
9241 loc
= c_parser_peek_token (parser
)->location
;
9242 offsetof_ref
= build_array_ref (loc
,
9247 else if (c_parser_next_token_is (parser
, CPP_DOT
))
9250 c_parser_consume_token (parser
);
9251 if (c_parser_next_token_is_not (parser
,
9254 c_parser_error (parser
, "expected identifier");
9257 c_token
*comp_tok
= c_parser_peek_token (parser
);
9258 offsetof_ref
= build_component_ref
9259 (loc
, offsetof_ref
, comp_tok
->value
,
9260 comp_tok
->location
);
9261 c_parser_consume_token (parser
);
9267 loc
= c_parser_peek_token (parser
)->location
;
9268 c_parser_consume_token (parser
);
9269 ce
= c_parser_expression (parser
);
9270 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
9272 idx
= c_fully_fold (idx
, false, NULL
);
9273 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
9275 offsetof_ref
= build_array_ref (loc
, offsetof_ref
, idx
);
9280 c_parser_error (parser
, "expected identifier");
9281 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
9282 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
9284 expr
.value
= fold_offsetof (offsetof_ref
);
9285 set_c_expr_source_range (&expr
, loc
, end_loc
);
9288 case RID_CHOOSE_EXPR
:
9290 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9291 c_expr_t
*e1_p
, *e2_p
, *e3_p
;
9293 location_t close_paren_loc
;
9295 c_parser_consume_token (parser
);
9296 if (!c_parser_get_builtin_args (parser
,
9297 "__builtin_choose_expr",
9305 if (vec_safe_length (cexpr_list
) != 3)
9307 error_at (loc
, "wrong number of arguments to "
9308 "%<__builtin_choose_expr%>");
9313 e1_p
= &(*cexpr_list
)[0];
9314 e2_p
= &(*cexpr_list
)[1];
9315 e3_p
= &(*cexpr_list
)[2];
9318 mark_exp_read (e2_p
->value
);
9319 mark_exp_read (e3_p
->value
);
9320 if (TREE_CODE (c
) != INTEGER_CST
9321 || !INTEGRAL_TYPE_P (TREE_TYPE (c
)))
9323 "first argument to %<__builtin_choose_expr%> not"
9325 constant_expression_warning (c
);
9326 expr
= integer_zerop (c
) ? *e3_p
: *e2_p
;
9327 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9330 case RID_TYPES_COMPATIBLE_P
:
9332 c_parser_consume_token (parser
);
9333 matching_parens parens
;
9334 if (!parens
.require_open (parser
))
9339 t1
= c_parser_type_name (parser
);
9345 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
9347 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
9351 t2
= c_parser_type_name (parser
);
9357 location_t close_paren_loc
= c_parser_peek_token (parser
)->location
;
9358 parens
.skip_until_found_close (parser
);
9360 e1
= groktypename (t1
, NULL
, NULL
);
9361 e2
= groktypename (t2
, NULL
, NULL
);
9362 if (e1
== error_mark_node
|| e2
== error_mark_node
)
9368 e1
= TYPE_MAIN_VARIANT (e1
);
9369 e2
= TYPE_MAIN_VARIANT (e2
);
9372 = comptypes (e1
, e2
) ? integer_one_node
: integer_zero_node
;
9373 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9376 case RID_BUILTIN_TGMATH
:
9378 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9379 location_t close_paren_loc
;
9381 c_parser_consume_token (parser
);
9382 if (!c_parser_get_builtin_args (parser
,
9391 if (vec_safe_length (cexpr_list
) < 3)
9393 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9400 FOR_EACH_VEC_ELT (*cexpr_list
, i
, p
)
9401 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
9402 unsigned int nargs
= check_tgmath_function (&(*cexpr_list
)[0], 1);
9408 if (vec_safe_length (cexpr_list
) < nargs
)
9410 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9414 unsigned int num_functions
= vec_safe_length (cexpr_list
) - nargs
;
9415 if (num_functions
< 2)
9417 error_at (loc
, "too few arguments to %<__builtin_tgmath%>");
9422 /* The first NUM_FUNCTIONS expressions are the function
9423 pointers. The remaining NARGS expressions are the
9424 arguments that are to be passed to one of those
9425 functions, chosen following <tgmath.h> rules. */
9426 for (unsigned int j
= 1; j
< num_functions
; j
++)
9428 unsigned int this_nargs
9429 = check_tgmath_function (&(*cexpr_list
)[j
], j
+ 1);
9430 if (this_nargs
== 0)
9435 if (this_nargs
!= nargs
)
9437 error_at ((*cexpr_list
)[j
].get_location (),
9438 "argument %u of %<__builtin_tgmath%> has "
9439 "wrong number of arguments", j
+ 1);
9445 /* The functions all have the same number of arguments.
9446 Determine whether arguments and return types vary in
9447 ways permitted for <tgmath.h> functions. */
9448 /* The first entry in each of these vectors is for the
9449 return type, subsequent entries for parameter
9451 auto_vec
<enum tgmath_parm_kind
> parm_kind (nargs
+ 1);
9452 auto_vec
<tree
> parm_first (nargs
+ 1);
9453 auto_vec
<bool> parm_complex (nargs
+ 1);
9454 auto_vec
<bool> parm_varies (nargs
+ 1);
9455 tree first_type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[0].value
));
9456 tree first_ret
= TYPE_MAIN_VARIANT (TREE_TYPE (first_type
));
9457 parm_first
.quick_push (first_ret
);
9458 parm_complex
.quick_push (TREE_CODE (first_ret
) == COMPLEX_TYPE
);
9459 parm_varies
.quick_push (false);
9460 function_args_iterator iter
;
9462 unsigned int argpos
;
9463 FOREACH_FUNCTION_ARGS (first_type
, t
, iter
)
9465 if (t
== void_type_node
)
9467 parm_first
.quick_push (TYPE_MAIN_VARIANT (t
));
9468 parm_complex
.quick_push (TREE_CODE (t
) == COMPLEX_TYPE
);
9469 parm_varies
.quick_push (false);
9471 for (unsigned int j
= 1; j
< num_functions
; j
++)
9473 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9474 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
9475 if (ret
!= parm_first
[0])
9477 parm_varies
[0] = true;
9478 if (!SCALAR_FLOAT_TYPE_P (parm_first
[0])
9479 && !COMPLEX_FLOAT_TYPE_P (parm_first
[0]))
9481 error_at ((*cexpr_list
)[0].get_location (),
9482 "invalid type-generic return type for "
9483 "argument %u of %<__builtin_tgmath%>",
9488 if (!SCALAR_FLOAT_TYPE_P (ret
)
9489 && !COMPLEX_FLOAT_TYPE_P (ret
))
9491 error_at ((*cexpr_list
)[j
].get_location (),
9492 "invalid type-generic return type for "
9493 "argument %u of %<__builtin_tgmath%>",
9499 if (TREE_CODE (ret
) == COMPLEX_TYPE
)
9500 parm_complex
[0] = true;
9502 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9504 if (t
== void_type_node
)
9506 t
= TYPE_MAIN_VARIANT (t
);
9507 if (t
!= parm_first
[argpos
])
9509 parm_varies
[argpos
] = true;
9510 if (!SCALAR_FLOAT_TYPE_P (parm_first
[argpos
])
9511 && !COMPLEX_FLOAT_TYPE_P (parm_first
[argpos
]))
9513 error_at ((*cexpr_list
)[0].get_location (),
9514 "invalid type-generic type for "
9515 "argument %u of argument %u of "
9516 "%<__builtin_tgmath%>", argpos
, 1);
9520 if (!SCALAR_FLOAT_TYPE_P (t
)
9521 && !COMPLEX_FLOAT_TYPE_P (t
))
9523 error_at ((*cexpr_list
)[j
].get_location (),
9524 "invalid type-generic type for "
9525 "argument %u of argument %u of "
9526 "%<__builtin_tgmath%>", argpos
, j
+ 1);
9531 if (TREE_CODE (t
) == COMPLEX_TYPE
)
9532 parm_complex
[argpos
] = true;
9536 enum tgmath_parm_kind max_variation
= tgmath_fixed
;
9537 for (unsigned int j
= 0; j
<= nargs
; j
++)
9539 enum tgmath_parm_kind this_kind
;
9542 if (parm_complex
[j
])
9543 max_variation
= this_kind
= tgmath_complex
;
9546 this_kind
= tgmath_real
;
9547 if (max_variation
!= tgmath_complex
)
9548 max_variation
= tgmath_real
;
9552 this_kind
= tgmath_fixed
;
9553 parm_kind
.quick_push (this_kind
);
9555 if (max_variation
== tgmath_fixed
)
9557 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
9558 "all have the same type");
9563 /* Identify a parameter (not the return type) that varies,
9564 including with complex types if any variation includes
9565 complex types; there must be at least one such
9567 unsigned int tgarg
= 0;
9568 for (unsigned int j
= 1; j
<= nargs
; j
++)
9569 if (parm_kind
[j
] == max_variation
)
9576 error_at (loc
, "function arguments of %<__builtin_tgmath%> "
9577 "lack type-generic parameter");
9582 /* Determine the type of the relevant parameter for each
9584 auto_vec
<tree
> tg_type (num_functions
);
9585 for (unsigned int j
= 0; j
< num_functions
; j
++)
9587 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9589 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9591 if (argpos
== tgarg
)
9593 tg_type
.quick_push (TYPE_MAIN_VARIANT (t
));
9600 /* Verify that the corresponding types are different for
9601 all the listed functions. Also determine whether all
9602 the types are complex, whether all the types are
9603 standard or binary, and whether all the types are
9605 bool all_complex
= true;
9606 bool all_binary
= true;
9607 bool all_decimal
= true;
9608 hash_set
<tree
> tg_types
;
9609 FOR_EACH_VEC_ELT (tg_type
, i
, t
)
9611 if (TREE_CODE (t
) == COMPLEX_TYPE
)
9612 all_decimal
= false;
9615 all_complex
= false;
9616 if (DECIMAL_FLOAT_TYPE_P (t
))
9619 all_decimal
= false;
9621 if (tg_types
.add (t
))
9623 error_at ((*cexpr_list
)[i
].get_location (),
9624 "duplicate type-generic parameter type for "
9625 "function argument %u of %<__builtin_tgmath%>",
9632 /* Verify that other parameters and the return type whose
9633 types vary have their types varying in the correct
9635 for (unsigned int j
= 0; j
< num_functions
; j
++)
9637 tree exp_type
= tg_type
[j
];
9638 tree exp_real_type
= exp_type
;
9639 if (TREE_CODE (exp_type
) == COMPLEX_TYPE
)
9640 exp_real_type
= TREE_TYPE (exp_type
);
9641 tree type
= TREE_TYPE (TREE_TYPE ((*cexpr_list
)[j
].value
));
9642 tree ret
= TYPE_MAIN_VARIANT (TREE_TYPE (type
));
9643 if ((parm_kind
[0] == tgmath_complex
&& ret
!= exp_type
)
9644 || (parm_kind
[0] == tgmath_real
&& ret
!= exp_real_type
))
9646 error_at ((*cexpr_list
)[j
].get_location (),
9647 "bad return type for function argument %u "
9648 "of %<__builtin_tgmath%>", j
+ 1);
9653 FOREACH_FUNCTION_ARGS (type
, t
, iter
)
9655 if (t
== void_type_node
)
9657 t
= TYPE_MAIN_VARIANT (t
);
9658 if ((parm_kind
[argpos
] == tgmath_complex
9660 || (parm_kind
[argpos
] == tgmath_real
9661 && t
!= exp_real_type
))
9663 error_at ((*cexpr_list
)[j
].get_location (),
9664 "bad type for argument %u of "
9665 "function argument %u of "
9666 "%<__builtin_tgmath%>", argpos
, j
+ 1);
9674 /* The functions listed are a valid set of functions for a
9675 <tgmath.h> macro to select between. Identify the
9676 matching function, if any. First, the argument types
9677 must be combined following <tgmath.h> rules. Integer
9678 types are treated as _Decimal64 if any type-generic
9679 argument is decimal, or if the only alternatives for
9680 type-generic arguments are of decimal types, and are
9681 otherwise treated as double (or _Complex double for
9682 complex integer types, or _Float64 or _Complex _Float64
9683 if all the return types are the same _FloatN or
9684 _FloatNx type). After that adjustment, types are
9685 combined following the usual arithmetic conversions.
9686 If the function only accepts complex arguments, a
9687 complex type is produced. */
9688 bool arg_complex
= all_complex
;
9689 bool arg_binary
= all_binary
;
9690 bool arg_int_decimal
= all_decimal
;
9691 for (unsigned int j
= 1; j
<= nargs
; j
++)
9693 if (parm_kind
[j
] == tgmath_fixed
)
9695 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9696 tree type
= TREE_TYPE (ce
->value
);
9697 if (!INTEGRAL_TYPE_P (type
)
9698 && !SCALAR_FLOAT_TYPE_P (type
)
9699 && TREE_CODE (type
) != COMPLEX_TYPE
)
9701 error_at (ce
->get_location (),
9702 "invalid type of argument %u of type-generic "
9707 if (DECIMAL_FLOAT_TYPE_P (type
))
9709 arg_int_decimal
= true;
9712 error_at (ce
->get_location (),
9713 "decimal floating-point argument %u to "
9714 "complex-only type-generic function", j
);
9718 else if (all_binary
)
9720 error_at (ce
->get_location (),
9721 "decimal floating-point argument %u to "
9722 "binary-only type-generic function", j
);
9726 else if (arg_complex
)
9728 error_at (ce
->get_location (),
9729 "both complex and decimal floating-point "
9730 "arguments to type-generic function");
9734 else if (arg_binary
)
9736 error_at (ce
->get_location (),
9737 "both binary and decimal floating-point "
9738 "arguments to type-generic function");
9743 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
9746 if (COMPLEX_FLOAT_TYPE_P (type
))
9750 error_at (ce
->get_location (),
9751 "complex argument %u to "
9752 "decimal-only type-generic function", j
);
9756 else if (arg_int_decimal
)
9758 error_at (ce
->get_location (),
9759 "both complex and decimal floating-point "
9760 "arguments to type-generic function");
9765 else if (SCALAR_FLOAT_TYPE_P (type
))
9770 error_at (ce
->get_location (),
9771 "binary argument %u to "
9772 "decimal-only type-generic function", j
);
9776 else if (arg_int_decimal
)
9778 error_at (ce
->get_location (),
9779 "both binary and decimal floating-point "
9780 "arguments to type-generic function");
9786 /* For a macro rounding its result to a narrower type, map
9787 integer types to _Float64 not double if the return type
9788 is a _FloatN or _FloatNx type. */
9789 bool arg_int_float64
= false;
9790 if (parm_kind
[0] == tgmath_fixed
9791 && SCALAR_FLOAT_TYPE_P (parm_first
[0])
9792 && float64_type_node
!= NULL_TREE
)
9793 for (unsigned int j
= 0; j
< NUM_FLOATN_NX_TYPES
; j
++)
9794 if (parm_first
[0] == FLOATN_TYPE_NODE (j
))
9796 arg_int_float64
= true;
9799 tree arg_real
= NULL_TREE
;
9800 for (unsigned int j
= 1; j
<= nargs
; j
++)
9802 if (parm_kind
[j
] == tgmath_fixed
)
9804 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
- 1];
9805 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (ce
->value
));
9806 if (TREE_CODE (type
) == COMPLEX_TYPE
)
9807 type
= TREE_TYPE (type
);
9808 if (INTEGRAL_TYPE_P (type
))
9809 type
= (arg_int_decimal
9810 ? dfloat64_type_node
9813 : double_type_node
);
9814 if (arg_real
== NULL_TREE
)
9817 arg_real
= common_type (arg_real
, type
);
9818 if (arg_real
== error_mark_node
)
9824 tree arg_type
= (arg_complex
9825 ? build_complex_type (arg_real
)
9828 /* Look for a function to call with type-generic parameter
9830 c_expr_t
*fn
= NULL
;
9831 for (unsigned int j
= 0; j
< num_functions
; j
++)
9833 if (tg_type
[j
] == arg_type
)
9835 fn
= &(*cexpr_list
)[j
];
9840 && parm_kind
[0] == tgmath_fixed
9841 && SCALAR_FLOAT_TYPE_P (parm_first
[0]))
9843 /* Presume this is a macro that rounds its result to a
9844 narrower type, and look for the first function with
9845 at least the range and precision of the argument
9847 for (unsigned int j
= 0; j
< num_functions
; j
++)
9850 != (TREE_CODE (tg_type
[j
]) == COMPLEX_TYPE
))
9852 tree real_tg_type
= (arg_complex
9853 ? TREE_TYPE (tg_type
[j
])
9855 if (DECIMAL_FLOAT_TYPE_P (arg_real
)
9856 != DECIMAL_FLOAT_TYPE_P (real_tg_type
))
9858 scalar_float_mode arg_mode
9859 = SCALAR_FLOAT_TYPE_MODE (arg_real
);
9860 scalar_float_mode tg_mode
9861 = SCALAR_FLOAT_TYPE_MODE (real_tg_type
);
9862 const real_format
*arg_fmt
= REAL_MODE_FORMAT (arg_mode
);
9863 const real_format
*tg_fmt
= REAL_MODE_FORMAT (tg_mode
);
9864 if (arg_fmt
->b
== tg_fmt
->b
9865 && arg_fmt
->p
<= tg_fmt
->p
9866 && arg_fmt
->emax
<= tg_fmt
->emax
9867 && (arg_fmt
->emin
- arg_fmt
->p
9868 >= tg_fmt
->emin
- tg_fmt
->p
))
9870 fn
= &(*cexpr_list
)[j
];
9877 error_at (loc
, "no matching function for type-generic call");
9882 /* Construct a call to FN. */
9883 vec
<tree
, va_gc
> *args
;
9884 vec_alloc (args
, nargs
);
9885 vec
<tree
, va_gc
> *origtypes
;
9886 vec_alloc (origtypes
, nargs
);
9887 auto_vec
<location_t
> arg_loc (nargs
);
9888 for (unsigned int j
= 0; j
< nargs
; j
++)
9890 c_expr_t
*ce
= &(*cexpr_list
)[num_functions
+ j
];
9891 args
->quick_push (ce
->value
);
9892 arg_loc
.quick_push (ce
->get_location ());
9893 origtypes
->quick_push (ce
->original_type
);
9895 expr
.value
= c_build_function_call_vec (loc
, arg_loc
, fn
->value
,
9897 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9900 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN
:
9902 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9905 location_t close_paren_loc
;
9907 c_parser_consume_token (parser
);
9908 if (!c_parser_get_builtin_args (parser
,
9909 "__builtin_call_with_static_chain",
9916 if (vec_safe_length (cexpr_list
) != 2)
9918 error_at (loc
, "wrong number of arguments to "
9919 "%<__builtin_call_with_static_chain%>");
9924 expr
= (*cexpr_list
)[0];
9925 e2_p
= &(*cexpr_list
)[1];
9926 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
9927 chain_value
= e2_p
->value
;
9928 mark_exp_read (chain_value
);
9930 if (TREE_CODE (expr
.value
) != CALL_EXPR
)
9931 error_at (loc
, "first argument to "
9932 "%<__builtin_call_with_static_chain%> "
9933 "must be a call expression");
9934 else if (TREE_CODE (TREE_TYPE (chain_value
)) != POINTER_TYPE
)
9935 error_at (loc
, "second argument to "
9936 "%<__builtin_call_with_static_chain%> "
9937 "must be a pointer type");
9939 CALL_EXPR_STATIC_CHAIN (expr
.value
) = chain_value
;
9940 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
9943 case RID_BUILTIN_COMPLEX
:
9945 vec
<c_expr_t
, va_gc
> *cexpr_list
;
9946 c_expr_t
*e1_p
, *e2_p
;
9947 location_t close_paren_loc
;
9949 c_parser_consume_token (parser
);
9950 if (!c_parser_get_builtin_args (parser
,
9951 "__builtin_complex",
9959 if (vec_safe_length (cexpr_list
) != 2)
9961 error_at (loc
, "wrong number of arguments to "
9962 "%<__builtin_complex%>");
9967 e1_p
= &(*cexpr_list
)[0];
9968 e2_p
= &(*cexpr_list
)[1];
9970 *e1_p
= convert_lvalue_to_rvalue (loc
, *e1_p
, true, true);
9971 if (TREE_CODE (e1_p
->value
) == EXCESS_PRECISION_EXPR
)
9972 e1_p
->value
= convert (TREE_TYPE (e1_p
->value
),
9973 TREE_OPERAND (e1_p
->value
, 0));
9974 *e2_p
= convert_lvalue_to_rvalue (loc
, *e2_p
, true, true);
9975 if (TREE_CODE (e2_p
->value
) == EXCESS_PRECISION_EXPR
)
9976 e2_p
->value
= convert (TREE_TYPE (e2_p
->value
),
9977 TREE_OPERAND (e2_p
->value
, 0));
9978 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
9979 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p
->value
))
9980 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
))
9981 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p
->value
)))
9983 error_at (loc
, "%<__builtin_complex%> operand "
9984 "not of real binary floating-point type");
9988 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p
->value
))
9989 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p
->value
)))
9992 "%<__builtin_complex%> operands of different types");
9996 pedwarn_c90 (loc
, OPT_Wpedantic
,
9997 "ISO C90 does not support complex types");
9998 expr
.value
= build2_loc (loc
, COMPLEX_EXPR
,
10001 (TREE_TYPE (e1_p
->value
))),
10002 e1_p
->value
, e2_p
->value
);
10003 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10006 case RID_BUILTIN_SHUFFLE
:
10008 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10011 location_t close_paren_loc
;
10013 c_parser_consume_token (parser
);
10014 if (!c_parser_get_builtin_args (parser
,
10015 "__builtin_shuffle",
10016 &cexpr_list
, false,
10023 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
10024 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
10026 if (vec_safe_length (cexpr_list
) == 2)
10027 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10029 (*cexpr_list
)[1].value
);
10031 else if (vec_safe_length (cexpr_list
) == 3)
10032 expr
.value
= c_build_vec_perm_expr (loc
, (*cexpr_list
)[0].value
,
10033 (*cexpr_list
)[1].value
,
10034 (*cexpr_list
)[2].value
);
10037 error_at (loc
, "wrong number of arguments to "
10038 "%<__builtin_shuffle%>");
10041 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10044 case RID_BUILTIN_SHUFFLEVECTOR
:
10046 vec
<c_expr_t
, va_gc
> *cexpr_list
;
10049 location_t close_paren_loc
;
10051 c_parser_consume_token (parser
);
10052 if (!c_parser_get_builtin_args (parser
,
10053 "__builtin_shufflevector",
10054 &cexpr_list
, false,
10061 FOR_EACH_VEC_SAFE_ELT (cexpr_list
, i
, p
)
10062 *p
= convert_lvalue_to_rvalue (loc
, *p
, true, true);
10064 if (vec_safe_length (cexpr_list
) < 3)
10066 error_at (loc
, "wrong number of arguments to "
10067 "%<__builtin_shuffle%>");
10072 auto_vec
<tree
, 16> mask
;
10073 for (i
= 2; i
< cexpr_list
->length (); ++i
)
10074 mask
.safe_push ((*cexpr_list
)[i
].value
);
10075 expr
.value
= c_build_shufflevector (loc
, (*cexpr_list
)[0].value
,
10076 (*cexpr_list
)[1].value
,
10079 set_c_expr_source_range (&expr
, loc
, close_paren_loc
);
10082 case RID_BUILTIN_CONVERTVECTOR
:
10084 location_t start_loc
= loc
;
10085 c_parser_consume_token (parser
);
10086 matching_parens parens
;
10087 if (!parens
.require_open (parser
))
10092 e1
= c_parser_expr_no_commas (parser
, NULL
);
10093 mark_exp_read (e1
.value
);
10094 if (!c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
10096 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10100 loc
= c_parser_peek_token (parser
)->location
;
10101 t1
= c_parser_type_name (parser
);
10102 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10103 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
10109 tree type_expr
= NULL_TREE
;
10110 expr
.value
= c_build_vec_convert (start_loc
, e1
.value
, loc
,
10111 groktypename (t1
, &type_expr
,
10113 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10117 case RID_BUILTIN_ASSOC_BARRIER
:
10119 location_t start_loc
= loc
;
10120 c_parser_consume_token (parser
);
10121 matching_parens parens
;
10122 if (!parens
.require_open (parser
))
10127 e1
= c_parser_expr_no_commas (parser
, NULL
);
10128 mark_exp_read (e1
.value
);
10129 location_t end_loc
= c_parser_peek_token (parser
)->get_finish ();
10130 parens
.skip_until_found_close (parser
);
10131 expr
= parser_build_unary_op (loc
, PAREN_EXPR
, e1
);
10132 set_c_expr_source_range (&expr
, start_loc
, end_loc
);
10135 case RID_AT_SELECTOR
:
10137 gcc_assert (c_dialect_objc ());
10138 c_parser_consume_token (parser
);
10139 matching_parens parens
;
10140 if (!parens
.require_open (parser
))
10145 tree sel
= c_parser_objc_selector_arg (parser
);
10146 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10147 parens
.skip_until_found_close (parser
);
10148 expr
.value
= objc_build_selector_expr (loc
, sel
);
10149 set_c_expr_source_range (&expr
, loc
, close_loc
);
10152 case RID_AT_PROTOCOL
:
10154 gcc_assert (c_dialect_objc ());
10155 c_parser_consume_token (parser
);
10156 matching_parens parens
;
10157 if (!parens
.require_open (parser
))
10162 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10164 c_parser_error (parser
, "expected identifier");
10165 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10169 tree id
= c_parser_peek_token (parser
)->value
;
10170 c_parser_consume_token (parser
);
10171 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10172 parens
.skip_until_found_close (parser
);
10173 expr
.value
= objc_build_protocol_expr (id
);
10174 set_c_expr_source_range (&expr
, loc
, close_loc
);
10177 case RID_AT_ENCODE
:
10179 /* Extension to support C-structures in the archiver. */
10180 gcc_assert (c_dialect_objc ());
10181 c_parser_consume_token (parser
);
10182 matching_parens parens
;
10183 if (!parens
.require_open (parser
))
10188 t1
= c_parser_type_name (parser
);
10192 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10195 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10196 parens
.skip_until_found_close (parser
);
10197 tree type
= groktypename (t1
, NULL
, NULL
);
10198 expr
.value
= objc_build_encode_expr (type
);
10199 set_c_expr_source_range (&expr
, loc
, close_loc
);
10203 expr
= c_parser_generic_selection (parser
);
10206 c_parser_error (parser
, "expected expression");
10211 case CPP_OPEN_SQUARE
:
10212 if (c_dialect_objc ())
10214 tree receiver
, args
;
10215 c_parser_consume_token (parser
);
10216 receiver
= c_parser_objc_receiver (parser
);
10217 args
= c_parser_objc_message_args (parser
);
10218 location_t close_loc
= c_parser_peek_token (parser
)->location
;
10219 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10221 expr
.value
= objc_build_message_expr (receiver
, args
);
10222 set_c_expr_source_range (&expr
, loc
, close_loc
);
10225 /* Else fall through to report error. */
10228 c_parser_error (parser
, "expected expression");
10233 return c_parser_postfix_expression_after_primary
10234 (parser
, EXPR_LOC_OR_LOC (expr
.value
, loc
), expr
);
10237 /* Parse a postfix expression after a parenthesized type name: the
10238 brace-enclosed initializer of a compound literal, possibly followed
10239 by some postfix operators. This is separate because it is not
10240 possible to tell until after the type name whether a cast
10241 expression has a cast or a compound literal, or whether the operand
10242 of sizeof is a parenthesized type name or starts with a compound
10243 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10244 location of the first token after the parentheses around the type
10247 static struct c_expr
10248 c_parser_postfix_expression_after_paren_type (c_parser
*parser
,
10249 struct c_type_name
*type_name
,
10250 location_t type_loc
)
10253 struct c_expr init
;
10255 struct c_expr expr
;
10256 location_t start_loc
;
10257 tree type_expr
= NULL_TREE
;
10258 bool type_expr_const
= true;
10259 check_compound_literal_type (type_loc
, type_name
);
10260 rich_location
richloc (line_table
, type_loc
);
10261 start_init (NULL_TREE
, NULL
, 0, &richloc
);
10262 type
= groktypename (type_name
, &type_expr
, &type_expr_const
);
10263 start_loc
= c_parser_peek_token (parser
)->location
;
10264 if (type
!= error_mark_node
&& C_TYPE_VARIABLE_SIZE (type
))
10266 error_at (type_loc
, "compound literal has variable size");
10267 type
= error_mark_node
;
10269 init
= c_parser_braced_init (parser
, type
, false, NULL
);
10271 maybe_warn_string_init (type_loc
, type
, init
);
10273 if (type
!= error_mark_node
10274 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type
))
10275 && current_function_decl
)
10277 error ("compound literal qualified by address-space qualifier");
10278 type
= error_mark_node
;
10281 pedwarn_c90 (start_loc
, OPT_Wpedantic
, "ISO C90 forbids compound literals");
10282 non_const
= ((init
.value
&& TREE_CODE (init
.value
) == CONSTRUCTOR
)
10283 ? CONSTRUCTOR_NON_CONST (init
.value
)
10284 : init
.original_code
== C_MAYBE_CONST_EXPR
);
10285 non_const
|= !type_expr_const
;
10286 unsigned int alignas_align
= 0;
10287 if (type
!= error_mark_node
10288 && type_name
->specs
->align_log
!= -1)
10290 alignas_align
= 1U << type_name
->specs
->align_log
;
10291 if (alignas_align
< min_align_of_type (type
))
10293 error_at (type_name
->specs
->locations
[cdw_alignas
],
10294 "%<_Alignas%> specifiers cannot reduce "
10295 "alignment of compound literal");
10299 expr
.value
= build_compound_literal (start_loc
, type
, init
.value
, non_const
,
10301 set_c_expr_source_range (&expr
, init
.src_range
);
10302 expr
.original_code
= ERROR_MARK
;
10303 expr
.original_type
= NULL
;
10304 if (type
!= error_mark_node
10305 && expr
.value
!= error_mark_node
10308 if (TREE_CODE (expr
.value
) == C_MAYBE_CONST_EXPR
)
10310 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr
.value
) == NULL_TREE
);
10311 C_MAYBE_CONST_EXPR_PRE (expr
.value
) = type_expr
;
10315 gcc_assert (!non_const
);
10316 expr
.value
= build2 (C_MAYBE_CONST_EXPR
, type
,
10317 type_expr
, expr
.value
);
10320 return c_parser_postfix_expression_after_primary (parser
, start_loc
, expr
);
10323 /* Callback function for sizeof_pointer_memaccess_warning to compare
10327 sizeof_ptr_memacc_comptypes (tree type1
, tree type2
)
10329 return comptypes (type1
, type2
) == 1;
10332 /* Warn for patterns where abs-like function appears to be used incorrectly,
10333 gracefully ignore any non-abs-like function. The warning location should
10334 be LOC. FNDECL is the declaration of called function, it must be a
10335 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10339 warn_for_abs (location_t loc
, tree fndecl
, tree arg
)
10341 /* Avoid warning in unreachable subexpressions. */
10342 if (c_inhibit_evaluation_warnings
)
10345 tree atype
= TREE_TYPE (arg
);
10347 /* Casts from pointers (and thus arrays and fndecls) will generate
10348 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10349 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10350 types and possibly other exotic types. */
10351 if (!INTEGRAL_TYPE_P (atype
)
10352 && !SCALAR_FLOAT_TYPE_P (atype
)
10353 && TREE_CODE (atype
) != COMPLEX_TYPE
)
10356 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
10361 case BUILT_IN_LABS
:
10362 case BUILT_IN_LLABS
:
10363 case BUILT_IN_IMAXABS
:
10364 if (!INTEGRAL_TYPE_P (atype
))
10366 if (SCALAR_FLOAT_TYPE_P (atype
))
10367 warning_at (loc
, OPT_Wabsolute_value
,
10368 "using integer absolute value function %qD when "
10369 "argument is of floating-point type %qT",
10371 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10372 warning_at (loc
, OPT_Wabsolute_value
,
10373 "using integer absolute value function %qD when "
10374 "argument is of complex type %qT", fndecl
, atype
);
10376 gcc_unreachable ();
10379 if (TYPE_UNSIGNED (atype
))
10380 warning_at (loc
, OPT_Wabsolute_value
,
10381 "taking the absolute value of unsigned type %qT "
10382 "has no effect", atype
);
10385 CASE_FLT_FN (BUILT_IN_FABS
):
10386 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS
):
10387 if (!SCALAR_FLOAT_TYPE_P (atype
)
10388 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype
)))
10390 if (INTEGRAL_TYPE_P (atype
))
10391 warning_at (loc
, OPT_Wabsolute_value
,
10392 "using floating-point absolute value function %qD "
10393 "when argument is of integer type %qT", fndecl
, atype
);
10394 else if (DECIMAL_FLOAT_TYPE_P (atype
))
10395 warning_at (loc
, OPT_Wabsolute_value
,
10396 "using floating-point absolute value function %qD "
10397 "when argument is of decimal floating-point type %qT",
10399 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10400 warning_at (loc
, OPT_Wabsolute_value
,
10401 "using floating-point absolute value function %qD when "
10402 "argument is of complex type %qT", fndecl
, atype
);
10404 gcc_unreachable ();
10409 CASE_FLT_FN (BUILT_IN_CABS
):
10410 if (TREE_CODE (atype
) != COMPLEX_TYPE
)
10412 if (INTEGRAL_TYPE_P (atype
))
10413 warning_at (loc
, OPT_Wabsolute_value
,
10414 "using complex absolute value function %qD when "
10415 "argument is of integer type %qT", fndecl
, atype
);
10416 else if (SCALAR_FLOAT_TYPE_P (atype
))
10417 warning_at (loc
, OPT_Wabsolute_value
,
10418 "using complex absolute value function %qD when "
10419 "argument is of floating-point type %qT",
10422 gcc_unreachable ();
10428 case BUILT_IN_FABSD32
:
10429 case BUILT_IN_FABSD64
:
10430 case BUILT_IN_FABSD128
:
10431 if (!DECIMAL_FLOAT_TYPE_P (atype
))
10433 if (INTEGRAL_TYPE_P (atype
))
10434 warning_at (loc
, OPT_Wabsolute_value
,
10435 "using decimal floating-point absolute value "
10436 "function %qD when argument is of integer type %qT",
10438 else if (SCALAR_FLOAT_TYPE_P (atype
))
10439 warning_at (loc
, OPT_Wabsolute_value
,
10440 "using decimal floating-point absolute value "
10441 "function %qD when argument is of floating-point "
10442 "type %qT", fndecl
, atype
);
10443 else if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10444 warning_at (loc
, OPT_Wabsolute_value
,
10445 "using decimal floating-point absolute value "
10446 "function %qD when argument is of complex type %qT",
10449 gcc_unreachable ();
10458 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl
)))
10461 tree ftype
= TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
10462 if (TREE_CODE (atype
) == COMPLEX_TYPE
)
10464 gcc_assert (TREE_CODE (ftype
) == COMPLEX_TYPE
);
10465 atype
= TREE_TYPE (atype
);
10466 ftype
= TREE_TYPE (ftype
);
10469 if (TYPE_PRECISION (ftype
) < TYPE_PRECISION (atype
))
10470 warning_at (loc
, OPT_Wabsolute_value
,
10471 "absolute value function %qD given an argument of type %qT "
10472 "but has parameter of type %qT which may cause truncation "
10473 "of value", fndecl
, atype
, ftype
);
10477 /* Parse a postfix expression after the initial primary or compound
10478 literal; that is, parse a series of postfix operators.
10480 EXPR_LOC is the location of the primary expression. */
10482 static struct c_expr
10483 c_parser_postfix_expression_after_primary (c_parser
*parser
,
10484 location_t expr_loc
,
10485 struct c_expr expr
)
10487 struct c_expr orig_expr
;
10489 location_t sizeof_arg_loc
[3], comp_loc
;
10490 tree sizeof_arg
[3];
10491 unsigned int literal_zero_mask
;
10493 vec
<tree
, va_gc
> *exprlist
;
10494 vec
<tree
, va_gc
> *origtypes
= NULL
;
10495 vec
<location_t
> arg_loc
= vNULL
;
10501 location_t op_loc
= c_parser_peek_token (parser
)->location
;
10502 switch (c_parser_peek_token (parser
)->type
)
10504 case CPP_OPEN_SQUARE
:
10505 /* Array reference. */
10506 c_parser_consume_token (parser
);
10507 idx
= c_parser_expression (parser
).value
;
10508 c_parser_skip_until_found (parser
, CPP_CLOSE_SQUARE
,
10510 start
= expr
.get_start ();
10511 finish
= parser
->tokens_buf
[0].location
;
10512 expr
.value
= build_array_ref (op_loc
, expr
.value
, idx
);
10513 set_c_expr_source_range (&expr
, start
, finish
);
10514 expr
.original_code
= ERROR_MARK
;
10515 expr
.original_type
= NULL
;
10517 case CPP_OPEN_PAREN
:
10518 /* Function call. */
10520 matching_parens parens
;
10521 parens
.consume_open (parser
);
10522 for (i
= 0; i
< 3; i
++)
10524 sizeof_arg
[i
] = NULL_TREE
;
10525 sizeof_arg_loc
[i
] = UNKNOWN_LOCATION
;
10527 literal_zero_mask
= 0;
10528 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10531 exprlist
= c_parser_expr_list (parser
, true, false, &origtypes
,
10532 sizeof_arg_loc
, sizeof_arg
,
10533 &arg_loc
, &literal_zero_mask
);
10534 parens
.skip_until_found_close (parser
);
10537 mark_exp_read (expr
.value
);
10538 if (warn_sizeof_pointer_memaccess
)
10539 sizeof_pointer_memaccess_warning (sizeof_arg_loc
,
10540 expr
.value
, exprlist
,
10542 sizeof_ptr_memacc_comptypes
);
10543 if (TREE_CODE (expr
.value
) == FUNCTION_DECL
)
10545 if (fndecl_built_in_p (expr
.value
, BUILT_IN_MEMSET
)
10546 && vec_safe_length (exprlist
) == 3)
10548 tree arg0
= (*exprlist
)[0];
10549 tree arg2
= (*exprlist
)[2];
10550 warn_for_memset (expr_loc
, arg0
, arg2
, literal_zero_mask
);
10552 if (warn_absolute_value
10553 && fndecl_built_in_p (expr
.value
, BUILT_IN_NORMAL
)
10554 && vec_safe_length (exprlist
) == 1)
10555 warn_for_abs (expr_loc
, expr
.value
, (*exprlist
)[0]);
10558 start
= expr
.get_start ();
10559 finish
= parser
->tokens_buf
[0].get_finish ();
10561 = c_build_function_call_vec (expr_loc
, arg_loc
, expr
.value
,
10562 exprlist
, origtypes
);
10563 set_c_expr_source_range (&expr
, start
, finish
);
10565 expr
.original_code
= ERROR_MARK
;
10566 if (TREE_CODE (expr
.value
) == INTEGER_CST
10567 && TREE_CODE (orig_expr
.value
) == FUNCTION_DECL
10568 && fndecl_built_in_p (orig_expr
.value
, BUILT_IN_CONSTANT_P
))
10569 expr
.original_code
= C_MAYBE_CONST_EXPR
;
10570 expr
.original_type
= NULL
;
10573 release_tree_vector (exprlist
);
10574 release_tree_vector (origtypes
);
10576 arg_loc
.release ();
10579 /* Structure element reference. */
10580 c_parser_consume_token (parser
);
10581 expr
= default_function_array_conversion (expr_loc
, expr
);
10582 if (c_parser_next_token_is (parser
, CPP_NAME
))
10584 c_token
*comp_tok
= c_parser_peek_token (parser
);
10585 ident
= comp_tok
->value
;
10586 comp_loc
= comp_tok
->location
;
10590 c_parser_error (parser
, "expected identifier");
10592 expr
.original_code
= ERROR_MARK
;
10593 expr
.original_type
= NULL
;
10596 start
= expr
.get_start ();
10597 finish
= c_parser_peek_token (parser
)->get_finish ();
10598 c_parser_consume_token (parser
);
10599 expr
.value
= build_component_ref (op_loc
, expr
.value
, ident
,
10601 set_c_expr_source_range (&expr
, start
, finish
);
10602 expr
.original_code
= ERROR_MARK
;
10603 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
10604 expr
.original_type
= NULL
;
10607 /* Remember the original type of a bitfield. */
10608 tree field
= TREE_OPERAND (expr
.value
, 1);
10609 if (TREE_CODE (field
) != FIELD_DECL
)
10610 expr
.original_type
= NULL
;
10612 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
10616 /* Structure element reference. */
10617 c_parser_consume_token (parser
);
10618 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, false);
10619 if (c_parser_next_token_is (parser
, CPP_NAME
))
10621 c_token
*comp_tok
= c_parser_peek_token (parser
);
10622 ident
= comp_tok
->value
;
10623 comp_loc
= comp_tok
->location
;
10627 c_parser_error (parser
, "expected identifier");
10629 expr
.original_code
= ERROR_MARK
;
10630 expr
.original_type
= NULL
;
10633 start
= expr
.get_start ();
10634 finish
= c_parser_peek_token (parser
)->get_finish ();
10635 c_parser_consume_token (parser
);
10636 expr
.value
= build_component_ref (op_loc
,
10637 build_indirect_ref (op_loc
,
10641 set_c_expr_source_range (&expr
, start
, finish
);
10642 expr
.original_code
= ERROR_MARK
;
10643 if (TREE_CODE (expr
.value
) != COMPONENT_REF
)
10644 expr
.original_type
= NULL
;
10647 /* Remember the original type of a bitfield. */
10648 tree field
= TREE_OPERAND (expr
.value
, 1);
10649 if (TREE_CODE (field
) != FIELD_DECL
)
10650 expr
.original_type
= NULL
;
10652 expr
.original_type
= DECL_BIT_FIELD_TYPE (field
);
10655 case CPP_PLUS_PLUS
:
10656 /* Postincrement. */
10657 start
= expr
.get_start ();
10658 finish
= c_parser_peek_token (parser
)->get_finish ();
10659 c_parser_consume_token (parser
);
10660 expr
= default_function_array_read_conversion (expr_loc
, expr
);
10661 expr
.value
= build_unary_op (op_loc
, POSTINCREMENT_EXPR
,
10662 expr
.value
, false);
10663 set_c_expr_source_range (&expr
, start
, finish
);
10664 expr
.original_code
= ERROR_MARK
;
10665 expr
.original_type
= NULL
;
10667 case CPP_MINUS_MINUS
:
10668 /* Postdecrement. */
10669 start
= expr
.get_start ();
10670 finish
= c_parser_peek_token (parser
)->get_finish ();
10671 c_parser_consume_token (parser
);
10672 expr
= default_function_array_read_conversion (expr_loc
, expr
);
10673 expr
.value
= build_unary_op (op_loc
, POSTDECREMENT_EXPR
,
10674 expr
.value
, false);
10675 set_c_expr_source_range (&expr
, start
, finish
);
10676 expr
.original_code
= ERROR_MARK
;
10677 expr
.original_type
= NULL
;
10685 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10688 assignment-expression
10689 expression , assignment-expression
10692 static struct c_expr
10693 c_parser_expression (c_parser
*parser
)
10695 location_t tloc
= c_parser_peek_token (parser
)->location
;
10696 struct c_expr expr
;
10697 expr
= c_parser_expr_no_commas (parser
, NULL
);
10698 if (c_parser_next_token_is (parser
, CPP_COMMA
))
10699 expr
= convert_lvalue_to_rvalue (tloc
, expr
, true, false);
10700 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10702 struct c_expr next
;
10704 location_t loc
= c_parser_peek_token (parser
)->location
;
10705 location_t expr_loc
;
10706 c_parser_consume_token (parser
);
10707 expr_loc
= c_parser_peek_token (parser
)->location
;
10708 lhsval
= expr
.value
;
10709 while (TREE_CODE (lhsval
) == COMPOUND_EXPR
10710 || TREE_CODE (lhsval
) == NOP_EXPR
)
10712 if (TREE_CODE (lhsval
) == COMPOUND_EXPR
)
10713 lhsval
= TREE_OPERAND (lhsval
, 1);
10715 lhsval
= TREE_OPERAND (lhsval
, 0);
10717 if (DECL_P (lhsval
) || handled_component_p (lhsval
))
10718 mark_exp_read (lhsval
);
10719 next
= c_parser_expr_no_commas (parser
, NULL
);
10720 next
= convert_lvalue_to_rvalue (expr_loc
, next
, true, false);
10721 expr
.value
= build_compound_expr (loc
, expr
.value
, next
.value
);
10722 expr
.original_code
= COMPOUND_EXPR
;
10723 expr
.original_type
= next
.original_type
;
10728 /* Parse an expression and convert functions or arrays to pointers and
10729 lvalues to rvalues. */
10731 static struct c_expr
10732 c_parser_expression_conv (c_parser
*parser
)
10734 struct c_expr expr
;
10735 location_t loc
= c_parser_peek_token (parser
)->location
;
10736 expr
= c_parser_expression (parser
);
10737 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, false);
10741 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10742 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10745 c_parser_check_literal_zero (c_parser
*parser
, unsigned *literal_zero_mask
,
10748 if (idx
>= HOST_BITS_PER_INT
)
10751 c_token
*tok
= c_parser_peek_token (parser
);
10760 /* If a parameter is literal zero alone, remember it
10761 for -Wmemset-transposed-args warning. */
10762 if (integer_zerop (tok
->value
)
10763 && !TREE_OVERFLOW (tok
->value
)
10764 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
10765 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
10766 *literal_zero_mask
|= 1U << idx
;
10772 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10773 functions and arrays to pointers and lvalues to rvalues. If
10774 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10775 locations of function arguments into this vector.
10777 nonempty-expr-list:
10778 assignment-expression
10779 nonempty-expr-list , assignment-expression
10782 static vec
<tree
, va_gc
> *
10783 c_parser_expr_list (c_parser
*parser
, bool convert_p
, bool fold_p
,
10784 vec
<tree
, va_gc
> **p_orig_types
,
10785 location_t
*sizeof_arg_loc
, tree
*sizeof_arg
,
10786 vec
<location_t
> *locations
,
10787 unsigned int *literal_zero_mask
)
10789 vec
<tree
, va_gc
> *ret
;
10790 vec
<tree
, va_gc
> *orig_types
;
10791 struct c_expr expr
;
10792 unsigned int idx
= 0;
10794 ret
= make_tree_vector ();
10795 if (p_orig_types
== NULL
)
10798 orig_types
= make_tree_vector ();
10800 if (literal_zero_mask
)
10801 c_parser_check_literal_zero (parser
, literal_zero_mask
, 0);
10802 expr
= c_parser_expr_no_commas (parser
, NULL
);
10804 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true, true);
10806 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
10807 ret
->quick_push (expr
.value
);
10809 orig_types
->quick_push (expr
.original_type
);
10811 locations
->safe_push (expr
.get_location ());
10812 if (sizeof_arg
!= NULL
10813 && (expr
.original_code
== SIZEOF_EXPR
10814 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
10816 sizeof_arg
[0] = c_last_sizeof_arg
;
10817 sizeof_arg_loc
[0] = c_last_sizeof_loc
;
10819 while (c_parser_next_token_is (parser
, CPP_COMMA
))
10821 c_parser_consume_token (parser
);
10822 if (literal_zero_mask
)
10823 c_parser_check_literal_zero (parser
, literal_zero_mask
, idx
+ 1);
10824 expr
= c_parser_expr_no_commas (parser
, NULL
);
10826 expr
= convert_lvalue_to_rvalue (expr
.get_location (), expr
, true,
10829 expr
.value
= c_fully_fold (expr
.value
, false, NULL
);
10830 vec_safe_push (ret
, expr
.value
);
10832 vec_safe_push (orig_types
, expr
.original_type
);
10834 locations
->safe_push (expr
.get_location ());
10836 && sizeof_arg
!= NULL
10837 && (expr
.original_code
== SIZEOF_EXPR
10838 || expr
.original_code
== PAREN_SIZEOF_EXPR
))
10840 sizeof_arg
[idx
] = c_last_sizeof_arg
;
10841 sizeof_arg_loc
[idx
] = c_last_sizeof_loc
;
10845 *p_orig_types
= orig_types
;
10849 /* Parse Objective-C-specific constructs. */
10851 /* Parse an objc-class-definition.
10853 objc-class-definition:
10854 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10855 objc-class-instance-variables[opt] objc-methodprotolist @end
10856 @implementation identifier objc-superclass[opt]
10857 objc-class-instance-variables[opt]
10858 @interface identifier ( identifier ) objc-protocol-refs[opt]
10859 objc-methodprotolist @end
10860 @interface identifier ( ) objc-protocol-refs[opt]
10861 objc-methodprotolist @end
10862 @implementation identifier ( identifier )
10867 "@interface identifier (" must start "@interface identifier (
10868 identifier ) ...": objc-methodprotolist in the first production may
10869 not start with a parenthesized identifier as a declarator of a data
10870 definition with no declaration specifiers if the objc-superclass,
10871 objc-protocol-refs and objc-class-instance-variables are omitted. */
10874 c_parser_objc_class_definition (c_parser
*parser
, tree attributes
)
10879 if (c_parser_next_token_is_keyword (parser
, RID_AT_INTERFACE
))
10881 else if (c_parser_next_token_is_keyword (parser
, RID_AT_IMPLEMENTATION
))
10884 gcc_unreachable ();
10886 c_parser_consume_token (parser
);
10887 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10889 c_parser_error (parser
, "expected identifier");
10892 id1
= c_parser_peek_token (parser
)->value
;
10893 location_t loc1
= c_parser_peek_token (parser
)->location
;
10894 c_parser_consume_token (parser
);
10895 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
10897 /* We have a category or class extension. */
10899 tree proto
= NULL_TREE
;
10900 matching_parens parens
;
10901 parens
.consume_open (parser
);
10902 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10904 if (iface_p
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
10906 /* We have a class extension. */
10911 c_parser_error (parser
, "expected identifier or %<)%>");
10912 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
10918 id2
= c_parser_peek_token (parser
)->value
;
10919 c_parser_consume_token (parser
);
10921 parens
.skip_until_found_close (parser
);
10924 objc_start_category_implementation (id1
, id2
);
10927 if (c_parser_next_token_is (parser
, CPP_LESS
))
10928 proto
= c_parser_objc_protocol_refs (parser
);
10929 objc_start_category_interface (id1
, id2
, proto
, attributes
);
10930 c_parser_objc_methodprotolist (parser
);
10931 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10932 objc_finish_interface ();
10935 if (c_parser_next_token_is (parser
, CPP_COLON
))
10937 c_parser_consume_token (parser
);
10938 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
10940 c_parser_error (parser
, "expected identifier");
10943 superclass
= c_parser_peek_token (parser
)->value
;
10944 c_parser_consume_token (parser
);
10947 superclass
= NULL_TREE
;
10950 tree proto
= NULL_TREE
;
10951 if (c_parser_next_token_is (parser
, CPP_LESS
))
10952 proto
= c_parser_objc_protocol_refs (parser
);
10953 objc_start_class_interface (id1
, loc1
, superclass
, proto
, attributes
);
10956 objc_start_class_implementation (id1
, superclass
);
10957 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
10958 c_parser_objc_class_instance_variables (parser
);
10961 objc_continue_interface ();
10962 c_parser_objc_methodprotolist (parser
);
10963 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
10964 objc_finish_interface ();
10968 objc_continue_implementation ();
10973 /* Parse objc-class-instance-variables.
10975 objc-class-instance-variables:
10976 { objc-instance-variable-decl-list[opt] }
10978 objc-instance-variable-decl-list:
10979 objc-visibility-spec
10980 objc-instance-variable-decl ;
10982 objc-instance-variable-decl-list objc-visibility-spec
10983 objc-instance-variable-decl-list objc-instance-variable-decl ;
10984 objc-instance-variable-decl-list ;
10986 objc-visibility-spec:
10991 objc-instance-variable-decl:
10996 c_parser_objc_class_instance_variables (c_parser
*parser
)
10998 gcc_assert (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
));
10999 c_parser_consume_token (parser
);
11000 while (c_parser_next_token_is_not (parser
, CPP_EOF
))
11003 /* Parse any stray semicolon. */
11004 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11006 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11007 "extra semicolon");
11008 c_parser_consume_token (parser
);
11011 /* Stop if at the end of the instance variables. */
11012 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
11014 c_parser_consume_token (parser
);
11017 /* Parse any objc-visibility-spec. */
11018 if (c_parser_next_token_is_keyword (parser
, RID_AT_PRIVATE
))
11020 c_parser_consume_token (parser
);
11021 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE
);
11024 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROTECTED
))
11026 c_parser_consume_token (parser
);
11027 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED
);
11030 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PUBLIC
))
11032 c_parser_consume_token (parser
);
11033 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC
);
11036 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PACKAGE
))
11038 c_parser_consume_token (parser
);
11039 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE
);
11042 else if (c_parser_next_token_is (parser
, CPP_PRAGMA
))
11044 c_parser_pragma (parser
, pragma_external
, NULL
);
11048 /* Parse some comma-separated declarations. */
11049 decls
= c_parser_struct_declaration (parser
);
11052 /* There is a syntax error. We want to skip the offending
11053 tokens up to the next ';' (included) or '}'
11056 /* First, skip manually a ')' or ']'. This is because they
11057 reduce the nesting level, so c_parser_skip_until_found()
11058 wouldn't be able to skip past them. */
11059 c_token
*token
= c_parser_peek_token (parser
);
11060 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_CLOSE_SQUARE
)
11061 c_parser_consume_token (parser
);
11063 /* Then, do the standard skipping. */
11064 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11066 /* We hopefully recovered. Start normal parsing again. */
11067 parser
->error
= false;
11072 /* Comma-separated instance variables are chained together
11073 in reverse order; add them one by one. */
11074 tree ivar
= nreverse (decls
);
11075 for (; ivar
; ivar
= DECL_CHAIN (ivar
))
11076 objc_add_instance_variable (copy_node (ivar
));
11078 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11082 /* Parse an objc-class-declaration.
11084 objc-class-declaration:
11085 @class identifier-list ;
11089 c_parser_objc_class_declaration (c_parser
*parser
)
11091 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_CLASS
));
11092 c_parser_consume_token (parser
);
11093 /* Any identifiers, including those declared as type names, are OK
11098 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11100 c_parser_error (parser
, "expected identifier");
11101 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11102 parser
->error
= false;
11105 id
= c_parser_peek_token (parser
)->value
;
11106 objc_declare_class (id
);
11107 c_parser_consume_token (parser
);
11108 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11109 c_parser_consume_token (parser
);
11113 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11116 /* Parse an objc-alias-declaration.
11118 objc-alias-declaration:
11119 @compatibility_alias identifier identifier ;
11123 c_parser_objc_alias_declaration (c_parser
*parser
)
11126 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_ALIAS
));
11127 c_parser_consume_token (parser
);
11128 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11130 c_parser_error (parser
, "expected identifier");
11131 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11134 id1
= c_parser_peek_token (parser
)->value
;
11135 c_parser_consume_token (parser
);
11136 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11138 c_parser_error (parser
, "expected identifier");
11139 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
11142 id2
= c_parser_peek_token (parser
)->value
;
11143 c_parser_consume_token (parser
);
11144 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11145 objc_declare_alias (id1
, id2
);
11148 /* Parse an objc-protocol-definition.
11150 objc-protocol-definition:
11151 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11152 @protocol identifier-list ;
11154 "@protocol identifier ;" should be resolved as "@protocol
11155 identifier-list ;": objc-methodprotolist may not start with a
11156 semicolon in the first alternative if objc-protocol-refs are
11160 c_parser_objc_protocol_definition (c_parser
*parser
, tree attributes
)
11162 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROTOCOL
));
11164 c_parser_consume_token (parser
);
11165 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11167 c_parser_error (parser
, "expected identifier");
11170 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
11171 || c_parser_peek_2nd_token (parser
)->type
== CPP_SEMICOLON
)
11173 /* Any identifiers, including those declared as type names, are
11178 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11180 c_parser_error (parser
, "expected identifier");
11183 id
= c_parser_peek_token (parser
)->value
;
11184 objc_declare_protocol (id
, attributes
);
11185 c_parser_consume_token (parser
);
11186 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11187 c_parser_consume_token (parser
);
11191 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11195 tree id
= c_parser_peek_token (parser
)->value
;
11196 tree proto
= NULL_TREE
;
11197 c_parser_consume_token (parser
);
11198 if (c_parser_next_token_is (parser
, CPP_LESS
))
11199 proto
= c_parser_objc_protocol_refs (parser
);
11200 parser
->objc_pq_context
= true;
11201 objc_start_protocol (id
, proto
, attributes
);
11202 c_parser_objc_methodprotolist (parser
);
11203 c_parser_require_keyword (parser
, RID_AT_END
, "expected %<@end%>");
11204 parser
->objc_pq_context
= false;
11205 objc_finish_interface ();
11209 /* Parse an objc-method-type.
11215 Return true if it is a class method (+) and false if it is
11216 an instance method (-).
11219 c_parser_objc_method_type (c_parser
*parser
)
11221 switch (c_parser_peek_token (parser
)->type
)
11224 c_parser_consume_token (parser
);
11227 c_parser_consume_token (parser
);
11230 gcc_unreachable ();
11234 /* Parse an objc-method-definition.
11236 objc-method-definition:
11237 objc-method-type objc-method-decl ;[opt] compound-statement
11241 c_parser_objc_method_definition (c_parser
*parser
)
11243 bool is_class_method
= c_parser_objc_method_type (parser
);
11244 tree decl
, attributes
= NULL_TREE
, expr
= NULL_TREE
;
11245 parser
->objc_pq_context
= true;
11246 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11248 if (decl
== error_mark_node
)
11249 return; /* Bail here. */
11251 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11253 c_parser_consume_token (parser
);
11254 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11255 "extra semicolon in method definition specified");
11258 if (!c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11260 c_parser_error (parser
, "expected %<{%>");
11264 parser
->objc_pq_context
= false;
11265 if (objc_start_method_definition (is_class_method
, decl
, attributes
, expr
))
11267 add_stmt (c_parser_compound_statement (parser
));
11268 objc_finish_method_definition (current_function_decl
);
11272 /* This code is executed when we find a method definition
11273 outside of an @implementation context (or invalid for other
11274 reasons). Parse the method (to keep going) but do not emit
11277 c_parser_compound_statement (parser
);
11281 /* Parse an objc-methodprotolist.
11283 objc-methodprotolist:
11285 objc-methodprotolist objc-methodproto
11286 objc-methodprotolist declaration
11287 objc-methodprotolist ;
11291 The declaration is a data definition, which may be missing
11292 declaration specifiers under the same rules and diagnostics as
11293 other data definitions outside functions, and the stray semicolon
11294 is diagnosed the same way as a stray semicolon outside a
11298 c_parser_objc_methodprotolist (c_parser
*parser
)
11302 /* The list is terminated by @end. */
11303 switch (c_parser_peek_token (parser
)->type
)
11305 case CPP_SEMICOLON
:
11306 pedwarn (c_parser_peek_token (parser
)->location
, OPT_Wpedantic
,
11307 "ISO C does not allow extra %<;%> outside of a function");
11308 c_parser_consume_token (parser
);
11312 c_parser_objc_methodproto (parser
);
11315 c_parser_pragma (parser
, pragma_external
, NULL
);
11320 if (c_parser_next_token_is_keyword (parser
, RID_AT_END
))
11322 else if (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
))
11323 c_parser_objc_at_property_declaration (parser
);
11324 else if (c_parser_next_token_is_keyword (parser
, RID_AT_OPTIONAL
))
11326 objc_set_method_opt (true);
11327 c_parser_consume_token (parser
);
11329 else if (c_parser_next_token_is_keyword (parser
, RID_AT_REQUIRED
))
11331 objc_set_method_opt (false);
11332 c_parser_consume_token (parser
);
11335 c_parser_declaration_or_fndef (parser
, false, false, true,
11342 /* Parse an objc-methodproto.
11345 objc-method-type objc-method-decl ;
11349 c_parser_objc_methodproto (c_parser
*parser
)
11351 bool is_class_method
= c_parser_objc_method_type (parser
);
11352 tree decl
, attributes
= NULL_TREE
;
11354 /* Remember protocol qualifiers in prototypes. */
11355 parser
->objc_pq_context
= true;
11356 decl
= c_parser_objc_method_decl (parser
, is_class_method
, &attributes
,
11358 /* Forget protocol qualifiers now. */
11359 parser
->objc_pq_context
= false;
11361 /* Do not allow the presence of attributes to hide an erroneous
11362 method implementation in the interface section. */
11363 if (!c_parser_next_token_is (parser
, CPP_SEMICOLON
))
11365 c_parser_error (parser
, "expected %<;%>");
11369 if (decl
!= error_mark_node
)
11370 objc_add_method_declaration (is_class_method
, decl
, attributes
);
11372 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
11375 /* If we are at a position that method attributes may be present, check that
11376 there are not any parsed already (a syntax error) and then collect any
11377 specified at the current location. Finally, if new attributes were present,
11378 check that the next token is legal ( ';' for decls and '{' for defs). */
11381 c_parser_objc_maybe_method_attributes (c_parser
* parser
, tree
* attributes
)
11386 c_parser_error (parser
,
11387 "method attributes must be specified at the end only");
11388 *attributes
= NULL_TREE
;
11392 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
11393 *attributes
= c_parser_gnu_attributes (parser
);
11395 /* If there were no attributes here, just report any earlier error. */
11396 if (*attributes
== NULL_TREE
|| bad
)
11399 /* If the attributes are followed by a ; or {, then just report any earlier
11401 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
11402 || c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
11405 /* We've got attributes, but not at the end. */
11406 c_parser_error (parser
,
11407 "expected %<;%> or %<{%> after method attribute definition");
11411 /* Parse an objc-method-decl.
11414 ( objc-type-name ) objc-selector
11416 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11417 objc-keyword-selector objc-optparmlist
11420 objc-keyword-selector:
11422 objc-keyword-selector objc-keyword-decl
11425 objc-selector : ( objc-type-name ) identifier
11426 objc-selector : identifier
11427 : ( objc-type-name ) identifier
11431 objc-optparms objc-optellipsis
11435 objc-opt-parms , parameter-declaration
11443 c_parser_objc_method_decl (c_parser
*parser
, bool is_class_method
,
11444 tree
*attributes
, tree
*expr
)
11446 tree type
= NULL_TREE
;
11448 tree parms
= NULL_TREE
;
11449 bool ellipsis
= false;
11450 bool attr_err
= false;
11452 *attributes
= NULL_TREE
;
11453 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11455 matching_parens parens
;
11456 parens
.consume_open (parser
);
11457 type
= c_parser_objc_type_name (parser
);
11458 parens
.skip_until_found_close (parser
);
11460 sel
= c_parser_objc_selector (parser
);
11461 /* If there is no selector, or a colon follows, we have an
11462 objc-keyword-selector. If there is a selector, and a colon does
11463 not follow, that selector ends the objc-method-decl. */
11464 if (!sel
|| c_parser_next_token_is (parser
, CPP_COLON
))
11467 tree list
= NULL_TREE
;
11470 tree atype
= NULL_TREE
, id
, keyworddecl
;
11471 tree param_attr
= NULL_TREE
;
11472 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11474 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
11476 c_parser_consume_token (parser
);
11477 atype
= c_parser_objc_type_name (parser
);
11478 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
11481 /* New ObjC allows attributes on method parameters. */
11482 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
11483 param_attr
= c_parser_gnu_attributes (parser
);
11484 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11486 c_parser_error (parser
, "expected identifier");
11487 return error_mark_node
;
11489 id
= c_parser_peek_token (parser
)->value
;
11490 c_parser_consume_token (parser
);
11491 keyworddecl
= objc_build_keyword_decl (tsel
, atype
, id
, param_attr
);
11492 list
= chainon (list
, keyworddecl
);
11493 tsel
= c_parser_objc_selector (parser
);
11494 if (!tsel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11498 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
11500 /* Parse the optional parameter list. Optional Objective-C
11501 method parameters follow the C syntax, and may include '...'
11502 to denote a variable number of arguments. */
11503 parms
= make_node (TREE_LIST
);
11504 while (c_parser_next_token_is (parser
, CPP_COMMA
))
11506 struct c_parm
*parm
;
11507 c_parser_consume_token (parser
);
11508 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
11511 c_parser_consume_token (parser
);
11512 attr_err
|= c_parser_objc_maybe_method_attributes
11513 (parser
, attributes
) ;
11516 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
11519 parms
= chainon (parms
,
11520 build_tree_list (NULL_TREE
, grokparm (parm
, expr
)));
11525 attr_err
|= c_parser_objc_maybe_method_attributes (parser
, attributes
) ;
11529 c_parser_error (parser
, "objective-c method declaration is expected");
11530 return error_mark_node
;
11534 return error_mark_node
;
11536 return objc_build_method_signature (is_class_method
, type
, sel
, parms
, ellipsis
);
11539 /* Parse an objc-type-name.
11542 objc-type-qualifiers[opt] type-name
11543 objc-type-qualifiers[opt]
11545 objc-type-qualifiers:
11546 objc-type-qualifier
11547 objc-type-qualifiers objc-type-qualifier
11549 objc-type-qualifier: one of
11550 in out inout bycopy byref oneway
11554 c_parser_objc_type_name (c_parser
*parser
)
11556 tree quals
= NULL_TREE
;
11557 struct c_type_name
*type_name
= NULL
;
11558 tree type
= NULL_TREE
;
11561 c_token
*token
= c_parser_peek_token (parser
);
11562 if (token
->type
== CPP_KEYWORD
11563 && (token
->keyword
== RID_IN
11564 || token
->keyword
== RID_OUT
11565 || token
->keyword
== RID_INOUT
11566 || token
->keyword
== RID_BYCOPY
11567 || token
->keyword
== RID_BYREF
11568 || token
->keyword
== RID_ONEWAY
))
11570 quals
= chainon (build_tree_list (NULL_TREE
, token
->value
), quals
);
11571 c_parser_consume_token (parser
);
11576 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_type
))
11577 type_name
= c_parser_type_name (parser
);
11579 type
= groktypename (type_name
, NULL
, NULL
);
11581 /* If the type is unknown, and error has already been produced and
11582 we need to recover from the error. In that case, use NULL_TREE
11583 for the type, as if no type had been specified; this will use the
11584 default type ('id') which is good for error recovery. */
11585 if (type
== error_mark_node
)
11588 return build_tree_list (quals
, type
);
11591 /* Parse objc-protocol-refs.
11593 objc-protocol-refs:
11594 < identifier-list >
11598 c_parser_objc_protocol_refs (c_parser
*parser
)
11600 tree list
= NULL_TREE
;
11601 gcc_assert (c_parser_next_token_is (parser
, CPP_LESS
));
11602 c_parser_consume_token (parser
);
11603 /* Any identifiers, including those declared as type names, are OK
11608 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
11610 c_parser_error (parser
, "expected identifier");
11613 id
= c_parser_peek_token (parser
)->value
;
11614 list
= chainon (list
, build_tree_list (NULL_TREE
, id
));
11615 c_parser_consume_token (parser
);
11616 if (c_parser_next_token_is (parser
, CPP_COMMA
))
11617 c_parser_consume_token (parser
);
11621 c_parser_require (parser
, CPP_GREATER
, "expected %<>%>");
11625 /* Parse an objc-try-catch-finally-statement.
11627 objc-try-catch-finally-statement:
11628 @try compound-statement objc-catch-list[opt]
11629 @try compound-statement objc-catch-list[opt] @finally compound-statement
11632 @catch ( objc-catch-parameter-declaration ) compound-statement
11633 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11635 objc-catch-parameter-declaration:
11636 parameter-declaration
11639 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11641 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11642 for C++. Keep them in sync. */
11645 c_parser_objc_try_catch_finally_statement (c_parser
*parser
)
11647 location_t location
;
11650 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_TRY
));
11651 c_parser_consume_token (parser
);
11652 location
= c_parser_peek_token (parser
)->location
;
11653 objc_maybe_warn_exceptions (location
);
11654 stmt
= c_parser_compound_statement (parser
);
11655 objc_begin_try_stmt (location
, stmt
);
11657 while (c_parser_next_token_is_keyword (parser
, RID_AT_CATCH
))
11659 struct c_parm
*parm
;
11660 tree parameter_declaration
= error_mark_node
;
11661 bool seen_open_paren
= false;
11663 c_parser_consume_token (parser
);
11664 matching_parens parens
;
11665 if (!parens
.require_open (parser
))
11666 seen_open_paren
= true;
11667 if (c_parser_next_token_is (parser
, CPP_ELLIPSIS
))
11669 /* We have "@catch (...)" (where the '...' are literally
11670 what is in the code). Skip the '...'.
11671 parameter_declaration is set to NULL_TREE, and
11672 objc_being_catch_clauses() knows that that means
11674 c_parser_consume_token (parser
);
11675 parameter_declaration
= NULL_TREE
;
11679 /* We have "@catch (NSException *exception)" or something
11680 like that. Parse the parameter declaration. */
11681 parm
= c_parser_parameter_declaration (parser
, NULL_TREE
, false);
11683 parameter_declaration
= error_mark_node
;
11685 parameter_declaration
= grokparm (parm
, NULL
);
11687 if (seen_open_paren
)
11688 parens
.require_close (parser
);
11691 /* If there was no open parenthesis, we are recovering from
11692 an error, and we are trying to figure out what mistake
11693 the user has made. */
11695 /* If there is an immediate closing parenthesis, the user
11696 probably forgot the opening one (ie, they typed "@catch
11697 NSException *e)". Parse the closing parenthesis and keep
11699 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
11700 c_parser_consume_token (parser
);
11702 /* If these is no immediate closing parenthesis, the user
11703 probably doesn't know that parenthesis are required at
11704 all (ie, they typed "@catch NSException *e"). So, just
11705 forget about the closing parenthesis and keep going. */
11707 objc_begin_catch_clause (parameter_declaration
);
11708 if (c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
11709 c_parser_compound_statement_nostart (parser
);
11710 objc_finish_catch_clause ();
11712 if (c_parser_next_token_is_keyword (parser
, RID_AT_FINALLY
))
11714 c_parser_consume_token (parser
);
11715 location
= c_parser_peek_token (parser
)->location
;
11716 stmt
= c_parser_compound_statement (parser
);
11717 objc_build_finally_clause (location
, stmt
);
11719 objc_finish_try_stmt ();
11722 /* Parse an objc-synchronized-statement.
11724 objc-synchronized-statement:
11725 @synchronized ( expression ) compound-statement
11729 c_parser_objc_synchronized_statement (c_parser
*parser
)
11733 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNCHRONIZED
));
11734 c_parser_consume_token (parser
);
11735 loc
= c_parser_peek_token (parser
)->location
;
11736 objc_maybe_warn_exceptions (loc
);
11737 matching_parens parens
;
11738 if (parens
.require_open (parser
))
11740 struct c_expr ce
= c_parser_expression (parser
);
11741 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
11743 expr
= c_fully_fold (expr
, false, NULL
);
11744 parens
.skip_until_found_close (parser
);
11747 expr
= error_mark_node
;
11748 stmt
= c_parser_compound_statement (parser
);
11749 objc_build_synchronized (loc
, expr
, stmt
);
11752 /* Parse an objc-selector; return NULL_TREE without an error if the
11753 next token is not an objc-selector.
11758 enum struct union if else while do for switch case default
11759 break continue return goto asm sizeof typeof __alignof
11760 unsigned long const short volatile signed restrict _Complex
11761 in out inout bycopy byref oneway int char float double void _Bool
11764 ??? Why this selection of keywords but not, for example, storage
11765 class specifiers? */
11768 c_parser_objc_selector (c_parser
*parser
)
11770 c_token
*token
= c_parser_peek_token (parser
);
11771 tree value
= token
->value
;
11772 if (token
->type
== CPP_NAME
)
11774 c_parser_consume_token (parser
);
11777 if (token
->type
!= CPP_KEYWORD
)
11779 switch (token
->keyword
)
11818 CASE_RID_FLOATN_NX
:
11822 case RID_AUTO_TYPE
:
11827 c_parser_consume_token (parser
);
11834 /* Parse an objc-selector-arg.
11838 objc-keywordname-list
11840 objc-keywordname-list:
11842 objc-keywordname-list objc-keywordname
11850 c_parser_objc_selector_arg (c_parser
*parser
)
11852 tree sel
= c_parser_objc_selector (parser
);
11853 tree list
= NULL_TREE
;
11855 && c_parser_next_token_is_not (parser
, CPP_COLON
)
11856 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
11860 if (c_parser_next_token_is (parser
, CPP_SCOPE
))
11862 c_parser_consume_token (parser
);
11863 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
11864 list
= chainon (list
, build_tree_list (NULL_TREE
, NULL_TREE
));
11868 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11870 list
= chainon (list
, build_tree_list (sel
, NULL_TREE
));
11872 sel
= c_parser_objc_selector (parser
);
11874 && c_parser_next_token_is_not (parser
, CPP_COLON
)
11875 && c_parser_next_token_is_not (parser
, CPP_SCOPE
))
11881 /* Parse an objc-receiver.
11890 c_parser_objc_receiver (c_parser
*parser
)
11892 location_t loc
= c_parser_peek_token (parser
)->location
;
11894 if (c_parser_peek_token (parser
)->type
== CPP_NAME
11895 && (c_parser_peek_token (parser
)->id_kind
== C_ID_TYPENAME
11896 || c_parser_peek_token (parser
)->id_kind
== C_ID_CLASSNAME
))
11898 tree id
= c_parser_peek_token (parser
)->value
;
11899 c_parser_consume_token (parser
);
11900 return objc_get_class_reference (id
);
11902 struct c_expr ce
= c_parser_expression (parser
);
11903 ce
= convert_lvalue_to_rvalue (loc
, ce
, false, false);
11904 return c_fully_fold (ce
.value
, false, NULL
);
11907 /* Parse objc-message-args.
11911 objc-keywordarg-list
11913 objc-keywordarg-list:
11915 objc-keywordarg-list objc-keywordarg
11918 objc-selector : objc-keywordexpr
11923 c_parser_objc_message_args (c_parser
*parser
)
11925 tree sel
= c_parser_objc_selector (parser
);
11926 tree list
= NULL_TREE
;
11927 if (sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11932 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
11933 return error_mark_node
;
11934 keywordexpr
= c_parser_objc_keywordexpr (parser
);
11935 list
= chainon (list
, build_tree_list (sel
, keywordexpr
));
11936 sel
= c_parser_objc_selector (parser
);
11937 if (!sel
&& c_parser_next_token_is_not (parser
, CPP_COLON
))
11943 /* Parse an objc-keywordexpr.
11950 c_parser_objc_keywordexpr (c_parser
*parser
)
11953 vec
<tree
, va_gc
> *expr_list
= c_parser_expr_list (parser
, true, true,
11954 NULL
, NULL
, NULL
, NULL
);
11955 if (vec_safe_length (expr_list
) == 1)
11957 /* Just return the expression, remove a level of
11959 ret
= (*expr_list
)[0];
11963 /* We have a comma expression, we will collapse later. */
11964 ret
= build_tree_list_vec (expr_list
);
11966 release_tree_vector (expr_list
);
11970 /* A check, needed in several places, that ObjC interface, implementation or
11971 method definitions are not prefixed by incorrect items. */
11973 c_parser_objc_diagnose_bad_element_prefix (c_parser
*parser
,
11974 struct c_declspecs
*specs
)
11976 if (!specs
->declspecs_seen_p
|| specs
->non_sc_seen_p
11977 || specs
->typespec_kind
!= ctsk_none
)
11979 c_parser_error (parser
,
11980 "no type or storage class may be specified here,");
11981 c_parser_skip_to_end_of_block_or_statement (parser
);
11987 /* Parse an Objective-C @property declaration. The syntax is:
11989 objc-property-declaration:
11990 '@property' objc-property-attributes[opt] struct-declaration ;
11992 objc-property-attributes:
11993 '(' objc-property-attribute-list ')'
11995 objc-property-attribute-list:
11996 objc-property-attribute
11997 objc-property-attribute-list, objc-property-attribute
11999 objc-property-attribute
12000 'getter' = identifier
12001 'setter' = identifier
12010 @property NSString *name;
12011 @property (readonly) id object;
12012 @property (retain, nonatomic, getter=getTheName) id name;
12013 @property int a, b, c;
12015 PS: This function is identical to cp_parser_objc_at_propery_declaration
12016 for C++. Keep them in sync. */
12018 c_parser_objc_at_property_declaration (c_parser
*parser
)
12020 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_PROPERTY
));
12021 location_t loc
= c_parser_peek_token (parser
)->location
;
12022 c_parser_consume_token (parser
); /* Eat '@property'. */
12024 /* Parse the optional attribute list.
12026 A list of parsed, but not verified, attributes. */
12027 vec
<property_attribute_info
*> prop_attr_list
= vNULL
;
12029 bool syntax_error
= false;
12030 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
12032 matching_parens parens
;
12034 location_t attr_start
= c_parser_peek_token (parser
)->location
;
12036 parens
.consume_open (parser
);
12038 /* Property attribute keywords are valid now. */
12039 parser
->objc_property_attr_context
= true;
12041 /* Allow @property (), with a warning. */
12042 location_t attr_end
= c_parser_peek_token (parser
)->location
;
12044 if (c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
12046 location_t attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
12047 warning_at (attr_comb
, OPT_Wattributes
,
12048 "empty property attribute list");
12053 c_token
*token
= c_parser_peek_token (parser
);
12054 attr_start
= token
->location
;
12055 attr_end
= get_finish (token
->location
);
12056 location_t attr_comb
= make_location (attr_start
, attr_start
,
12059 if (token
->type
== CPP_CLOSE_PAREN
|| token
->type
== CPP_COMMA
)
12061 warning_at (attr_comb
, OPT_Wattributes
,
12062 "missing property attribute");
12063 if (token
->type
== CPP_CLOSE_PAREN
)
12065 c_parser_consume_token (parser
);
12069 tree attr_name
= NULL_TREE
;
12070 enum rid keyword
= RID_MAX
; /* Not a valid property attribute. */
12071 bool add_at
= false;
12072 if (token
->type
== CPP_KEYWORD
)
12074 keyword
= token
->keyword
;
12075 if (OBJC_IS_AT_KEYWORD (keyword
))
12077 /* For '@' keywords the token value has the keyword,
12078 prepend the '@' for diagnostics. */
12079 attr_name
= token
->value
;
12083 attr_name
= ridpointers
[(int)keyword
];
12085 else if (token
->type
== CPP_NAME
)
12086 attr_name
= token
->value
;
12087 c_parser_consume_token (parser
);
12089 enum objc_property_attribute_kind prop_kind
12090 = objc_prop_attr_kind_for_rid (keyword
);
12091 property_attribute_info
*prop
12092 = new property_attribute_info (attr_name
, attr_comb
, prop_kind
);
12093 prop_attr_list
.safe_push (prop
);
12096 switch (prop
->prop_kind
)
12099 case OBJC_PROPERTY_ATTR_UNKNOWN
:
12101 error_at (attr_comb
, "unknown property attribute %<%s%s%>",
12102 add_at
? "@" : "", IDENTIFIER_POINTER (attr_name
));
12104 error_at (attr_comb
, "unknown property attribute");
12105 prop
->parse_error
= syntax_error
= true;
12108 case OBJC_PROPERTY_ATTR_GETTER
:
12109 case OBJC_PROPERTY_ATTR_SETTER
:
12110 if (c_parser_next_token_is_not (parser
, CPP_EQ
))
12112 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
12113 error_at (attr_comb
, "expected %<=%> after Objective-C %qE",
12115 prop
->parse_error
= syntax_error
= true;
12118 token
= c_parser_peek_token (parser
);
12119 attr_end
= token
->location
;
12120 c_parser_consume_token (parser
); /* eat the = */
12121 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12123 attr_comb
= make_location (attr_end
, attr_start
, attr_end
);
12124 error_at (attr_comb
, "expected %qE selector name",
12126 prop
->parse_error
= syntax_error
= true;
12129 /* Get the end of the method name, and consume the name. */
12130 token
= c_parser_peek_token (parser
);
12131 attr_end
= get_finish (token
->location
);
12132 meth_name
= token
->value
;
12133 c_parser_consume_token (parser
);
12134 if (prop
->prop_kind
== OBJC_PROPERTY_ATTR_SETTER
)
12136 if (c_parser_next_token_is_not (parser
, CPP_COLON
))
12138 attr_comb
= make_location (attr_end
, attr_start
,
12140 error_at (attr_comb
, "setter method names must"
12141 " terminate with %<:%>");
12142 prop
->parse_error
= syntax_error
= true;
12146 attr_end
= get_finish (c_parser_peek_token
12147 (parser
)->location
);
12148 c_parser_consume_token (parser
);
12150 attr_comb
= make_location (attr_start
, attr_start
,
12154 attr_comb
= make_location (attr_start
, attr_start
,
12156 prop
->ident
= meth_name
;
12157 /* Updated location including all that was successfully
12159 prop
->prop_loc
= attr_comb
;
12163 /* If we see a comma here, then keep going - even if we already
12164 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12165 this makes a more useful output and avoid spurious warnings about
12166 missing attributes that are, in fact, specified after the one with
12167 the syntax error. */
12168 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12169 c_parser_consume_token (parser
);
12173 parser
->objc_property_attr_context
= false;
12175 if (syntax_error
&& c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
12176 /* We don't really want to chew the whole of the file looking for a
12177 matching closing parenthesis, so we will try to read the decl and
12178 let the error handling for that close out the statement. */
12181 syntax_error
= false, parens
.skip_until_found_close (parser
);
12184 /* 'properties' is the list of properties that we read. Usually a
12185 single one, but maybe more (eg, in "@property int a, b, c;" there
12187 tree properties
= c_parser_struct_declaration (parser
);
12189 if (properties
== error_mark_node
)
12190 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12193 if (properties
== NULL_TREE
)
12194 c_parser_error (parser
, "expected identifier");
12197 /* Comma-separated properties are chained together in reverse order;
12198 add them one by one. */
12199 properties
= nreverse (properties
);
12200 for (; properties
; properties
= TREE_CHAIN (properties
))
12201 objc_add_property_declaration (loc
, copy_node (properties
),
12204 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12207 while (!prop_attr_list
.is_empty())
12208 delete prop_attr_list
.pop ();
12209 prop_attr_list
.release ();
12210 parser
->error
= false;
12213 /* Parse an Objective-C @synthesize declaration. The syntax is:
12215 objc-synthesize-declaration:
12216 @synthesize objc-synthesize-identifier-list ;
12218 objc-synthesize-identifier-list:
12219 objc-synthesize-identifier
12220 objc-synthesize-identifier-list, objc-synthesize-identifier
12222 objc-synthesize-identifier
12224 identifier = identifier
12227 @synthesize MyProperty;
12228 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12230 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12231 for C++. Keep them in sync.
12234 c_parser_objc_at_synthesize_declaration (c_parser
*parser
)
12236 tree list
= NULL_TREE
;
12238 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_SYNTHESIZE
));
12239 loc
= c_parser_peek_token (parser
)->location
;
12241 c_parser_consume_token (parser
);
12244 tree property
, ivar
;
12245 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12247 c_parser_error (parser
, "expected identifier");
12248 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12249 /* Once we find the semicolon, we can resume normal parsing.
12250 We have to reset parser->error manually because
12251 c_parser_skip_until_found() won't reset it for us if the
12252 next token is precisely a semicolon. */
12253 parser
->error
= false;
12256 property
= c_parser_peek_token (parser
)->value
;
12257 c_parser_consume_token (parser
);
12258 if (c_parser_next_token_is (parser
, CPP_EQ
))
12260 c_parser_consume_token (parser
);
12261 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12263 c_parser_error (parser
, "expected identifier");
12264 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12265 parser
->error
= false;
12268 ivar
= c_parser_peek_token (parser
)->value
;
12269 c_parser_consume_token (parser
);
12273 list
= chainon (list
, build_tree_list (ivar
, property
));
12274 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12275 c_parser_consume_token (parser
);
12279 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12280 objc_add_synthesize_declaration (loc
, list
);
12283 /* Parse an Objective-C @dynamic declaration. The syntax is:
12285 objc-dynamic-declaration:
12286 @dynamic identifier-list ;
12289 @dynamic MyProperty;
12290 @dynamic MyProperty, AnotherProperty;
12292 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12293 for C++. Keep them in sync.
12296 c_parser_objc_at_dynamic_declaration (c_parser
*parser
)
12298 tree list
= NULL_TREE
;
12300 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_AT_DYNAMIC
));
12301 loc
= c_parser_peek_token (parser
)->location
;
12303 c_parser_consume_token (parser
);
12307 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
12309 c_parser_error (parser
, "expected identifier");
12310 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, NULL
);
12311 parser
->error
= false;
12314 property
= c_parser_peek_token (parser
)->value
;
12315 list
= chainon (list
, build_tree_list (NULL_TREE
, property
));
12316 c_parser_consume_token (parser
);
12317 if (c_parser_next_token_is (parser
, CPP_COMMA
))
12318 c_parser_consume_token (parser
);
12322 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
12323 objc_add_dynamic_declaration (loc
, list
);
12327 /* Parse a pragma GCC ivdep. */
12330 c_parse_pragma_ivdep (c_parser
*parser
)
12332 c_parser_consume_pragma (parser
);
12333 c_parser_skip_to_pragma_eol (parser
);
12337 /* Parse a pragma GCC unroll. */
12339 static unsigned short
12340 c_parser_pragma_unroll (c_parser
*parser
)
12342 unsigned short unroll
;
12343 c_parser_consume_pragma (parser
);
12344 location_t location
= c_parser_peek_token (parser
)->location
;
12345 tree expr
= c_parser_expr_no_commas (parser
, NULL
).value
;
12346 mark_exp_read (expr
);
12347 expr
= c_fully_fold (expr
, false, NULL
);
12348 HOST_WIDE_INT lunroll
= 0;
12349 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
12350 || TREE_CODE (expr
) != INTEGER_CST
12351 || (lunroll
= tree_to_shwi (expr
)) < 0
12352 || lunroll
>= USHRT_MAX
)
12354 error_at (location
, "%<#pragma GCC unroll%> requires an"
12355 " assignment-expression that evaluates to a non-negative"
12356 " integral constant less than %u", USHRT_MAX
);
12361 unroll
= (unsigned short)lunroll
;
12366 c_parser_skip_to_pragma_eol (parser
);
12370 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12371 should be considered, statements. ALLOW_STMT is true if we're within
12372 the context of a function and such pragmas are to be allowed. Returns
12373 true if we actually parsed such a pragma. */
12376 c_parser_pragma (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
12379 const char *construct
= NULL
;
12381 input_location
= c_parser_peek_token (parser
)->location
;
12382 id
= c_parser_peek_token (parser
)->pragma_kind
;
12383 gcc_assert (id
!= PRAGMA_NONE
);
12387 case PRAGMA_OACC_DECLARE
:
12388 c_parser_oacc_declare (parser
);
12391 case PRAGMA_OACC_ENTER_DATA
:
12392 if (context
!= pragma_compound
)
12394 construct
= "acc enter data";
12396 if (context
== pragma_stmt
)
12398 error_at (c_parser_peek_token (parser
)->location
,
12399 "%<#pragma %s%> may only be used in compound "
12400 "statements", construct
);
12401 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12406 c_parser_oacc_enter_exit_data (parser
, true);
12409 case PRAGMA_OACC_EXIT_DATA
:
12410 if (context
!= pragma_compound
)
12412 construct
= "acc exit data";
12415 c_parser_oacc_enter_exit_data (parser
, false);
12418 case PRAGMA_OACC_ROUTINE
:
12419 if (context
!= pragma_external
)
12421 error_at (c_parser_peek_token (parser
)->location
,
12422 "%<#pragma acc routine%> must be at file scope");
12423 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12426 c_parser_oacc_routine (parser
, context
);
12429 case PRAGMA_OACC_UPDATE
:
12430 if (context
!= pragma_compound
)
12432 construct
= "acc update";
12435 c_parser_oacc_update (parser
);
12438 case PRAGMA_OMP_BARRIER
:
12439 if (context
!= pragma_compound
)
12441 construct
= "omp barrier";
12444 c_parser_omp_barrier (parser
);
12447 case PRAGMA_OMP_DEPOBJ
:
12448 if (context
!= pragma_compound
)
12450 construct
= "omp depobj";
12453 c_parser_omp_depobj (parser
);
12456 case PRAGMA_OMP_FLUSH
:
12457 if (context
!= pragma_compound
)
12459 construct
= "omp flush";
12462 c_parser_omp_flush (parser
);
12465 case PRAGMA_OMP_TASKWAIT
:
12466 if (context
!= pragma_compound
)
12468 construct
= "omp taskwait";
12471 c_parser_omp_taskwait (parser
);
12474 case PRAGMA_OMP_TASKYIELD
:
12475 if (context
!= pragma_compound
)
12477 construct
= "omp taskyield";
12480 c_parser_omp_taskyield (parser
);
12483 case PRAGMA_OMP_CANCEL
:
12484 if (context
!= pragma_compound
)
12486 construct
= "omp cancel";
12489 c_parser_omp_cancel (parser
);
12492 case PRAGMA_OMP_CANCELLATION_POINT
:
12493 return c_parser_omp_cancellation_point (parser
, context
);
12495 case PRAGMA_OMP_THREADPRIVATE
:
12496 c_parser_omp_threadprivate (parser
);
12499 case PRAGMA_OMP_TARGET
:
12500 return c_parser_omp_target (parser
, context
, if_p
);
12502 case PRAGMA_OMP_END_DECLARE_TARGET
:
12503 c_parser_omp_end_declare_target (parser
);
12506 case PRAGMA_OMP_SCAN
:
12507 error_at (c_parser_peek_token (parser
)->location
,
12508 "%<#pragma omp scan%> may only be used in "
12509 "a loop construct with %<inscan%> %<reduction%> clause");
12510 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12513 case PRAGMA_OMP_SECTION
:
12514 error_at (c_parser_peek_token (parser
)->location
,
12515 "%<#pragma omp section%> may only be used in "
12516 "%<#pragma omp sections%> construct");
12517 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12520 case PRAGMA_OMP_DECLARE
:
12521 return c_parser_omp_declare (parser
, context
);
12523 case PRAGMA_OMP_REQUIRES
:
12524 if (context
!= pragma_external
)
12526 error_at (c_parser_peek_token (parser
)->location
,
12527 "%<#pragma omp requires%> may only be used at file scope");
12528 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12531 c_parser_omp_requires (parser
);
12534 case PRAGMA_OMP_NOTHING
:
12535 c_parser_omp_nothing (parser
);
12538 case PRAGMA_OMP_ERROR
:
12539 return c_parser_omp_error (parser
, context
);
12541 case PRAGMA_OMP_ORDERED
:
12542 return c_parser_omp_ordered (parser
, context
, if_p
);
12546 const bool ivdep
= c_parse_pragma_ivdep (parser
);
12547 unsigned short unroll
;
12548 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_UNROLL
)
12549 unroll
= c_parser_pragma_unroll (parser
);
12552 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12553 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12554 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12556 c_parser_error (parser
, "for, while or do statement expected");
12559 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12560 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12561 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12562 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12564 c_parser_do_statement (parser
, ivdep
, unroll
);
12568 case PRAGMA_UNROLL
:
12570 unsigned short unroll
= c_parser_pragma_unroll (parser
);
12572 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_IVDEP
)
12573 ivdep
= c_parse_pragma_ivdep (parser
);
12576 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
)
12577 && !c_parser_next_token_is_keyword (parser
, RID_WHILE
)
12578 && !c_parser_next_token_is_keyword (parser
, RID_DO
))
12580 c_parser_error (parser
, "for, while or do statement expected");
12583 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12584 c_parser_for_statement (parser
, ivdep
, unroll
, if_p
);
12585 else if (c_parser_next_token_is_keyword (parser
, RID_WHILE
))
12586 c_parser_while_statement (parser
, ivdep
, unroll
, if_p
);
12588 c_parser_do_statement (parser
, ivdep
, unroll
);
12592 case PRAGMA_GCC_PCH_PREPROCESS
:
12593 c_parser_error (parser
, "%<#pragma GCC pch_preprocess%> must be first");
12594 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12597 case PRAGMA_OACC_WAIT
:
12598 if (context
!= pragma_compound
)
12600 construct
= "acc wait";
12603 /* FALL THROUGH. */
12606 if (id
< PRAGMA_FIRST_EXTERNAL
)
12608 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
12611 c_parser_error (parser
, "expected declaration specifiers");
12612 c_parser_skip_until_found (parser
, CPP_PRAGMA_EOL
, NULL
);
12615 c_parser_omp_construct (parser
, if_p
);
12621 c_parser_consume_pragma (parser
);
12622 c_invoke_pragma_handler (id
);
12624 /* Skip to EOL, but suppress any error message. Those will have been
12625 generated by the handler routine through calling error, as opposed
12626 to calling c_parser_error. */
12627 parser
->error
= true;
12628 c_parser_skip_to_pragma_eol (parser
);
12633 /* The interface the pragma parsers have to the lexer. */
12636 pragma_lex (tree
*value
, location_t
*loc
)
12638 c_token
*tok
= c_parser_peek_token (the_parser
);
12639 enum cpp_ttype ret
= tok
->type
;
12641 *value
= tok
->value
;
12643 *loc
= tok
->location
;
12645 if (ret
== CPP_PRAGMA_EOL
|| ret
== CPP_EOF
)
12647 else if (ret
== CPP_STRING
)
12648 *value
= c_parser_string_literal (the_parser
, false, false).value
;
12651 if (ret
== CPP_KEYWORD
)
12653 c_parser_consume_token (the_parser
);
12660 c_parser_pragma_pch_preprocess (c_parser
*parser
)
12664 parser
->lex_joined_string
= true;
12665 c_parser_consume_pragma (parser
);
12666 if (c_parser_next_token_is (parser
, CPP_STRING
))
12668 name
= c_parser_peek_token (parser
)->value
;
12669 c_parser_consume_token (parser
);
12672 c_parser_error (parser
, "expected string literal");
12673 c_parser_skip_to_pragma_eol (parser
);
12674 parser
->lex_joined_string
= false;
12677 c_common_pch_pragma (parse_in
, TREE_STRING_POINTER (name
));
12680 /* OpenACC and OpenMP parsing routines. */
12682 /* Returns name of the next clause.
12683 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12684 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12685 returned and the token is consumed. */
12687 static pragma_omp_clause
12688 c_parser_omp_clause_name (c_parser
*parser
)
12690 pragma_omp_clause result
= PRAGMA_OMP_CLAUSE_NONE
;
12692 if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
12693 result
= PRAGMA_OACC_CLAUSE_AUTO
;
12694 else if (c_parser_next_token_is_keyword (parser
, RID_IF
))
12695 result
= PRAGMA_OMP_CLAUSE_IF
;
12696 else if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
12697 result
= PRAGMA_OMP_CLAUSE_DEFAULT
;
12698 else if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
12699 result
= PRAGMA_OMP_CLAUSE_FOR
;
12700 else if (c_parser_next_token_is (parser
, CPP_NAME
))
12702 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
12707 if (!strcmp ("affinity", p
))
12708 result
= PRAGMA_OMP_CLAUSE_AFFINITY
;
12709 else if (!strcmp ("aligned", p
))
12710 result
= PRAGMA_OMP_CLAUSE_ALIGNED
;
12711 else if (!strcmp ("allocate", p
))
12712 result
= PRAGMA_OMP_CLAUSE_ALLOCATE
;
12713 else if (!strcmp ("async", p
))
12714 result
= PRAGMA_OACC_CLAUSE_ASYNC
;
12715 else if (!strcmp ("attach", p
))
12716 result
= PRAGMA_OACC_CLAUSE_ATTACH
;
12719 if (!strcmp ("bind", p
))
12720 result
= PRAGMA_OMP_CLAUSE_BIND
;
12723 if (!strcmp ("collapse", p
))
12724 result
= PRAGMA_OMP_CLAUSE_COLLAPSE
;
12725 else if (!strcmp ("copy", p
))
12726 result
= PRAGMA_OACC_CLAUSE_COPY
;
12727 else if (!strcmp ("copyin", p
))
12728 result
= PRAGMA_OMP_CLAUSE_COPYIN
;
12729 else if (!strcmp ("copyout", p
))
12730 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12731 else if (!strcmp ("copyprivate", p
))
12732 result
= PRAGMA_OMP_CLAUSE_COPYPRIVATE
;
12733 else if (!strcmp ("create", p
))
12734 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12737 if (!strcmp ("defaultmap", p
))
12738 result
= PRAGMA_OMP_CLAUSE_DEFAULTMAP
;
12739 else if (!strcmp ("delete", p
))
12740 result
= PRAGMA_OACC_CLAUSE_DELETE
;
12741 else if (!strcmp ("depend", p
))
12742 result
= PRAGMA_OMP_CLAUSE_DEPEND
;
12743 else if (!strcmp ("detach", p
))
12744 result
= PRAGMA_OACC_CLAUSE_DETACH
;
12745 else if (!strcmp ("device", p
))
12746 result
= PRAGMA_OMP_CLAUSE_DEVICE
;
12747 else if (!strcmp ("deviceptr", p
))
12748 result
= PRAGMA_OACC_CLAUSE_DEVICEPTR
;
12749 else if (!strcmp ("device_resident", p
))
12750 result
= PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
;
12751 else if (!strcmp ("device_type", p
))
12752 result
= PRAGMA_OMP_CLAUSE_DEVICE_TYPE
;
12753 else if (!strcmp ("dist_schedule", p
))
12754 result
= PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
;
12757 if (!strcmp ("filter", p
))
12758 result
= PRAGMA_OMP_CLAUSE_FILTER
;
12759 else if (!strcmp ("final", p
))
12760 result
= PRAGMA_OMP_CLAUSE_FINAL
;
12761 else if (!strcmp ("finalize", p
))
12762 result
= PRAGMA_OACC_CLAUSE_FINALIZE
;
12763 else if (!strcmp ("firstprivate", p
))
12764 result
= PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
;
12765 else if (!strcmp ("from", p
))
12766 result
= PRAGMA_OMP_CLAUSE_FROM
;
12769 if (!strcmp ("gang", p
))
12770 result
= PRAGMA_OACC_CLAUSE_GANG
;
12771 else if (!strcmp ("grainsize", p
))
12772 result
= PRAGMA_OMP_CLAUSE_GRAINSIZE
;
12775 if (!strcmp ("has_device_addr", p
))
12776 result
= PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
;
12777 else if (!strcmp ("hint", p
))
12778 result
= PRAGMA_OMP_CLAUSE_HINT
;
12779 else if (!strcmp ("host", p
))
12780 result
= PRAGMA_OACC_CLAUSE_HOST
;
12783 if (!strcmp ("if_present", p
))
12784 result
= PRAGMA_OACC_CLAUSE_IF_PRESENT
;
12785 else if (!strcmp ("in_reduction", p
))
12786 result
= PRAGMA_OMP_CLAUSE_IN_REDUCTION
;
12787 else if (!strcmp ("inbranch", p
))
12788 result
= PRAGMA_OMP_CLAUSE_INBRANCH
;
12789 else if (!strcmp ("independent", p
))
12790 result
= PRAGMA_OACC_CLAUSE_INDEPENDENT
;
12791 else if (!strcmp ("is_device_ptr", p
))
12792 result
= PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
;
12795 if (!strcmp ("lastprivate", p
))
12796 result
= PRAGMA_OMP_CLAUSE_LASTPRIVATE
;
12797 else if (!strcmp ("linear", p
))
12798 result
= PRAGMA_OMP_CLAUSE_LINEAR
;
12799 else if (!strcmp ("link", p
))
12800 result
= PRAGMA_OMP_CLAUSE_LINK
;
12803 if (!strcmp ("map", p
))
12804 result
= PRAGMA_OMP_CLAUSE_MAP
;
12805 else if (!strcmp ("mergeable", p
))
12806 result
= PRAGMA_OMP_CLAUSE_MERGEABLE
;
12809 if (!strcmp ("no_create", p
))
12810 result
= PRAGMA_OACC_CLAUSE_NO_CREATE
;
12811 else if (!strcmp ("nogroup", p
))
12812 result
= PRAGMA_OMP_CLAUSE_NOGROUP
;
12813 else if (!strcmp ("nohost", p
))
12814 result
= PRAGMA_OACC_CLAUSE_NOHOST
;
12815 else if (!strcmp ("nontemporal", p
))
12816 result
= PRAGMA_OMP_CLAUSE_NONTEMPORAL
;
12817 else if (!strcmp ("notinbranch", p
))
12818 result
= PRAGMA_OMP_CLAUSE_NOTINBRANCH
;
12819 else if (!strcmp ("nowait", p
))
12820 result
= PRAGMA_OMP_CLAUSE_NOWAIT
;
12821 else if (!strcmp ("num_gangs", p
))
12822 result
= PRAGMA_OACC_CLAUSE_NUM_GANGS
;
12823 else if (!strcmp ("num_tasks", p
))
12824 result
= PRAGMA_OMP_CLAUSE_NUM_TASKS
;
12825 else if (!strcmp ("num_teams", p
))
12826 result
= PRAGMA_OMP_CLAUSE_NUM_TEAMS
;
12827 else if (!strcmp ("num_threads", p
))
12828 result
= PRAGMA_OMP_CLAUSE_NUM_THREADS
;
12829 else if (!strcmp ("num_workers", p
))
12830 result
= PRAGMA_OACC_CLAUSE_NUM_WORKERS
;
12833 if (!strcmp ("ordered", p
))
12834 result
= PRAGMA_OMP_CLAUSE_ORDERED
;
12835 else if (!strcmp ("order", p
))
12836 result
= PRAGMA_OMP_CLAUSE_ORDER
;
12839 if (!strcmp ("parallel", p
))
12840 result
= PRAGMA_OMP_CLAUSE_PARALLEL
;
12841 else if (!strcmp ("present", p
))
12842 result
= PRAGMA_OACC_CLAUSE_PRESENT
;
12843 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12845 else if (!strcmp ("present_or_copy", p
)
12846 || !strcmp ("pcopy", p
))
12847 result
= PRAGMA_OACC_CLAUSE_COPY
;
12848 else if (!strcmp ("present_or_copyin", p
)
12849 || !strcmp ("pcopyin", p
))
12850 result
= PRAGMA_OACC_CLAUSE_COPYIN
;
12851 else if (!strcmp ("present_or_copyout", p
)
12852 || !strcmp ("pcopyout", p
))
12853 result
= PRAGMA_OACC_CLAUSE_COPYOUT
;
12854 else if (!strcmp ("present_or_create", p
)
12855 || !strcmp ("pcreate", p
))
12856 result
= PRAGMA_OACC_CLAUSE_CREATE
;
12857 else if (!strcmp ("priority", p
))
12858 result
= PRAGMA_OMP_CLAUSE_PRIORITY
;
12859 else if (!strcmp ("private", p
))
12860 result
= PRAGMA_OMP_CLAUSE_PRIVATE
;
12861 else if (!strcmp ("proc_bind", p
))
12862 result
= PRAGMA_OMP_CLAUSE_PROC_BIND
;
12865 if (!strcmp ("reduction", p
))
12866 result
= PRAGMA_OMP_CLAUSE_REDUCTION
;
12869 if (!strcmp ("safelen", p
))
12870 result
= PRAGMA_OMP_CLAUSE_SAFELEN
;
12871 else if (!strcmp ("schedule", p
))
12872 result
= PRAGMA_OMP_CLAUSE_SCHEDULE
;
12873 else if (!strcmp ("sections", p
))
12874 result
= PRAGMA_OMP_CLAUSE_SECTIONS
;
12875 else if (!strcmp ("self", p
)) /* "self" is a synonym for "host". */
12876 result
= PRAGMA_OACC_CLAUSE_HOST
;
12877 else if (!strcmp ("seq", p
))
12878 result
= PRAGMA_OACC_CLAUSE_SEQ
;
12879 else if (!strcmp ("shared", p
))
12880 result
= PRAGMA_OMP_CLAUSE_SHARED
;
12881 else if (!strcmp ("simd", p
))
12882 result
= PRAGMA_OMP_CLAUSE_SIMD
;
12883 else if (!strcmp ("simdlen", p
))
12884 result
= PRAGMA_OMP_CLAUSE_SIMDLEN
;
12887 if (!strcmp ("task_reduction", p
))
12888 result
= PRAGMA_OMP_CLAUSE_TASK_REDUCTION
;
12889 else if (!strcmp ("taskgroup", p
))
12890 result
= PRAGMA_OMP_CLAUSE_TASKGROUP
;
12891 else if (!strcmp ("thread_limit", p
))
12892 result
= PRAGMA_OMP_CLAUSE_THREAD_LIMIT
;
12893 else if (!strcmp ("threads", p
))
12894 result
= PRAGMA_OMP_CLAUSE_THREADS
;
12895 else if (!strcmp ("tile", p
))
12896 result
= PRAGMA_OACC_CLAUSE_TILE
;
12897 else if (!strcmp ("to", p
))
12898 result
= PRAGMA_OMP_CLAUSE_TO
;
12901 if (!strcmp ("uniform", p
))
12902 result
= PRAGMA_OMP_CLAUSE_UNIFORM
;
12903 else if (!strcmp ("untied", p
))
12904 result
= PRAGMA_OMP_CLAUSE_UNTIED
;
12905 else if (!strcmp ("use_device", p
))
12906 result
= PRAGMA_OACC_CLAUSE_USE_DEVICE
;
12907 else if (!strcmp ("use_device_addr", p
))
12908 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
;
12909 else if (!strcmp ("use_device_ptr", p
))
12910 result
= PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
;
12913 if (!strcmp ("vector", p
))
12914 result
= PRAGMA_OACC_CLAUSE_VECTOR
;
12915 else if (!strcmp ("vector_length", p
))
12916 result
= PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
;
12919 if (!strcmp ("wait", p
))
12920 result
= PRAGMA_OACC_CLAUSE_WAIT
;
12921 else if (!strcmp ("worker", p
))
12922 result
= PRAGMA_OACC_CLAUSE_WORKER
;
12927 if (result
!= PRAGMA_OMP_CLAUSE_NONE
)
12928 c_parser_consume_token (parser
);
12933 /* Validate that a clause of the given type does not already exist. */
12936 check_no_duplicate_clause (tree clauses
, enum omp_clause_code code
,
12939 if (tree c
= omp_find_clause (clauses
, code
))
12940 error_at (OMP_CLAUSE_LOCATION (c
), "too many %qs clauses", name
);
12944 Parse wait clause or wait directive parameters. */
12947 c_parser_oacc_wait_list (c_parser
*parser
, location_t clause_loc
, tree list
)
12949 vec
<tree
, va_gc
> *args
;
12952 matching_parens parens
;
12953 if (!parens
.require_open (parser
))
12956 args
= c_parser_expr_list (parser
, false, true, NULL
, NULL
, NULL
, NULL
);
12957 args_tree
= build_tree_list_vec (args
);
12959 for (t
= args_tree
; t
; t
= TREE_CHAIN (t
))
12961 tree targ
= TREE_VALUE (t
);
12963 if (targ
!= error_mark_node
)
12965 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ
)))
12967 c_parser_error (parser
, "expression must be integral");
12968 targ
= error_mark_node
;
12972 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
12974 OMP_CLAUSE_DECL (c
) = targ
;
12975 OMP_CLAUSE_CHAIN (c
) = list
;
12981 release_tree_vector (args
);
12982 parens
.require_close (parser
);
12986 /* OpenACC 2.0, OpenMP 2.5:
12989 variable-list , identifier
12991 If KIND is nonzero, create the appropriate node and install the
12992 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
12993 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
12995 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
12996 return the list created.
12998 The optional ALLOW_DEREF argument is true if list items can use the deref
13003 tree low_bound
, length
;
13006 omp_dim (tree lb
, tree len
, location_t lo
, bool nc
)
13007 : low_bound (lb
), length (len
), loc (lo
), no_colon (nc
) {}
13011 c_parser_omp_variable_list (c_parser
*parser
,
13012 location_t clause_loc
,
13013 enum omp_clause_code kind
, tree list
,
13014 bool allow_deref
= false)
13016 auto_vec
<omp_dim
> dims
;
13017 bool array_section_p
;
13018 auto_vec
<c_token
> tokens
;
13019 unsigned int tokens_avail
= 0;
13024 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13026 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
13027 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
13029 struct c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13030 if (expr
.value
!= error_mark_node
)
13032 tree u
= build_omp_clause (clause_loc
, kind
);
13033 OMP_CLAUSE_DECL (u
) = expr
.value
;
13034 OMP_CLAUSE_CHAIN (u
) = list
;
13038 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
13041 c_parser_consume_token (parser
);
13046 tokens
.truncate (0);
13047 unsigned int nesting_depth
= 0;
13050 c_token
*token
= c_parser_peek_token (parser
);
13051 switch (token
->type
)
13054 case CPP_PRAGMA_EOL
:
13056 case CPP_OPEN_BRACE
:
13057 case CPP_OPEN_PAREN
:
13058 case CPP_OPEN_SQUARE
:
13061 case CPP_CLOSE_BRACE
:
13062 case CPP_CLOSE_PAREN
:
13063 case CPP_CLOSE_SQUARE
:
13064 if (nesting_depth
-- == 0)
13068 if (nesting_depth
== 0)
13073 tokens
.safe_push (*token
);
13074 c_parser_consume_token (parser
);
13080 /* Make sure nothing tries to read past the end of the tokens. */
13082 memset (&eof_token
, 0, sizeof (eof_token
));
13083 eof_token
.type
= CPP_EOF
;
13084 tokens
.safe_push (eof_token
);
13085 tokens
.safe_push (eof_token
);
13087 tokens_avail
= parser
->tokens_avail
;
13088 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
13089 parser
->tokens
= tokens
.address ();
13090 parser
->tokens_avail
= tokens
.length ();
13093 tree t
= NULL_TREE
;
13095 if (c_parser_next_token_is (parser
, CPP_NAME
)
13096 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
13098 t
= lookup_name (c_parser_peek_token (parser
)->value
);
13100 if (t
== NULL_TREE
)
13102 undeclared_variable (c_parser_peek_token (parser
)->location
,
13103 c_parser_peek_token (parser
)->value
);
13104 t
= error_mark_node
;
13107 c_parser_consume_token (parser
);
13109 else if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
13110 && (c_parser_peek_token (parser
)->keyword
== RID_FUNCTION_NAME
13111 || (c_parser_peek_token (parser
)->keyword
13112 == RID_PRETTY_FUNCTION_NAME
)
13113 || (c_parser_peek_token (parser
)->keyword
13114 == RID_C99_FUNCTION_NAME
)))
13115 t
= c_parser_predefined_identifier (parser
).value
;
13119 c_parser_error (parser
, "expected identifier");
13123 if (t
== error_mark_node
)
13125 else if (kind
!= 0)
13129 case OMP_CLAUSE__CACHE_
:
13130 /* The OpenACC cache directive explicitly only allows "array
13131 elements or subarrays". */
13132 if (c_parser_peek_token (parser
)->type
!= CPP_OPEN_SQUARE
)
13134 c_parser_error (parser
, "expected %<[%>");
13135 t
= error_mark_node
;
13139 case OMP_CLAUSE_MAP
:
13140 case OMP_CLAUSE_FROM
:
13141 case OMP_CLAUSE_TO
:
13142 start_component_ref
:
13143 while (c_parser_next_token_is (parser
, CPP_DOT
)
13145 && c_parser_next_token_is (parser
, CPP_DEREF
)))
13147 location_t op_loc
= c_parser_peek_token (parser
)->location
;
13148 if (c_parser_next_token_is (parser
, CPP_DEREF
))
13152 t_expr
.original_code
= ERROR_MARK
;
13153 t_expr
.original_type
= NULL
;
13154 set_c_expr_source_range (&t_expr
, op_loc
, op_loc
);
13155 t_expr
= convert_lvalue_to_rvalue (op_loc
, t_expr
,
13157 t
= build_indirect_ref (op_loc
, t_expr
.value
, RO_ARROW
);
13159 c_parser_consume_token (parser
);
13160 if (!c_parser_next_token_is (parser
, CPP_NAME
))
13162 c_parser_error (parser
, "expected identifier");
13163 t
= error_mark_node
;
13167 c_token
*comp_tok
= c_parser_peek_token (parser
);
13168 tree ident
= comp_tok
->value
;
13169 location_t comp_loc
= comp_tok
->location
;
13170 c_parser_consume_token (parser
);
13171 t
= build_component_ref (op_loc
, t
, ident
, comp_loc
);
13174 case OMP_CLAUSE_AFFINITY
:
13175 case OMP_CLAUSE_DEPEND
:
13176 case OMP_CLAUSE_REDUCTION
:
13177 case OMP_CLAUSE_IN_REDUCTION
:
13178 case OMP_CLAUSE_TASK_REDUCTION
:
13179 case OMP_CLAUSE_HAS_DEVICE_ADDR
:
13180 array_section_p
= false;
13182 while (c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
13184 location_t loc
= UNKNOWN_LOCATION
;
13185 tree low_bound
= NULL_TREE
, length
= NULL_TREE
;
13186 bool no_colon
= false;
13188 c_parser_consume_token (parser
);
13189 if (!c_parser_next_token_is (parser
, CPP_COLON
))
13191 location_t expr_loc
13192 = c_parser_peek_token (parser
)->location
;
13193 c_expr expr
= c_parser_expression (parser
);
13194 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13196 low_bound
= expr
.value
;
13199 if (c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13201 length
= integer_one_node
;
13206 /* Look for `:'. */
13207 if (!c_parser_require (parser
, CPP_COLON
,
13210 t
= error_mark_node
;
13213 array_section_p
= true;
13214 if (!c_parser_next_token_is (parser
, CPP_CLOSE_SQUARE
))
13216 location_t expr_loc
13217 = c_parser_peek_token (parser
)->location
;
13218 c_expr expr
= c_parser_expression (parser
);
13219 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
,
13221 length
= expr
.value
;
13224 /* Look for the closing `]'. */
13225 if (!c_parser_require (parser
, CPP_CLOSE_SQUARE
,
13228 t
= error_mark_node
;
13232 dims
.safe_push (omp_dim (low_bound
, length
, loc
, no_colon
));
13235 if (t
!= error_mark_node
)
13237 if ((kind
== OMP_CLAUSE_MAP
13238 || kind
== OMP_CLAUSE_FROM
13239 || kind
== OMP_CLAUSE_TO
)
13240 && !array_section_p
13241 && (c_parser_next_token_is (parser
, CPP_DOT
)
13243 && c_parser_next_token_is (parser
,
13246 for (unsigned i
= 0; i
< dims
.length (); i
++)
13248 gcc_assert (dims
[i
].length
== integer_one_node
);
13249 t
= build_array_ref (dims
[i
].loc
,
13250 t
, dims
[i
].low_bound
);
13252 goto start_component_ref
;
13255 for (unsigned i
= 0; i
< dims
.length (); i
++)
13256 t
= tree_cons (dims
[i
].low_bound
, dims
[i
].length
, t
);
13259 if ((kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13260 && t
!= error_mark_node
13261 && parser
->tokens_avail
!= 2)
13263 if (array_section_p
)
13265 error_at (c_parser_peek_token (parser
)->location
,
13266 "expected %<)%> or %<,%>");
13267 t
= error_mark_node
;
13271 parser
->tokens
= tokens
.address ();
13272 parser
->tokens_avail
= tokens
.length ();
13274 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
13275 if (t
!= error_mark_node
&& parser
->tokens_avail
!= 2)
13277 error_at (c_parser_peek_token (parser
)->location
,
13278 "expected %<)%> or %<,%>");
13279 t
= error_mark_node
;
13288 if (t
!= error_mark_node
)
13290 tree u
= build_omp_clause (clause_loc
, kind
);
13291 OMP_CLAUSE_DECL (u
) = t
;
13292 OMP_CLAUSE_CHAIN (u
) = list
;
13297 list
= tree_cons (t
, NULL_TREE
, list
);
13299 if (kind
== OMP_CLAUSE_DEPEND
|| kind
== OMP_CLAUSE_AFFINITY
)
13301 parser
->tokens
= &parser
->tokens_buf
[0];
13302 parser
->tokens_avail
= tokens_avail
;
13304 if (c_parser_next_token_is_not (parser
, CPP_COMMA
))
13307 c_parser_consume_token (parser
);
13314 /* Similarly, but expect leading and trailing parenthesis. This is a very
13315 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13316 argument is true if list items can use the deref (->) operator. */
13319 c_parser_omp_var_list_parens (c_parser
*parser
, enum omp_clause_code kind
,
13320 tree list
, bool allow_deref
= false)
13322 /* The clauses location. */
13323 location_t loc
= c_parser_peek_token (parser
)->location
;
13325 matching_parens parens
;
13326 if (parens
.require_open (parser
))
13328 list
= c_parser_omp_variable_list (parser
, loc
, kind
, list
, allow_deref
);
13329 parens
.skip_until_found_close (parser
);
13335 copy ( variable-list )
13336 copyin ( variable-list )
13337 copyout ( variable-list )
13338 create ( variable-list )
13339 delete ( variable-list )
13340 present ( variable-list )
13343 no_create ( variable-list )
13344 attach ( variable-list )
13345 detach ( variable-list ) */
13348 c_parser_oacc_data_clause (c_parser
*parser
, pragma_omp_clause c_kind
,
13351 enum gomp_map_kind kind
;
13354 case PRAGMA_OACC_CLAUSE_ATTACH
:
13355 kind
= GOMP_MAP_ATTACH
;
13357 case PRAGMA_OACC_CLAUSE_COPY
:
13358 kind
= GOMP_MAP_TOFROM
;
13360 case PRAGMA_OACC_CLAUSE_COPYIN
:
13361 kind
= GOMP_MAP_TO
;
13363 case PRAGMA_OACC_CLAUSE_COPYOUT
:
13364 kind
= GOMP_MAP_FROM
;
13366 case PRAGMA_OACC_CLAUSE_CREATE
:
13367 kind
= GOMP_MAP_ALLOC
;
13369 case PRAGMA_OACC_CLAUSE_DELETE
:
13370 kind
= GOMP_MAP_RELEASE
;
13372 case PRAGMA_OACC_CLAUSE_DETACH
:
13373 kind
= GOMP_MAP_DETACH
;
13375 case PRAGMA_OACC_CLAUSE_DEVICE
:
13376 kind
= GOMP_MAP_FORCE_TO
;
13378 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
13379 kind
= GOMP_MAP_DEVICE_RESIDENT
;
13381 case PRAGMA_OACC_CLAUSE_HOST
:
13382 kind
= GOMP_MAP_FORCE_FROM
;
13384 case PRAGMA_OACC_CLAUSE_LINK
:
13385 kind
= GOMP_MAP_LINK
;
13387 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
13388 kind
= GOMP_MAP_IF_PRESENT
;
13390 case PRAGMA_OACC_CLAUSE_PRESENT
:
13391 kind
= GOMP_MAP_FORCE_PRESENT
;
13394 gcc_unreachable ();
13397 nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_MAP
, list
, true);
13399 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13400 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
13406 deviceptr ( variable-list ) */
13409 c_parser_oacc_data_clause_deviceptr (c_parser
*parser
, tree list
)
13411 location_t loc
= c_parser_peek_token (parser
)->location
;
13414 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13415 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13416 variable-list must only allow for pointer variables. */
13417 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
13418 for (t
= vars
; t
&& t
; t
= TREE_CHAIN (t
))
13420 tree v
= TREE_PURPOSE (t
);
13422 /* FIXME diagnostics: Ideally we should keep individual
13423 locations for all the variables in the var list to make the
13424 following errors more precise. Perhaps
13425 c_parser_omp_var_list_parens() should construct a list of
13426 locations to go along with the var list. */
13428 if (!VAR_P (v
) && TREE_CODE (v
) != PARM_DECL
)
13429 error_at (loc
, "%qD is not a variable", v
);
13430 else if (TREE_TYPE (v
) == error_mark_node
)
13432 else if (!POINTER_TYPE_P (TREE_TYPE (v
)))
13433 error_at (loc
, "%qD is not a pointer variable", v
);
13435 tree u
= build_omp_clause (loc
, OMP_CLAUSE_MAP
);
13436 OMP_CLAUSE_SET_MAP_KIND (u
, GOMP_MAP_FORCE_DEVICEPTR
);
13437 OMP_CLAUSE_DECL (u
) = v
;
13438 OMP_CLAUSE_CHAIN (u
) = list
;
13445 /* OpenACC 2.0, OpenMP 3.0:
13446 collapse ( constant-expression ) */
13449 c_parser_omp_clause_collapse (c_parser
*parser
, tree list
)
13451 tree c
, num
= error_mark_node
;
13455 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
13456 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
13458 loc
= c_parser_peek_token (parser
)->location
;
13459 matching_parens parens
;
13460 if (parens
.require_open (parser
))
13462 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
13463 parens
.skip_until_found_close (parser
);
13465 if (num
== error_mark_node
)
13467 mark_exp_read (num
);
13468 num
= c_fully_fold (num
, false, NULL
);
13469 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
13470 || !tree_fits_shwi_p (num
)
13471 || (n
= tree_to_shwi (num
)) <= 0
13475 "collapse argument needs positive constant integer expression");
13478 c
= build_omp_clause (loc
, OMP_CLAUSE_COLLAPSE
);
13479 OMP_CLAUSE_COLLAPSE_EXPR (c
) = num
;
13480 OMP_CLAUSE_CHAIN (c
) = list
;
13485 copyin ( variable-list ) */
13488 c_parser_omp_clause_copyin (c_parser
*parser
, tree list
)
13490 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYIN
, list
);
13494 copyprivate ( variable-list ) */
13497 c_parser_omp_clause_copyprivate (c_parser
*parser
, tree list
)
13499 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_COPYPRIVATE
, list
);
13503 default ( none | shared )
13506 default ( private | firstprivate )
13509 default ( none | present ) */
13512 c_parser_omp_clause_default (c_parser
*parser
, tree list
, bool is_oacc
)
13514 enum omp_clause_default_kind kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
13515 location_t loc
= c_parser_peek_token (parser
)->location
;
13518 matching_parens parens
;
13519 if (!parens
.require_open (parser
))
13521 if (c_parser_next_token_is (parser
, CPP_NAME
))
13523 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13528 if (strcmp ("none", p
) != 0)
13530 kind
= OMP_CLAUSE_DEFAULT_NONE
;
13536 if (strcmp ("present", p
) != 0)
13538 kind
= OMP_CLAUSE_DEFAULT_PRESENT
;
13542 if (strcmp ("private", p
) != 0)
13544 kind
= OMP_CLAUSE_DEFAULT_PRIVATE
;
13549 if (strcmp ("firstprivate", p
) != 0 || is_oacc
)
13551 kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
13555 if (strcmp ("shared", p
) != 0 || is_oacc
)
13557 kind
= OMP_CLAUSE_DEFAULT_SHARED
;
13564 c_parser_consume_token (parser
);
13570 c_parser_error (parser
, "expected %<none%> or %<present%>");
13572 c_parser_error (parser
, "expected %<none%>, %<shared%>, "
13573 "%<private%> or %<firstprivate%>");
13575 parens
.skip_until_found_close (parser
);
13577 if (kind
== OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
13580 check_no_duplicate_clause (list
, OMP_CLAUSE_DEFAULT
, "default");
13581 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULT
);
13582 OMP_CLAUSE_CHAIN (c
) = list
;
13583 OMP_CLAUSE_DEFAULT_KIND (c
) = kind
;
13589 firstprivate ( variable-list ) */
13592 c_parser_omp_clause_firstprivate (c_parser
*parser
, tree list
)
13594 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FIRSTPRIVATE
, list
);
13598 final ( expression ) */
13601 c_parser_omp_clause_final (c_parser
*parser
, tree list
)
13603 location_t loc
= c_parser_peek_token (parser
)->location
;
13604 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
13606 matching_parens parens
;
13608 if (!parens
.require_open (parser
))
13609 t
= error_mark_node
;
13612 location_t eloc
= c_parser_peek_token (parser
)->location
;
13613 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13614 t
= convert_lvalue_to_rvalue (eloc
, expr
, true, true).value
;
13615 t
= c_objc_common_truthvalue_conversion (eloc
, t
);
13616 t
= c_fully_fold (t
, false, NULL
);
13617 parens
.skip_until_found_close (parser
);
13620 check_no_duplicate_clause (list
, OMP_CLAUSE_FINAL
, "final");
13622 c
= build_omp_clause (loc
, OMP_CLAUSE_FINAL
);
13623 OMP_CLAUSE_FINAL_EXPR (c
) = t
;
13624 OMP_CLAUSE_CHAIN (c
) = list
;
13628 c_parser_error (parser
, "expected %<(%>");
13633 /* OpenACC, OpenMP 2.5:
13637 if ( directive-name-modifier : expression )
13639 directive-name-modifier:
13640 parallel | task | taskloop | target data | target | target update
13641 | target enter data | target exit data
13644 directive-name-modifier:
13645 ... | simd | cancel */
13648 c_parser_omp_clause_if (c_parser
*parser
, tree list
, bool is_omp
)
13650 location_t location
= c_parser_peek_token (parser
)->location
;
13651 enum tree_code if_modifier
= ERROR_MARK
;
13653 matching_parens parens
;
13654 if (!parens
.require_open (parser
))
13657 if (is_omp
&& c_parser_next_token_is (parser
, CPP_NAME
))
13659 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13661 if (strcmp (p
, "cancel") == 0)
13662 if_modifier
= VOID_CST
;
13663 else if (strcmp (p
, "parallel") == 0)
13664 if_modifier
= OMP_PARALLEL
;
13665 else if (strcmp (p
, "simd") == 0)
13666 if_modifier
= OMP_SIMD
;
13667 else if (strcmp (p
, "task") == 0)
13668 if_modifier
= OMP_TASK
;
13669 else if (strcmp (p
, "taskloop") == 0)
13670 if_modifier
= OMP_TASKLOOP
;
13671 else if (strcmp (p
, "target") == 0)
13673 if_modifier
= OMP_TARGET
;
13674 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
13676 p
= IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser
)->value
);
13677 if (strcmp ("data", p
) == 0)
13678 if_modifier
= OMP_TARGET_DATA
;
13679 else if (strcmp ("update", p
) == 0)
13680 if_modifier
= OMP_TARGET_UPDATE
;
13681 else if (strcmp ("enter", p
) == 0)
13682 if_modifier
= OMP_TARGET_ENTER_DATA
;
13683 else if (strcmp ("exit", p
) == 0)
13684 if_modifier
= OMP_TARGET_EXIT_DATA
;
13685 if (if_modifier
!= OMP_TARGET
)
13688 c_parser_consume_token (parser
);
13692 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
13693 error_at (loc
, "expected %<data%>, %<update%>, %<enter%> "
13695 if_modifier
= ERROR_MARK
;
13697 if (if_modifier
== OMP_TARGET_ENTER_DATA
13698 || if_modifier
== OMP_TARGET_EXIT_DATA
)
13700 if (c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
13702 p
= IDENTIFIER_POINTER
13703 (c_parser_peek_2nd_token (parser
)->value
);
13704 if (strcmp ("data", p
) == 0)
13708 c_parser_consume_token (parser
);
13712 = c_parser_peek_2nd_token (parser
)->location
;
13713 error_at (loc
, "expected %<data%>");
13714 if_modifier
= ERROR_MARK
;
13719 if (if_modifier
!= ERROR_MARK
)
13721 if (c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13723 c_parser_consume_token (parser
);
13724 c_parser_consume_token (parser
);
13730 location_t loc
= c_parser_peek_2nd_token (parser
)->location
;
13731 error_at (loc
, "expected %<:%>");
13733 if_modifier
= ERROR_MARK
;
13738 location_t loc
= c_parser_peek_token (parser
)->location
;
13739 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13740 expr
= convert_lvalue_to_rvalue (loc
, expr
, true, true);
13741 tree t
= c_objc_common_truthvalue_conversion (loc
, expr
.value
), c
;
13742 t
= c_fully_fold (t
, false, NULL
);
13743 parens
.skip_until_found_close (parser
);
13745 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
13746 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IF
)
13748 if (if_modifier
!= ERROR_MARK
13749 && OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
13751 const char *p
= NULL
;
13752 switch (if_modifier
)
13754 case VOID_CST
: p
= "cancel"; break;
13755 case OMP_PARALLEL
: p
= "parallel"; break;
13756 case OMP_SIMD
: p
= "simd"; break;
13757 case OMP_TASK
: p
= "task"; break;
13758 case OMP_TASKLOOP
: p
= "taskloop"; break;
13759 case OMP_TARGET_DATA
: p
= "target data"; break;
13760 case OMP_TARGET
: p
= "target"; break;
13761 case OMP_TARGET_UPDATE
: p
= "target update"; break;
13762 case OMP_TARGET_ENTER_DATA
: p
= "target enter data"; break;
13763 case OMP_TARGET_EXIT_DATA
: p
= "target exit data"; break;
13764 default: gcc_unreachable ();
13766 error_at (location
, "too many %<if%> clauses with %qs modifier",
13770 else if (OMP_CLAUSE_IF_MODIFIER (c
) == if_modifier
)
13773 error_at (location
, "too many %<if%> clauses");
13775 error_at (location
, "too many %<if%> clauses without modifier");
13778 else if (if_modifier
== ERROR_MARK
13779 || OMP_CLAUSE_IF_MODIFIER (c
) == ERROR_MARK
)
13781 error_at (location
, "if any %<if%> clause has modifier, then all "
13782 "%<if%> clauses have to use modifier");
13787 c
= build_omp_clause (location
, OMP_CLAUSE_IF
);
13788 OMP_CLAUSE_IF_MODIFIER (c
) = if_modifier
;
13789 OMP_CLAUSE_IF_EXPR (c
) = t
;
13790 OMP_CLAUSE_CHAIN (c
) = list
;
13795 lastprivate ( variable-list )
13798 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13801 c_parser_omp_clause_lastprivate (c_parser
*parser
, tree list
)
13803 /* The clauses location. */
13804 location_t loc
= c_parser_peek_token (parser
)->location
;
13806 if (c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
13808 bool conditional
= false;
13809 if (c_parser_next_token_is (parser
, CPP_NAME
)
13810 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
13813 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
13814 if (strcmp (p
, "conditional") == 0)
13816 conditional
= true;
13817 c_parser_consume_token (parser
);
13818 c_parser_consume_token (parser
);
13821 tree nlist
= c_parser_omp_variable_list (parser
, loc
,
13822 OMP_CLAUSE_LASTPRIVATE
, list
);
13823 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
13825 for (tree c
= nlist
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
13826 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 1;
13836 c_parser_omp_clause_mergeable (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13840 /* FIXME: Should we allow duplicates? */
13841 check_no_duplicate_clause (list
, OMP_CLAUSE_MERGEABLE
, "mergeable");
13843 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
13844 OMP_CLAUSE_MERGEABLE
);
13845 OMP_CLAUSE_CHAIN (c
) = list
;
13854 c_parser_omp_clause_nowait (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
13857 location_t loc
= c_parser_peek_token (parser
)->location
;
13859 check_no_duplicate_clause (list
, OMP_CLAUSE_NOWAIT
, "nowait");
13861 c
= build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
13862 OMP_CLAUSE_CHAIN (c
) = list
;
13867 num_threads ( expression ) */
13870 c_parser_omp_clause_num_threads (c_parser
*parser
, tree list
)
13872 location_t num_threads_loc
= c_parser_peek_token (parser
)->location
;
13873 matching_parens parens
;
13874 if (parens
.require_open (parser
))
13876 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13877 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13878 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13879 tree c
, t
= expr
.value
;
13880 t
= c_fully_fold (t
, false, NULL
);
13882 parens
.skip_until_found_close (parser
);
13884 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13886 c_parser_error (parser
, "expected integer expression");
13890 /* Attempt to statically determine when the number isn't positive. */
13891 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13892 build_int_cst (TREE_TYPE (t
), 0));
13893 protected_set_expr_location (c
, expr_loc
);
13894 if (c
== boolean_true_node
)
13896 warning_at (expr_loc
, 0,
13897 "%<num_threads%> value must be positive");
13898 t
= integer_one_node
;
13901 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_THREADS
, "num_threads");
13903 c
= build_omp_clause (num_threads_loc
, OMP_CLAUSE_NUM_THREADS
);
13904 OMP_CLAUSE_NUM_THREADS_EXPR (c
) = t
;
13905 OMP_CLAUSE_CHAIN (c
) = list
;
13913 num_tasks ( expression )
13916 num_tasks ( strict : expression ) */
13919 c_parser_omp_clause_num_tasks (c_parser
*parser
, tree list
)
13921 location_t num_tasks_loc
= c_parser_peek_token (parser
)->location
;
13922 matching_parens parens
;
13923 if (parens
.require_open (parser
))
13925 bool strict
= false;
13926 if (c_parser_next_token_is (parser
, CPP_NAME
)
13927 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
13928 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
13932 c_parser_consume_token (parser
);
13933 c_parser_consume_token (parser
);
13936 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13937 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13938 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
13939 tree c
, t
= expr
.value
;
13940 t
= c_fully_fold (t
, false, NULL
);
13942 parens
.skip_until_found_close (parser
);
13944 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
13946 c_parser_error (parser
, "expected integer expression");
13950 /* Attempt to statically determine when the number isn't positive. */
13951 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
13952 build_int_cst (TREE_TYPE (t
), 0));
13953 if (CAN_HAVE_LOCATION_P (c
))
13954 SET_EXPR_LOCATION (c
, expr_loc
);
13955 if (c
== boolean_true_node
)
13957 warning_at (expr_loc
, 0, "%<num_tasks%> value must be positive");
13958 t
= integer_one_node
;
13961 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TASKS
, "num_tasks");
13963 c
= build_omp_clause (num_tasks_loc
, OMP_CLAUSE_NUM_TASKS
);
13964 OMP_CLAUSE_NUM_TASKS_EXPR (c
) = t
;
13965 OMP_CLAUSE_NUM_TASKS_STRICT (c
) = strict
;
13966 OMP_CLAUSE_CHAIN (c
) = list
;
13974 grainsize ( expression )
13977 grainsize ( strict : expression ) */
13980 c_parser_omp_clause_grainsize (c_parser
*parser
, tree list
)
13982 location_t grainsize_loc
= c_parser_peek_token (parser
)->location
;
13983 matching_parens parens
;
13984 if (parens
.require_open (parser
))
13986 bool strict
= false;
13987 if (c_parser_next_token_is (parser
, CPP_NAME
)
13988 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
13989 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
13993 c_parser_consume_token (parser
);
13994 c_parser_consume_token (parser
);
13997 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
13998 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
13999 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14000 tree c
, t
= expr
.value
;
14001 t
= c_fully_fold (t
, false, NULL
);
14003 parens
.skip_until_found_close (parser
);
14005 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14007 c_parser_error (parser
, "expected integer expression");
14011 /* Attempt to statically determine when the number isn't positive. */
14012 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14013 build_int_cst (TREE_TYPE (t
), 0));
14014 if (CAN_HAVE_LOCATION_P (c
))
14015 SET_EXPR_LOCATION (c
, expr_loc
);
14016 if (c
== boolean_true_node
)
14018 warning_at (expr_loc
, 0, "%<grainsize%> value must be positive");
14019 t
= integer_one_node
;
14022 check_no_duplicate_clause (list
, OMP_CLAUSE_GRAINSIZE
, "grainsize");
14024 c
= build_omp_clause (grainsize_loc
, OMP_CLAUSE_GRAINSIZE
);
14025 OMP_CLAUSE_GRAINSIZE_EXPR (c
) = t
;
14026 OMP_CLAUSE_GRAINSIZE_STRICT (c
) = strict
;
14027 OMP_CLAUSE_CHAIN (c
) = list
;
14035 priority ( expression ) */
14038 c_parser_omp_clause_priority (c_parser
*parser
, tree list
)
14040 location_t priority_loc
= c_parser_peek_token (parser
)->location
;
14041 matching_parens parens
;
14042 if (parens
.require_open (parser
))
14044 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14045 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14046 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14047 tree c
, t
= expr
.value
;
14048 t
= c_fully_fold (t
, false, NULL
);
14050 parens
.skip_until_found_close (parser
);
14052 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14054 c_parser_error (parser
, "expected integer expression");
14058 /* Attempt to statically determine when the number isn't
14060 c
= fold_build2_loc (expr_loc
, LT_EXPR
, boolean_type_node
, t
,
14061 build_int_cst (TREE_TYPE (t
), 0));
14062 if (CAN_HAVE_LOCATION_P (c
))
14063 SET_EXPR_LOCATION (c
, expr_loc
);
14064 if (c
== boolean_true_node
)
14066 warning_at (expr_loc
, 0, "%<priority%> value must be non-negative");
14067 t
= integer_one_node
;
14070 check_no_duplicate_clause (list
, OMP_CLAUSE_PRIORITY
, "priority");
14072 c
= build_omp_clause (priority_loc
, OMP_CLAUSE_PRIORITY
);
14073 OMP_CLAUSE_PRIORITY_EXPR (c
) = t
;
14074 OMP_CLAUSE_CHAIN (c
) = list
;
14082 hint ( expression ) */
14085 c_parser_omp_clause_hint (c_parser
*parser
, tree list
)
14087 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
14088 matching_parens parens
;
14089 if (parens
.require_open (parser
))
14091 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14092 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14093 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14094 tree c
, t
= expr
.value
;
14095 t
= c_fully_fold (t
, false, NULL
);
14096 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
14097 || TREE_CODE (t
) != INTEGER_CST
14098 || tree_int_cst_sgn (t
) == -1)
14100 c_parser_error (parser
, "expected constant integer expression "
14101 "with valid sync-hint value");
14104 parens
.skip_until_found_close (parser
);
14105 check_no_duplicate_clause (list
, OMP_CLAUSE_HINT
, "hint");
14107 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_HINT
);
14108 OMP_CLAUSE_HINT_EXPR (c
) = t
;
14109 OMP_CLAUSE_CHAIN (c
) = list
;
14117 filter ( integer-expression ) */
14120 c_parser_omp_clause_filter (c_parser
*parser
, tree list
)
14122 location_t hint_loc
= c_parser_peek_token (parser
)->location
;
14123 matching_parens parens
;
14124 if (parens
.require_open (parser
))
14126 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14127 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
14128 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14129 tree c
, t
= expr
.value
;
14130 t
= c_fully_fold (t
, false, NULL
);
14131 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14133 c_parser_error (parser
, "expected integer expression");
14136 parens
.skip_until_found_close (parser
);
14137 check_no_duplicate_clause (list
, OMP_CLAUSE_FILTER
, "filter");
14139 c
= build_omp_clause (hint_loc
, OMP_CLAUSE_FILTER
);
14140 OMP_CLAUSE_FILTER_EXPR (c
) = t
;
14141 OMP_CLAUSE_CHAIN (c
) = list
;
14149 defaultmap ( tofrom : scalar )
14152 defaultmap ( implicit-behavior [ : variable-category ] ) */
14155 c_parser_omp_clause_defaultmap (c_parser
*parser
, tree list
)
14157 location_t loc
= c_parser_peek_token (parser
)->location
;
14160 enum omp_clause_defaultmap_kind behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
14161 enum omp_clause_defaultmap_kind category
14162 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
14164 matching_parens parens
;
14165 if (!parens
.require_open (parser
))
14167 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
))
14169 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
14172 c_parser_error (parser
, "expected %<alloc%>, %<to%>, %<from%>, "
14173 "%<tofrom%>, %<firstprivate%>, %<none%> "
14178 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14183 if (strcmp ("alloc", p
) == 0)
14184 behavior
= OMP_CLAUSE_DEFAULTMAP_ALLOC
;
14186 goto invalid_behavior
;
14190 if (strcmp ("default", p
) == 0)
14191 behavior
= OMP_CLAUSE_DEFAULTMAP_DEFAULT
;
14193 goto invalid_behavior
;
14197 if (strcmp ("firstprivate", p
) == 0)
14198 behavior
= OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
14199 else if (strcmp ("from", p
) == 0)
14200 behavior
= OMP_CLAUSE_DEFAULTMAP_FROM
;
14202 goto invalid_behavior
;
14206 if (strcmp ("none", p
) == 0)
14207 behavior
= OMP_CLAUSE_DEFAULTMAP_NONE
;
14209 goto invalid_behavior
;
14213 if (strcmp ("tofrom", p
) == 0)
14214 behavior
= OMP_CLAUSE_DEFAULTMAP_TOFROM
;
14215 else if (strcmp ("to", p
) == 0)
14216 behavior
= OMP_CLAUSE_DEFAULTMAP_TO
;
14218 goto invalid_behavior
;
14222 goto invalid_behavior
;
14224 c_parser_consume_token (parser
);
14226 if (!c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
14228 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14230 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14233 c_parser_error (parser
, "expected %<scalar%>, %<aggregate%> or "
14237 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14241 if (strcmp ("aggregate", p
) == 0)
14242 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
;
14244 goto invalid_category
;
14248 if (strcmp ("pointer", p
) == 0)
14249 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
;
14251 goto invalid_category
;
14255 if (strcmp ("scalar", p
) == 0)
14256 category
= OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
;
14258 goto invalid_category
;
14262 goto invalid_category
;
14265 c_parser_consume_token (parser
);
14267 parens
.skip_until_found_close (parser
);
14269 for (c
= list
; c
; c
= OMP_CLAUSE_CHAIN (c
))
14270 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEFAULTMAP
14271 && (category
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14272 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
) == category
14273 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
)
14274 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)))
14276 enum omp_clause_defaultmap_kind cat
= category
;
14277 location_t loc
= OMP_CLAUSE_LOCATION (c
);
14278 if (cat
== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
14279 cat
= OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
);
14283 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
14286 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
14289 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
14292 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
14296 gcc_unreachable ();
14299 error_at (loc
, "too many %<defaultmap%> clauses with %qs category",
14302 error_at (loc
, "too many %<defaultmap%> clauses with unspecified "
14307 c
= build_omp_clause (loc
, OMP_CLAUSE_DEFAULTMAP
);
14308 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c
, behavior
, category
);
14309 OMP_CLAUSE_CHAIN (c
) = list
;
14313 parens
.skip_until_found_close (parser
);
14318 use_device ( variable-list )
14321 use_device_ptr ( variable-list ) */
14324 c_parser_omp_clause_use_device_ptr (c_parser
*parser
, tree list
)
14326 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_PTR
,
14331 use_device_addr ( variable-list ) */
14334 c_parser_omp_clause_use_device_addr (c_parser
*parser
, tree list
)
14336 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_USE_DEVICE_ADDR
,
14341 has_device_addr ( variable-list ) */
14344 c_parser_omp_clause_has_device_addr (c_parser
*parser
, tree list
)
14346 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_HAS_DEVICE_ADDR
,
14351 is_device_ptr ( variable-list ) */
14354 c_parser_omp_clause_is_device_ptr (c_parser
*parser
, tree list
)
14356 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_IS_DEVICE_PTR
, list
);
14360 num_gangs ( expression )
14361 num_workers ( expression )
14362 vector_length ( expression ) */
14365 c_parser_oacc_single_int_clause (c_parser
*parser
, omp_clause_code code
,
14368 location_t loc
= c_parser_peek_token (parser
)->location
;
14370 matching_parens parens
;
14371 if (!parens
.require_open (parser
))
14374 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14375 c_expr expr
= c_parser_expression (parser
);
14376 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
14377 tree c
, t
= expr
.value
;
14378 t
= c_fully_fold (t
, false, NULL
);
14380 parens
.skip_until_found_close (parser
);
14382 if (t
== error_mark_node
)
14384 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14386 error_at (expr_loc
, "%qs expression must be integral",
14387 omp_clause_code_name
[code
]);
14391 /* Attempt to statically determine when the number isn't positive. */
14392 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
14393 build_int_cst (TREE_TYPE (t
), 0));
14394 protected_set_expr_location (c
, expr_loc
);
14395 if (c
== boolean_true_node
)
14397 warning_at (expr_loc
, 0,
14398 "%qs value must be positive",
14399 omp_clause_code_name
[code
]);
14400 t
= integer_one_node
;
14403 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14405 c
= build_omp_clause (loc
, code
);
14406 OMP_CLAUSE_OPERAND (c
, 0) = t
;
14407 OMP_CLAUSE_CHAIN (c
) = list
;
14413 gang [( gang-arg-list )]
14414 worker [( [num:] int-expr )]
14415 vector [( [length:] int-expr )]
14417 where gang-arg is one of:
14422 and size-expr may be:
14429 c_parser_oacc_shape_clause (c_parser
*parser
, location_t loc
,
14430 omp_clause_code kind
,
14431 const char *str
, tree list
)
14433 const char *id
= "num";
14434 tree ops
[2] = { NULL_TREE
, NULL_TREE
}, c
;
14436 if (kind
== OMP_CLAUSE_VECTOR
)
14439 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14441 c_parser_consume_token (parser
);
14445 c_token
*next
= c_parser_peek_token (parser
);
14448 /* Gang static argument. */
14449 if (kind
== OMP_CLAUSE_GANG
14450 && c_parser_next_token_is_keyword (parser
, RID_STATIC
))
14452 c_parser_consume_token (parser
);
14454 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14455 goto cleanup_error
;
14458 if (ops
[idx
] != NULL_TREE
)
14460 c_parser_error (parser
, "too many %<static%> arguments");
14461 goto cleanup_error
;
14464 /* Check for the '*' argument. */
14465 if (c_parser_next_token_is (parser
, CPP_MULT
)
14466 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14467 || c_parser_peek_2nd_token (parser
)->type
14468 == CPP_CLOSE_PAREN
))
14470 c_parser_consume_token (parser
);
14471 ops
[idx
] = integer_minus_one_node
;
14473 if (c_parser_next_token_is (parser
, CPP_COMMA
))
14475 c_parser_consume_token (parser
);
14482 /* Worker num: argument and vector length: arguments. */
14483 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14484 && strcmp (id
, IDENTIFIER_POINTER (next
->value
)) == 0
14485 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14487 c_parser_consume_token (parser
); /* id */
14488 c_parser_consume_token (parser
); /* ':' */
14491 /* Now collect the actual argument. */
14492 if (ops
[idx
] != NULL_TREE
)
14494 c_parser_error (parser
, "unexpected argument");
14495 goto cleanup_error
;
14498 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14499 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14500 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14501 tree expr
= cexpr
.value
;
14502 if (expr
== error_mark_node
)
14503 goto cleanup_error
;
14505 expr
= c_fully_fold (expr
, false, NULL
);
14507 /* Attempt to statically determine when the number isn't a
14508 positive integer. */
14510 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
14512 c_parser_error (parser
, "expected integer expression");
14516 tree c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, expr
,
14517 build_int_cst (TREE_TYPE (expr
), 0));
14518 if (c
== boolean_true_node
)
14520 warning_at (loc
, 0,
14521 "%qs value must be positive", str
);
14522 expr
= integer_one_node
;
14527 if (kind
== OMP_CLAUSE_GANG
14528 && c_parser_next_token_is (parser
, CPP_COMMA
))
14530 c_parser_consume_token (parser
);
14537 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14538 goto cleanup_error
;
14541 check_no_duplicate_clause (list
, kind
, str
);
14543 c
= build_omp_clause (loc
, kind
);
14546 OMP_CLAUSE_OPERAND (c
, 1) = ops
[1];
14548 OMP_CLAUSE_OPERAND (c
, 0) = ops
[0];
14549 OMP_CLAUSE_CHAIN (c
) = list
;
14554 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14566 c_parser_oacc_simple_clause (location_t loc
, enum omp_clause_code code
,
14569 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
14571 tree c
= build_omp_clause (loc
, code
);
14572 OMP_CLAUSE_CHAIN (c
) = list
;
14578 async [( int-expr )] */
14581 c_parser_oacc_clause_async (c_parser
*parser
, tree list
)
14584 location_t loc
= c_parser_peek_token (parser
)->location
;
14586 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14588 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14590 c_parser_consume_token (parser
);
14592 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
14593 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
14594 c_parser_error (parser
, "expected integer expression");
14595 else if (t
== error_mark_node
14596 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
14600 t
= c_fully_fold (t
, false, NULL
);
14602 check_no_duplicate_clause (list
, OMP_CLAUSE_ASYNC
, "async");
14604 c
= build_omp_clause (loc
, OMP_CLAUSE_ASYNC
);
14605 OMP_CLAUSE_ASYNC_EXPR (c
) = t
;
14606 OMP_CLAUSE_CHAIN (c
) = list
;
14613 tile ( size-expr-list ) */
14616 c_parser_oacc_clause_tile (c_parser
*parser
, tree list
)
14618 tree c
, expr
= error_mark_node
;
14620 tree tile
= NULL_TREE
;
14622 check_no_duplicate_clause (list
, OMP_CLAUSE_TILE
, "tile");
14623 check_no_duplicate_clause (list
, OMP_CLAUSE_COLLAPSE
, "collapse");
14625 loc
= c_parser_peek_token (parser
)->location
;
14626 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
14631 if (tile
&& !c_parser_require (parser
, CPP_COMMA
, "expected %<,%>"))
14634 if (c_parser_next_token_is (parser
, CPP_MULT
)
14635 && (c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
14636 || c_parser_peek_2nd_token (parser
)->type
== CPP_CLOSE_PAREN
))
14638 c_parser_consume_token (parser
);
14639 expr
= integer_zero_node
;
14643 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
14644 c_expr cexpr
= c_parser_expr_no_commas (parser
, NULL
);
14645 cexpr
= convert_lvalue_to_rvalue (expr_loc
, cexpr
, false, true);
14646 expr
= cexpr
.value
;
14648 if (expr
== error_mark_node
)
14650 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
14655 expr
= c_fully_fold (expr
, false, NULL
);
14657 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr
))
14658 || !tree_fits_shwi_p (expr
)
14659 || tree_to_shwi (expr
) <= 0)
14661 error_at (expr_loc
, "%<tile%> argument needs positive"
14662 " integral constant");
14663 expr
= integer_zero_node
;
14667 tile
= tree_cons (NULL_TREE
, expr
, tile
);
14669 while (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
));
14671 /* Consume the trailing ')'. */
14672 c_parser_consume_token (parser
);
14674 c
= build_omp_clause (loc
, OMP_CLAUSE_TILE
);
14675 tile
= nreverse (tile
);
14676 OMP_CLAUSE_TILE_LIST (c
) = tile
;
14677 OMP_CLAUSE_CHAIN (c
) = list
;
14682 wait [( int-expr-list )] */
14685 c_parser_oacc_clause_wait (c_parser
*parser
, tree list
)
14687 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14689 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
14690 list
= c_parser_oacc_wait_list (parser
, clause_loc
, list
);
14693 tree c
= build_omp_clause (clause_loc
, OMP_CLAUSE_WAIT
);
14695 OMP_CLAUSE_DECL (c
) = build_int_cst (integer_type_node
, GOMP_ASYNC_NOVAL
);
14696 OMP_CLAUSE_CHAIN (c
) = list
;
14705 order ( concurrent )
14708 order ( order-modifier : concurrent )
14715 c_parser_omp_clause_order (c_parser
*parser
, tree list
)
14717 location_t loc
= c_parser_peek_token (parser
)->location
;
14720 bool unconstrained
= false;
14721 bool reproducible
= false;
14723 matching_parens parens
;
14724 if (!parens
.require_open (parser
))
14726 if (c_parser_next_token_is (parser
, CPP_NAME
)
14727 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
14729 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14730 if (strcmp (p
, "unconstrained") == 0)
14731 unconstrained
= true;
14732 else if (strcmp (p
, "reproducible") == 0)
14733 reproducible
= true;
14736 c_parser_error (parser
, "expected %<reproducible%> or "
14737 "%<unconstrained%>");
14740 c_parser_consume_token (parser
);
14741 c_parser_consume_token (parser
);
14743 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14745 c_parser_error (parser
, "expected %<concurrent%>");
14748 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14749 if (strcmp (p
, "concurrent") != 0)
14751 c_parser_error (parser
, "expected %<concurrent%>");
14754 c_parser_consume_token (parser
);
14755 parens
.skip_until_found_close (parser
);
14756 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDER
, "order");
14757 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDER
);
14758 OMP_CLAUSE_ORDER_UNCONSTRAINED (c
) = unconstrained
;
14759 OMP_CLAUSE_ORDER_REPRODUCIBLE (c
) = reproducible
;
14760 OMP_CLAUSE_CHAIN (c
) = list
;
14764 parens
.skip_until_found_close (parser
);
14770 bind ( teams | parallel | thread ) */
14773 c_parser_omp_clause_bind (c_parser
*parser
, tree list
)
14775 location_t loc
= c_parser_peek_token (parser
)->location
;
14778 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
14780 matching_parens parens
;
14781 if (!parens
.require_open (parser
))
14783 if (!c_parser_next_token_is (parser
, CPP_NAME
))
14786 c_parser_error (parser
,
14787 "expected %<teams%>, %<parallel%> or %<thread%>");
14788 parens
.skip_until_found_close (parser
);
14791 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14792 if (strcmp (p
, "teams") == 0)
14793 kind
= OMP_CLAUSE_BIND_TEAMS
;
14794 else if (strcmp (p
, "parallel") == 0)
14795 kind
= OMP_CLAUSE_BIND_PARALLEL
;
14796 else if (strcmp (p
, "thread") != 0)
14798 c_parser_consume_token (parser
);
14799 parens
.skip_until_found_close (parser
);
14800 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14801 c
= build_omp_clause (loc
, OMP_CLAUSE_BIND
);
14802 OMP_CLAUSE_BIND_KIND (c
) = kind
;
14803 OMP_CLAUSE_CHAIN (c
) = list
;
14812 ordered ( constant-expression ) */
14815 c_parser_omp_clause_ordered (c_parser
*parser
, tree list
)
14817 check_no_duplicate_clause (list
, OMP_CLAUSE_ORDERED
, "ordered");
14819 tree c
, num
= NULL_TREE
;
14821 location_t loc
= c_parser_peek_token (parser
)->location
;
14822 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
14824 matching_parens parens
;
14825 parens
.consume_open (parser
);
14826 num
= c_parser_expr_no_commas (parser
, NULL
).value
;
14827 parens
.skip_until_found_close (parser
);
14829 if (num
== error_mark_node
)
14833 mark_exp_read (num
);
14834 num
= c_fully_fold (num
, false, NULL
);
14835 if (!INTEGRAL_TYPE_P (TREE_TYPE (num
))
14836 || !tree_fits_shwi_p (num
)
14837 || (n
= tree_to_shwi (num
)) <= 0
14840 error_at (loc
, "ordered argument needs positive "
14841 "constant integer expression");
14845 c
= build_omp_clause (loc
, OMP_CLAUSE_ORDERED
);
14846 OMP_CLAUSE_ORDERED_EXPR (c
) = num
;
14847 OMP_CLAUSE_CHAIN (c
) = list
;
14852 private ( variable-list ) */
14855 c_parser_omp_clause_private (c_parser
*parser
, tree list
)
14857 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_PRIVATE
, list
);
14861 reduction ( reduction-operator : variable-list )
14863 reduction-operator:
14864 One of: + * - & ^ | && ||
14868 reduction-operator:
14869 One of: + * - & ^ | && || max min
14873 reduction-operator:
14874 One of: + * - & ^ | && ||
14878 reduction ( reduction-modifier, reduction-operator : variable-list )
14879 in_reduction ( reduction-operator : variable-list )
14880 task_reduction ( reduction-operator : variable-list ) */
14883 c_parser_omp_clause_reduction (c_parser
*parser
, enum omp_clause_code kind
,
14884 bool is_omp
, tree list
)
14886 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
14887 matching_parens parens
;
14888 if (parens
.require_open (parser
))
14891 bool inscan
= false;
14892 enum tree_code code
= ERROR_MARK
;
14893 tree reduc_id
= NULL_TREE
;
14895 if (kind
== OMP_CLAUSE_REDUCTION
&& is_omp
)
14897 if (c_parser_next_token_is_keyword (parser
, RID_DEFAULT
)
14898 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
14900 c_parser_consume_token (parser
);
14901 c_parser_consume_token (parser
);
14903 else if (c_parser_next_token_is (parser
, CPP_NAME
)
14904 && c_parser_peek_2nd_token (parser
)->type
== CPP_COMMA
)
14907 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14908 if (strcmp (p
, "task") == 0)
14910 else if (strcmp (p
, "inscan") == 0)
14912 if (task
|| inscan
)
14914 c_parser_consume_token (parser
);
14915 c_parser_consume_token (parser
);
14920 switch (c_parser_peek_token (parser
)->type
)
14932 code
= BIT_AND_EXPR
;
14935 code
= BIT_XOR_EXPR
;
14938 code
= BIT_IOR_EXPR
;
14941 code
= TRUTH_ANDIF_EXPR
;
14944 code
= TRUTH_ORIF_EXPR
;
14949 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
14950 if (strcmp (p
, "min") == 0)
14955 if (strcmp (p
, "max") == 0)
14960 reduc_id
= c_parser_peek_token (parser
)->value
;
14964 c_parser_error (parser
,
14965 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
14966 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
14967 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
14970 c_parser_consume_token (parser
);
14971 reduc_id
= c_omp_reduction_id (code
, reduc_id
);
14972 if (c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
14976 nl
= c_parser_omp_variable_list (parser
, clause_loc
, kind
, list
);
14977 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
14979 tree d
= OMP_CLAUSE_DECL (c
), type
;
14980 if (TREE_CODE (d
) != TREE_LIST
)
14981 type
= TREE_TYPE (d
);
14986 for (t
= d
; TREE_CODE (t
) == TREE_LIST
; t
= TREE_CHAIN (t
))
14988 type
= TREE_TYPE (t
);
14991 if (TREE_CODE (type
) != POINTER_TYPE
14992 && TREE_CODE (type
) != ARRAY_TYPE
)
14994 type
= TREE_TYPE (type
);
14998 while (TREE_CODE (type
) == ARRAY_TYPE
)
14999 type
= TREE_TYPE (type
);
15000 OMP_CLAUSE_REDUCTION_CODE (c
) = code
;
15002 OMP_CLAUSE_REDUCTION_TASK (c
) = 1;
15004 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 1;
15005 if (code
== ERROR_MARK
15006 || !(INTEGRAL_TYPE_P (type
)
15007 || TREE_CODE (type
) == REAL_TYPE
15008 || TREE_CODE (type
) == COMPLEX_TYPE
))
15009 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
)
15010 = c_omp_reduction_lookup (reduc_id
,
15011 TYPE_MAIN_VARIANT (type
));
15016 parens
.skip_until_found_close (parser
);
15022 schedule ( schedule-kind )
15023 schedule ( schedule-kind , expression )
15026 static | dynamic | guided | runtime | auto
15029 schedule ( schedule-modifier : schedule-kind )
15030 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15038 c_parser_omp_clause_schedule (c_parser
*parser
, tree list
)
15041 location_t loc
= c_parser_peek_token (parser
)->location
;
15042 int modifiers
= 0, nmodifiers
= 0;
15044 matching_parens parens
;
15045 if (!parens
.require_open (parser
))
15048 c
= build_omp_clause (loc
, OMP_CLAUSE_SCHEDULE
);
15050 location_t comma
= UNKNOWN_LOCATION
;
15051 while (c_parser_next_token_is (parser
, CPP_NAME
))
15053 tree kind
= c_parser_peek_token (parser
)->value
;
15054 const char *p
= IDENTIFIER_POINTER (kind
);
15055 if (strcmp ("simd", p
) == 0)
15056 OMP_CLAUSE_SCHEDULE_SIMD (c
) = 1;
15057 else if (strcmp ("monotonic", p
) == 0)
15058 modifiers
|= OMP_CLAUSE_SCHEDULE_MONOTONIC
;
15059 else if (strcmp ("nonmonotonic", p
) == 0)
15060 modifiers
|= OMP_CLAUSE_SCHEDULE_NONMONOTONIC
;
15063 comma
= UNKNOWN_LOCATION
;
15064 c_parser_consume_token (parser
);
15065 if (nmodifiers
++ == 0
15066 && c_parser_next_token_is (parser
, CPP_COMMA
))
15068 comma
= c_parser_peek_token (parser
)->location
;
15069 c_parser_consume_token (parser
);
15073 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
15077 if (comma
!= UNKNOWN_LOCATION
)
15078 error_at (comma
, "expected %<:%>");
15080 if ((modifiers
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
15081 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
15082 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15083 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC
))
15085 error_at (loc
, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15090 if (c_parser_next_token_is (parser
, CPP_NAME
))
15092 tree kind
= c_parser_peek_token (parser
)->value
;
15093 const char *p
= IDENTIFIER_POINTER (kind
);
15098 if (strcmp ("dynamic", p
) != 0)
15100 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_DYNAMIC
;
15104 if (strcmp ("guided", p
) != 0)
15106 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_GUIDED
;
15110 if (strcmp ("runtime", p
) != 0)
15112 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_RUNTIME
;
15119 else if (c_parser_next_token_is_keyword (parser
, RID_STATIC
))
15120 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_STATIC
;
15121 else if (c_parser_next_token_is_keyword (parser
, RID_AUTO
))
15122 OMP_CLAUSE_SCHEDULE_KIND (c
) = OMP_CLAUSE_SCHEDULE_AUTO
;
15126 c_parser_consume_token (parser
);
15127 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15130 c_parser_consume_token (parser
);
15132 here
= c_parser_peek_token (parser
)->location
;
15133 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15134 expr
= convert_lvalue_to_rvalue (here
, expr
, false, true);
15136 t
= c_fully_fold (t
, false, NULL
);
15138 if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_RUNTIME
)
15139 error_at (here
, "schedule %<runtime%> does not take "
15140 "a %<chunk_size%> parameter");
15141 else if (OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_AUTO
)
15143 "schedule %<auto%> does not take "
15144 "a %<chunk_size%> parameter");
15145 else if (TREE_CODE (TREE_TYPE (t
)) == INTEGER_TYPE
)
15147 /* Attempt to statically determine when the number isn't
15149 tree s
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, t
,
15150 build_int_cst (TREE_TYPE (t
), 0));
15151 protected_set_expr_location (s
, loc
);
15152 if (s
== boolean_true_node
)
15154 warning_at (loc
, 0,
15155 "chunk size value must be positive");
15156 t
= integer_one_node
;
15158 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c
) = t
;
15161 c_parser_error (parser
, "expected integer expression");
15163 parens
.skip_until_found_close (parser
);
15166 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
15167 "expected %<,%> or %<)%>");
15169 OMP_CLAUSE_SCHEDULE_KIND (c
)
15170 = (enum omp_clause_schedule_kind
)
15171 (OMP_CLAUSE_SCHEDULE_KIND (c
) | modifiers
);
15173 check_no_duplicate_clause (list
, OMP_CLAUSE_SCHEDULE
, "schedule");
15174 OMP_CLAUSE_CHAIN (c
) = list
;
15178 c_parser_error (parser
, "invalid schedule kind");
15179 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, 0);
15184 shared ( variable-list ) */
15187 c_parser_omp_clause_shared (c_parser
*parser
, tree list
)
15189 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_SHARED
, list
);
15196 c_parser_omp_clause_untied (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
15200 /* FIXME: Should we allow duplicates? */
15201 check_no_duplicate_clause (list
, OMP_CLAUSE_UNTIED
, "untied");
15203 c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
15204 OMP_CLAUSE_UNTIED
);
15205 OMP_CLAUSE_CHAIN (c
) = list
;
15215 c_parser_omp_clause_branch (c_parser
*parser ATTRIBUTE_UNUSED
,
15216 enum omp_clause_code code
, tree list
)
15218 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15220 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15221 OMP_CLAUSE_CHAIN (c
) = list
;
15233 c_parser_omp_clause_cancelkind (c_parser
*parser ATTRIBUTE_UNUSED
,
15234 enum omp_clause_code code
, tree list
)
15236 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15237 OMP_CLAUSE_CHAIN (c
) = list
;
15246 c_parser_omp_clause_nogroup (c_parser
*parser ATTRIBUTE_UNUSED
, tree list
)
15248 check_no_duplicate_clause (list
, OMP_CLAUSE_NOGROUP
, "nogroup");
15249 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
,
15250 OMP_CLAUSE_NOGROUP
);
15251 OMP_CLAUSE_CHAIN (c
) = list
;
15260 c_parser_omp_clause_orderedkind (c_parser
*parser ATTRIBUTE_UNUSED
,
15261 enum omp_clause_code code
, tree list
)
15263 check_no_duplicate_clause (list
, code
, omp_clause_code_name
[code
]);
15264 tree c
= build_omp_clause (c_parser_peek_token (parser
)->location
, code
);
15265 OMP_CLAUSE_CHAIN (c
) = list
;
15270 num_teams ( expression )
15273 num_teams ( expression : expression ) */
15276 c_parser_omp_clause_num_teams (c_parser
*parser
, tree list
)
15278 location_t num_teams_loc
= c_parser_peek_token (parser
)->location
;
15279 matching_parens parens
;
15280 if (parens
.require_open (parser
))
15282 location_t upper_loc
= c_parser_peek_token (parser
)->location
;
15283 location_t lower_loc
= UNKNOWN_LOCATION
;
15284 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15285 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
15286 tree c
, upper
= expr
.value
, lower
= NULL_TREE
;
15287 upper
= c_fully_fold (upper
, false, NULL
);
15289 if (c_parser_next_token_is (parser
, CPP_COLON
))
15291 c_parser_consume_token (parser
);
15292 lower_loc
= upper_loc
;
15294 upper_loc
= c_parser_peek_token (parser
)->location
;
15295 expr
= c_parser_expr_no_commas (parser
, NULL
);
15296 expr
= convert_lvalue_to_rvalue (upper_loc
, expr
, false, true);
15297 upper
= expr
.value
;
15298 upper
= c_fully_fold (upper
, false, NULL
);
15301 parens
.skip_until_found_close (parser
);
15303 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper
))
15304 || (lower
&& !INTEGRAL_TYPE_P (TREE_TYPE (lower
))))
15306 c_parser_error (parser
, "expected integer expression");
15310 /* Attempt to statically determine when the number isn't positive. */
15311 c
= fold_build2_loc (upper_loc
, LE_EXPR
, boolean_type_node
, upper
,
15312 build_int_cst (TREE_TYPE (upper
), 0));
15313 protected_set_expr_location (c
, upper_loc
);
15314 if (c
== boolean_true_node
)
15316 warning_at (upper_loc
, 0, "%<num_teams%> value must be positive");
15317 upper
= integer_one_node
;
15321 c
= fold_build2_loc (lower_loc
, LE_EXPR
, boolean_type_node
, lower
,
15322 build_int_cst (TREE_TYPE (lower
), 0));
15323 protected_set_expr_location (c
, lower_loc
);
15324 if (c
== boolean_true_node
)
15326 warning_at (lower_loc
, 0, "%<num_teams%> value must be positive");
15329 else if (TREE_CODE (lower
) == INTEGER_CST
15330 && TREE_CODE (upper
) == INTEGER_CST
15331 && tree_int_cst_lt (upper
, lower
))
15333 warning_at (lower_loc
, 0, "%<num_teams%> lower bound %qE bigger "
15334 "than upper bound %qE", lower
, upper
);
15339 check_no_duplicate_clause (list
, OMP_CLAUSE_NUM_TEAMS
, "num_teams");
15341 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
15342 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c
) = upper
;
15343 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
) = lower
;
15344 OMP_CLAUSE_CHAIN (c
) = list
;
15352 thread_limit ( expression ) */
15355 c_parser_omp_clause_thread_limit (c_parser
*parser
, tree list
)
15357 location_t num_thread_limit_loc
= c_parser_peek_token (parser
)->location
;
15358 matching_parens parens
;
15359 if (parens
.require_open (parser
))
15361 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15362 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15363 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15364 tree c
, t
= expr
.value
;
15365 t
= c_fully_fold (t
, false, NULL
);
15367 parens
.skip_until_found_close (parser
);
15369 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
15371 c_parser_error (parser
, "expected integer expression");
15375 /* Attempt to statically determine when the number isn't positive. */
15376 c
= fold_build2_loc (expr_loc
, LE_EXPR
, boolean_type_node
, t
,
15377 build_int_cst (TREE_TYPE (t
), 0));
15378 protected_set_expr_location (c
, expr_loc
);
15379 if (c
== boolean_true_node
)
15381 warning_at (expr_loc
, 0, "%<thread_limit%> value must be positive");
15382 t
= integer_one_node
;
15385 check_no_duplicate_clause (list
, OMP_CLAUSE_THREAD_LIMIT
,
15388 c
= build_omp_clause (num_thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
15389 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = t
;
15390 OMP_CLAUSE_CHAIN (c
) = list
;
15398 aligned ( variable-list )
15399 aligned ( variable-list : constant-expression ) */
15402 c_parser_omp_clause_aligned (c_parser
*parser
, tree list
)
15404 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15407 matching_parens parens
;
15408 if (!parens
.require_open (parser
))
15411 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15412 OMP_CLAUSE_ALIGNED
, list
);
15414 if (c_parser_next_token_is (parser
, CPP_COLON
))
15416 c_parser_consume_token (parser
);
15417 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15418 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15419 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15420 tree alignment
= expr
.value
;
15421 alignment
= c_fully_fold (alignment
, false, NULL
);
15422 if (TREE_CODE (alignment
) != INTEGER_CST
15423 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment
))
15424 || tree_int_cst_sgn (alignment
) != 1)
15426 error_at (clause_loc
, "%<aligned%> clause alignment expression must "
15427 "be positive constant integer expression");
15428 alignment
= NULL_TREE
;
15431 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15432 OMP_CLAUSE_ALIGNED_ALIGNMENT (c
) = alignment
;
15435 parens
.skip_until_found_close (parser
);
15440 allocate ( variable-list )
15441 allocate ( expression : variable-list )
15444 allocate ( allocator-modifier : variable-list )
15445 allocate ( allocator-modifier , allocator-modifier : variable-list )
15447 allocator-modifier:
15448 allocator ( expression )
15449 align ( expression ) */
15452 c_parser_omp_clause_allocate (c_parser
*parser
, tree list
)
15454 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15456 tree allocator
= NULL_TREE
;
15457 tree align
= NULL_TREE
;
15459 matching_parens parens
;
15460 if (!parens
.require_open (parser
))
15463 if ((c_parser_next_token_is_not (parser
, CPP_NAME
)
15464 && c_parser_next_token_is_not (parser
, CPP_KEYWORD
))
15465 || (c_parser_peek_2nd_token (parser
)->type
!= CPP_COMMA
15466 && c_parser_peek_2nd_token (parser
)->type
!= CPP_CLOSE_PAREN
))
15468 bool has_modifiers
= false;
15469 tree orig_type
= NULL_TREE
;
15470 if (c_parser_next_token_is (parser
, CPP_NAME
)
15471 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
15473 unsigned int n
= 3;
15475 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15476 if ((strcmp (p
, "allocator") == 0 || strcmp (p
, "align") == 0)
15477 && c_parser_check_balanced_raw_token_sequence (parser
, &n
)
15478 && (c_parser_peek_nth_token_raw (parser
, n
)->type
15479 == CPP_CLOSE_PAREN
))
15481 if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
15483 has_modifiers
= true;
15484 else if (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
15486 && (c_parser_peek_nth_token_raw (parser
, n
+ 2)->type
15488 && (c_parser_peek_nth_token_raw (parser
, n
+ 3)->type
15489 == CPP_OPEN_PAREN
))
15491 c_token
*tok
= c_parser_peek_nth_token_raw (parser
, n
+ 2);
15492 const char *q
= IDENTIFIER_POINTER (tok
->value
);
15494 if ((strcmp (q
, "allocator") == 0
15495 || strcmp (q
, "align") == 0)
15496 && c_parser_check_balanced_raw_token_sequence (parser
,
15498 && (c_parser_peek_nth_token_raw (parser
, n
)->type
15499 == CPP_CLOSE_PAREN
)
15500 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
15502 has_modifiers
= true;
15507 c_parser_consume_token (parser
);
15508 matching_parens parens2
;;
15509 parens2
.require_open (parser
);
15510 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15511 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15512 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15513 if (strcmp (p
, "allocator") == 0)
15515 allocator
= expr
.value
;
15516 allocator
= c_fully_fold (allocator
, false, NULL
);
15517 orig_type
= expr
.original_type
15518 ? expr
.original_type
: TREE_TYPE (allocator
);
15519 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
15523 align
= expr
.value
;
15524 align
= c_fully_fold (align
, false, NULL
);
15526 parens2
.skip_until_found_close (parser
);
15527 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15529 c_parser_consume_token (parser
);
15530 c_token
*tok
= c_parser_peek_token (parser
);
15531 const char *q
= "";
15532 if (c_parser_next_token_is (parser
, CPP_NAME
))
15533 q
= IDENTIFIER_POINTER (tok
->value
);
15534 if (strcmp (q
, "allocator") != 0 && strcmp (q
, "align") != 0)
15536 c_parser_error (parser
, "expected %<allocator%> or "
15538 parens
.skip_until_found_close (parser
);
15541 else if (strcmp (p
, q
) == 0)
15543 error_at (tok
->location
, "duplicate %qs modifier", p
);
15544 parens
.skip_until_found_close (parser
);
15547 c_parser_consume_token (parser
);
15548 if (!parens2
.require_open (parser
))
15550 parens
.skip_until_found_close (parser
);
15553 expr_loc
= c_parser_peek_token (parser
)->location
;
15554 expr
= c_parser_expr_no_commas (parser
, NULL
);
15555 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false,
15557 if (strcmp (q
, "allocator") == 0)
15559 allocator
= expr
.value
;
15560 allocator
= c_fully_fold (allocator
, false, NULL
);
15561 orig_type
= expr
.original_type
15562 ? expr
.original_type
: TREE_TYPE (allocator
);
15563 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
15567 align
= expr
.value
;
15568 align
= c_fully_fold (align
, false, NULL
);
15570 parens2
.skip_until_found_close (parser
);
15574 if (!has_modifiers
)
15576 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15577 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15578 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15579 allocator
= expr
.value
;
15580 allocator
= c_fully_fold (allocator
, false, NULL
);
15581 orig_type
= expr
.original_type
15582 ? expr
.original_type
: TREE_TYPE (allocator
);
15583 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
15586 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
15587 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
15588 || (TYPE_NAME (orig_type
)
15589 != get_identifier ("omp_allocator_handle_t"))))
15591 error_at (clause_loc
, "%<allocate%> clause allocator expression "
15592 "has type %qT rather than "
15593 "%<omp_allocator_handle_t%>",
15594 TREE_TYPE (allocator
));
15595 allocator
= NULL_TREE
;
15598 && (!INTEGRAL_TYPE_P (TREE_TYPE (align
))
15599 || !tree_fits_uhwi_p (align
)
15600 || !integer_pow2p (align
)))
15602 error_at (clause_loc
, "%<allocate%> clause %<align%> modifier "
15603 "argument needs to be positive constant "
15604 "power of two integer expression");
15607 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15609 parens
.skip_until_found_close (parser
);
15614 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15615 OMP_CLAUSE_ALLOCATE
, list
);
15617 if (allocator
|| align
)
15618 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15620 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
15621 OMP_CLAUSE_ALLOCATE_ALIGN (c
) = align
;
15624 parens
.skip_until_found_close (parser
);
15629 linear ( variable-list )
15630 linear ( variable-list : expression )
15633 linear ( modifier ( variable-list ) )
15634 linear ( modifier ( variable-list ) : expression ) */
15637 c_parser_omp_clause_linear (c_parser
*parser
, tree list
)
15639 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15641 enum omp_clause_linear_kind kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15643 matching_parens parens
;
15644 if (!parens
.require_open (parser
))
15647 if (c_parser_next_token_is (parser
, CPP_NAME
))
15649 c_token
*tok
= c_parser_peek_token (parser
);
15650 const char *p
= IDENTIFIER_POINTER (tok
->value
);
15651 if (strcmp ("val", p
) == 0)
15652 kind
= OMP_CLAUSE_LINEAR_VAL
;
15653 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
)
15654 kind
= OMP_CLAUSE_LINEAR_DEFAULT
;
15655 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15657 c_parser_consume_token (parser
);
15658 c_parser_consume_token (parser
);
15662 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
15663 OMP_CLAUSE_LINEAR
, list
);
15665 if (kind
!= OMP_CLAUSE_LINEAR_DEFAULT
)
15666 parens
.skip_until_found_close (parser
);
15668 if (c_parser_next_token_is (parser
, CPP_COLON
))
15670 c_parser_consume_token (parser
);
15671 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15672 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15673 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15675 step
= c_fully_fold (step
, false, NULL
);
15676 if (!INTEGRAL_TYPE_P (TREE_TYPE (step
)))
15678 error_at (clause_loc
, "%<linear%> clause step expression must "
15680 step
= integer_one_node
;
15685 step
= integer_one_node
;
15687 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
15689 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
15690 OMP_CLAUSE_LINEAR_KIND (c
) = kind
;
15693 parens
.skip_until_found_close (parser
);
15698 nontemporal ( variable-list ) */
15701 c_parser_omp_clause_nontemporal (c_parser
*parser
, tree list
)
15703 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_NONTEMPORAL
, list
);
15707 safelen ( constant-expression ) */
15710 c_parser_omp_clause_safelen (c_parser
*parser
, tree list
)
15712 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15715 matching_parens parens
;
15716 if (!parens
.require_open (parser
))
15719 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15720 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15721 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15723 t
= c_fully_fold (t
, false, NULL
);
15724 if (TREE_CODE (t
) != INTEGER_CST
15725 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
15726 || tree_int_cst_sgn (t
) != 1)
15728 error_at (clause_loc
, "%<safelen%> clause expression must "
15729 "be positive constant integer expression");
15733 parens
.skip_until_found_close (parser
);
15734 if (t
== NULL_TREE
|| t
== error_mark_node
)
15737 check_no_duplicate_clause (list
, OMP_CLAUSE_SAFELEN
, "safelen");
15739 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SAFELEN
);
15740 OMP_CLAUSE_SAFELEN_EXPR (c
) = t
;
15741 OMP_CLAUSE_CHAIN (c
) = list
;
15746 simdlen ( constant-expression ) */
15749 c_parser_omp_clause_simdlen (c_parser
*parser
, tree list
)
15751 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15754 matching_parens parens
;
15755 if (!parens
.require_open (parser
))
15758 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
15759 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15760 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
15762 t
= c_fully_fold (t
, false, NULL
);
15763 if (TREE_CODE (t
) != INTEGER_CST
15764 || !INTEGRAL_TYPE_P (TREE_TYPE (t
))
15765 || tree_int_cst_sgn (t
) != 1)
15767 error_at (clause_loc
, "%<simdlen%> clause expression must "
15768 "be positive constant integer expression");
15772 parens
.skip_until_found_close (parser
);
15773 if (t
== NULL_TREE
|| t
== error_mark_node
)
15776 check_no_duplicate_clause (list
, OMP_CLAUSE_SIMDLEN
, "simdlen");
15778 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_SIMDLEN
);
15779 OMP_CLAUSE_SIMDLEN_EXPR (c
) = t
;
15780 OMP_CLAUSE_CHAIN (c
) = list
;
15786 identifier [+/- integer]
15787 vec , identifier [+/- integer]
15791 c_parser_omp_clause_depend_sink (c_parser
*parser
, location_t clause_loc
,
15795 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
15796 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
15798 c_parser_error (parser
, "expected identifier");
15802 while (c_parser_next_token_is (parser
, CPP_NAME
)
15803 && c_parser_peek_token (parser
)->id_kind
== C_ID_ID
)
15805 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
15806 tree addend
= NULL
;
15808 if (t
== NULL_TREE
)
15810 undeclared_variable (c_parser_peek_token (parser
)->location
,
15811 c_parser_peek_token (parser
)->value
);
15812 t
= error_mark_node
;
15815 c_parser_consume_token (parser
);
15818 if (c_parser_next_token_is (parser
, CPP_MINUS
))
15820 else if (!c_parser_next_token_is (parser
, CPP_PLUS
))
15822 addend
= integer_zero_node
;
15824 goto add_to_vector
;
15826 c_parser_consume_token (parser
);
15828 if (c_parser_next_token_is_not (parser
, CPP_NUMBER
))
15830 c_parser_error (parser
, "expected integer");
15834 addend
= c_parser_peek_token (parser
)->value
;
15835 if (TREE_CODE (addend
) != INTEGER_CST
)
15837 c_parser_error (parser
, "expected integer");
15840 c_parser_consume_token (parser
);
15843 if (t
!= error_mark_node
)
15845 vec
= tree_cons (addend
, t
, vec
);
15847 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec
) = 1;
15850 if (c_parser_next_token_is_not (parser
, CPP_COMMA
)
15851 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
15852 || c_parser_peek_2nd_token (parser
)->id_kind
!= C_ID_ID
)
15855 c_parser_consume_token (parser
);
15858 if (vec
== NULL_TREE
)
15861 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
15862 OMP_CLAUSE_DEPEND_KIND (u
) = OMP_CLAUSE_DEPEND_SINK
;
15863 OMP_CLAUSE_DECL (u
) = nreverse (vec
);
15864 OMP_CLAUSE_CHAIN (u
) = list
;
15869 iterators ( iterators-definition )
15871 iterators-definition:
15873 iterator-specifier , iterators-definition
15875 iterator-specifier:
15876 identifier = range-specification
15877 iterator-type identifier = range-specification
15879 range-specification:
15881 begin : end : step */
15884 c_parser_omp_iterators (c_parser
*parser
)
15886 tree ret
= NULL_TREE
, *last
= &ret
;
15887 c_parser_consume_token (parser
);
15891 matching_parens parens
;
15892 if (!parens
.require_open (parser
))
15893 return error_mark_node
;
15897 tree iter_type
= NULL_TREE
, type_expr
= NULL_TREE
;
15898 if (c_parser_next_tokens_start_typename (parser
, cla_prefer_id
))
15900 struct c_type_name
*type
= c_parser_type_name (parser
);
15902 iter_type
= groktypename (type
, &type_expr
, NULL
);
15904 if (iter_type
== NULL_TREE
)
15905 iter_type
= integer_type_node
;
15907 location_t loc
= c_parser_peek_token (parser
)->location
;
15908 if (!c_parser_next_token_is (parser
, CPP_NAME
))
15910 c_parser_error (parser
, "expected identifier");
15914 tree id
= c_parser_peek_token (parser
)->value
;
15915 c_parser_consume_token (parser
);
15917 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
15920 location_t eloc
= c_parser_peek_token (parser
)->location
;
15921 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
15922 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15923 tree begin
= expr
.value
;
15925 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
15928 eloc
= c_parser_peek_token (parser
)->location
;
15929 expr
= c_parser_expr_no_commas (parser
, NULL
);
15930 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15931 tree end
= expr
.value
;
15933 tree step
= integer_one_node
;
15934 if (c_parser_next_token_is (parser
, CPP_COLON
))
15936 c_parser_consume_token (parser
);
15937 eloc
= c_parser_peek_token (parser
)->location
;
15938 expr
= c_parser_expr_no_commas (parser
, NULL
);
15939 expr
= convert_lvalue_to_rvalue (eloc
, expr
, true, false);
15943 tree iter_var
= build_decl (loc
, VAR_DECL
, id
, iter_type
);
15944 DECL_ARTIFICIAL (iter_var
) = 1;
15945 DECL_CONTEXT (iter_var
) = current_function_decl
;
15946 pushdecl (iter_var
);
15948 *last
= make_tree_vec (6);
15949 TREE_VEC_ELT (*last
, 0) = iter_var
;
15950 TREE_VEC_ELT (*last
, 1) = begin
;
15951 TREE_VEC_ELT (*last
, 2) = end
;
15952 TREE_VEC_ELT (*last
, 3) = step
;
15953 last
= &TREE_CHAIN (*last
);
15955 if (c_parser_next_token_is (parser
, CPP_COMMA
))
15957 c_parser_consume_token (parser
);
15964 parens
.skip_until_found_close (parser
);
15965 return ret
? ret
: error_mark_node
;
15969 affinity ( [aff-modifier :] variable-list )
15971 iterator ( iterators-definition ) */
15974 c_parser_omp_clause_affinity (c_parser
*parser
, tree list
)
15976 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
15977 tree nl
, iterators
= NULL_TREE
;
15979 matching_parens parens
;
15980 if (!parens
.require_open (parser
))
15983 if (c_parser_next_token_is (parser
, CPP_NAME
))
15985 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
15986 bool parse_iter
= ((strcmp ("iterator", p
) == 0)
15987 && (c_parser_peek_2nd_token (parser
)->type
15988 == CPP_OPEN_PAREN
));
15992 parse_iter
= (c_parser_check_balanced_raw_token_sequence (parser
, &n
)
15993 && (c_parser_peek_nth_token_raw (parser
, n
)->type
15994 == CPP_CLOSE_PAREN
)
15995 && (c_parser_peek_nth_token_raw (parser
, n
+ 1)->type
16000 iterators
= c_parser_omp_iterators (parser
);
16001 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16005 parens
.skip_until_found_close (parser
);
16010 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_AFFINITY
,
16014 tree block
= pop_scope ();
16015 if (iterators
!= error_mark_node
)
16017 TREE_VEC_ELT (iterators
, 5) = block
;
16018 for (tree c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16019 OMP_CLAUSE_DECL (c
) = build_tree_list (iterators
,
16020 OMP_CLAUSE_DECL (c
));
16024 parens
.skip_until_found_close (parser
);
16030 depend ( depend-kind: variable-list )
16038 depend ( sink : vec )
16041 depend ( depend-modifier , depend-kind: variable-list )
16044 in | out | inout | mutexinoutset | depobj
16047 iterator ( iterators-definition ) */
16050 c_parser_omp_clause_depend (c_parser
*parser
, tree list
)
16052 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16053 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_LAST
;
16054 tree nl
, c
, iterators
= NULL_TREE
;
16056 matching_parens parens
;
16057 if (!parens
.require_open (parser
))
16062 if (c_parser_next_token_is_not (parser
, CPP_NAME
))
16065 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16066 if (strcmp ("iterator", p
) == 0 && iterators
== NULL_TREE
)
16068 iterators
= c_parser_omp_iterators (parser
);
16069 c_parser_require (parser
, CPP_COMMA
, "expected %<,%>");
16072 if (strcmp ("in", p
) == 0)
16073 kind
= OMP_CLAUSE_DEPEND_IN
;
16074 else if (strcmp ("inout", p
) == 0)
16075 kind
= OMP_CLAUSE_DEPEND_INOUT
;
16076 else if (strcmp ("mutexinoutset", p
) == 0)
16077 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
16078 else if (strcmp ("out", p
) == 0)
16079 kind
= OMP_CLAUSE_DEPEND_OUT
;
16080 else if (strcmp ("depobj", p
) == 0)
16081 kind
= OMP_CLAUSE_DEPEND_DEPOBJ
;
16082 else if (strcmp ("sink", p
) == 0)
16083 kind
= OMP_CLAUSE_DEPEND_SINK
;
16084 else if (strcmp ("source", p
) == 0)
16085 kind
= OMP_CLAUSE_DEPEND_SOURCE
;
16092 c_parser_consume_token (parser
);
16095 && (kind
== OMP_CLAUSE_DEPEND_SOURCE
|| kind
== OMP_CLAUSE_DEPEND_SINK
))
16098 error_at (clause_loc
, "%<iterator%> modifier incompatible with %qs",
16099 kind
== OMP_CLAUSE_DEPEND_SOURCE
? "source" : "sink");
16100 iterators
= NULL_TREE
;
16103 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
16105 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEPEND
);
16106 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
16107 OMP_CLAUSE_DECL (c
) = NULL_TREE
;
16108 OMP_CLAUSE_CHAIN (c
) = list
;
16109 parens
.skip_until_found_close (parser
);
16113 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
16116 if (kind
== OMP_CLAUSE_DEPEND_SINK
)
16117 nl
= c_parser_omp_clause_depend_sink (parser
, clause_loc
, list
);
16120 nl
= c_parser_omp_variable_list (parser
, clause_loc
,
16121 OMP_CLAUSE_DEPEND
, list
);
16125 tree block
= pop_scope ();
16126 if (iterators
== error_mark_node
)
16127 iterators
= NULL_TREE
;
16129 TREE_VEC_ELT (iterators
, 5) = block
;
16132 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16134 OMP_CLAUSE_DEPEND_KIND (c
) = kind
;
16136 OMP_CLAUSE_DECL (c
)
16137 = build_tree_list (iterators
, OMP_CLAUSE_DECL (c
));
16141 parens
.skip_until_found_close (parser
);
16145 c_parser_error (parser
, "invalid depend kind");
16147 parens
.skip_until_found_close (parser
);
16154 map ( map-kind: variable-list )
16155 map ( variable-list )
16158 alloc | to | from | tofrom
16162 alloc | to | from | tofrom | release | delete
16164 map ( always [,] map-kind: variable-list )
16167 map ( [map-type-modifier[,] ...] map-kind: variable-list )
16173 c_parser_omp_clause_map (c_parser
*parser
, tree list
)
16175 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16176 enum gomp_map_kind kind
= GOMP_MAP_TOFROM
;
16179 matching_parens parens
;
16180 if (!parens
.require_open (parser
))
16184 int map_kind_pos
= 0;
16185 while (c_parser_peek_nth_token_raw (parser
, pos
)->type
== CPP_NAME
)
16187 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COLON
)
16189 map_kind_pos
= pos
;
16193 if (c_parser_peek_nth_token_raw (parser
, pos
+ 1)->type
== CPP_COMMA
)
16198 int always_modifier
= 0;
16199 int close_modifier
= 0;
16200 for (int pos
= 1; pos
< map_kind_pos
; ++pos
)
16202 c_token
*tok
= c_parser_peek_token (parser
);
16204 if (tok
->type
== CPP_COMMA
)
16206 c_parser_consume_token (parser
);
16210 const char *p
= IDENTIFIER_POINTER (tok
->value
);
16211 if (strcmp ("always", p
) == 0)
16213 if (always_modifier
)
16215 c_parser_error (parser
, "too many %<always%> modifiers");
16216 parens
.skip_until_found_close (parser
);
16221 else if (strcmp ("close", p
) == 0)
16223 if (close_modifier
)
16225 c_parser_error (parser
, "too many %<close%> modifiers");
16226 parens
.skip_until_found_close (parser
);
16233 c_parser_error (parser
, "%<#pragma omp target%> with "
16234 "modifier other than %<always%> or "
16235 "%<close%> on %<map%> clause");
16236 parens
.skip_until_found_close (parser
);
16240 c_parser_consume_token (parser
);
16243 if (c_parser_next_token_is (parser
, CPP_NAME
)
16244 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16246 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16247 if (strcmp ("alloc", p
) == 0)
16248 kind
= GOMP_MAP_ALLOC
;
16249 else if (strcmp ("to", p
) == 0)
16250 kind
= always_modifier
? GOMP_MAP_ALWAYS_TO
: GOMP_MAP_TO
;
16251 else if (strcmp ("from", p
) == 0)
16252 kind
= always_modifier
? GOMP_MAP_ALWAYS_FROM
: GOMP_MAP_FROM
;
16253 else if (strcmp ("tofrom", p
) == 0)
16254 kind
= always_modifier
? GOMP_MAP_ALWAYS_TOFROM
: GOMP_MAP_TOFROM
;
16255 else if (strcmp ("release", p
) == 0)
16256 kind
= GOMP_MAP_RELEASE
;
16257 else if (strcmp ("delete", p
) == 0)
16258 kind
= GOMP_MAP_DELETE
;
16261 c_parser_error (parser
, "invalid map kind");
16262 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
16266 c_parser_consume_token (parser
);
16267 c_parser_consume_token (parser
);
16270 nl
= c_parser_omp_variable_list (parser
, clause_loc
, OMP_CLAUSE_MAP
, list
,
16273 for (c
= nl
; c
!= list
; c
= OMP_CLAUSE_CHAIN (c
))
16274 OMP_CLAUSE_SET_MAP_KIND (c
, kind
);
16276 parens
.skip_until_found_close (parser
);
16281 device ( expression )
16284 device ( [device-modifier :] integer-expression )
16287 ancestor | device_num */
16290 c_parser_omp_clause_device (c_parser
*parser
, tree list
)
16292 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16293 location_t expr_loc
;
16296 bool ancestor
= false;
16298 matching_parens parens
;
16299 if (!parens
.require_open (parser
))
16302 if (c_parser_next_token_is (parser
, CPP_NAME
)
16303 && c_parser_peek_2nd_token (parser
)->type
== CPP_COLON
)
16305 c_token
*tok
= c_parser_peek_token (parser
);
16306 const char *p
= IDENTIFIER_POINTER (tok
->value
);
16307 if (strcmp ("ancestor", p
) == 0)
16309 /* A requires directive with the reverse_offload clause must be
16311 if ((omp_requires_mask
& OMP_REQUIRES_REVERSE_OFFLOAD
) == 0)
16313 error_at (tok
->location
, "%<ancestor%> device modifier not "
16314 "preceded by %<requires%> directive "
16315 "with %<reverse_offload%> clause");
16316 parens
.skip_until_found_close (parser
);
16321 else if (strcmp ("device_num", p
) == 0)
16325 error_at (tok
->location
, "expected %<ancestor%> or %<device_num%>");
16326 parens
.skip_until_found_close (parser
);
16329 c_parser_consume_token (parser
);
16330 c_parser_consume_token (parser
);
16333 expr_loc
= c_parser_peek_token (parser
)->location
;
16334 expr
= c_parser_expr_no_commas (parser
, NULL
);
16335 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16337 t
= c_fully_fold (t
, false, NULL
);
16339 parens
.skip_until_found_close (parser
);
16341 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
)))
16343 c_parser_error (parser
, "expected integer expression");
16346 if (ancestor
&& TREE_CODE (t
) == INTEGER_CST
&& !integer_onep (t
))
16348 error_at (expr_loc
, "the %<device%> clause expression must evaluate to "
16353 check_no_duplicate_clause (list
, OMP_CLAUSE_DEVICE
, "device");
16355 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE
);
16357 OMP_CLAUSE_DEVICE_ID (c
) = t
;
16358 OMP_CLAUSE_CHAIN (c
) = list
;
16359 OMP_CLAUSE_DEVICE_ANCESTOR (c
) = ancestor
;
16366 dist_schedule ( static )
16367 dist_schedule ( static , expression ) */
16370 c_parser_omp_clause_dist_schedule (c_parser
*parser
, tree list
)
16372 tree c
, t
= NULL_TREE
;
16373 location_t loc
= c_parser_peek_token (parser
)->location
;
16375 matching_parens parens
;
16376 if (!parens
.require_open (parser
))
16379 if (!c_parser_next_token_is_keyword (parser
, RID_STATIC
))
16381 c_parser_error (parser
, "invalid dist_schedule kind");
16382 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
16387 c_parser_consume_token (parser
);
16388 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16390 c_parser_consume_token (parser
);
16392 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
16393 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
16394 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
16396 t
= c_fully_fold (t
, false, NULL
);
16397 parens
.skip_until_found_close (parser
);
16400 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
16401 "expected %<,%> or %<)%>");
16403 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
16404 "dist_schedule"); */
16405 if (omp_find_clause (list
, OMP_CLAUSE_DIST_SCHEDULE
))
16406 warning_at (loc
, 0, "too many %qs clauses", "dist_schedule");
16407 if (t
== error_mark_node
)
16410 c
= build_omp_clause (loc
, OMP_CLAUSE_DIST_SCHEDULE
);
16411 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c
) = t
;
16412 OMP_CLAUSE_CHAIN (c
) = list
;
16417 proc_bind ( proc-bind-kind )
16420 primary | master | close | spread
16421 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
16424 c_parser_omp_clause_proc_bind (c_parser
*parser
, tree list
)
16426 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16427 enum omp_clause_proc_bind_kind kind
;
16430 matching_parens parens
;
16431 if (!parens
.require_open (parser
))
16434 if (c_parser_next_token_is (parser
, CPP_NAME
))
16436 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16437 if (strcmp ("primary", p
) == 0)
16438 kind
= OMP_CLAUSE_PROC_BIND_PRIMARY
;
16439 else if (strcmp ("master", p
) == 0)
16440 kind
= OMP_CLAUSE_PROC_BIND_MASTER
;
16441 else if (strcmp ("close", p
) == 0)
16442 kind
= OMP_CLAUSE_PROC_BIND_CLOSE
;
16443 else if (strcmp ("spread", p
) == 0)
16444 kind
= OMP_CLAUSE_PROC_BIND_SPREAD
;
16451 check_no_duplicate_clause (list
, OMP_CLAUSE_PROC_BIND
, "proc_bind");
16452 c_parser_consume_token (parser
);
16453 parens
.skip_until_found_close (parser
);
16454 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_PROC_BIND
);
16455 OMP_CLAUSE_PROC_BIND_KIND (c
) = kind
;
16456 OMP_CLAUSE_CHAIN (c
) = list
;
16460 c_parser_error (parser
, "invalid proc_bind kind");
16461 parens
.skip_until_found_close (parser
);
16466 device_type ( host | nohost | any ) */
16469 c_parser_omp_clause_device_type (c_parser
*parser
, tree list
)
16471 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16472 enum omp_clause_device_type_kind kind
;
16475 matching_parens parens
;
16476 if (!parens
.require_open (parser
))
16479 if (c_parser_next_token_is (parser
, CPP_NAME
))
16481 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
16482 if (strcmp ("host", p
) == 0)
16483 kind
= OMP_CLAUSE_DEVICE_TYPE_HOST
;
16484 else if (strcmp ("nohost", p
) == 0)
16485 kind
= OMP_CLAUSE_DEVICE_TYPE_NOHOST
;
16486 else if (strcmp ("any", p
) == 0)
16487 kind
= OMP_CLAUSE_DEVICE_TYPE_ANY
;
16494 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
16496 c_parser_consume_token (parser
);
16497 parens
.skip_until_found_close (parser
);
16498 c
= build_omp_clause (clause_loc
, OMP_CLAUSE_DEVICE_TYPE
);
16499 OMP_CLAUSE_DEVICE_TYPE_KIND (c
) = kind
;
16500 OMP_CLAUSE_CHAIN (c
) = list
;
16504 c_parser_error (parser
, "expected %<host%>, %<nohost%> or %<any%>");
16505 parens
.skip_until_found_close (parser
);
16510 to ( variable-list ) */
16513 c_parser_omp_clause_to (c_parser
*parser
, tree list
)
16515 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO
, list
, true);
16519 from ( variable-list ) */
16522 c_parser_omp_clause_from (c_parser
*parser
, tree list
)
16524 return c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_FROM
, list
, true);
16528 uniform ( variable-list ) */
16531 c_parser_omp_clause_uniform (c_parser
*parser
, tree list
)
16533 /* The clauses location. */
16534 location_t loc
= c_parser_peek_token (parser
)->location
;
16536 matching_parens parens
;
16537 if (parens
.require_open (parser
))
16539 list
= c_parser_omp_variable_list (parser
, loc
, OMP_CLAUSE_UNIFORM
,
16541 parens
.skip_until_found_close (parser
);
16547 detach ( event-handle ) */
16550 c_parser_omp_clause_detach (c_parser
*parser
, tree list
)
16552 matching_parens parens
;
16553 location_t clause_loc
= c_parser_peek_token (parser
)->location
;
16555 if (!parens
.require_open (parser
))
16558 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
16559 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
16561 c_parser_error (parser
, "expected identifier");
16562 parens
.skip_until_found_close (parser
);
16566 tree t
= lookup_name (c_parser_peek_token (parser
)->value
);
16567 if (t
== NULL_TREE
)
16569 undeclared_variable (c_parser_peek_token (parser
)->location
,
16570 c_parser_peek_token (parser
)->value
);
16571 parens
.skip_until_found_close (parser
);
16574 c_parser_consume_token (parser
);
16576 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (t
));
16577 if (!INTEGRAL_TYPE_P (type
)
16578 || TREE_CODE (type
) != ENUMERAL_TYPE
16579 || TYPE_NAME (type
) != get_identifier ("omp_event_handle_t"))
16581 error_at (clause_loc
, "%<detach%> clause event handle "
16582 "has type %qT rather than "
16583 "%<omp_event_handle_t%>",
16585 parens
.skip_until_found_close (parser
);
16589 tree u
= build_omp_clause (clause_loc
, OMP_CLAUSE_DETACH
);
16590 OMP_CLAUSE_DECL (u
) = t
;
16591 OMP_CLAUSE_CHAIN (u
) = list
;
16592 parens
.skip_until_found_close (parser
);
16596 /* Parse all OpenACC clauses. The set clauses allowed by the directive
16597 is a bitmask in MASK. Return the list of clauses found. */
16600 c_parser_oacc_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
16601 const char *where
, bool finish_p
= true)
16603 tree clauses
= NULL
;
16606 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
16609 pragma_omp_clause c_kind
;
16610 const char *c_name
;
16611 tree prev
= clauses
;
16613 if (!first
&& c_parser_next_token_is (parser
, CPP_COMMA
))
16614 c_parser_consume_token (parser
);
16616 here
= c_parser_peek_token (parser
)->location
;
16617 c_kind
= c_parser_omp_clause_name (parser
);
16621 case PRAGMA_OACC_CLAUSE_ASYNC
:
16622 clauses
= c_parser_oacc_clause_async (parser
, clauses
);
16625 case PRAGMA_OACC_CLAUSE_AUTO
:
16626 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_AUTO
,
16630 case PRAGMA_OACC_CLAUSE_ATTACH
:
16631 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16634 case PRAGMA_OACC_CLAUSE_COLLAPSE
:
16635 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
16636 c_name
= "collapse";
16638 case PRAGMA_OACC_CLAUSE_COPY
:
16639 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16642 case PRAGMA_OACC_CLAUSE_COPYIN
:
16643 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16646 case PRAGMA_OACC_CLAUSE_COPYOUT
:
16647 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16648 c_name
= "copyout";
16650 case PRAGMA_OACC_CLAUSE_CREATE
:
16651 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16654 case PRAGMA_OACC_CLAUSE_DELETE
:
16655 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16658 case PRAGMA_OMP_CLAUSE_DEFAULT
:
16659 clauses
= c_parser_omp_clause_default (parser
, clauses
, true);
16660 c_name
= "default";
16662 case PRAGMA_OACC_CLAUSE_DETACH
:
16663 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16666 case PRAGMA_OACC_CLAUSE_DEVICE
:
16667 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16670 case PRAGMA_OACC_CLAUSE_DEVICEPTR
:
16671 clauses
= c_parser_oacc_data_clause_deviceptr (parser
, clauses
);
16672 c_name
= "deviceptr";
16674 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT
:
16675 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16676 c_name
= "device_resident";
16678 case PRAGMA_OACC_CLAUSE_FINALIZE
:
16679 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_FINALIZE
,
16681 c_name
= "finalize";
16683 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE
:
16684 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
16685 c_name
= "firstprivate";
16687 case PRAGMA_OACC_CLAUSE_GANG
:
16689 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_GANG
,
16692 case PRAGMA_OACC_CLAUSE_HOST
:
16693 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16696 case PRAGMA_OACC_CLAUSE_IF
:
16697 clauses
= c_parser_omp_clause_if (parser
, clauses
, false);
16700 case PRAGMA_OACC_CLAUSE_IF_PRESENT
:
16701 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_IF_PRESENT
,
16703 c_name
= "if_present";
16705 case PRAGMA_OACC_CLAUSE_INDEPENDENT
:
16706 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_INDEPENDENT
,
16708 c_name
= "independent";
16710 case PRAGMA_OACC_CLAUSE_LINK
:
16711 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16714 case PRAGMA_OACC_CLAUSE_NO_CREATE
:
16715 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16716 c_name
= "no_create";
16718 case PRAGMA_OACC_CLAUSE_NOHOST
:
16719 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_NOHOST
,
16723 case PRAGMA_OACC_CLAUSE_NUM_GANGS
:
16724 clauses
= c_parser_oacc_single_int_clause (parser
,
16725 OMP_CLAUSE_NUM_GANGS
,
16727 c_name
= "num_gangs";
16729 case PRAGMA_OACC_CLAUSE_NUM_WORKERS
:
16730 clauses
= c_parser_oacc_single_int_clause (parser
,
16731 OMP_CLAUSE_NUM_WORKERS
,
16733 c_name
= "num_workers";
16735 case PRAGMA_OACC_CLAUSE_PRESENT
:
16736 clauses
= c_parser_oacc_data_clause (parser
, c_kind
, clauses
);
16737 c_name
= "present";
16739 case PRAGMA_OACC_CLAUSE_PRIVATE
:
16740 clauses
= c_parser_omp_clause_private (parser
, clauses
);
16741 c_name
= "private";
16743 case PRAGMA_OACC_CLAUSE_REDUCTION
:
16745 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
16747 c_name
= "reduction";
16749 case PRAGMA_OACC_CLAUSE_SEQ
:
16750 clauses
= c_parser_oacc_simple_clause (here
, OMP_CLAUSE_SEQ
,
16754 case PRAGMA_OACC_CLAUSE_TILE
:
16755 clauses
= c_parser_oacc_clause_tile (parser
, clauses
);
16758 case PRAGMA_OACC_CLAUSE_USE_DEVICE
:
16759 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
16760 c_name
= "use_device";
16762 case PRAGMA_OACC_CLAUSE_VECTOR
:
16764 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_VECTOR
,
16767 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH
:
16768 clauses
= c_parser_oacc_single_int_clause (parser
,
16769 OMP_CLAUSE_VECTOR_LENGTH
,
16771 c_name
= "vector_length";
16773 case PRAGMA_OACC_CLAUSE_WAIT
:
16774 clauses
= c_parser_oacc_clause_wait (parser
, clauses
);
16777 case PRAGMA_OACC_CLAUSE_WORKER
:
16779 clauses
= c_parser_oacc_shape_clause (parser
, here
, OMP_CLAUSE_WORKER
,
16783 c_parser_error (parser
, "expected %<#pragma acc%> clause");
16789 if (((mask
>> c_kind
) & 1) == 0)
16791 /* Remove the invalid clause(s) from the list to avoid
16792 confusing the rest of the compiler. */
16794 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
16799 c_parser_skip_to_pragma_eol (parser
);
16802 return c_finish_omp_clauses (clauses
, C_ORT_ACC
);
16807 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16808 is a bitmask in MASK. Return the list of clauses found.
16809 FINISH_P set if c_finish_omp_clauses should be called.
16810 NESTED non-zero if clauses should be terminated by closing paren instead
16811 of end of pragma. If it is 2, additionally commas are required in between
16815 c_parser_omp_all_clauses (c_parser
*parser
, omp_clause_mask mask
,
16816 const char *where
, bool finish_p
= true,
16819 tree clauses
= NULL
;
16822 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
16825 pragma_omp_clause c_kind
;
16826 const char *c_name
;
16827 tree prev
= clauses
;
16829 if (nested
&& c_parser_next_token_is (parser
, CPP_CLOSE_PAREN
))
16834 if (c_parser_next_token_is (parser
, CPP_COMMA
))
16835 c_parser_consume_token (parser
);
16836 else if (nested
== 2)
16837 error_at (c_parser_peek_token (parser
)->location
,
16838 "clauses in %<simd%> trait should be separated "
16842 here
= c_parser_peek_token (parser
)->location
;
16843 c_kind
= c_parser_omp_clause_name (parser
);
16847 case PRAGMA_OMP_CLAUSE_BIND
:
16848 clauses
= c_parser_omp_clause_bind (parser
, clauses
);
16851 case PRAGMA_OMP_CLAUSE_COLLAPSE
:
16852 clauses
= c_parser_omp_clause_collapse (parser
, clauses
);
16853 c_name
= "collapse";
16855 case PRAGMA_OMP_CLAUSE_COPYIN
:
16856 clauses
= c_parser_omp_clause_copyin (parser
, clauses
);
16859 case PRAGMA_OMP_CLAUSE_COPYPRIVATE
:
16860 clauses
= c_parser_omp_clause_copyprivate (parser
, clauses
);
16861 c_name
= "copyprivate";
16863 case PRAGMA_OMP_CLAUSE_DEFAULT
:
16864 clauses
= c_parser_omp_clause_default (parser
, clauses
, false);
16865 c_name
= "default";
16867 case PRAGMA_OMP_CLAUSE_DETACH
:
16868 clauses
= c_parser_omp_clause_detach (parser
, clauses
);
16871 case PRAGMA_OMP_CLAUSE_FILTER
:
16872 clauses
= c_parser_omp_clause_filter (parser
, clauses
);
16875 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE
:
16876 clauses
= c_parser_omp_clause_firstprivate (parser
, clauses
);
16877 c_name
= "firstprivate";
16879 case PRAGMA_OMP_CLAUSE_FINAL
:
16880 clauses
= c_parser_omp_clause_final (parser
, clauses
);
16883 case PRAGMA_OMP_CLAUSE_GRAINSIZE
:
16884 clauses
= c_parser_omp_clause_grainsize (parser
, clauses
);
16885 c_name
= "grainsize";
16887 case PRAGMA_OMP_CLAUSE_HINT
:
16888 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
16891 case PRAGMA_OMP_CLAUSE_DEFAULTMAP
:
16892 clauses
= c_parser_omp_clause_defaultmap (parser
, clauses
);
16893 c_name
= "defaultmap";
16895 case PRAGMA_OMP_CLAUSE_IF
:
16896 clauses
= c_parser_omp_clause_if (parser
, clauses
, true);
16899 case PRAGMA_OMP_CLAUSE_IN_REDUCTION
:
16901 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_IN_REDUCTION
,
16903 c_name
= "in_reduction";
16905 case PRAGMA_OMP_CLAUSE_LASTPRIVATE
:
16906 clauses
= c_parser_omp_clause_lastprivate (parser
, clauses
);
16907 c_name
= "lastprivate";
16909 case PRAGMA_OMP_CLAUSE_MERGEABLE
:
16910 clauses
= c_parser_omp_clause_mergeable (parser
, clauses
);
16911 c_name
= "mergeable";
16913 case PRAGMA_OMP_CLAUSE_NOWAIT
:
16914 clauses
= c_parser_omp_clause_nowait (parser
, clauses
);
16917 case PRAGMA_OMP_CLAUSE_NUM_TASKS
:
16918 clauses
= c_parser_omp_clause_num_tasks (parser
, clauses
);
16919 c_name
= "num_tasks";
16921 case PRAGMA_OMP_CLAUSE_NUM_THREADS
:
16922 clauses
= c_parser_omp_clause_num_threads (parser
, clauses
);
16923 c_name
= "num_threads";
16925 case PRAGMA_OMP_CLAUSE_ORDER
:
16926 clauses
= c_parser_omp_clause_order (parser
, clauses
);
16929 case PRAGMA_OMP_CLAUSE_ORDERED
:
16930 clauses
= c_parser_omp_clause_ordered (parser
, clauses
);
16931 c_name
= "ordered";
16933 case PRAGMA_OMP_CLAUSE_PRIORITY
:
16934 clauses
= c_parser_omp_clause_priority (parser
, clauses
);
16935 c_name
= "priority";
16937 case PRAGMA_OMP_CLAUSE_PRIVATE
:
16938 clauses
= c_parser_omp_clause_private (parser
, clauses
);
16939 c_name
= "private";
16941 case PRAGMA_OMP_CLAUSE_REDUCTION
:
16943 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_REDUCTION
,
16945 c_name
= "reduction";
16947 case PRAGMA_OMP_CLAUSE_SCHEDULE
:
16948 clauses
= c_parser_omp_clause_schedule (parser
, clauses
);
16949 c_name
= "schedule";
16951 case PRAGMA_OMP_CLAUSE_SHARED
:
16952 clauses
= c_parser_omp_clause_shared (parser
, clauses
);
16955 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION
:
16957 = c_parser_omp_clause_reduction (parser
, OMP_CLAUSE_TASK_REDUCTION
,
16959 c_name
= "task_reduction";
16961 case PRAGMA_OMP_CLAUSE_UNTIED
:
16962 clauses
= c_parser_omp_clause_untied (parser
, clauses
);
16965 case PRAGMA_OMP_CLAUSE_INBRANCH
:
16966 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_INBRANCH
,
16968 c_name
= "inbranch";
16970 case PRAGMA_OMP_CLAUSE_NONTEMPORAL
:
16971 clauses
= c_parser_omp_clause_nontemporal (parser
, clauses
);
16972 c_name
= "nontemporal";
16974 case PRAGMA_OMP_CLAUSE_NOTINBRANCH
:
16975 clauses
= c_parser_omp_clause_branch (parser
, OMP_CLAUSE_NOTINBRANCH
,
16977 c_name
= "notinbranch";
16979 case PRAGMA_OMP_CLAUSE_PARALLEL
:
16981 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_PARALLEL
,
16983 c_name
= "parallel";
16987 error_at (here
, "%qs must be the first clause of %qs",
16992 case PRAGMA_OMP_CLAUSE_FOR
:
16994 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_FOR
,
16998 goto clause_not_first
;
17000 case PRAGMA_OMP_CLAUSE_SECTIONS
:
17002 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_SECTIONS
,
17004 c_name
= "sections";
17006 goto clause_not_first
;
17008 case PRAGMA_OMP_CLAUSE_TASKGROUP
:
17010 = c_parser_omp_clause_cancelkind (parser
, OMP_CLAUSE_TASKGROUP
,
17012 c_name
= "taskgroup";
17014 goto clause_not_first
;
17016 case PRAGMA_OMP_CLAUSE_LINK
:
17018 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_LINK
, clauses
);
17021 case PRAGMA_OMP_CLAUSE_TO
:
17022 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINK
)) != 0)
17024 = c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO_DECLARE
,
17027 clauses
= c_parser_omp_clause_to (parser
, clauses
);
17030 case PRAGMA_OMP_CLAUSE_FROM
:
17031 clauses
= c_parser_omp_clause_from (parser
, clauses
);
17034 case PRAGMA_OMP_CLAUSE_UNIFORM
:
17035 clauses
= c_parser_omp_clause_uniform (parser
, clauses
);
17036 c_name
= "uniform";
17038 case PRAGMA_OMP_CLAUSE_NUM_TEAMS
:
17039 clauses
= c_parser_omp_clause_num_teams (parser
, clauses
);
17040 c_name
= "num_teams";
17042 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT
:
17043 clauses
= c_parser_omp_clause_thread_limit (parser
, clauses
);
17044 c_name
= "thread_limit";
17046 case PRAGMA_OMP_CLAUSE_ALIGNED
:
17047 clauses
= c_parser_omp_clause_aligned (parser
, clauses
);
17048 c_name
= "aligned";
17050 case PRAGMA_OMP_CLAUSE_ALLOCATE
:
17051 clauses
= c_parser_omp_clause_allocate (parser
, clauses
);
17052 c_name
= "allocate";
17054 case PRAGMA_OMP_CLAUSE_LINEAR
:
17055 clauses
= c_parser_omp_clause_linear (parser
, clauses
);
17058 case PRAGMA_OMP_CLAUSE_AFFINITY
:
17059 clauses
= c_parser_omp_clause_affinity (parser
, clauses
);
17060 c_name
= "affinity";
17062 case PRAGMA_OMP_CLAUSE_DEPEND
:
17063 clauses
= c_parser_omp_clause_depend (parser
, clauses
);
17066 case PRAGMA_OMP_CLAUSE_MAP
:
17067 clauses
= c_parser_omp_clause_map (parser
, clauses
);
17070 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
:
17071 clauses
= c_parser_omp_clause_use_device_ptr (parser
, clauses
);
17072 c_name
= "use_device_ptr";
17074 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
:
17075 clauses
= c_parser_omp_clause_use_device_addr (parser
, clauses
);
17076 c_name
= "use_device_addr";
17078 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR
:
17079 clauses
= c_parser_omp_clause_has_device_addr (parser
, clauses
);
17080 c_name
= "has_device_addr";
17082 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR
:
17083 clauses
= c_parser_omp_clause_is_device_ptr (parser
, clauses
);
17084 c_name
= "is_device_ptr";
17086 case PRAGMA_OMP_CLAUSE_DEVICE
:
17087 clauses
= c_parser_omp_clause_device (parser
, clauses
);
17090 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
:
17091 clauses
= c_parser_omp_clause_dist_schedule (parser
, clauses
);
17092 c_name
= "dist_schedule";
17094 case PRAGMA_OMP_CLAUSE_PROC_BIND
:
17095 clauses
= c_parser_omp_clause_proc_bind (parser
, clauses
);
17096 c_name
= "proc_bind";
17098 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE
:
17099 clauses
= c_parser_omp_clause_device_type (parser
, clauses
);
17100 c_name
= "device_type";
17102 case PRAGMA_OMP_CLAUSE_SAFELEN
:
17103 clauses
= c_parser_omp_clause_safelen (parser
, clauses
);
17104 c_name
= "safelen";
17106 case PRAGMA_OMP_CLAUSE_SIMDLEN
:
17107 clauses
= c_parser_omp_clause_simdlen (parser
, clauses
);
17108 c_name
= "simdlen";
17110 case PRAGMA_OMP_CLAUSE_NOGROUP
:
17111 clauses
= c_parser_omp_clause_nogroup (parser
, clauses
);
17112 c_name
= "nogroup";
17114 case PRAGMA_OMP_CLAUSE_THREADS
:
17116 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_THREADS
,
17118 c_name
= "threads";
17120 case PRAGMA_OMP_CLAUSE_SIMD
:
17122 = c_parser_omp_clause_orderedkind (parser
, OMP_CLAUSE_SIMD
,
17127 c_parser_error (parser
, "expected %<#pragma omp%> clause");
17133 if (((mask
>> c_kind
) & 1) == 0)
17135 /* Remove the invalid clause(s) from the list to avoid
17136 confusing the rest of the compiler. */
17138 error_at (here
, "%qs is not valid for %qs", c_name
, where
);
17144 c_parser_skip_to_pragma_eol (parser
);
17148 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_UNIFORM
)) != 0)
17149 return c_finish_omp_clauses (clauses
, C_ORT_OMP_DECLARE_SIMD
);
17150 return c_finish_omp_clauses (clauses
, C_ORT_OMP
);
17156 /* OpenACC 2.0, OpenMP 2.5:
17160 In practice, we're also interested in adding the statement to an
17161 outer node. So it is convenient if we work around the fact that
17162 c_parser_statement calls add_stmt. */
17165 c_parser_omp_structured_block (c_parser
*parser
, bool *if_p
)
17167 tree stmt
= push_stmt_list ();
17168 c_parser_statement (parser
, if_p
);
17169 return pop_stmt_list (stmt
);
17173 # pragma acc cache (variable-list) new-line
17175 LOC is the location of the #pragma token.
17179 c_parser_oacc_cache (location_t loc
, c_parser
*parser
)
17181 tree stmt
, clauses
;
17183 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE__CACHE_
, NULL
);
17184 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
17186 c_parser_skip_to_pragma_eol (parser
);
17188 stmt
= make_node (OACC_CACHE
);
17189 TREE_TYPE (stmt
) = void_type_node
;
17190 OACC_CACHE_CLAUSES (stmt
) = clauses
;
17191 SET_EXPR_LOCATION (stmt
, loc
);
17198 # pragma acc data oacc-data-clause[optseq] new-line
17201 LOC is the location of the #pragma token.
17204 #define OACC_DATA_CLAUSE_MASK \
17205 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17206 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17207 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17208 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17209 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17210 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17211 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17212 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17213 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17216 c_parser_oacc_data (location_t loc
, c_parser
*parser
, bool *if_p
)
17218 tree stmt
, clauses
, block
;
17220 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DATA_CLAUSE_MASK
,
17221 "#pragma acc data");
17223 block
= c_begin_omp_parallel ();
17224 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
17226 stmt
= c_finish_oacc_data (loc
, clauses
, block
);
17232 # pragma acc declare oacc-data-clause[optseq] new-line
17235 #define OACC_DECLARE_CLAUSE_MASK \
17236 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17237 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17238 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17239 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17240 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17241 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
17242 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
17243 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17246 c_parser_oacc_declare (c_parser
*parser
)
17248 location_t pragma_loc
= c_parser_peek_token (parser
)->location
;
17249 tree clauses
, stmt
, t
, decl
;
17251 bool error
= false;
17253 c_parser_consume_pragma (parser
);
17255 clauses
= c_parser_oacc_all_clauses (parser
, OACC_DECLARE_CLAUSE_MASK
,
17256 "#pragma acc declare");
17259 error_at (pragma_loc
,
17260 "no valid clauses specified in %<#pragma acc declare%>");
17264 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
17266 location_t loc
= OMP_CLAUSE_LOCATION (t
);
17267 decl
= OMP_CLAUSE_DECL (t
);
17268 if (!DECL_P (decl
))
17270 error_at (loc
, "array section in %<#pragma acc declare%>");
17275 switch (OMP_CLAUSE_MAP_KIND (t
))
17277 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
17278 case GOMP_MAP_ALLOC
:
17280 case GOMP_MAP_FORCE_DEVICEPTR
:
17281 case GOMP_MAP_DEVICE_RESIDENT
:
17284 case GOMP_MAP_LINK
:
17285 if (!global_bindings_p ()
17286 && (TREE_STATIC (decl
)
17287 || !DECL_EXTERNAL (decl
)))
17290 "%qD must be a global variable in "
17291 "%<#pragma acc declare link%>",
17299 if (global_bindings_p ())
17301 error_at (loc
, "invalid OpenACC clause at file scope");
17305 if (DECL_EXTERNAL (decl
))
17308 "invalid use of %<extern%> variable %qD "
17309 "in %<#pragma acc declare%>", decl
);
17313 else if (TREE_PUBLIC (decl
))
17316 "invalid use of %<global%> variable %qD "
17317 "in %<#pragma acc declare%>", decl
);
17324 if (!c_check_in_current_scope (decl
))
17327 "%qD must be a variable declared in the same scope as "
17328 "%<#pragma acc declare%>", decl
);
17333 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl
))
17334 || lookup_attribute ("omp declare target link",
17335 DECL_ATTRIBUTES (decl
)))
17337 error_at (loc
, "variable %qD used more than once with "
17338 "%<#pragma acc declare%>", decl
);
17347 if (OMP_CLAUSE_MAP_KIND (t
) == GOMP_MAP_LINK
)
17348 id
= get_identifier ("omp declare target link");
17350 id
= get_identifier ("omp declare target");
17352 DECL_ATTRIBUTES (decl
)
17353 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
17355 if (global_bindings_p ())
17357 symtab_node
*node
= symtab_node::get (decl
);
17360 node
->offloadable
= 1;
17361 if (ENABLE_OFFLOADING
)
17363 g
->have_offload
= true;
17364 if (is_a
<varpool_node
*> (node
))
17365 vec_safe_push (offload_vars
, decl
);
17372 if (error
|| global_bindings_p ())
17375 stmt
= make_node (OACC_DECLARE
);
17376 TREE_TYPE (stmt
) = void_type_node
;
17377 OACC_DECLARE_CLAUSES (stmt
) = clauses
;
17378 SET_EXPR_LOCATION (stmt
, pragma_loc
);
17386 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
17390 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
17393 LOC is the location of the #pragma token.
17396 #define OACC_ENTER_DATA_CLAUSE_MASK \
17397 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17398 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17399 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17400 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17401 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17402 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17404 #define OACC_EXIT_DATA_CLAUSE_MASK \
17405 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17406 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17407 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17408 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
17409 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
17410 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
17411 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17414 c_parser_oacc_enter_exit_data (c_parser
*parser
, bool enter
)
17416 location_t loc
= c_parser_peek_token (parser
)->location
;
17417 tree clauses
, stmt
;
17418 const char *p
= "";
17420 c_parser_consume_pragma (parser
);
17422 if (c_parser_next_token_is (parser
, CPP_NAME
))
17424 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17425 c_parser_consume_token (parser
);
17428 if (strcmp (p
, "data") != 0)
17430 error_at (loc
, "expected %<data%> after %<#pragma acc %s%>",
17431 enter
? "enter" : "exit");
17432 parser
->error
= true;
17433 c_parser_skip_to_pragma_eol (parser
);
17438 clauses
= c_parser_oacc_all_clauses (parser
, OACC_ENTER_DATA_CLAUSE_MASK
,
17439 "#pragma acc enter data");
17441 clauses
= c_parser_oacc_all_clauses (parser
, OACC_EXIT_DATA_CLAUSE_MASK
,
17442 "#pragma acc exit data");
17444 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
17446 error_at (loc
, "%<#pragma acc %s data%> has no data movement clause",
17447 enter
? "enter" : "exit");
17451 stmt
= enter
? make_node (OACC_ENTER_DATA
) : make_node (OACC_EXIT_DATA
);
17452 TREE_TYPE (stmt
) = void_type_node
;
17453 OMP_STANDALONE_CLAUSES (stmt
) = clauses
;
17454 SET_EXPR_LOCATION (stmt
, loc
);
17460 # pragma acc host_data oacc-data-clause[optseq] new-line
17464 #define OACC_HOST_DATA_CLAUSE_MASK \
17465 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
17466 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17467 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
17470 c_parser_oacc_host_data (location_t loc
, c_parser
*parser
, bool *if_p
)
17472 tree stmt
, clauses
, block
;
17474 clauses
= c_parser_oacc_all_clauses (parser
, OACC_HOST_DATA_CLAUSE_MASK
,
17475 "#pragma acc host_data");
17477 block
= c_begin_omp_parallel ();
17478 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
17479 stmt
= c_finish_oacc_host_data (loc
, clauses
, block
);
17486 # pragma acc loop oacc-loop-clause[optseq] new-line
17489 LOC is the location of the #pragma token.
17492 #define OACC_LOOP_CLAUSE_MASK \
17493 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
17494 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17495 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17497 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17498 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17499 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
17500 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
17501 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17502 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
17504 c_parser_oacc_loop (location_t loc
, c_parser
*parser
, char *p_name
,
17505 omp_clause_mask mask
, tree
*cclauses
, bool *if_p
)
17507 bool is_parallel
= ((mask
>> PRAGMA_OACC_CLAUSE_REDUCTION
) & 1) == 1;
17509 strcat (p_name
, " loop");
17510 mask
|= OACC_LOOP_CLAUSE_MASK
;
17512 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
,
17516 clauses
= c_oacc_split_loop_clauses (clauses
, cclauses
, is_parallel
);
17518 *cclauses
= c_finish_omp_clauses (*cclauses
, C_ORT_ACC
);
17520 clauses
= c_finish_omp_clauses (clauses
, C_ORT_ACC
);
17523 tree block
= c_begin_compound_stmt (true);
17524 tree stmt
= c_parser_omp_for_loop (loc
, parser
, OACC_LOOP
, clauses
, NULL
,
17526 block
= c_end_compound_stmt (loc
, block
, true);
17533 # pragma acc kernels oacc-kernels-clause[optseq] new-line
17538 # pragma acc parallel oacc-parallel-clause[optseq] new-line
17543 # pragma acc serial oacc-serial-clause[optseq] new-line
17546 LOC is the location of the #pragma token.
17549 #define OACC_KERNELS_CLAUSE_MASK \
17550 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17551 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17552 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17553 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17554 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17555 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17556 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17557 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17558 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17559 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17560 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17561 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17562 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17563 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17564 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17566 #define OACC_PARALLEL_CLAUSE_MASK \
17567 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17568 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17569 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17570 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17571 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17572 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17574 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17575 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17576 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17577 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17578 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17579 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17580 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17581 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17582 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17583 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17584 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17586 #define OACC_SERIAL_CLAUSE_MASK \
17587 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17588 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17589 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17590 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17591 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17592 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17593 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17594 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17595 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17596 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17597 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17598 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17599 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17600 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17601 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17604 c_parser_oacc_compute (location_t loc
, c_parser
*parser
,
17605 enum pragma_kind p_kind
, char *p_name
, bool *if_p
)
17607 omp_clause_mask mask
;
17608 enum tree_code code
;
17611 case PRAGMA_OACC_KERNELS
:
17612 strcat (p_name
, " kernels");
17613 mask
= OACC_KERNELS_CLAUSE_MASK
;
17614 code
= OACC_KERNELS
;
17616 case PRAGMA_OACC_PARALLEL
:
17617 strcat (p_name
, " parallel");
17618 mask
= OACC_PARALLEL_CLAUSE_MASK
;
17619 code
= OACC_PARALLEL
;
17621 case PRAGMA_OACC_SERIAL
:
17622 strcat (p_name
, " serial");
17623 mask
= OACC_SERIAL_CLAUSE_MASK
;
17624 code
= OACC_SERIAL
;
17627 gcc_unreachable ();
17630 if (c_parser_next_token_is (parser
, CPP_NAME
))
17632 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17633 if (strcmp (p
, "loop") == 0)
17635 c_parser_consume_token (parser
);
17636 tree block
= c_begin_omp_parallel ();
17638 c_parser_oacc_loop (loc
, parser
, p_name
, mask
, &clauses
, if_p
);
17639 return c_finish_omp_construct (loc
, code
, block
, clauses
);
17643 tree clauses
= c_parser_oacc_all_clauses (parser
, mask
, p_name
);
17645 tree block
= c_begin_omp_parallel ();
17646 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
17648 return c_finish_omp_construct (loc
, code
, block
, clauses
);
17652 # pragma acc routine oacc-routine-clause[optseq] new-line
17653 function-definition
17655 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
17658 #define OACC_ROUTINE_CLAUSE_MASK \
17659 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17660 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17661 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17662 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17663 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
17665 /* Parse an OpenACC routine directive. For named directives, we apply
17666 immediately to the named function. For unnamed ones we then parse
17667 a declaration or definition, which must be for a function. */
17670 c_parser_oacc_routine (c_parser
*parser
, enum pragma_context context
)
17672 gcc_checking_assert (context
== pragma_external
);
17674 oacc_routine_data data
;
17675 data
.error_seen
= false;
17676 data
.fndecl_seen
= false;
17677 data
.loc
= c_parser_peek_token (parser
)->location
;
17679 c_parser_consume_pragma (parser
);
17681 /* Look for optional '( name )'. */
17682 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
17684 c_parser_consume_token (parser
); /* '(' */
17686 tree decl
= NULL_TREE
;
17687 c_token
*name_token
= c_parser_peek_token (parser
);
17688 location_t name_loc
= name_token
->location
;
17689 if (name_token
->type
== CPP_NAME
17690 && (name_token
->id_kind
== C_ID_ID
17691 || name_token
->id_kind
== C_ID_TYPENAME
))
17693 decl
= lookup_name (name_token
->value
);
17695 error_at (name_loc
,
17696 "%qE has not been declared", name_token
->value
);
17697 c_parser_consume_token (parser
);
17700 c_parser_error (parser
, "expected function name");
17703 || !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
17705 c_parser_skip_to_pragma_eol (parser
, false);
17710 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
17711 "#pragma acc routine");
17712 /* The clauses are in reverse order; fix that to make later diagnostic
17713 emission easier. */
17714 data
.clauses
= nreverse (data
.clauses
);
17716 if (TREE_CODE (decl
) != FUNCTION_DECL
)
17718 error_at (name_loc
, "%qD does not refer to a function", decl
);
17722 c_finish_oacc_routine (&data
, decl
, false);
17724 else /* No optional '( name )'. */
17727 = c_parser_oacc_all_clauses (parser
, OACC_ROUTINE_CLAUSE_MASK
,
17728 "#pragma acc routine");
17729 /* The clauses are in reverse order; fix that to make later diagnostic
17730 emission easier. */
17731 data
.clauses
= nreverse (data
.clauses
);
17733 /* Emit a helpful diagnostic if there's another pragma following this
17734 one. Also don't allow a static assertion declaration, as in the
17735 following we'll just parse a *single* "declaration or function
17736 definition", and the static assertion counts an one. */
17737 if (c_parser_next_token_is (parser
, CPP_PRAGMA
)
17738 || c_parser_next_token_is_keyword (parser
, RID_STATIC_ASSERT
))
17740 error_at (data
.loc
,
17741 "%<#pragma acc routine%> not immediately followed by"
17742 " function declaration or definition");
17743 /* ..., and then just keep going. */
17747 /* We only have to consider the pragma_external case here. */
17748 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
17749 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
17751 int ext
= disable_extension_diagnostics ();
17753 c_parser_consume_token (parser
);
17754 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
17755 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
17756 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
17757 NULL
, NULL
, false, NULL
, &data
);
17758 restore_extension_diagnostics (ext
);
17761 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
17762 NULL
, NULL
, false, NULL
, &data
);
17766 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17767 IS_DEFN is true if we're applying it to the definition. */
17770 c_finish_oacc_routine (struct oacc_routine_data
*data
, tree fndecl
,
17773 /* Keep going if we're in error reporting mode. */
17774 if (data
->error_seen
17775 || fndecl
== error_mark_node
)
17778 if (data
->fndecl_seen
)
17780 error_at (data
->loc
,
17781 "%<#pragma acc routine%> not immediately followed by"
17782 " a single function declaration or definition");
17783 data
->error_seen
= true;
17786 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
17788 error_at (data
->loc
,
17789 "%<#pragma acc routine%> not immediately followed by"
17790 " function declaration or definition");
17791 data
->error_seen
= true;
17796 = oacc_verify_routine_clauses (fndecl
, &data
->clauses
, data
->loc
,
17797 "#pragma acc routine");
17798 if (compatible
< 0)
17800 data
->error_seen
= true;
17803 if (compatible
> 0)
17808 if (TREE_USED (fndecl
) || (!is_defn
&& DECL_SAVED_TREE (fndecl
)))
17810 error_at (data
->loc
,
17812 ? G_("%<#pragma acc routine%> must be applied before use")
17813 : G_("%<#pragma acc routine%> must be applied before"
17815 data
->error_seen
= true;
17819 /* Set the routine's level of parallelism. */
17820 tree dims
= oacc_build_routine_dims (data
->clauses
);
17821 oacc_replace_fn_attrib (fndecl
, dims
);
17823 /* Add an "omp declare target" attribute. */
17824 DECL_ATTRIBUTES (fndecl
)
17825 = tree_cons (get_identifier ("omp declare target"),
17826 data
->clauses
, DECL_ATTRIBUTES (fndecl
));
17829 /* Remember that we've used this "#pragma acc routine". */
17830 data
->fndecl_seen
= true;
17834 # pragma acc update oacc-update-clause[optseq] new-line
17837 #define OACC_UPDATE_CLAUSE_MASK \
17838 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17839 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17840 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17841 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17842 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
17843 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17846 c_parser_oacc_update (c_parser
*parser
)
17848 location_t loc
= c_parser_peek_token (parser
)->location
;
17850 c_parser_consume_pragma (parser
);
17852 tree clauses
= c_parser_oacc_all_clauses (parser
, OACC_UPDATE_CLAUSE_MASK
,
17853 "#pragma acc update");
17854 if (omp_find_clause (clauses
, OMP_CLAUSE_MAP
) == NULL_TREE
)
17857 "%<#pragma acc update%> must contain at least one "
17858 "%<device%> or %<host%> or %<self%> clause");
17865 tree stmt
= make_node (OACC_UPDATE
);
17866 TREE_TYPE (stmt
) = void_type_node
;
17867 OACC_UPDATE_CLAUSES (stmt
) = clauses
;
17868 SET_EXPR_LOCATION (stmt
, loc
);
17873 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
17875 LOC is the location of the #pragma token.
17878 #define OACC_WAIT_CLAUSE_MASK \
17879 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
17882 c_parser_oacc_wait (location_t loc
, c_parser
*parser
, char *p_name
)
17884 tree clauses
, list
= NULL_TREE
, stmt
= NULL_TREE
;
17886 if (c_parser_peek_token (parser
)->type
== CPP_OPEN_PAREN
)
17887 list
= c_parser_oacc_wait_list (parser
, loc
, list
);
17889 strcpy (p_name
, " wait");
17890 clauses
= c_parser_oacc_all_clauses (parser
, OACC_WAIT_CLAUSE_MASK
, p_name
);
17891 stmt
= c_finish_oacc_wait (loc
, list
, clauses
);
17898 # pragma omp allocate (list) [allocator(allocator)] */
17901 c_parser_omp_allocate (location_t loc
, c_parser
*parser
)
17903 tree allocator
= NULL_TREE
;
17904 tree nl
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ALLOCATE
, NULL_TREE
);
17905 if (c_parser_next_token_is (parser
, CPP_NAME
))
17907 matching_parens parens
;
17908 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
17909 c_parser_consume_token (parser
);
17910 if (strcmp ("allocator", p
) != 0)
17911 error_at (c_parser_peek_token (parser
)->location
,
17912 "expected %<allocator%>");
17913 else if (parens
.require_open (parser
))
17915 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
17916 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
17917 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, false, true);
17918 allocator
= expr
.value
;
17919 allocator
= c_fully_fold (allocator
, false, NULL
);
17921 = expr
.original_type
? expr
.original_type
: TREE_TYPE (allocator
);
17922 orig_type
= TYPE_MAIN_VARIANT (orig_type
);
17923 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator
))
17924 || TREE_CODE (orig_type
) != ENUMERAL_TYPE
17925 || TYPE_NAME (orig_type
)
17926 != get_identifier ("omp_allocator_handle_t"))
17928 error_at (expr_loc
, "%<allocator%> clause allocator expression "
17929 "has type %qT rather than "
17930 "%<omp_allocator_handle_t%>",
17931 TREE_TYPE (allocator
));
17932 allocator
= NULL_TREE
;
17934 parens
.skip_until_found_close (parser
);
17937 c_parser_skip_to_pragma_eol (parser
);
17940 for (tree c
= nl
; c
!= NULL_TREE
; c
= OMP_CLAUSE_CHAIN (c
))
17941 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) = allocator
;
17943 sorry_at (loc
, "%<#pragma omp allocate%> not yet supported");
17947 # pragma omp atomic new-line
17951 x binop= expr | x++ | ++x | x-- | --x
17953 +, *, -, /, &, ^, |, <<, >>
17955 where x is an lvalue expression with scalar type.
17958 # pragma omp atomic new-line
17961 # pragma omp atomic read new-line
17964 # pragma omp atomic write new-line
17967 # pragma omp atomic update new-line
17970 # pragma omp atomic capture new-line
17973 # pragma omp atomic capture new-line
17981 expression-stmt | x = x binop expr
17983 v = expression-stmt
17985 { v = x; update-stmt; } | { update-stmt; v = x; }
17989 expression-stmt | x = x binop expr | x = expr binop x
17993 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
17996 # pragma omp atomic compare new-line
17997 conditional-update-atomic
17999 # pragma omp atomic compare capture new-line
18000 conditional-update-capture-atomic
18002 conditional-update-atomic:
18003 cond-expr-stmt | cond-update-stmt
18005 x = expr ordop x ? expr : x;
18006 x = x ordop expr ? expr : x;
18007 x = x == e ? d : x;
18009 if (expr ordop x) { x = expr; }
18010 if (x ordop expr) { x = expr; }
18011 if (x == e) { x = d; }
18014 conditional-update-capture-atomic:
18016 { v = x; cond-expr-stmt }
18017 { cond-expr-stmt v = x; }
18018 { v = x; cond-update-stmt }
18019 { cond-update-stmt v = x; }
18020 if (x == e) { x = d; } else { v = x; }
18021 { r = x == e; if (r) { x = d; } }
18022 { r = x == e; if (r) { x = d; } else { v = x; } }
18024 where x, r and v are lvalue expressions with scalar type,
18025 expr, e and d are expressions with scalar type and e might be
18028 LOC is the location of the #pragma token. */
18031 c_parser_omp_atomic (location_t loc
, c_parser
*parser
, bool openacc
)
18033 tree lhs
= NULL_TREE
, rhs
= NULL_TREE
, v
= NULL_TREE
, r
= NULL_TREE
;
18034 tree lhs1
= NULL_TREE
, rhs1
= NULL_TREE
;
18035 tree stmt
, orig_lhs
, unfolded_lhs
= NULL_TREE
, unfolded_lhs1
= NULL_TREE
;
18036 enum tree_code code
= ERROR_MARK
, opcode
= NOP_EXPR
;
18037 enum omp_memory_order memory_order
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18038 struct c_expr expr
;
18040 bool structured_block
= false;
18041 bool swapped
= false;
18044 tree clauses
= NULL_TREE
;
18045 bool capture
= false;
18046 bool compare
= false;
18048 enum omp_memory_order fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18049 bool no_semicolon
= false;
18050 bool extra_scope
= false;
18052 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
18055 && c_parser_next_token_is (parser
, CPP_COMMA
)
18056 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
18057 c_parser_consume_token (parser
);
18061 if (c_parser_next_token_is (parser
, CPP_NAME
))
18064 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18065 location_t cloc
= c_parser_peek_token (parser
)->location
;
18066 enum tree_code new_code
= ERROR_MARK
;
18067 enum omp_memory_order new_memory_order
18068 = OMP_MEMORY_ORDER_UNSPECIFIED
;
18069 bool new_capture
= false;
18070 bool new_compare
= false;
18071 bool new_weak
= false;
18072 enum omp_memory_order new_fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18074 if (!strcmp (p
, "read"))
18075 new_code
= OMP_ATOMIC_READ
;
18076 else if (!strcmp (p
, "write"))
18077 new_code
= NOP_EXPR
;
18078 else if (!strcmp (p
, "update"))
18079 new_code
= OMP_ATOMIC
;
18080 else if (openacc
&& !strcmp (p
, "capture"))
18081 new_code
= OMP_ATOMIC_CAPTURE_NEW
;
18085 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
18086 "or %<capture%> clause");
18088 else if (!strcmp (p
, "capture"))
18089 new_capture
= true;
18090 else if (!strcmp (p
, "compare"))
18091 new_compare
= true;
18092 else if (!strcmp (p
, "weak"))
18094 else if (!strcmp (p
, "fail"))
18096 matching_parens parens
;
18098 c_parser_consume_token (parser
);
18099 if (!parens
.require_open (parser
))
18102 if (c_parser_next_token_is (parser
, CPP_NAME
))
18105 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
18107 if (!strcmp (q
, "seq_cst"))
18108 new_fail
= OMP_MEMORY_ORDER_SEQ_CST
;
18109 else if (!strcmp (q
, "acquire"))
18110 new_fail
= OMP_MEMORY_ORDER_ACQUIRE
;
18111 else if (!strcmp (q
, "relaxed"))
18112 new_fail
= OMP_MEMORY_ORDER_RELAXED
;
18115 if (new_fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18117 c_parser_consume_token (parser
);
18118 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18119 error_at (cloc
, "too many %qs clauses", "fail");
18124 c_parser_error (parser
, "expected %<seq_cst%>, %<acquire%> "
18126 parens
.skip_until_found_close (parser
);
18129 else if (!strcmp (p
, "seq_cst"))
18130 new_memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18131 else if (!strcmp (p
, "acq_rel"))
18132 new_memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
18133 else if (!strcmp (p
, "release"))
18134 new_memory_order
= OMP_MEMORY_ORDER_RELEASE
;
18135 else if (!strcmp (p
, "acquire"))
18136 new_memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
18137 else if (!strcmp (p
, "relaxed"))
18138 new_memory_order
= OMP_MEMORY_ORDER_RELAXED
;
18139 else if (!strcmp (p
, "hint"))
18141 c_parser_consume_token (parser
);
18142 clauses
= c_parser_omp_clause_hint (parser
, clauses
);
18148 error_at (cloc
, "expected %<read%>, %<write%>, %<update%>, "
18149 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
18150 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
18151 "%<relaxed%> or %<hint%> clause");
18155 if (new_code
!= ERROR_MARK
)
18157 /* OpenACC permits 'update capture'. */
18159 && code
== OMP_ATOMIC
18160 && new_code
== OMP_ATOMIC_CAPTURE_NEW
)
18162 else if (code
!= ERROR_MARK
)
18163 error_at (cloc
, "too many atomic clauses");
18167 else if (new_memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18169 if (memory_order
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18170 error_at (cloc
, "too many memory order clauses");
18172 memory_order
= new_memory_order
;
18174 else if (new_capture
)
18177 error_at (cloc
, "too many %qs clauses", "capture");
18181 else if (new_compare
)
18184 error_at (cloc
, "too many %qs clauses", "compare");
18191 error_at (cloc
, "too many %qs clauses", "weak");
18195 c_parser_consume_token (parser
);
18201 c_parser_skip_to_pragma_eol (parser
);
18203 if (code
== ERROR_MARK
)
18207 if (code
!= OMP_ATOMIC
)
18208 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
18209 "clauses", "capture");
18211 code
= OMP_ATOMIC_CAPTURE_NEW
;
18213 if (compare
&& code
!= OMP_ATOMIC
&& code
!= OMP_ATOMIC_CAPTURE_NEW
)
18215 error_at (loc
, "%qs clause is incompatible with %<read%> or %<write%> "
18216 "clauses", "compare");
18219 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
&& !compare
)
18221 error_at (loc
, "%qs clause requires %qs clause", "fail", "compare");
18222 fail
= OMP_MEMORY_ORDER_UNSPECIFIED
;
18224 if (weak
&& !compare
)
18226 error_at (loc
, "%qs clause requires %qs clause", "weak", "compare");
18230 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
18231 else if (memory_order
== OMP_MEMORY_ORDER_UNSPECIFIED
)
18234 = (enum omp_requires
) (omp_requires_mask
18235 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
);
18236 switch ((enum omp_memory_order
)
18237 (omp_requires_mask
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
))
18239 case OMP_MEMORY_ORDER_UNSPECIFIED
:
18240 case OMP_MEMORY_ORDER_RELAXED
:
18241 memory_order
= OMP_MEMORY_ORDER_RELAXED
;
18243 case OMP_MEMORY_ORDER_SEQ_CST
:
18244 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18246 case OMP_MEMORY_ORDER_ACQ_REL
:
18249 case OMP_ATOMIC_READ
:
18250 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
18252 case NOP_EXPR
: /* atomic write */
18253 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
18256 memory_order
= OMP_MEMORY_ORDER_ACQ_REL
;
18261 gcc_unreachable ();
18267 case OMP_ATOMIC_READ
:
18268 if (memory_order
== OMP_MEMORY_ORDER_RELEASE
)
18270 error_at (loc
, "%<#pragma omp atomic read%> incompatible with "
18271 "%<release%> clause");
18272 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18274 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
18275 memory_order
= OMP_MEMORY_ORDER_ACQUIRE
;
18277 case NOP_EXPR
: /* atomic write */
18278 if (memory_order
== OMP_MEMORY_ORDER_ACQUIRE
)
18280 error_at (loc
, "%<#pragma omp atomic write%> incompatible with "
18281 "%<acquire%> clause");
18282 memory_order
= OMP_MEMORY_ORDER_SEQ_CST
;
18284 else if (memory_order
== OMP_MEMORY_ORDER_ACQ_REL
)
18285 memory_order
= OMP_MEMORY_ORDER_RELEASE
;
18290 if (fail
!= OMP_MEMORY_ORDER_UNSPECIFIED
)
18292 = (enum omp_memory_order
) (memory_order
18293 | (fail
<< OMP_FAIL_MEMORY_ORDER_SHIFT
));
18297 case OMP_ATOMIC_READ
:
18298 case NOP_EXPR
: /* atomic write */
18299 v
= c_parser_cast_expression (parser
, NULL
).value
;
18300 non_lvalue_p
= !lvalue_p (v
);
18301 v
= c_fully_fold (v
, false, NULL
, true);
18302 if (v
== error_mark_node
)
18305 v
= non_lvalue (v
);
18306 loc
= c_parser_peek_token (parser
)->location
;
18307 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18309 if (code
== NOP_EXPR
)
18311 lhs
= c_parser_expression (parser
).value
;
18312 lhs
= c_fully_fold (lhs
, false, NULL
);
18313 if (lhs
== error_mark_node
)
18318 lhs
= c_parser_cast_expression (parser
, NULL
).value
;
18319 non_lvalue_p
= !lvalue_p (lhs
);
18320 lhs
= c_fully_fold (lhs
, false, NULL
, true);
18321 if (lhs
== error_mark_node
)
18324 lhs
= non_lvalue (lhs
);
18326 if (code
== NOP_EXPR
)
18328 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
18336 case OMP_ATOMIC_CAPTURE_NEW
:
18337 if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
18339 c_parser_consume_token (parser
);
18340 structured_block
= true;
18343 && c_parser_next_token_is_keyword (parser
, RID_IF
))
18347 v
= c_parser_cast_expression (parser
, NULL
).value
;
18348 non_lvalue_p
= !lvalue_p (v
);
18349 v
= c_fully_fold (v
, false, NULL
, true);
18350 if (v
== error_mark_node
)
18353 v
= non_lvalue (v
);
18354 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18356 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
18358 eloc
= c_parser_peek_token (parser
)->location
;
18359 error_at (eloc
, "expected expression");
18368 /* For structured_block case we don't know yet whether
18369 old or new x should be captured. */
18371 if (compare
&& c_parser_next_token_is_keyword (parser
, RID_IF
))
18373 c_parser_consume_token (parser
);
18375 matching_parens parens
;
18376 if (!parens
.require_open (parser
))
18378 eloc
= c_parser_peek_token (parser
)->location
;
18382 cmp_expr
= c_parser_cast_expression (parser
, NULL
);
18383 cmp_expr
= default_function_array_conversion (eloc
, cmp_expr
);
18386 cmp_expr
= c_parser_binary_expression (parser
, NULL
, void_list_node
);
18387 parens
.skip_until_found_close (parser
);
18388 if (cmp_expr
.value
== error_mark_node
)
18392 if (!c_tree_equal (cmp_expr
.value
, unfolded_lhs
))
18394 cmp_expr
.value
= rhs1
;
18396 gcc_assert (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
);
18398 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
18400 else if (!structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
18402 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
18403 "expected %<==%> comparison in %<if%> condition");
18406 else if (TREE_CODE (cmp_expr
.value
) != GT_EXPR
18407 && TREE_CODE (cmp_expr
.value
) != LT_EXPR
)
18409 error_at (EXPR_LOC_OR_LOC (cmp_expr
.value
, eloc
),
18410 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
18414 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
18417 extra_scope
= true;
18418 eloc
= c_parser_peek_token (parser
)->location
;
18419 expr
= c_parser_cast_expression (parser
, NULL
);
18421 expr
= default_function_array_conversion (eloc
, expr
);
18422 unfolded_lhs
= expr
.value
;
18423 lhs
= c_fully_fold (lhs
, false, NULL
, true);
18425 if (lhs
== error_mark_node
)
18427 if (!lvalue_p (unfolded_lhs
))
18428 lhs
= non_lvalue (lhs
);
18429 if (!c_parser_next_token_is (parser
, CPP_EQ
))
18431 c_parser_error (parser
, "expected %<=%>");
18434 c_parser_consume_token (parser
);
18435 eloc
= c_parser_peek_token (parser
)->location
;
18436 expr
= c_parser_expr_no_commas (parser
, NULL
);
18439 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
18442 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
18445 extra_scope
= false;
18446 no_semicolon
= true;
18448 if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), unfolded_lhs
))
18450 if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
18452 opcode
= COND_EXPR
;
18453 rhs
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
18454 false, NULL
, true);
18455 rhs1
= c_fully_fold (rhs1
, false, NULL
, true);
18457 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), rhs1
))
18459 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
18460 ? MIN_EXPR
: MAX_EXPR
);
18461 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
18462 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 0),
18463 false, NULL
, true);
18468 else if (TREE_CODE (cmp_expr
.value
) == EQ_EXPR
)
18470 else if (c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 1), unfolded_lhs
)
18471 && c_tree_equal (TREE_OPERAND (cmp_expr
.value
, 0), rhs1
))
18473 opcode
= (TREE_CODE (cmp_expr
.value
) == GT_EXPR
18474 ? MAX_EXPR
: MIN_EXPR
);
18475 rhs
= c_fully_fold (rhs1
, false, NULL
, true);
18476 rhs1
= c_fully_fold (TREE_OPERAND (cmp_expr
.value
, 1),
18477 false, NULL
, true);
18482 c_parser_error (parser
,
18483 "invalid form of %<#pragma omp atomic compare%>");
18487 if (c_parser_next_token_is_keyword (parser
, RID_ELSE
))
18489 if (code
!= OMP_ATOMIC_CAPTURE_NEW
18490 || (structured_block
&& r
== NULL_TREE
)
18491 || TREE_CODE (cmp_expr
.value
) != EQ_EXPR
)
18493 eloc
= c_parser_peek_token (parser
)->location
;
18494 error_at (eloc
, "unexpected %<else%>");
18498 c_parser_consume_token (parser
);
18500 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
18503 extra_scope
= true;
18504 v
= c_parser_cast_expression (parser
, NULL
).value
;
18505 non_lvalue_p
= !lvalue_p (v
);
18506 v
= c_fully_fold (v
, false, NULL
, true);
18507 if (v
== error_mark_node
)
18510 v
= non_lvalue (v
);
18511 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18514 expr
= c_parser_expr_no_commas (parser
, NULL
);
18516 if (!c_tree_equal (expr
.value
, unfolded_lhs
))
18519 if (!c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
18522 if (!c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>"))
18525 extra_scope
= false;
18526 code
= OMP_ATOMIC_CAPTURE_OLD
;
18527 if (r
== NULL_TREE
)
18528 /* Signal to c_finish_omp_atomic that in
18529 if (x == e) { x = d; } else { v = x; }
18530 case the store to v should be conditional. */
18531 r
= void_list_node
;
18533 else if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
18535 c_parser_require_keyword (parser
, RID_ELSE
, "expected %<else%>");
18538 else if (code
== OMP_ATOMIC_CAPTURE_NEW
18544 eloc
= c_parser_peek_token (parser
)->location
;
18545 expr
= c_parser_cast_expression (parser
, NULL
);
18547 expr
= default_function_array_conversion (eloc
, expr
);
18548 unfolded_lhs
= expr
.value
;
18549 lhs
= c_fully_fold (lhs
, false, NULL
, true);
18551 switch (TREE_CODE (lhs
))
18554 error_at (eloc
, "invalid form of %<pragma omp atomic compare%>");
18558 c_parser_skip_to_end_of_block_or_statement (parser
);
18559 if (extra_scope
&& c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18560 c_parser_consume_token (parser
);
18561 if (structured_block
)
18563 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18564 c_parser_consume_token (parser
);
18565 else if (code
== OMP_ATOMIC_CAPTURE_NEW
)
18567 c_parser_skip_to_end_of_block_or_statement (parser
);
18568 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
18569 c_parser_consume_token (parser
);
18574 case POSTINCREMENT_EXPR
:
18575 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
18576 code
= OMP_ATOMIC_CAPTURE_OLD
;
18578 case PREINCREMENT_EXPR
:
18579 lhs
= TREE_OPERAND (lhs
, 0);
18580 unfolded_lhs
= NULL_TREE
;
18581 opcode
= PLUS_EXPR
;
18582 rhs
= integer_one_node
;
18584 goto invalid_compare
;
18587 case POSTDECREMENT_EXPR
:
18588 if (code
== OMP_ATOMIC_CAPTURE_NEW
&& !structured_block
)
18589 code
= OMP_ATOMIC_CAPTURE_OLD
;
18591 case PREDECREMENT_EXPR
:
18592 lhs
= TREE_OPERAND (lhs
, 0);
18593 unfolded_lhs
= NULL_TREE
;
18594 opcode
= MINUS_EXPR
;
18595 rhs
= integer_one_node
;
18597 goto invalid_compare
;
18600 case COMPOUND_EXPR
:
18601 if (TREE_CODE (TREE_OPERAND (lhs
, 0)) == SAVE_EXPR
18602 && TREE_CODE (TREE_OPERAND (lhs
, 1)) == COMPOUND_EXPR
18603 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0)) == MODIFY_EXPR
18604 && TREE_OPERAND (TREE_OPERAND (lhs
, 1), 1) == TREE_OPERAND (lhs
, 0)
18605 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
18606 (TREE_OPERAND (lhs
, 1), 0), 0)))
18608 /* Undo effects of boolean_increment for post {in,de}crement. */
18609 lhs
= TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0);
18612 if (TREE_CODE (lhs
) == MODIFY_EXPR
18613 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs
, 0))) == BOOLEAN_TYPE
)
18615 /* Undo effects of boolean_increment. */
18616 if (integer_onep (TREE_OPERAND (lhs
, 1)))
18618 /* This is pre or post increment. */
18619 rhs
= TREE_OPERAND (lhs
, 1);
18620 lhs
= TREE_OPERAND (lhs
, 0);
18621 unfolded_lhs
= NULL_TREE
;
18623 if (code
== OMP_ATOMIC_CAPTURE_NEW
18624 && !structured_block
18625 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
18626 code
= OMP_ATOMIC_CAPTURE_OLD
;
18628 goto invalid_compare
;
18631 if (TREE_CODE (TREE_OPERAND (lhs
, 1)) == TRUTH_NOT_EXPR
18632 && TREE_OPERAND (lhs
, 0)
18633 == TREE_OPERAND (TREE_OPERAND (lhs
, 1), 0))
18635 /* This is pre or post decrement. */
18636 rhs
= TREE_OPERAND (lhs
, 1);
18637 lhs
= TREE_OPERAND (lhs
, 0);
18638 unfolded_lhs
= NULL_TREE
;
18640 if (code
== OMP_ATOMIC_CAPTURE_NEW
18641 && !structured_block
18642 && TREE_CODE (orig_lhs
) == COMPOUND_EXPR
)
18643 code
= OMP_ATOMIC_CAPTURE_OLD
;
18645 goto invalid_compare
;
18651 if (!lvalue_p (unfolded_lhs
))
18652 lhs
= non_lvalue (lhs
);
18653 if (compare
&& !c_parser_next_token_is (parser
, CPP_EQ
))
18655 c_parser_error (parser
, "expected %<=%>");
18658 switch (c_parser_peek_token (parser
)->type
)
18661 opcode
= MULT_EXPR
;
18664 opcode
= TRUNC_DIV_EXPR
;
18667 opcode
= PLUS_EXPR
;
18670 opcode
= MINUS_EXPR
;
18672 case CPP_LSHIFT_EQ
:
18673 opcode
= LSHIFT_EXPR
;
18675 case CPP_RSHIFT_EQ
:
18676 opcode
= RSHIFT_EXPR
;
18679 opcode
= BIT_AND_EXPR
;
18682 opcode
= BIT_IOR_EXPR
;
18685 opcode
= BIT_XOR_EXPR
;
18688 c_parser_consume_token (parser
);
18689 eloc
= c_parser_peek_token (parser
)->location
;
18690 expr
= c_parser_expr_no_commas (parser
, NULL
, unfolded_lhs
);
18692 switch (TREE_CODE (rhs1
))
18695 case TRUNC_DIV_EXPR
:
18706 if (c_tree_equal (TREE_OPERAND (rhs1
, 0), unfolded_lhs
))
18708 opcode
= TREE_CODE (rhs1
);
18709 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
18711 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
18715 if (c_tree_equal (TREE_OPERAND (rhs1
, 1), unfolded_lhs
))
18717 opcode
= TREE_CODE (rhs1
);
18718 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 0), false, NULL
,
18720 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
18722 swapped
= !commutative_tree_code (opcode
);
18729 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) != GT_EXPR
18730 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != LT_EXPR
18731 && TREE_CODE (TREE_OPERAND (rhs1
, 0)) != EQ_EXPR
)
18733 if (!TREE_OPERAND (rhs1
, 1))
18735 if (!c_tree_equal (TREE_OPERAND (rhs1
, 2), unfolded_lhs
))
18737 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
18740 if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
18742 opcode
= COND_EXPR
;
18743 rhs
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
18745 false, NULL
, true);
18746 rhs1
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false,
18750 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
18751 TREE_OPERAND (rhs1
, 1)))
18753 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
18754 ? MIN_EXPR
: MAX_EXPR
);
18755 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
18757 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
18759 false, NULL
, true);
18763 else if (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == EQ_EXPR
)
18765 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 1),
18768 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1
, 0), 0),
18769 TREE_OPERAND (rhs1
, 1)))
18771 opcode
= (TREE_CODE (TREE_OPERAND (rhs1
, 0)) == GT_EXPR
18772 ? MAX_EXPR
: MIN_EXPR
);
18773 rhs
= c_fully_fold (TREE_OPERAND (rhs1
, 1), false, NULL
,
18775 rhs1
= c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1
,
18777 false, NULL
, true);
18784 || code
!= OMP_ATOMIC_CAPTURE_NEW
18785 || !structured_block
18789 if (c_parser_next_token_is (parser
, CPP_SEMICOLON
)
18790 && c_parser_peek_2nd_token (parser
)->keyword
== RID_IF
)
18794 c_parser_consume_token (parser
);
18803 if (c_parser_peek_token (parser
)->type
== CPP_SEMICOLON
)
18805 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
)
18807 code
= OMP_ATOMIC_CAPTURE_OLD
;
18810 expr
= default_function_array_read_conversion (eloc
, expr
);
18811 unfolded_lhs1
= expr
.value
;
18812 lhs1
= c_fully_fold (unfolded_lhs1
, false, NULL
, true);
18814 c_parser_consume_token (parser
);
18817 if (structured_block
&& !compare
)
18820 expr
= default_function_array_read_conversion (eloc
, expr
);
18821 rhs
= c_fully_fold (expr
.value
, false, NULL
, true);
18826 c_parser_error (parser
, "invalid form of %<#pragma omp atomic%>");
18829 c_parser_error (parser
,
18830 "invalid operator for %<#pragma omp atomic%>");
18834 /* Arrange to pass the location of the assignment operator to
18835 c_finish_omp_atomic. */
18836 loc
= c_parser_peek_token (parser
)->location
;
18837 c_parser_consume_token (parser
);
18838 eloc
= c_parser_peek_token (parser
)->location
;
18839 expr
= c_parser_expression (parser
);
18840 expr
= default_function_array_read_conversion (eloc
, expr
);
18842 rhs
= c_fully_fold (rhs
, false, NULL
, true);
18846 if (structured_block
&& code
== OMP_ATOMIC_CAPTURE_NEW
&& r
== NULL_TREE
)
18849 && !c_parser_require (parser
, CPP_SEMICOLON
, "expected %<;%>"))
18851 no_semicolon
= false;
18852 v
= c_parser_cast_expression (parser
, NULL
).value
;
18853 non_lvalue_p
= !lvalue_p (v
);
18854 v
= c_fully_fold (v
, false, NULL
, true);
18855 if (v
== error_mark_node
)
18858 v
= non_lvalue (v
);
18859 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
18861 eloc
= c_parser_peek_token (parser
)->location
;
18862 expr
= c_parser_cast_expression (parser
, NULL
);
18864 expr
= default_function_array_read_conversion (eloc
, expr
);
18865 unfolded_lhs1
= expr
.value
;
18866 lhs1
= c_fully_fold (lhs1
, false, NULL
, true);
18867 if (lhs1
== error_mark_node
)
18869 if (!lvalue_p (unfolded_lhs1
))
18870 lhs1
= non_lvalue (lhs1
);
18872 if (structured_block
)
18875 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
18876 c_parser_require (parser
, CPP_CLOSE_BRACE
, "expected %<}%>");
18879 if (weak
&& opcode
!= COND_EXPR
)
18881 error_at (loc
, "%<weak%> clause requires atomic equality comparison");
18884 if (unfolded_lhs
&& unfolded_lhs1
18885 && !c_tree_equal (unfolded_lhs
, unfolded_lhs1
))
18887 error ("%<#pragma omp atomic capture%> uses two different "
18888 "expressions for memory");
18889 stmt
= error_mark_node
;
18892 stmt
= c_finish_omp_atomic (loc
, code
, opcode
, lhs
, rhs
, v
, lhs1
, rhs1
, r
,
18893 swapped
, memory_order
, weak
);
18894 if (stmt
!= error_mark_node
)
18897 if (!structured_block
&& !no_semicolon
)
18898 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
18903 # pragma omp barrier new-line
18907 c_parser_omp_barrier (c_parser
*parser
)
18909 location_t loc
= c_parser_peek_token (parser
)->location
;
18910 c_parser_consume_pragma (parser
);
18911 c_parser_skip_to_pragma_eol (parser
);
18913 c_finish_omp_barrier (loc
);
18917 # pragma omp critical [(name)] new-line
18921 # pragma omp critical [(name) [hint(expression)]] new-line
18923 LOC is the location of the #pragma itself. */
18925 #define OMP_CRITICAL_CLAUSE_MASK \
18926 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
18929 c_parser_omp_critical (location_t loc
, c_parser
*parser
, bool *if_p
)
18931 tree stmt
, name
= NULL_TREE
, clauses
= NULL_TREE
;
18933 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
18935 c_parser_consume_token (parser
);
18936 if (c_parser_next_token_is (parser
, CPP_NAME
))
18938 name
= c_parser_peek_token (parser
)->value
;
18939 c_parser_consume_token (parser
);
18940 c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>");
18943 c_parser_error (parser
, "expected identifier");
18945 if (c_parser_next_token_is (parser
, CPP_COMMA
)
18946 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
18947 c_parser_consume_token (parser
);
18949 clauses
= c_parser_omp_all_clauses (parser
, OMP_CRITICAL_CLAUSE_MASK
,
18950 "#pragma omp critical");
18951 stmt
= c_parser_omp_structured_block (parser
, if_p
);
18952 return c_finish_omp_critical (loc
, stmt
, name
, clauses
);
18956 # pragma omp depobj ( depobj ) depobj-clause new-line
18959 depend (dependence-type : locator)
18961 update (dependence-type)
18970 c_parser_omp_depobj (c_parser
*parser
)
18972 location_t loc
= c_parser_peek_token (parser
)->location
;
18973 c_parser_consume_pragma (parser
);
18974 matching_parens parens
;
18975 if (!parens
.require_open (parser
))
18977 c_parser_skip_to_pragma_eol (parser
);
18981 tree depobj
= c_parser_expr_no_commas (parser
, NULL
).value
;
18982 if (depobj
!= error_mark_node
)
18984 if (!lvalue_p (depobj
))
18986 error_at (EXPR_LOC_OR_LOC (depobj
, loc
),
18987 "%<depobj%> expression is not lvalue expression");
18988 depobj
= error_mark_node
;
18992 tree addr
= build_unary_op (EXPR_LOC_OR_LOC (depobj
, loc
), ADDR_EXPR
,
18994 if (addr
== error_mark_node
)
18995 depobj
= error_mark_node
;
18997 depobj
= build_indirect_ref (EXPR_LOC_OR_LOC (depobj
, loc
),
18998 addr
, RO_UNARY_STAR
);
19002 parens
.skip_until_found_close (parser
);
19003 tree clause
= NULL_TREE
;
19004 enum omp_clause_depend_kind kind
= OMP_CLAUSE_DEPEND_SOURCE
;
19005 location_t c_loc
= c_parser_peek_token (parser
)->location
;
19006 if (c_parser_next_token_is (parser
, CPP_NAME
))
19008 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19010 c_parser_consume_token (parser
);
19011 if (!strcmp ("depend", p
))
19013 clause
= c_parser_omp_clause_depend (parser
, NULL_TREE
);
19014 clause
= c_finish_omp_clauses (clause
, C_ORT_OMP
);
19016 clause
= error_mark_node
;
19018 else if (!strcmp ("destroy", p
))
19019 kind
= OMP_CLAUSE_DEPEND_LAST
;
19020 else if (!strcmp ("update", p
))
19022 matching_parens c_parens
;
19023 if (c_parens
.require_open (parser
))
19025 location_t c2_loc
= c_parser_peek_token (parser
)->location
;
19026 if (c_parser_next_token_is (parser
, CPP_NAME
))
19029 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19031 c_parser_consume_token (parser
);
19032 if (!strcmp ("in", p2
))
19033 kind
= OMP_CLAUSE_DEPEND_IN
;
19034 else if (!strcmp ("out", p2
))
19035 kind
= OMP_CLAUSE_DEPEND_OUT
;
19036 else if (!strcmp ("inout", p2
))
19037 kind
= OMP_CLAUSE_DEPEND_INOUT
;
19038 else if (!strcmp ("mutexinoutset", p2
))
19039 kind
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET
;
19041 if (kind
== OMP_CLAUSE_DEPEND_SOURCE
)
19043 clause
= error_mark_node
;
19044 error_at (c2_loc
, "expected %<in%>, %<out%>, %<inout%> or "
19045 "%<mutexinoutset%>");
19047 c_parens
.skip_until_found_close (parser
);
19050 clause
= error_mark_node
;
19053 if (!clause
&& kind
== OMP_CLAUSE_DEPEND_SOURCE
)
19055 clause
= error_mark_node
;
19056 error_at (c_loc
, "expected %<depend%>, %<destroy%> or %<update%> clause");
19058 c_parser_skip_to_pragma_eol (parser
);
19060 c_finish_omp_depobj (loc
, depobj
, kind
, clause
);
19065 # pragma omp flush flush-vars[opt] new-line
19071 # pragma omp flush memory-order-clause new-line */
19074 c_parser_omp_flush (c_parser
*parser
)
19076 location_t loc
= c_parser_peek_token (parser
)->location
;
19077 c_parser_consume_pragma (parser
);
19078 enum memmodel mo
= MEMMODEL_LAST
;
19079 if (c_parser_next_token_is (parser
, CPP_NAME
))
19082 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19084 if (!strcmp (p
, "seq_cst"))
19085 mo
= MEMMODEL_SEQ_CST
;
19086 else if (!strcmp (p
, "acq_rel"))
19087 mo
= MEMMODEL_ACQ_REL
;
19088 else if (!strcmp (p
, "release"))
19089 mo
= MEMMODEL_RELEASE
;
19090 else if (!strcmp (p
, "acquire"))
19091 mo
= MEMMODEL_ACQUIRE
;
19093 error_at (c_parser_peek_token (parser
)->location
,
19094 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
19096 c_parser_consume_token (parser
);
19098 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
19100 if (mo
!= MEMMODEL_LAST
)
19101 error_at (c_parser_peek_token (parser
)->location
,
19102 "%<flush%> list specified together with memory order "
19104 c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
19106 else if (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
19107 c_parser_error (parser
, "expected %<(%> or end of line");
19108 c_parser_skip_to_pragma_eol (parser
);
19110 c_finish_omp_flush (loc
, mo
);
19113 /* Parse an OpenMP structured block sequence. KIND is the corresponding
19114 separating directive. */
19117 c_parser_omp_structured_block_sequence (c_parser
*parser
,
19118 enum pragma_kind kind
)
19120 tree stmt
= push_stmt_list ();
19121 c_parser_statement (parser
, NULL
);
19124 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
19126 if (c_parser_next_token_is (parser
, CPP_EOF
))
19129 if (kind
!= PRAGMA_NONE
19130 && c_parser_peek_token (parser
)->pragma_kind
== kind
)
19132 c_parser_statement (parser
, NULL
);
19135 return pop_stmt_list (stmt
);
19141 { structured-block scan-directive structured-block } */
19144 c_parser_omp_scan_loop_body (c_parser
*parser
, bool open_brace_parsed
)
19148 tree clauses
= NULL_TREE
;
19150 loc
= c_parser_peek_token (parser
)->location
;
19151 if (!open_brace_parsed
19152 && !c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
19154 /* Avoid skipping until the end of the block. */
19155 parser
->error
= false;
19159 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_OMP_SCAN
);
19160 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, NULL_TREE
);
19161 SET_EXPR_LOCATION (substmt
, loc
);
19162 add_stmt (substmt
);
19164 loc
= c_parser_peek_token (parser
)->location
;
19165 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SCAN
)
19167 enum omp_clause_code clause
= OMP_CLAUSE_ERROR
;
19169 c_parser_consume_pragma (parser
);
19171 if (c_parser_next_token_is (parser
, CPP_NAME
))
19174 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19175 if (strcmp (p
, "inclusive") == 0)
19176 clause
= OMP_CLAUSE_INCLUSIVE
;
19177 else if (strcmp (p
, "exclusive") == 0)
19178 clause
= OMP_CLAUSE_EXCLUSIVE
;
19180 if (clause
!= OMP_CLAUSE_ERROR
)
19182 c_parser_consume_token (parser
);
19183 clauses
= c_parser_omp_var_list_parens (parser
, clause
, NULL_TREE
);
19186 c_parser_error (parser
, "expected %<inclusive%> or "
19187 "%<exclusive%> clause");
19188 c_parser_skip_to_pragma_eol (parser
);
19191 error ("expected %<#pragma omp scan%>");
19193 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
19194 substmt
= c_parser_omp_structured_block_sequence (parser
, PRAGMA_NONE
);
19195 substmt
= build2 (OMP_SCAN
, void_type_node
, substmt
, clauses
);
19196 SET_EXPR_LOCATION (substmt
, loc
);
19197 add_stmt (substmt
);
19199 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
19203 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
19204 The real trick here is to determine the loop control variable early
19205 so that we can push a new decl if necessary to make it private.
19206 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
19210 c_parser_omp_for_loop (location_t loc
, c_parser
*parser
, enum tree_code code
,
19211 tree clauses
, tree
*cclauses
, bool *if_p
)
19213 tree decl
, cond
, incr
, body
, init
, stmt
, cl
;
19214 unsigned char save_in_statement
;
19215 tree declv
, condv
, incrv
, initv
, ret
= NULL_TREE
;
19216 tree pre_body
= NULL_TREE
, this_pre_body
;
19217 tree ordered_cl
= NULL_TREE
;
19218 bool fail
= false, open_brace_parsed
= false;
19219 int i
, collapse
= 1, ordered
= 0, count
, nbraces
= 0;
19220 location_t for_loc
;
19221 bool tiling
= false;
19222 bool inscan
= false;
19223 vec
<tree
, va_gc
> *for_block
= make_tree_vector ();
19225 for (cl
= clauses
; cl
; cl
= OMP_CLAUSE_CHAIN (cl
))
19226 if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_COLLAPSE
)
19227 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl
));
19228 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_TILE
)
19231 collapse
= list_length (OMP_CLAUSE_TILE_LIST (cl
));
19233 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_ORDERED
19234 && OMP_CLAUSE_ORDERED_EXPR (cl
))
19237 ordered
= tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl
));
19239 else if (OMP_CLAUSE_CODE (cl
) == OMP_CLAUSE_REDUCTION
19240 && OMP_CLAUSE_REDUCTION_INSCAN (cl
)
19241 && (code
== OMP_SIMD
|| code
== OMP_FOR
))
19244 if (ordered
&& ordered
< collapse
)
19246 error_at (OMP_CLAUSE_LOCATION (ordered_cl
),
19247 "%<ordered%> clause parameter is less than %<collapse%>");
19248 OMP_CLAUSE_ORDERED_EXPR (ordered_cl
)
19249 = build_int_cst (NULL_TREE
, collapse
);
19250 ordered
= collapse
;
19254 for (tree
*pc
= &clauses
; *pc
; )
19255 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LINEAR
)
19257 error_at (OMP_CLAUSE_LOCATION (*pc
),
19258 "%<linear%> clause may not be specified together "
19259 "with %<ordered%> clause with a parameter");
19260 *pc
= OMP_CLAUSE_CHAIN (*pc
);
19263 pc
= &OMP_CLAUSE_CHAIN (*pc
);
19266 gcc_assert (tiling
|| (collapse
>= 1 && ordered
>= 0));
19267 count
= ordered
? ordered
: collapse
;
19269 declv
= make_tree_vec (count
);
19270 initv
= make_tree_vec (count
);
19271 condv
= make_tree_vec (count
);
19272 incrv
= make_tree_vec (count
);
19274 if (!c_parser_next_token_is_keyword (parser
, RID_FOR
))
19276 c_parser_error (parser
, "for statement expected");
19279 for_loc
= c_parser_peek_token (parser
)->location
;
19280 c_parser_consume_token (parser
);
19282 /* Forbid break/continue in the loop initializer, condition, and
19283 increment expressions. */
19284 save_in_statement
= in_statement
;
19285 in_statement
= IN_OMP_BLOCK
;
19287 for (i
= 0; i
< count
; i
++)
19289 int bracecount
= 0;
19291 matching_parens parens
;
19292 if (!parens
.require_open (parser
))
19295 /* Parse the initialization declaration or expression. */
19296 if (c_parser_next_tokens_start_declaration (parser
))
19299 vec_safe_push (for_block
, c_begin_compound_stmt (true));
19300 this_pre_body
= push_stmt_list ();
19301 c_in_omp_for
= true;
19302 c_parser_declaration_or_fndef (parser
, true, true, true, true, true);
19303 c_in_omp_for
= false;
19306 this_pre_body
= pop_stmt_list (this_pre_body
);
19310 pre_body
= push_stmt_list ();
19312 add_stmt (this_pre_body
);
19313 pre_body
= pop_stmt_list (pre_body
);
19316 pre_body
= this_pre_body
;
19318 decl
= check_for_loop_decls (for_loc
, flag_isoc99
);
19321 if (DECL_INITIAL (decl
) == error_mark_node
)
19322 decl
= error_mark_node
;
19325 else if (c_parser_next_token_is (parser
, CPP_NAME
)
19326 && c_parser_peek_2nd_token (parser
)->type
== CPP_EQ
)
19328 struct c_expr decl_exp
;
19329 struct c_expr init_exp
;
19330 location_t init_loc
;
19332 decl_exp
= c_parser_postfix_expression (parser
);
19333 decl
= decl_exp
.value
;
19335 c_parser_require (parser
, CPP_EQ
, "expected %<=%>");
19337 init_loc
= c_parser_peek_token (parser
)->location
;
19338 init_exp
= c_parser_expr_no_commas (parser
, NULL
);
19339 init_exp
= default_function_array_read_conversion (init_loc
,
19341 c_in_omp_for
= true;
19342 init
= build_modify_expr (init_loc
, decl
, decl_exp
.original_type
,
19343 NOP_EXPR
, init_loc
, init_exp
.value
,
19344 init_exp
.original_type
);
19345 c_in_omp_for
= false;
19346 init
= c_process_expr_stmt (init_loc
, init
);
19348 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19353 c_parser_error (parser
,
19354 "expected iteration declaration or initialization");
19355 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
,
19361 /* Parse the loop condition. */
19363 if (c_parser_next_token_is_not (parser
, CPP_SEMICOLON
))
19365 location_t cond_loc
= c_parser_peek_token (parser
)->location
;
19366 c_in_omp_for
= true;
19367 struct c_expr cond_expr
19368 = c_parser_binary_expression (parser
, NULL
, NULL_TREE
);
19369 c_in_omp_for
= false;
19371 cond
= cond_expr
.value
;
19372 cond
= c_objc_common_truthvalue_conversion (cond_loc
, cond
);
19373 switch (cond_expr
.original_code
)
19381 if (code
!= OACC_LOOP
)
19385 /* Can't be cond = error_mark_node, because we want to preserve
19386 the location until c_finish_omp_for. */
19387 cond
= build1 (NOP_EXPR
, boolean_type_node
, error_mark_node
);
19390 protected_set_expr_location (cond
, cond_loc
);
19392 c_parser_skip_until_found (parser
, CPP_SEMICOLON
, "expected %<;%>");
19394 /* Parse the increment expression. */
19396 if (c_parser_next_token_is_not (parser
, CPP_CLOSE_PAREN
))
19398 location_t incr_loc
= c_parser_peek_token (parser
)->location
;
19400 incr
= c_process_expr_stmt (incr_loc
,
19401 c_parser_expression (parser
).value
);
19403 parens
.skip_until_found_close (parser
);
19405 if (decl
== NULL
|| decl
== error_mark_node
|| init
== error_mark_node
)
19409 TREE_VEC_ELT (declv
, i
) = decl
;
19410 TREE_VEC_ELT (initv
, i
) = init
;
19411 TREE_VEC_ELT (condv
, i
) = cond
;
19412 TREE_VEC_ELT (incrv
, i
) = incr
;
19416 if (i
== count
- 1)
19419 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
19420 in between the collapsed for loops to be still considered perfectly
19421 nested. Hopefully the final version clarifies this.
19422 For now handle (multiple) {'s and empty statements. */
19425 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
19427 c_parser_consume_token (parser
);
19430 else if (c_parser_next_token_is (parser
, CPP_OPEN_BRACE
))
19432 c_parser_consume_token (parser
);
19435 else if (bracecount
19436 && c_parser_next_token_is (parser
, CPP_SEMICOLON
))
19437 c_parser_consume_token (parser
);
19440 c_parser_error (parser
, "not enough perfectly nested loops");
19443 open_brace_parsed
= true;
19453 nbraces
+= bracecount
;
19459 in_statement
= IN_OMP_FOR
;
19460 body
= push_stmt_list ();
19463 c_parser_omp_scan_loop_body (parser
, open_brace_parsed
);
19464 else if (open_brace_parsed
)
19466 location_t here
= c_parser_peek_token (parser
)->location
;
19467 stmt
= c_begin_compound_stmt (true);
19468 c_parser_compound_statement_nostart (parser
);
19469 add_stmt (c_end_compound_stmt (here
, stmt
, true));
19472 add_stmt (c_parser_c99_block_statement (parser
, if_p
));
19474 body
= pop_stmt_list (body
);
19475 in_statement
= save_in_statement
;
19479 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
19481 c_parser_consume_token (parser
);
19484 else if (c_parser_next_token_is (parser
, CPP_SEMICOLON
))
19485 c_parser_consume_token (parser
);
19488 c_parser_error (parser
, "collapsed loops not perfectly nested");
19491 location_t here
= c_parser_peek_token (parser
)->location
;
19492 stmt
= c_begin_compound_stmt (true);
19494 c_parser_compound_statement_nostart (parser
);
19495 body
= c_end_compound_stmt (here
, stmt
, true);
19502 /* Only bother calling c_finish_omp_for if we haven't already generated
19503 an error from the initialization parsing. */
19506 c_in_omp_for
= true;
19507 stmt
= c_finish_omp_for (loc
, code
, declv
, NULL
, initv
, condv
,
19508 incrv
, body
, pre_body
, true);
19509 c_in_omp_for
= false;
19511 /* Check for iterators appearing in lb, b or incr expressions. */
19512 if (stmt
&& !c_omp_check_loop_iv (stmt
, declv
, NULL
))
19519 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (stmt
)); i
++)
19521 tree init
= TREE_VEC_ELT (OMP_FOR_INIT (stmt
), i
);
19522 gcc_assert (TREE_CODE (init
) == MODIFY_EXPR
);
19523 tree decl
= TREE_OPERAND (init
, 0);
19524 tree cond
= TREE_VEC_ELT (OMP_FOR_COND (stmt
), i
);
19525 gcc_assert (COMPARISON_CLASS_P (cond
));
19526 gcc_assert (TREE_OPERAND (cond
, 0) == decl
);
19528 tree op0
= TREE_OPERAND (init
, 1);
19529 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
19530 || TREE_CODE (op0
) != TREE_VEC
)
19531 TREE_OPERAND (init
, 1) = c_fully_fold (op0
, false, NULL
);
19534 TREE_VEC_ELT (op0
, 1)
19535 = c_fully_fold (TREE_VEC_ELT (op0
, 1), false, NULL
);
19536 TREE_VEC_ELT (op0
, 2)
19537 = c_fully_fold (TREE_VEC_ELT (op0
, 2), false, NULL
);
19540 tree op1
= TREE_OPERAND (cond
, 1);
19541 if (!OMP_FOR_NON_RECTANGULAR (stmt
)
19542 || TREE_CODE (op1
) != TREE_VEC
)
19543 TREE_OPERAND (cond
, 1) = c_fully_fold (op1
, false, NULL
);
19546 TREE_VEC_ELT (op1
, 1)
19547 = c_fully_fold (TREE_VEC_ELT (op1
, 1), false, NULL
);
19548 TREE_VEC_ELT (op1
, 2)
19549 = c_fully_fold (TREE_VEC_ELT (op1
, 2), false, NULL
);
19553 if (cclauses
!= NULL
19554 && cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
] != NULL
)
19557 for (c
= &cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
]; *c
; )
19558 if (OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_FIRSTPRIVATE
19559 && OMP_CLAUSE_CODE (*c
) != OMP_CLAUSE_LASTPRIVATE
)
19560 c
= &OMP_CLAUSE_CHAIN (*c
);
19563 for (i
= 0; i
< count
; i
++)
19564 if (TREE_VEC_ELT (declv
, i
) == OMP_CLAUSE_DECL (*c
))
19567 c
= &OMP_CLAUSE_CHAIN (*c
);
19568 else if (OMP_CLAUSE_CODE (*c
) == OMP_CLAUSE_FIRSTPRIVATE
)
19571 "iteration variable %qD should not be firstprivate",
19572 OMP_CLAUSE_DECL (*c
));
19573 *c
= OMP_CLAUSE_CHAIN (*c
);
19577 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
19579 *c
= OMP_CLAUSE_CHAIN (*c
);
19580 if (code
== OMP_SIMD
)
19582 OMP_CLAUSE_CHAIN (l
)
19583 = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
19584 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
] = l
;
19588 OMP_CLAUSE_CHAIN (l
) = clauses
;
19594 OMP_FOR_CLAUSES (stmt
) = clauses
;
19599 while (!for_block
->is_empty ())
19601 /* FIXME diagnostics: LOC below should be the actual location of
19602 this particular for block. We need to build a list of
19603 locations to go along with FOR_BLOCK. */
19604 stmt
= c_end_compound_stmt (loc
, for_block
->pop (), true);
19607 release_tree_vector (for_block
);
19611 /* Helper function for OpenMP parsing, split clauses and call
19612 finish_omp_clauses on each of the set of clauses afterwards. */
19615 omp_split_clauses (location_t loc
, enum tree_code code
,
19616 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
19619 c_omp_split_clauses (loc
, code
, mask
, clauses
, cclauses
);
19620 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
19622 cclauses
[i
] = c_finish_omp_clauses (cclauses
[i
],
19623 i
== C_OMP_CLAUSE_SPLIT_TARGET
19624 ? C_ORT_OMP_TARGET
: C_ORT_OMP
);
19628 #pragma omp loop loop-clause[optseq] new-line
19631 LOC is the location of the #pragma token.
19634 #define OMP_LOOP_CLAUSE_MASK \
19635 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19636 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
19640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19643 c_parser_omp_loop (location_t loc
, c_parser
*parser
,
19644 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19647 tree block
, clauses
, ret
;
19649 strcat (p_name
, " loop");
19650 mask
|= OMP_LOOP_CLAUSE_MASK
;
19652 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19655 omp_split_clauses (loc
, OMP_LOOP
, mask
, clauses
, cclauses
);
19656 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_LOOP
];
19659 block
= c_begin_compound_stmt (true);
19660 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_LOOP
, clauses
, cclauses
, if_p
);
19661 block
= c_end_compound_stmt (loc
, block
, true);
19668 #pragma omp simd simd-clause[optseq] new-line
19671 LOC is the location of the #pragma token.
19674 #define OMP_SIMD_CLAUSE_MASK \
19675 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
19676 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19677 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19678 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19679 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19680 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19681 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19682 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19683 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19684 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
19685 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19688 c_parser_omp_simd (location_t loc
, c_parser
*parser
,
19689 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19692 tree block
, clauses
, ret
;
19694 strcat (p_name
, " simd");
19695 mask
|= OMP_SIMD_CLAUSE_MASK
;
19697 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19700 omp_split_clauses (loc
, OMP_SIMD
, mask
, clauses
, cclauses
);
19701 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SIMD
];
19702 tree c
= omp_find_clause (cclauses
[C_OMP_CLAUSE_SPLIT_FOR
],
19703 OMP_CLAUSE_ORDERED
);
19704 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
19706 error_at (OMP_CLAUSE_LOCATION (c
),
19707 "%<ordered%> clause with parameter may not be specified "
19708 "on %qs construct", p_name
);
19709 OMP_CLAUSE_ORDERED_EXPR (c
) = NULL_TREE
;
19713 block
= c_begin_compound_stmt (true);
19714 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_SIMD
, clauses
, cclauses
, if_p
);
19715 block
= c_end_compound_stmt (loc
, block
, true);
19722 #pragma omp for for-clause[optseq] new-line
19726 #pragma omp for simd for-simd-clause[optseq] new-line
19729 LOC is the location of the #pragma token.
19732 #define OMP_FOR_CLAUSE_MASK \
19733 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
19739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
19740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19742 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19746 c_parser_omp_for (location_t loc
, c_parser
*parser
,
19747 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19750 tree block
, clauses
, ret
;
19752 strcat (p_name
, " for");
19753 mask
|= OMP_FOR_CLAUSE_MASK
;
19754 /* parallel for{, simd} disallows nowait clause, but for
19755 target {teams distribute ,}parallel for{, simd} it should be accepted. */
19756 if (cclauses
&& (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) == 0)
19757 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
19758 /* Composite distribute parallel for{, simd} disallows ordered clause. */
19759 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
19760 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_ORDERED
);
19762 if (c_parser_next_token_is (parser
, CPP_NAME
))
19764 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19766 if (strcmp (p
, "simd") == 0)
19768 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19769 if (cclauses
== NULL
)
19770 cclauses
= cclauses_buf
;
19772 c_parser_consume_token (parser
);
19773 if (!flag_openmp
) /* flag_openmp_simd */
19774 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
19776 block
= c_begin_compound_stmt (true);
19777 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
19778 block
= c_end_compound_stmt (loc
, block
, true);
19779 if (ret
== NULL_TREE
)
19781 ret
= make_node (OMP_FOR
);
19782 TREE_TYPE (ret
) = void_type_node
;
19783 OMP_FOR_BODY (ret
) = block
;
19784 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
19785 SET_EXPR_LOCATION (ret
, loc
);
19790 if (!flag_openmp
) /* flag_openmp_simd */
19792 c_parser_skip_to_pragma_eol (parser
, false);
19796 /* Composite distribute parallel for disallows linear clause. */
19797 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
19798 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_LINEAR
);
19800 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19803 omp_split_clauses (loc
, OMP_FOR
, mask
, clauses
, cclauses
);
19804 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_FOR
];
19807 block
= c_begin_compound_stmt (true);
19808 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_FOR
, clauses
, cclauses
, if_p
);
19809 block
= c_end_compound_stmt (loc
, block
, true);
19815 static tree
c_parser_omp_taskloop (location_t
, c_parser
*, char *,
19816 omp_clause_mask
, tree
*, bool *);
19819 # pragma omp master new-line
19822 LOC is the location of the #pragma token.
19826 c_parser_omp_master (location_t loc
, c_parser
*parser
,
19827 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19830 tree block
, clauses
, ret
;
19832 strcat (p_name
, " master");
19834 if (c_parser_next_token_is (parser
, CPP_NAME
))
19836 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19838 if (strcmp (p
, "taskloop") == 0)
19840 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19841 if (cclauses
== NULL
)
19842 cclauses
= cclauses_buf
;
19844 c_parser_consume_token (parser
);
19845 if (!flag_openmp
) /* flag_openmp_simd */
19846 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
19848 block
= c_begin_compound_stmt (true);
19849 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
19851 block
= c_end_compound_stmt (loc
, block
, true);
19852 if (ret
== NULL_TREE
)
19854 ret
= c_finish_omp_master (loc
, block
);
19855 OMP_MASTER_COMBINED (ret
) = 1;
19859 if (!flag_openmp
) /* flag_openmp_simd */
19861 c_parser_skip_to_pragma_eol (parser
, false);
19867 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, false);
19868 omp_split_clauses (loc
, OMP_MASTER
, mask
, clauses
, cclauses
);
19871 c_parser_skip_to_pragma_eol (parser
);
19873 return c_finish_omp_master (loc
, c_parser_omp_structured_block (parser
,
19878 # pragma omp masked masked-clauses new-line
19881 LOC is the location of the #pragma token.
19884 #define OMP_MASKED_CLAUSE_MASK \
19885 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
19888 c_parser_omp_masked (location_t loc
, c_parser
*parser
,
19889 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
19892 tree block
, clauses
, ret
;
19894 strcat (p_name
, " masked");
19895 mask
|= OMP_MASKED_CLAUSE_MASK
;
19897 if (c_parser_next_token_is (parser
, CPP_NAME
))
19899 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19901 if (strcmp (p
, "taskloop") == 0)
19903 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
19904 if (cclauses
== NULL
)
19905 cclauses
= cclauses_buf
;
19907 c_parser_consume_token (parser
);
19908 if (!flag_openmp
) /* flag_openmp_simd */
19909 return c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
19911 block
= c_begin_compound_stmt (true);
19912 ret
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, cclauses
,
19914 block
= c_end_compound_stmt (loc
, block
, true);
19915 if (ret
== NULL_TREE
)
19917 ret
= c_finish_omp_masked (loc
, block
,
19918 cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
]);
19919 OMP_MASKED_COMBINED (ret
) = 1;
19923 if (!flag_openmp
) /* flag_openmp_simd */
19925 c_parser_skip_to_pragma_eol (parser
, false);
19929 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
19932 omp_split_clauses (loc
, OMP_MASKED
, mask
, clauses
, cclauses
);
19933 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_MASKED
];
19936 return c_finish_omp_masked (loc
, c_parser_omp_structured_block (parser
,
19942 # pragma omp ordered new-line
19946 # pragma omp ordered ordered-clauses new-line
19949 # pragma omp ordered depend-clauses new-line */
19951 #define OMP_ORDERED_CLAUSE_MASK \
19952 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
19953 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
19955 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
19956 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19959 c_parser_omp_ordered (c_parser
*parser
, enum pragma_context context
,
19962 location_t loc
= c_parser_peek_token (parser
)->location
;
19963 c_parser_consume_pragma (parser
);
19965 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
19967 c_parser_error (parser
, "expected declaration specifiers");
19968 c_parser_skip_to_pragma_eol (parser
, false);
19972 if (c_parser_next_token_is (parser
, CPP_NAME
))
19974 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
19976 if (!strcmp ("depend", p
))
19978 if (!flag_openmp
) /* flag_openmp_simd */
19980 c_parser_skip_to_pragma_eol (parser
, false);
19983 if (context
== pragma_stmt
)
19986 "%<#pragma omp ordered%> with %<depend%> clause may "
19987 "only be used in compound statements");
19988 c_parser_skip_to_pragma_eol (parser
, false);
19993 = c_parser_omp_all_clauses (parser
,
19994 OMP_ORDERED_DEPEND_CLAUSE_MASK
,
19995 "#pragma omp ordered");
19996 c_finish_omp_ordered (loc
, clauses
, NULL_TREE
);
20001 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_ORDERED_CLAUSE_MASK
,
20002 "#pragma omp ordered");
20004 if (!flag_openmp
/* flag_openmp_simd */
20005 && omp_find_clause (clauses
, OMP_CLAUSE_SIMD
) == NULL_TREE
)
20008 c_finish_omp_ordered (loc
, clauses
,
20009 c_parser_omp_structured_block (parser
, if_p
));
20016 { section-sequence }
20019 section-directive[opt] structured-block
20020 section-sequence section-directive structured-block
20022 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20024 SECTIONS_LOC is the location of the #pragma omp sections. */
20027 c_parser_omp_sections_scope (location_t sections_loc
, c_parser
*parser
)
20029 tree stmt
, substmt
;
20030 bool error_suppress
= false;
20033 loc
= c_parser_peek_token (parser
)->location
;
20034 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
20036 /* Avoid skipping until the end of the block. */
20037 parser
->error
= false;
20041 stmt
= push_stmt_list ();
20043 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_SECTION
)
20045 substmt
= c_parser_omp_structured_block_sequence (parser
,
20046 PRAGMA_OMP_SECTION
);
20047 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
20048 SET_EXPR_LOCATION (substmt
, loc
);
20049 add_stmt (substmt
);
20054 if (c_parser_next_token_is (parser
, CPP_CLOSE_BRACE
))
20056 if (c_parser_next_token_is (parser
, CPP_EOF
))
20059 loc
= c_parser_peek_token (parser
)->location
;
20060 if (c_parser_peek_token (parser
)->pragma_kind
== PRAGMA_OMP_SECTION
)
20062 c_parser_consume_pragma (parser
);
20063 c_parser_skip_to_pragma_eol (parser
);
20064 error_suppress
= false;
20066 else if (!error_suppress
)
20068 error_at (loc
, "expected %<#pragma omp section%> or %<}%>");
20069 error_suppress
= true;
20072 substmt
= c_parser_omp_structured_block_sequence (parser
,
20073 PRAGMA_OMP_SECTION
);
20074 substmt
= build1 (OMP_SECTION
, void_type_node
, substmt
);
20075 SET_EXPR_LOCATION (substmt
, loc
);
20076 add_stmt (substmt
);
20078 c_parser_skip_until_found (parser
, CPP_CLOSE_BRACE
,
20079 "expected %<#pragma omp section%> or %<}%>");
20081 substmt
= pop_stmt_list (stmt
);
20083 stmt
= make_node (OMP_SECTIONS
);
20084 SET_EXPR_LOCATION (stmt
, sections_loc
);
20085 TREE_TYPE (stmt
) = void_type_node
;
20086 OMP_SECTIONS_BODY (stmt
) = substmt
;
20088 return add_stmt (stmt
);
20092 # pragma omp sections sections-clause[optseq] newline
20095 LOC is the location of the #pragma token.
20098 #define OMP_SECTIONS_CLAUSE_MASK \
20099 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20100 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20101 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20102 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20103 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20104 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20107 c_parser_omp_sections (location_t loc
, c_parser
*parser
,
20108 char *p_name
, omp_clause_mask mask
, tree
*cclauses
)
20110 tree block
, clauses
, ret
;
20112 strcat (p_name
, " sections");
20113 mask
|= OMP_SECTIONS_CLAUSE_MASK
;
20115 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOWAIT
);
20117 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20120 omp_split_clauses (loc
, OMP_SECTIONS
, mask
, clauses
, cclauses
);
20121 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
];
20124 block
= c_begin_compound_stmt (true);
20125 ret
= c_parser_omp_sections_scope (loc
, parser
);
20127 OMP_SECTIONS_CLAUSES (ret
) = clauses
;
20128 block
= c_end_compound_stmt (loc
, block
, true);
20135 # pragma omp parallel parallel-clause[optseq] new-line
20137 # pragma omp parallel for parallel-for-clause[optseq] new-line
20139 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
20143 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
20146 LOC is the location of the #pragma token.
20149 #define OMP_PARALLEL_CLAUSE_MASK \
20150 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20151 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20154 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20155 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
20156 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20157 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
20158 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20159 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
20162 c_parser_omp_parallel (location_t loc
, c_parser
*parser
,
20163 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20166 tree stmt
, clauses
, block
;
20168 strcat (p_name
, " parallel");
20169 mask
|= OMP_PARALLEL_CLAUSE_MASK
;
20170 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
20171 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
)) != 0
20172 && (mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) == 0)
20173 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_COPYIN
);
20175 if (c_parser_next_token_is_keyword (parser
, RID_FOR
))
20177 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20178 if (cclauses
== NULL
)
20179 cclauses
= cclauses_buf
;
20181 c_parser_consume_token (parser
);
20182 if (!flag_openmp
) /* flag_openmp_simd */
20183 return c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
20184 block
= c_begin_omp_parallel ();
20185 tree ret
= c_parser_omp_for (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
20187 = c_finish_omp_parallel (loc
, cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20189 if (ret
== NULL_TREE
)
20191 OMP_PARALLEL_COMBINED (stmt
) = 1;
20194 /* When combined with distribute, parallel has to be followed by for.
20195 #pragma omp target parallel is allowed though. */
20197 && (mask
& (OMP_CLAUSE_MASK_1
20198 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE
)) != 0)
20200 error_at (loc
, "expected %<for%> after %qs", p_name
);
20201 c_parser_skip_to_pragma_eol (parser
);
20204 else if (c_parser_next_token_is (parser
, CPP_NAME
))
20206 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20207 if (cclauses
== NULL
&& strcmp (p
, "masked") == 0)
20209 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20210 cclauses
= cclauses_buf
;
20212 c_parser_consume_token (parser
);
20213 if (!flag_openmp
) /* flag_openmp_simd */
20214 return c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
20216 block
= c_begin_omp_parallel ();
20217 tree ret
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, cclauses
,
20219 stmt
= c_finish_omp_parallel (loc
,
20220 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20224 /* masked does have just filter clause, but during gimplification
20225 isn't represented by a gimplification omp context, so for
20226 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
20228 #pragma omp parallel masked
20229 #pragma omp taskloop simd lastprivate (x)
20230 isn't confused with
20231 #pragma omp parallel masked taskloop simd lastprivate (x) */
20232 if (OMP_MASKED_COMBINED (ret
))
20233 OMP_PARALLEL_COMBINED (stmt
) = 1;
20236 else if (cclauses
== NULL
&& strcmp (p
, "master") == 0)
20238 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20239 cclauses
= cclauses_buf
;
20241 c_parser_consume_token (parser
);
20242 if (!flag_openmp
) /* flag_openmp_simd */
20243 return c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
20245 block
= c_begin_omp_parallel ();
20246 tree ret
= c_parser_omp_master (loc
, parser
, p_name
, mask
, cclauses
,
20248 stmt
= c_finish_omp_parallel (loc
,
20249 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20253 /* master doesn't have any clauses and during gimplification
20254 isn't represented by a gimplification omp context, so for
20255 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
20257 #pragma omp parallel master
20258 #pragma omp taskloop simd lastprivate (x)
20259 isn't confused with
20260 #pragma omp parallel master taskloop simd lastprivate (x) */
20261 if (OMP_MASTER_COMBINED (ret
))
20262 OMP_PARALLEL_COMBINED (stmt
) = 1;
20265 else if (strcmp (p
, "loop") == 0)
20267 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20268 if (cclauses
== NULL
)
20269 cclauses
= cclauses_buf
;
20271 c_parser_consume_token (parser
);
20272 if (!flag_openmp
) /* flag_openmp_simd */
20273 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
20275 block
= c_begin_omp_parallel ();
20276 tree ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
20279 = c_finish_omp_parallel (loc
,
20280 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20282 if (ret
== NULL_TREE
)
20284 OMP_PARALLEL_COMBINED (stmt
) = 1;
20287 else if (!flag_openmp
) /* flag_openmp_simd */
20289 c_parser_skip_to_pragma_eol (parser
, false);
20292 else if (cclauses
== NULL
&& strcmp (p
, "sections") == 0)
20294 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20295 cclauses
= cclauses_buf
;
20297 c_parser_consume_token (parser
);
20298 block
= c_begin_omp_parallel ();
20299 c_parser_omp_sections (loc
, parser
, p_name
, mask
, cclauses
);
20300 stmt
= c_finish_omp_parallel (loc
,
20301 cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
],
20303 OMP_PARALLEL_COMBINED (stmt
) = 1;
20307 else if (!flag_openmp
) /* flag_openmp_simd */
20309 c_parser_skip_to_pragma_eol (parser
, false);
20313 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20316 omp_split_clauses (loc
, OMP_PARALLEL
, mask
, clauses
, cclauses
);
20317 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_PARALLEL
];
20320 block
= c_begin_omp_parallel ();
20321 c_parser_statement (parser
, if_p
);
20322 stmt
= c_finish_omp_parallel (loc
, clauses
, block
);
20328 # pragma omp single single-clause[optseq] new-line
20331 LOC is the location of the #pragma.
20334 #define OMP_SINGLE_CLAUSE_MASK \
20335 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20336 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20337 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
20338 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20339 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20342 c_parser_omp_single (location_t loc
, c_parser
*parser
, bool *if_p
)
20344 tree stmt
= make_node (OMP_SINGLE
);
20345 SET_EXPR_LOCATION (stmt
, loc
);
20346 TREE_TYPE (stmt
) = void_type_node
;
20348 OMP_SINGLE_CLAUSES (stmt
)
20349 = c_parser_omp_all_clauses (parser
, OMP_SINGLE_CLAUSE_MASK
,
20350 "#pragma omp single");
20351 OMP_SINGLE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
20353 return add_stmt (stmt
);
20357 # pragma omp scope scope-clause[optseq] new-line
20360 LOC is the location of the #pragma.
20363 #define OMP_SCOPE_CLAUSE_MASK \
20364 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20365 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20366 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20369 c_parser_omp_scope (location_t loc
, c_parser
*parser
, bool *if_p
)
20371 tree stmt
= make_node (OMP_SCOPE
);
20372 SET_EXPR_LOCATION (stmt
, loc
);
20373 TREE_TYPE (stmt
) = void_type_node
;
20375 OMP_SCOPE_CLAUSES (stmt
)
20376 = c_parser_omp_all_clauses (parser
, OMP_SCOPE_CLAUSE_MASK
,
20377 "#pragma omp scope");
20378 OMP_SCOPE_BODY (stmt
) = c_parser_omp_structured_block (parser
, if_p
);
20380 return add_stmt (stmt
);
20384 # pragma omp task task-clause[optseq] new-line
20386 LOC is the location of the #pragma.
20389 #define OMP_TASK_CLAUSE_MASK \
20390 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20391 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
20392 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20393 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20394 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20395 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20396 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
20397 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
20398 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20399 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
20400 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20401 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
20402 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
20403 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
20406 c_parser_omp_task (location_t loc
, c_parser
*parser
, bool *if_p
)
20408 tree clauses
, block
;
20410 clauses
= c_parser_omp_all_clauses (parser
, OMP_TASK_CLAUSE_MASK
,
20411 "#pragma omp task");
20413 block
= c_begin_omp_task ();
20414 c_parser_statement (parser
, if_p
);
20415 return c_finish_omp_task (loc
, clauses
, block
);
20419 # pragma omp taskwait new-line
20422 # pragma omp taskwait taskwait-clause[optseq] new-line
20425 #define OMP_TASKWAIT_CLAUSE_MASK \
20426 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
20429 c_parser_omp_taskwait (c_parser
*parser
)
20431 location_t loc
= c_parser_peek_token (parser
)->location
;
20432 c_parser_consume_pragma (parser
);
20435 = c_parser_omp_all_clauses (parser
, OMP_TASKWAIT_CLAUSE_MASK
,
20436 "#pragma omp taskwait");
20440 tree stmt
= make_node (OMP_TASK
);
20441 TREE_TYPE (stmt
) = void_node
;
20442 OMP_TASK_CLAUSES (stmt
) = clauses
;
20443 OMP_TASK_BODY (stmt
) = NULL_TREE
;
20444 SET_EXPR_LOCATION (stmt
, loc
);
20448 c_finish_omp_taskwait (loc
);
20452 # pragma omp taskyield new-line
20456 c_parser_omp_taskyield (c_parser
*parser
)
20458 location_t loc
= c_parser_peek_token (parser
)->location
;
20459 c_parser_consume_pragma (parser
);
20460 c_parser_skip_to_pragma_eol (parser
);
20462 c_finish_omp_taskyield (loc
);
20466 # pragma omp taskgroup new-line
20469 # pragma omp taskgroup taskgroup-clause[optseq] new-line
20472 #define OMP_TASKGROUP_CLAUSE_MASK \
20473 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20474 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
20477 c_parser_omp_taskgroup (location_t loc
, c_parser
*parser
, bool *if_p
)
20479 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_TASKGROUP_CLAUSE_MASK
,
20480 "#pragma omp taskgroup");
20482 tree body
= c_parser_omp_structured_block (parser
, if_p
);
20483 return c_finish_omp_taskgroup (loc
, body
, clauses
);
20487 # pragma omp cancel cancel-clause[optseq] new-line
20489 LOC is the location of the #pragma.
20492 #define OMP_CANCEL_CLAUSE_MASK \
20493 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20494 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20495 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
20497 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
20500 c_parser_omp_cancel (c_parser
*parser
)
20502 location_t loc
= c_parser_peek_token (parser
)->location
;
20504 c_parser_consume_pragma (parser
);
20505 tree clauses
= c_parser_omp_all_clauses (parser
, OMP_CANCEL_CLAUSE_MASK
,
20506 "#pragma omp cancel");
20508 c_finish_omp_cancel (loc
, clauses
);
20512 # pragma omp cancellation point cancelpt-clause[optseq] new-line
20514 LOC is the location of the #pragma.
20517 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
20518 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20519 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20520 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20521 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
20524 c_parser_omp_cancellation_point (c_parser
*parser
, enum pragma_context context
)
20526 location_t loc
= c_parser_peek_token (parser
)->location
;
20528 bool point_seen
= false;
20530 c_parser_consume_pragma (parser
);
20531 if (c_parser_next_token_is (parser
, CPP_NAME
))
20533 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20534 if (strcmp (p
, "point") == 0)
20536 c_parser_consume_token (parser
);
20542 c_parser_error (parser
, "expected %<point%>");
20543 c_parser_skip_to_pragma_eol (parser
);
20547 if (context
!= pragma_compound
)
20549 if (context
== pragma_stmt
)
20551 "%<#pragma %s%> may only be used in compound statements",
20552 "omp cancellation point");
20554 c_parser_error (parser
, "expected declaration specifiers");
20555 c_parser_skip_to_pragma_eol (parser
, false);
20560 = c_parser_omp_all_clauses (parser
, OMP_CANCELLATION_POINT_CLAUSE_MASK
,
20561 "#pragma omp cancellation point");
20563 c_finish_omp_cancellation_point (loc
, clauses
);
20568 #pragma omp distribute distribute-clause[optseq] new-line
20571 #define OMP_DISTRIBUTE_CLAUSE_MASK \
20572 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20574 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20575 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
20576 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20577 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20578 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20581 c_parser_omp_distribute (location_t loc
, c_parser
*parser
,
20582 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20585 tree clauses
, block
, ret
;
20587 strcat (p_name
, " distribute");
20588 mask
|= OMP_DISTRIBUTE_CLAUSE_MASK
;
20590 if (c_parser_next_token_is (parser
, CPP_NAME
))
20592 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20594 bool parallel
= false;
20596 if (strcmp (p
, "simd") == 0)
20599 parallel
= strcmp (p
, "parallel") == 0;
20600 if (parallel
|| simd
)
20602 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20603 if (cclauses
== NULL
)
20604 cclauses
= cclauses_buf
;
20605 c_parser_consume_token (parser
);
20606 if (!flag_openmp
) /* flag_openmp_simd */
20609 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
20612 return c_parser_omp_parallel (loc
, parser
, p_name
, mask
,
20615 block
= c_begin_compound_stmt (true);
20617 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
20620 ret
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, cclauses
,
20622 block
= c_end_compound_stmt (loc
, block
, true);
20625 ret
= make_node (OMP_DISTRIBUTE
);
20626 TREE_TYPE (ret
) = void_type_node
;
20627 OMP_FOR_BODY (ret
) = block
;
20628 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
20629 SET_EXPR_LOCATION (ret
, loc
);
20634 if (!flag_openmp
) /* flag_openmp_simd */
20636 c_parser_skip_to_pragma_eol (parser
, false);
20640 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20643 omp_split_clauses (loc
, OMP_DISTRIBUTE
, mask
, clauses
, cclauses
);
20644 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_DISTRIBUTE
];
20647 block
= c_begin_compound_stmt (true);
20648 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_DISTRIBUTE
, clauses
, NULL
,
20650 block
= c_end_compound_stmt (loc
, block
, true);
20657 # pragma omp teams teams-clause[optseq] new-line
20658 structured-block */
20660 #define OMP_TEAMS_CLAUSE_MASK \
20661 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20662 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20663 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20664 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20665 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
20666 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
20667 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20668 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
20671 c_parser_omp_teams (location_t loc
, c_parser
*parser
,
20672 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
20675 tree clauses
, block
, ret
;
20677 strcat (p_name
, " teams");
20678 mask
|= OMP_TEAMS_CLAUSE_MASK
;
20680 if (c_parser_next_token_is (parser
, CPP_NAME
))
20682 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20683 if (strcmp (p
, "distribute") == 0)
20685 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20686 if (cclauses
== NULL
)
20687 cclauses
= cclauses_buf
;
20689 c_parser_consume_token (parser
);
20690 if (!flag_openmp
) /* flag_openmp_simd */
20691 return c_parser_omp_distribute (loc
, parser
, p_name
, mask
,
20693 block
= c_begin_omp_parallel ();
20694 ret
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, cclauses
,
20696 block
= c_end_compound_stmt (loc
, block
, true);
20699 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
20700 ret
= make_node (OMP_TEAMS
);
20701 TREE_TYPE (ret
) = void_type_node
;
20702 OMP_TEAMS_CLAUSES (ret
) = clauses
;
20703 OMP_TEAMS_BODY (ret
) = block
;
20704 OMP_TEAMS_COMBINED (ret
) = 1;
20705 SET_EXPR_LOCATION (ret
, loc
);
20706 return add_stmt (ret
);
20708 else if (strcmp (p
, "loop") == 0)
20710 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
20711 if (cclauses
== NULL
)
20712 cclauses
= cclauses_buf
;
20714 c_parser_consume_token (parser
);
20715 if (!flag_openmp
) /* flag_openmp_simd */
20716 return c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
,
20718 block
= c_begin_omp_parallel ();
20719 ret
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
20720 block
= c_end_compound_stmt (loc
, block
, true);
20723 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
20724 ret
= make_node (OMP_TEAMS
);
20725 TREE_TYPE (ret
) = void_type_node
;
20726 OMP_TEAMS_CLAUSES (ret
) = clauses
;
20727 OMP_TEAMS_BODY (ret
) = block
;
20728 OMP_TEAMS_COMBINED (ret
) = 1;
20729 SET_EXPR_LOCATION (ret
, loc
);
20730 return add_stmt (ret
);
20733 if (!flag_openmp
) /* flag_openmp_simd */
20735 c_parser_skip_to_pragma_eol (parser
, false);
20739 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
20742 omp_split_clauses (loc
, OMP_TEAMS
, mask
, clauses
, cclauses
);
20743 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
20746 tree stmt
= make_node (OMP_TEAMS
);
20747 TREE_TYPE (stmt
) = void_type_node
;
20748 OMP_TEAMS_CLAUSES (stmt
) = clauses
;
20749 block
= c_begin_omp_parallel ();
20750 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
20751 OMP_TEAMS_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
20752 SET_EXPR_LOCATION (stmt
, loc
);
20754 return add_stmt (stmt
);
20758 # pragma omp target data target-data-clause[optseq] new-line
20759 structured-block */
20761 #define OMP_TARGET_DATA_CLAUSE_MASK \
20762 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20763 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20764 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20765 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
20766 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
20769 c_parser_omp_target_data (location_t loc
, c_parser
*parser
, bool *if_p
)
20772 = c_parser_omp_all_clauses (parser
, OMP_TARGET_DATA_CLAUSE_MASK
,
20773 "#pragma omp target data");
20774 c_omp_adjust_map_clauses (clauses
, false);
20776 for (tree
*pc
= &clauses
; *pc
;)
20778 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
20779 switch (OMP_CLAUSE_MAP_KIND (*pc
))
20782 case GOMP_MAP_ALWAYS_TO
:
20783 case GOMP_MAP_FROM
:
20784 case GOMP_MAP_ALWAYS_FROM
:
20785 case GOMP_MAP_TOFROM
:
20786 case GOMP_MAP_ALWAYS_TOFROM
:
20787 case GOMP_MAP_ALLOC
:
20790 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
20791 case GOMP_MAP_ALWAYS_POINTER
:
20792 case GOMP_MAP_ATTACH_DETACH
:
20796 error_at (OMP_CLAUSE_LOCATION (*pc
),
20797 "%<#pragma omp target data%> with map-type other "
20798 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
20799 "on %<map%> clause");
20800 *pc
= OMP_CLAUSE_CHAIN (*pc
);
20803 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
20804 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
20806 pc
= &OMP_CLAUSE_CHAIN (*pc
);
20813 "%<#pragma omp target data%> must contain at least "
20814 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
20819 tree stmt
= make_node (OMP_TARGET_DATA
);
20820 TREE_TYPE (stmt
) = void_type_node
;
20821 OMP_TARGET_DATA_CLAUSES (stmt
) = clauses
;
20822 keep_next_level ();
20823 tree block
= c_begin_compound_stmt (true);
20824 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
20825 OMP_TARGET_DATA_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
20827 SET_EXPR_LOCATION (stmt
, loc
);
20828 return add_stmt (stmt
);
20832 # pragma omp target update target-update-clause[optseq] new-line */
20834 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
20835 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
20836 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
20837 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20838 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20839 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20840 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20843 c_parser_omp_target_update (location_t loc
, c_parser
*parser
,
20844 enum pragma_context context
)
20846 if (context
== pragma_stmt
)
20848 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
20849 "omp target update");
20850 c_parser_skip_to_pragma_eol (parser
, false);
20855 = c_parser_omp_all_clauses (parser
, OMP_TARGET_UPDATE_CLAUSE_MASK
,
20856 "#pragma omp target update");
20857 if (omp_find_clause (clauses
, OMP_CLAUSE_TO
) == NULL_TREE
20858 && omp_find_clause (clauses
, OMP_CLAUSE_FROM
) == NULL_TREE
)
20861 "%<#pragma omp target update%> must contain at least one "
20862 "%<from%> or %<to%> clauses");
20866 tree stmt
= make_node (OMP_TARGET_UPDATE
);
20867 TREE_TYPE (stmt
) = void_type_node
;
20868 OMP_TARGET_UPDATE_CLAUSES (stmt
) = clauses
;
20869 SET_EXPR_LOCATION (stmt
, loc
);
20875 # pragma omp target enter data target-data-clause[optseq] new-line */
20877 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
20878 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20879 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20880 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20881 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20882 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20885 c_parser_omp_target_enter_data (location_t loc
, c_parser
*parser
,
20886 enum pragma_context context
)
20888 bool data_seen
= false;
20889 if (c_parser_next_token_is (parser
, CPP_NAME
))
20891 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20892 if (strcmp (p
, "data") == 0)
20894 c_parser_consume_token (parser
);
20900 c_parser_error (parser
, "expected %<data%>");
20901 c_parser_skip_to_pragma_eol (parser
);
20905 if (context
== pragma_stmt
)
20907 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
20908 "omp target enter data");
20909 c_parser_skip_to_pragma_eol (parser
, false);
20914 = c_parser_omp_all_clauses (parser
, OMP_TARGET_ENTER_DATA_CLAUSE_MASK
,
20915 "#pragma omp target enter data");
20916 c_omp_adjust_map_clauses (clauses
, false);
20918 for (tree
*pc
= &clauses
; *pc
;)
20920 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
20921 switch (OMP_CLAUSE_MAP_KIND (*pc
))
20924 case GOMP_MAP_ALWAYS_TO
:
20925 case GOMP_MAP_ALLOC
:
20928 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
20929 case GOMP_MAP_ALWAYS_POINTER
:
20930 case GOMP_MAP_ATTACH_DETACH
:
20934 error_at (OMP_CLAUSE_LOCATION (*pc
),
20935 "%<#pragma omp target enter data%> with map-type other "
20936 "than %<to%> or %<alloc%> on %<map%> clause");
20937 *pc
= OMP_CLAUSE_CHAIN (*pc
);
20940 pc
= &OMP_CLAUSE_CHAIN (*pc
);
20947 "%<#pragma omp target enter data%> must contain at least "
20948 "one %<map%> clause");
20952 tree stmt
= make_node (OMP_TARGET_ENTER_DATA
);
20953 TREE_TYPE (stmt
) = void_type_node
;
20954 OMP_TARGET_ENTER_DATA_CLAUSES (stmt
) = clauses
;
20955 SET_EXPR_LOCATION (stmt
, loc
);
20961 # pragma omp target exit data target-data-clause[optseq] new-line */
20963 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
20964 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20965 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20966 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20967 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20968 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20971 c_parser_omp_target_exit_data (location_t loc
, c_parser
*parser
,
20972 enum pragma_context context
)
20974 bool data_seen
= false;
20975 if (c_parser_next_token_is (parser
, CPP_NAME
))
20977 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
20978 if (strcmp (p
, "data") == 0)
20980 c_parser_consume_token (parser
);
20986 c_parser_error (parser
, "expected %<data%>");
20987 c_parser_skip_to_pragma_eol (parser
);
20991 if (context
== pragma_stmt
)
20993 error_at (loc
, "%<#pragma %s%> may only be used in compound statements",
20994 "omp target exit data");
20995 c_parser_skip_to_pragma_eol (parser
, false);
21000 = c_parser_omp_all_clauses (parser
, OMP_TARGET_EXIT_DATA_CLAUSE_MASK
,
21001 "#pragma omp target exit data");
21002 c_omp_adjust_map_clauses (clauses
, false);
21004 for (tree
*pc
= &clauses
; *pc
;)
21006 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21007 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21009 case GOMP_MAP_FROM
:
21010 case GOMP_MAP_ALWAYS_FROM
:
21011 case GOMP_MAP_RELEASE
:
21012 case GOMP_MAP_DELETE
:
21015 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
21016 case GOMP_MAP_ALWAYS_POINTER
:
21017 case GOMP_MAP_ATTACH_DETACH
:
21021 error_at (OMP_CLAUSE_LOCATION (*pc
),
21022 "%<#pragma omp target exit data%> with map-type other "
21023 "than %<from%>, %<release%> or %<delete%> on %<map%>"
21025 *pc
= OMP_CLAUSE_CHAIN (*pc
);
21028 pc
= &OMP_CLAUSE_CHAIN (*pc
);
21035 "%<#pragma omp target exit data%> must contain at least one "
21040 tree stmt
= make_node (OMP_TARGET_EXIT_DATA
);
21041 TREE_TYPE (stmt
) = void_type_node
;
21042 OMP_TARGET_EXIT_DATA_CLAUSES (stmt
) = clauses
;
21043 SET_EXPR_LOCATION (stmt
, loc
);
21049 # pragma omp target target-clause[optseq] new-line
21050 structured-block */
21052 #define OMP_TARGET_CLAUSE_MASK \
21053 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21054 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21055 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21056 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21057 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
21058 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21059 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21060 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21061 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
21062 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
21063 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21064 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
21065 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
21068 c_parser_omp_target (c_parser
*parser
, enum pragma_context context
, bool *if_p
)
21070 location_t loc
= c_parser_peek_token (parser
)->location
;
21071 c_parser_consume_pragma (parser
);
21072 tree
*pc
= NULL
, stmt
, block
;
21074 if (context
!= pragma_stmt
&& context
!= pragma_compound
)
21076 c_parser_error (parser
, "expected declaration specifiers");
21077 c_parser_skip_to_pragma_eol (parser
);
21083 = (enum omp_requires
) (omp_requires_mask
| OMP_REQUIRES_TARGET_USED
);
21085 if (c_parser_next_token_is (parser
, CPP_NAME
))
21087 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21088 enum tree_code ccode
= ERROR_MARK
;
21090 if (strcmp (p
, "teams") == 0)
21092 else if (strcmp (p
, "parallel") == 0)
21093 ccode
= OMP_PARALLEL
;
21094 else if (strcmp (p
, "simd") == 0)
21096 if (ccode
!= ERROR_MARK
)
21098 tree cclauses
[C_OMP_CLAUSE_SPLIT_COUNT
];
21099 char p_name
[sizeof ("#pragma omp target teams distribute "
21100 "parallel for simd")];
21102 c_parser_consume_token (parser
);
21103 strcpy (p_name
, "#pragma omp target");
21104 if (!flag_openmp
) /* flag_openmp_simd */
21110 stmt
= c_parser_omp_teams (loc
, parser
, p_name
,
21111 OMP_TARGET_CLAUSE_MASK
,
21115 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
,
21116 OMP_TARGET_CLAUSE_MASK
,
21120 stmt
= c_parser_omp_simd (loc
, parser
, p_name
,
21121 OMP_TARGET_CLAUSE_MASK
,
21125 gcc_unreachable ();
21127 return stmt
!= NULL_TREE
;
21129 keep_next_level ();
21130 tree block
= c_begin_compound_stmt (true), ret
;
21134 ret
= c_parser_omp_teams (loc
, parser
, p_name
,
21135 OMP_TARGET_CLAUSE_MASK
, cclauses
,
21139 ret
= c_parser_omp_parallel (loc
, parser
, p_name
,
21140 OMP_TARGET_CLAUSE_MASK
, cclauses
,
21144 ret
= c_parser_omp_simd (loc
, parser
, p_name
,
21145 OMP_TARGET_CLAUSE_MASK
, cclauses
,
21149 gcc_unreachable ();
21151 block
= c_end_compound_stmt (loc
, block
, true);
21152 if (ret
== NULL_TREE
)
21154 if (ccode
== OMP_TEAMS
)
21155 /* For combined target teams, ensure the num_teams and
21156 thread_limit clause expressions are evaluated on the host,
21157 before entering the target construct. */
21158 for (tree c
= cclauses
[C_OMP_CLAUSE_SPLIT_TEAMS
];
21159 c
; c
= OMP_CLAUSE_CHAIN (c
))
21160 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
21161 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
21163 i
<= (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
); ++i
)
21164 if (OMP_CLAUSE_OPERAND (c
, i
)
21165 && TREE_CODE (OMP_CLAUSE_OPERAND (c
, i
)) != INTEGER_CST
)
21167 tree expr
= OMP_CLAUSE_OPERAND (c
, i
);
21168 tree tmp
= create_tmp_var_raw (TREE_TYPE (expr
));
21169 expr
= build4 (TARGET_EXPR
, TREE_TYPE (expr
), tmp
,
21170 expr
, NULL_TREE
, NULL_TREE
);
21172 OMP_CLAUSE_OPERAND (c
, i
) = expr
;
21173 tree tc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
21174 OMP_CLAUSE_FIRSTPRIVATE
);
21175 OMP_CLAUSE_DECL (tc
) = tmp
;
21176 OMP_CLAUSE_CHAIN (tc
)
21177 = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
21178 cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
] = tc
;
21180 tree stmt
= make_node (OMP_TARGET
);
21181 TREE_TYPE (stmt
) = void_type_node
;
21182 OMP_TARGET_CLAUSES (stmt
) = cclauses
[C_OMP_CLAUSE_SPLIT_TARGET
];
21183 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
21184 OMP_TARGET_BODY (stmt
) = block
;
21185 OMP_TARGET_COMBINED (stmt
) = 1;
21186 SET_EXPR_LOCATION (stmt
, loc
);
21188 pc
= &OMP_TARGET_CLAUSES (stmt
);
21189 goto check_clauses
;
21191 else if (!flag_openmp
) /* flag_openmp_simd */
21193 c_parser_skip_to_pragma_eol (parser
, false);
21196 else if (strcmp (p
, "data") == 0)
21198 c_parser_consume_token (parser
);
21199 c_parser_omp_target_data (loc
, parser
, if_p
);
21202 else if (strcmp (p
, "enter") == 0)
21204 c_parser_consume_token (parser
);
21205 return c_parser_omp_target_enter_data (loc
, parser
, context
);
21207 else if (strcmp (p
, "exit") == 0)
21209 c_parser_consume_token (parser
);
21210 return c_parser_omp_target_exit_data (loc
, parser
, context
);
21212 else if (strcmp (p
, "update") == 0)
21214 c_parser_consume_token (parser
);
21215 return c_parser_omp_target_update (loc
, parser
, context
);
21218 if (!flag_openmp
) /* flag_openmp_simd */
21220 c_parser_skip_to_pragma_eol (parser
, false);
21224 stmt
= make_node (OMP_TARGET
);
21225 TREE_TYPE (stmt
) = void_type_node
;
21227 OMP_TARGET_CLAUSES (stmt
)
21228 = c_parser_omp_all_clauses (parser
, OMP_TARGET_CLAUSE_MASK
,
21229 "#pragma omp target", false);
21230 for (tree c
= OMP_TARGET_CLAUSES (stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
21231 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
)
21233 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
21234 OMP_CLAUSE_DECL (nc
) = OMP_CLAUSE_DECL (c
);
21235 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_ALWAYS_TOFROM
);
21236 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
21237 OMP_CLAUSE_CHAIN (c
) = nc
;
21239 OMP_TARGET_CLAUSES (stmt
)
21240 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt
), C_ORT_OMP_TARGET
);
21241 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt
), true);
21243 pc
= &OMP_TARGET_CLAUSES (stmt
);
21244 keep_next_level ();
21245 block
= c_begin_compound_stmt (true);
21246 add_stmt (c_parser_omp_structured_block (parser
, if_p
));
21247 OMP_TARGET_BODY (stmt
) = c_end_compound_stmt (loc
, block
, true);
21249 SET_EXPR_LOCATION (stmt
, loc
);
21255 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_MAP
)
21256 switch (OMP_CLAUSE_MAP_KIND (*pc
))
21259 case GOMP_MAP_ALWAYS_TO
:
21260 case GOMP_MAP_FROM
:
21261 case GOMP_MAP_ALWAYS_FROM
:
21262 case GOMP_MAP_TOFROM
:
21263 case GOMP_MAP_ALWAYS_TOFROM
:
21264 case GOMP_MAP_ALLOC
:
21265 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
21266 case GOMP_MAP_ALWAYS_POINTER
:
21267 case GOMP_MAP_ATTACH_DETACH
:
21270 error_at (OMP_CLAUSE_LOCATION (*pc
),
21271 "%<#pragma omp target%> with map-type other "
21272 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21273 "on %<map%> clause");
21274 *pc
= OMP_CLAUSE_CHAIN (*pc
);
21277 pc
= &OMP_CLAUSE_CHAIN (*pc
);
21279 cfun
->has_omp_target
= true;
21284 # pragma omp declare simd declare-simd-clauses[optseq] new-line
21287 # pragma omp declare variant (identifier) match(context-selector) new-line
21290 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
21291 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
21292 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
21293 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
21294 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
21295 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
21296 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
21299 c_parser_omp_declare_simd (c_parser
*parser
, enum pragma_context context
)
21301 c_token
*token
= c_parser_peek_token (parser
);
21302 gcc_assert (token
->type
== CPP_NAME
);
21303 tree kind
= token
->value
;
21304 gcc_assert (strcmp (IDENTIFIER_POINTER (kind
), "simd") == 0
21305 || strcmp (IDENTIFIER_POINTER (kind
), "variant") == 0);
21307 auto_vec
<c_token
> clauses
;
21308 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21310 c_token
*token
= c_parser_peek_token (parser
);
21311 if (token
->type
== CPP_EOF
)
21313 c_parser_skip_to_pragma_eol (parser
);
21316 clauses
.safe_push (*token
);
21317 c_parser_consume_token (parser
);
21319 clauses
.safe_push (*c_parser_peek_token (parser
));
21320 c_parser_skip_to_pragma_eol (parser
);
21322 while (c_parser_next_token_is (parser
, CPP_PRAGMA
))
21324 if (c_parser_peek_token (parser
)->pragma_kind
!= PRAGMA_OMP_DECLARE
21325 || c_parser_peek_2nd_token (parser
)->type
!= CPP_NAME
21326 || c_parser_peek_2nd_token (parser
)->value
!= kind
)
21328 error ("%<#pragma omp declare %s%> must be followed by "
21329 "function declaration or definition or another "
21330 "%<#pragma omp declare %s%>",
21331 IDENTIFIER_POINTER (kind
), IDENTIFIER_POINTER (kind
));
21334 c_parser_consume_pragma (parser
);
21335 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
21337 c_token
*token
= c_parser_peek_token (parser
);
21338 if (token
->type
== CPP_EOF
)
21340 c_parser_skip_to_pragma_eol (parser
);
21343 clauses
.safe_push (*token
);
21344 c_parser_consume_token (parser
);
21346 clauses
.safe_push (*c_parser_peek_token (parser
));
21347 c_parser_skip_to_pragma_eol (parser
);
21350 /* Make sure nothing tries to read past the end of the tokens. */
21352 memset (&eof_token
, 0, sizeof (eof_token
));
21353 eof_token
.type
= CPP_EOF
;
21354 clauses
.safe_push (eof_token
);
21355 clauses
.safe_push (eof_token
);
21359 case pragma_external
:
21360 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21361 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
21363 int ext
= disable_extension_diagnostics ();
21365 c_parser_consume_token (parser
);
21366 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21367 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
21368 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
21370 restore_extension_diagnostics (ext
);
21373 c_parser_declaration_or_fndef (parser
, true, true, true, false, true,
21376 case pragma_struct
:
21379 error ("%<#pragma omp declare %s%> must be followed by "
21380 "function declaration or definition",
21381 IDENTIFIER_POINTER (kind
));
21383 case pragma_compound
:
21384 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21385 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
)
21387 int ext
= disable_extension_diagnostics ();
21389 c_parser_consume_token (parser
);
21390 while (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21391 && c_parser_peek_token (parser
)->keyword
== RID_EXTENSION
);
21392 if (c_parser_next_tokens_start_declaration (parser
))
21394 c_parser_declaration_or_fndef (parser
, true, true, true, true,
21395 true, NULL
, &clauses
);
21396 restore_extension_diagnostics (ext
);
21399 restore_extension_diagnostics (ext
);
21401 else if (c_parser_next_tokens_start_declaration (parser
))
21403 c_parser_declaration_or_fndef (parser
, true, true, true, true, true,
21407 error ("%<#pragma omp declare %s%> must be followed by "
21408 "function declaration or definition",
21409 IDENTIFIER_POINTER (kind
));
21412 gcc_unreachable ();
21416 static const char *const omp_construct_selectors
[] = {
21417 "simd", "target", "teams", "parallel", "for", NULL
};
21418 static const char *const omp_device_selectors
[] = {
21419 "kind", "isa", "arch", NULL
};
21420 static const char *const omp_implementation_selectors
[] = {
21421 "vendor", "extension", "atomic_default_mem_order", "unified_address",
21422 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL
};
21423 static const char *const omp_user_selectors
[] = {
21424 "condition", NULL
};
21429 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
21432 score(score-expression) */
21435 c_parser_omp_context_selector (c_parser
*parser
, tree set
, tree parms
)
21437 tree ret
= NULL_TREE
;
21441 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21442 || c_parser_next_token_is (parser
, CPP_NAME
))
21443 selector
= c_parser_peek_token (parser
)->value
;
21446 c_parser_error (parser
, "expected trait selector name");
21447 return error_mark_node
;
21450 tree properties
= NULL_TREE
;
21451 const char *const *selectors
= NULL
;
21452 bool allow_score
= true;
21453 bool allow_user
= false;
21454 int property_limit
= 0;
21455 enum { CTX_PROPERTY_NONE
, CTX_PROPERTY_USER
, CTX_PROPERTY_NAME_LIST
,
21456 CTX_PROPERTY_ID
, CTX_PROPERTY_EXPR
,
21457 CTX_PROPERTY_SIMD
} property_kind
= CTX_PROPERTY_NONE
;
21458 switch (IDENTIFIER_POINTER (set
)[0])
21460 case 'c': /* construct */
21461 selectors
= omp_construct_selectors
;
21462 allow_score
= false;
21463 property_limit
= 1;
21464 property_kind
= CTX_PROPERTY_SIMD
;
21466 case 'd': /* device */
21467 selectors
= omp_device_selectors
;
21468 allow_score
= false;
21470 property_limit
= 3;
21471 property_kind
= CTX_PROPERTY_NAME_LIST
;
21473 case 'i': /* implementation */
21474 selectors
= omp_implementation_selectors
;
21476 property_limit
= 3;
21477 property_kind
= CTX_PROPERTY_NAME_LIST
;
21479 case 'u': /* user */
21480 selectors
= omp_user_selectors
;
21481 property_limit
= 1;
21482 property_kind
= CTX_PROPERTY_EXPR
;
21485 gcc_unreachable ();
21487 for (int i
= 0; ; i
++)
21489 if (selectors
[i
] == NULL
)
21493 property_kind
= CTX_PROPERTY_USER
;
21498 error_at (c_parser_peek_token (parser
)->location
,
21499 "selector %qs not allowed for context selector "
21500 "set %qs", IDENTIFIER_POINTER (selector
),
21501 IDENTIFIER_POINTER (set
));
21502 c_parser_consume_token (parser
);
21503 return error_mark_node
;
21506 if (i
== property_limit
)
21507 property_kind
= CTX_PROPERTY_NONE
;
21508 if (strcmp (selectors
[i
], IDENTIFIER_POINTER (selector
)) == 0)
21511 if (property_kind
== CTX_PROPERTY_NAME_LIST
21512 && IDENTIFIER_POINTER (set
)[0] == 'i'
21513 && strcmp (IDENTIFIER_POINTER (selector
),
21514 "atomic_default_mem_order") == 0)
21515 property_kind
= CTX_PROPERTY_ID
;
21517 c_parser_consume_token (parser
);
21519 if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
21521 if (property_kind
== CTX_PROPERTY_NONE
)
21523 error_at (c_parser_peek_token (parser
)->location
,
21524 "selector %qs does not accept any properties",
21525 IDENTIFIER_POINTER (selector
));
21526 return error_mark_node
;
21529 matching_parens parens
;
21530 parens
.require_open (parser
);
21532 c_token
*token
= c_parser_peek_token (parser
);
21534 && c_parser_next_token_is (parser
, CPP_NAME
)
21535 && strcmp (IDENTIFIER_POINTER (token
->value
), "score") == 0
21536 && c_parser_peek_2nd_token (parser
)->type
== CPP_OPEN_PAREN
)
21538 c_parser_consume_token (parser
);
21540 matching_parens parens2
;
21541 parens2
.require_open (parser
);
21542 tree score
= c_parser_expr_no_commas (parser
, NULL
).value
;
21543 parens2
.skip_until_found_close (parser
);
21544 c_parser_require (parser
, CPP_COLON
, "expected %<:%>");
21545 if (score
!= error_mark_node
)
21547 mark_exp_read (score
);
21548 score
= c_fully_fold (score
, false, NULL
);
21549 if (!INTEGRAL_TYPE_P (TREE_TYPE (score
))
21550 || TREE_CODE (score
) != INTEGER_CST
)
21551 error_at (token
->location
, "score argument must be "
21552 "constant integer expression");
21553 else if (tree_int_cst_sgn (score
) < 0)
21554 error_at (token
->location
, "score argument must be "
21557 properties
= tree_cons (get_identifier (" score"),
21558 score
, properties
);
21560 token
= c_parser_peek_token (parser
);
21563 switch (property_kind
)
21566 case CTX_PROPERTY_USER
:
21569 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
21570 if (TREE_CODE (t
) == STRING_CST
)
21571 properties
= tree_cons (NULL_TREE
, t
, properties
);
21572 else if (t
!= error_mark_node
)
21575 t
= c_fully_fold (t
, false, NULL
);
21576 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
21577 || !tree_fits_shwi_p (t
))
21578 error_at (token
->location
, "property must be "
21579 "constant integer expression or string "
21582 properties
= tree_cons (NULL_TREE
, t
, properties
);
21585 return error_mark_node
;
21587 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21588 c_parser_consume_token (parser
);
21594 case CTX_PROPERTY_ID
:
21595 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21596 || c_parser_next_token_is (parser
, CPP_NAME
))
21598 tree prop
= c_parser_peek_token (parser
)->value
;
21599 c_parser_consume_token (parser
);
21600 properties
= tree_cons (prop
, NULL_TREE
, properties
);
21604 c_parser_error (parser
, "expected identifier");
21605 return error_mark_node
;
21608 case CTX_PROPERTY_NAME_LIST
:
21611 tree prop
= NULL_TREE
, value
= NULL_TREE
;
21612 if (c_parser_next_token_is (parser
, CPP_KEYWORD
)
21613 || c_parser_next_token_is (parser
, CPP_NAME
))
21615 prop
= c_parser_peek_token (parser
)->value
;
21616 c_parser_consume_token (parser
);
21618 else if (c_parser_next_token_is (parser
, CPP_STRING
))
21619 value
= c_parser_string_literal (parser
, false,
21623 c_parser_error (parser
, "expected identifier or "
21625 return error_mark_node
;
21628 properties
= tree_cons (prop
, value
, properties
);
21630 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21631 c_parser_consume_token (parser
);
21637 case CTX_PROPERTY_EXPR
:
21638 t
= c_parser_expr_no_commas (parser
, NULL
).value
;
21639 if (t
!= error_mark_node
)
21642 t
= c_fully_fold (t
, false, NULL
);
21643 if (!INTEGRAL_TYPE_P (TREE_TYPE (t
))
21644 || !tree_fits_shwi_p (t
))
21645 error_at (token
->location
, "property must be "
21646 "constant integer expression");
21648 properties
= tree_cons (NULL_TREE
, t
, properties
);
21651 return error_mark_node
;
21653 case CTX_PROPERTY_SIMD
:
21654 if (parms
== NULL_TREE
)
21656 error_at (token
->location
, "properties for %<simd%> "
21657 "selector may not be specified in "
21658 "%<metadirective%>");
21659 return error_mark_node
;
21662 c
= c_parser_omp_all_clauses (parser
,
21663 OMP_DECLARE_SIMD_CLAUSE_MASK
,
21665 c
= c_omp_declare_simd_clauses_to_numbers (parms
21667 ? NULL_TREE
: parms
,
21672 gcc_unreachable ();
21675 parens
.skip_until_found_close (parser
);
21676 properties
= nreverse (properties
);
21678 else if (property_kind
== CTX_PROPERTY_NAME_LIST
21679 || property_kind
== CTX_PROPERTY_ID
21680 || property_kind
== CTX_PROPERTY_EXPR
)
21682 c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>");
21683 return error_mark_node
;
21686 ret
= tree_cons (selector
, properties
, ret
);
21688 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21689 c_parser_consume_token (parser
);
21695 return nreverse (ret
);
21700 trait-set-selector[,trait-set-selector[,...]]
21702 trait-set-selector:
21703 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
21705 trait-set-selector-name:
21712 c_parser_omp_context_selector_specification (c_parser
*parser
, tree parms
)
21714 tree ret
= NULL_TREE
;
21717 const char *setp
= "";
21718 if (c_parser_next_token_is (parser
, CPP_NAME
))
21719 setp
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21723 if (strcmp (setp
, "construct") == 0)
21727 if (strcmp (setp
, "device") == 0)
21731 if (strcmp (setp
, "implementation") == 0)
21735 if (strcmp (setp
, "user") == 0)
21743 c_parser_error (parser
, "expected %<construct%>, %<device%>, "
21744 "%<implementation%> or %<user%>");
21745 return error_mark_node
;
21748 tree set
= c_parser_peek_token (parser
)->value
;
21749 c_parser_consume_token (parser
);
21751 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
21752 return error_mark_node
;
21754 matching_braces braces
;
21755 if (!braces
.require_open (parser
))
21756 return error_mark_node
;
21758 tree selectors
= c_parser_omp_context_selector (parser
, set
, parms
);
21759 if (selectors
== error_mark_node
)
21760 ret
= error_mark_node
;
21761 else if (ret
!= error_mark_node
)
21762 ret
= tree_cons (set
, selectors
, ret
);
21764 braces
.skip_until_found_close (parser
);
21766 if (c_parser_next_token_is (parser
, CPP_COMMA
))
21767 c_parser_consume_token (parser
);
21773 if (ret
== error_mark_node
)
21775 return nreverse (ret
);
21778 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
21779 that into "omp declare variant base" attribute. */
21782 c_finish_omp_declare_variant (c_parser
*parser
, tree fndecl
, tree parms
)
21784 matching_parens parens
;
21785 if (!parens
.require_open (parser
))
21788 c_parser_skip_to_pragma_eol (parser
, false);
21792 if (c_parser_next_token_is_not (parser
, CPP_NAME
)
21793 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
21795 c_parser_error (parser
, "expected identifier");
21799 c_token
*token
= c_parser_peek_token (parser
);
21800 tree variant
= lookup_name (token
->value
);
21802 if (variant
== NULL_TREE
)
21804 undeclared_variable (token
->location
, token
->value
);
21805 variant
= error_mark_node
;
21808 c_parser_consume_token (parser
);
21810 parens
.require_close (parser
);
21812 const char *clause
= "";
21813 location_t match_loc
= c_parser_peek_token (parser
)->location
;
21814 if (c_parser_next_token_is (parser
, CPP_NAME
))
21815 clause
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
21816 if (strcmp (clause
, "match"))
21818 c_parser_error (parser
, "expected %<match%>");
21822 c_parser_consume_token (parser
);
21824 if (!parens
.require_open (parser
))
21827 if (parms
== NULL_TREE
)
21828 parms
= error_mark_node
;
21830 tree ctx
= c_parser_omp_context_selector_specification (parser
, parms
);
21831 if (ctx
== error_mark_node
)
21833 ctx
= omp_check_context_selector (match_loc
, ctx
);
21834 if (ctx
!= error_mark_node
&& variant
!= error_mark_node
)
21836 if (TREE_CODE (variant
) != FUNCTION_DECL
)
21838 error_at (token
->location
, "variant %qD is not a function", variant
);
21839 variant
= error_mark_node
;
21841 else if (omp_get_context_selector (ctx
, "construct", "simd") == NULL_TREE
21842 && !comptypes (TREE_TYPE (fndecl
), TREE_TYPE (variant
)))
21844 error_at (token
->location
, "variant %qD and base %qD have "
21845 "incompatible types", variant
, fndecl
);
21846 variant
= error_mark_node
;
21848 else if (fndecl_built_in_p (variant
)
21849 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
21850 "__builtin_", strlen ("__builtin_")) == 0
21851 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
21852 "__sync_", strlen ("__sync_")) == 0
21853 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant
)),
21854 "__atomic_", strlen ("__atomic_")) == 0))
21856 error_at (token
->location
, "variant %qD is a built-in", variant
);
21857 variant
= error_mark_node
;
21859 if (variant
!= error_mark_node
)
21861 C_DECL_USED (variant
) = 1;
21862 tree construct
= omp_get_context_selector (ctx
, "construct", NULL
);
21863 omp_mark_declare_variant (match_loc
, variant
, construct
);
21864 if (omp_context_selector_matches (ctx
))
21867 = tree_cons (get_identifier ("omp declare variant base"),
21868 build_tree_list (variant
, ctx
),
21869 DECL_ATTRIBUTES (fndecl
));
21870 DECL_ATTRIBUTES (fndecl
) = attr
;
21875 parens
.require_close (parser
);
21876 c_parser_skip_to_pragma_eol (parser
);
21879 /* Finalize #pragma omp declare simd or #pragma omp declare variant
21880 clauses after FNDECL has been parsed, and put that into "omp declare simd"
21881 or "omp declare variant base" attribute. */
21884 c_finish_omp_declare_simd (c_parser
*parser
, tree fndecl
, tree parms
,
21885 vec
<c_token
> *pclauses
)
21887 vec
<c_token
> &clauses
= *pclauses
;
21889 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
21890 indicates error has been reported and CPP_PRAGMA that
21891 c_finish_omp_declare_simd has already processed the tokens. */
21892 if (clauses
.exists () && clauses
[0].type
== CPP_EOF
)
21894 const char *kind
= "simd";
21895 if (clauses
.exists ()
21896 && (clauses
[0].type
== CPP_NAME
|| clauses
[0].type
== CPP_PRAGMA
))
21897 kind
= IDENTIFIER_POINTER (clauses
[0].value
);
21898 gcc_assert (strcmp (kind
, "simd") == 0 || strcmp (kind
, "variant") == 0);
21899 if (fndecl
== NULL_TREE
|| TREE_CODE (fndecl
) != FUNCTION_DECL
)
21901 error ("%<#pragma omp declare %s%> not immediately followed by "
21902 "a function declaration or definition", kind
);
21903 clauses
[0].type
= CPP_EOF
;
21906 if (clauses
.exists () && clauses
[0].type
!= CPP_NAME
)
21908 error_at (DECL_SOURCE_LOCATION (fndecl
),
21909 "%<#pragma omp declare %s%> not immediately followed by "
21910 "a single function declaration or definition", kind
);
21911 clauses
[0].type
= CPP_EOF
;
21915 if (parms
== NULL_TREE
)
21916 parms
= DECL_ARGUMENTS (fndecl
);
21918 unsigned int tokens_avail
= parser
->tokens_avail
;
21919 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
21921 parser
->tokens
= clauses
.address ();
21922 parser
->tokens_avail
= clauses
.length ();
21924 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
21925 while (parser
->tokens_avail
> 3)
21927 c_token
*token
= c_parser_peek_token (parser
);
21928 gcc_assert (token
->type
== CPP_NAME
21929 && strcmp (IDENTIFIER_POINTER (token
->value
), kind
) == 0);
21930 c_parser_consume_token (parser
);
21931 parser
->in_pragma
= true;
21933 if (strcmp (kind
, "simd") == 0)
21936 c
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_SIMD_CLAUSE_MASK
,
21937 "#pragma omp declare simd");
21938 c
= c_omp_declare_simd_clauses_to_numbers (parms
, c
);
21939 if (c
!= NULL_TREE
)
21940 c
= tree_cons (NULL_TREE
, c
, NULL_TREE
);
21941 c
= build_tree_list (get_identifier ("omp declare simd"), c
);
21942 TREE_CHAIN (c
) = DECL_ATTRIBUTES (fndecl
);
21943 DECL_ATTRIBUTES (fndecl
) = c
;
21947 gcc_assert (strcmp (kind
, "variant") == 0);
21948 c_finish_omp_declare_variant (parser
, fndecl
, parms
);
21952 parser
->tokens
= &parser
->tokens_buf
[0];
21953 parser
->tokens_avail
= tokens_avail
;
21954 if (clauses
.exists ())
21955 clauses
[0].type
= CPP_PRAGMA
;
21960 # pragma omp declare target new-line
21961 declarations and definitions
21962 # pragma omp end declare target new-line
21965 # pragma omp declare target ( extended-list ) new-line
21967 # pragma omp declare target declare-target-clauses[seq] new-line */
21969 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
21970 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
21971 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
21972 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
21975 c_parser_omp_declare_target (c_parser
*parser
)
21977 tree clauses
= NULL_TREE
;
21978 int device_type
= 0;
21979 bool only_device_type
= true;
21980 if (c_parser_next_token_is (parser
, CPP_NAME
))
21981 clauses
= c_parser_omp_all_clauses (parser
, OMP_DECLARE_TARGET_CLAUSE_MASK
,
21982 "#pragma omp declare target");
21983 else if (c_parser_next_token_is (parser
, CPP_OPEN_PAREN
))
21985 clauses
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_TO_DECLARE
,
21987 clauses
= c_finish_omp_clauses (clauses
, C_ORT_OMP
);
21988 c_parser_skip_to_pragma_eol (parser
);
21992 c_parser_skip_to_pragma_eol (parser
);
21993 current_omp_declare_target_attribute
++;
21996 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
21997 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
21998 device_type
|= OMP_CLAUSE_DEVICE_TYPE_KIND (c
);
21999 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
22001 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE_TYPE
)
22003 tree t
= OMP_CLAUSE_DECL (c
), id
;
22004 tree at1
= lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t
));
22005 tree at2
= lookup_attribute ("omp declare target link",
22006 DECL_ATTRIBUTES (t
));
22007 only_device_type
= false;
22008 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINK
)
22010 id
= get_identifier ("omp declare target link");
22011 std::swap (at1
, at2
);
22014 id
= get_identifier ("omp declare target");
22017 error_at (OMP_CLAUSE_LOCATION (c
),
22018 "%qD specified both in declare target %<link%> and %<to%>"
22024 DECL_ATTRIBUTES (t
) = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
22025 if (TREE_CODE (t
) != FUNCTION_DECL
&& !is_global_var (t
))
22028 symtab_node
*node
= symtab_node::get (t
);
22031 node
->offloadable
= 1;
22032 if (ENABLE_OFFLOADING
)
22034 g
->have_offload
= true;
22035 if (is_a
<varpool_node
*> (node
))
22036 vec_safe_push (offload_vars
, t
);
22040 if (TREE_CODE (t
) != FUNCTION_DECL
)
22042 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_HOST
) != 0)
22044 tree at3
= lookup_attribute ("omp declare target host",
22045 DECL_ATTRIBUTES (t
));
22046 if (at3
== NULL_TREE
)
22048 id
= get_identifier ("omp declare target host");
22049 DECL_ATTRIBUTES (t
)
22050 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
22053 if ((device_type
& OMP_CLAUSE_DEVICE_TYPE_NOHOST
) != 0)
22055 tree at3
= lookup_attribute ("omp declare target nohost",
22056 DECL_ATTRIBUTES (t
));
22057 if (at3
== NULL_TREE
)
22059 id
= get_identifier ("omp declare target nohost");
22060 DECL_ATTRIBUTES (t
)
22061 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
22065 if (device_type
&& only_device_type
)
22066 warning_at (OMP_CLAUSE_LOCATION (clauses
), 0,
22067 "directive with only %<device_type%> clauses ignored");
22071 c_parser_omp_end_declare_target (c_parser
*parser
)
22073 location_t loc
= c_parser_peek_token (parser
)->location
;
22074 c_parser_consume_pragma (parser
);
22075 if (c_parser_next_token_is (parser
, CPP_NAME
)
22076 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
22079 c_parser_consume_token (parser
);
22080 if (c_parser_next_token_is (parser
, CPP_NAME
)
22081 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
),
22083 c_parser_consume_token (parser
);
22086 c_parser_error (parser
, "expected %<target%>");
22087 c_parser_skip_to_pragma_eol (parser
);
22093 c_parser_error (parser
, "expected %<declare%>");
22094 c_parser_skip_to_pragma_eol (parser
);
22097 c_parser_skip_to_pragma_eol (parser
);
22098 if (!current_omp_declare_target_attribute
)
22099 error_at (loc
, "%<#pragma omp end declare target%> without corresponding "
22100 "%<#pragma omp declare target%>");
22102 current_omp_declare_target_attribute
--;
22107 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22108 initializer-clause[opt] new-line
22110 initializer-clause:
22111 initializer (omp_priv = initializer)
22112 initializer (function-name (argument-list)) */
22115 c_parser_omp_declare_reduction (c_parser
*parser
, enum pragma_context context
)
22117 unsigned int tokens_avail
= 0, i
;
22118 vec
<tree
> types
= vNULL
;
22119 vec
<c_token
> clauses
= vNULL
;
22120 enum tree_code reduc_code
= ERROR_MARK
;
22121 tree reduc_id
= NULL_TREE
;
22123 location_t rloc
= c_parser_peek_token (parser
)->location
;
22125 if (context
== pragma_struct
|| context
== pragma_param
)
22127 error ("%<#pragma omp declare reduction%> not at file or block scope");
22131 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
22134 switch (c_parser_peek_token (parser
)->type
)
22137 reduc_code
= PLUS_EXPR
;
22140 reduc_code
= MULT_EXPR
;
22143 reduc_code
= MINUS_EXPR
;
22146 reduc_code
= BIT_AND_EXPR
;
22149 reduc_code
= BIT_XOR_EXPR
;
22152 reduc_code
= BIT_IOR_EXPR
;
22155 reduc_code
= TRUTH_ANDIF_EXPR
;
22158 reduc_code
= TRUTH_ORIF_EXPR
;
22162 p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22163 if (strcmp (p
, "min") == 0)
22165 reduc_code
= MIN_EXPR
;
22168 if (strcmp (p
, "max") == 0)
22170 reduc_code
= MAX_EXPR
;
22173 reduc_id
= c_parser_peek_token (parser
)->value
;
22176 c_parser_error (parser
,
22177 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
22178 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
22182 tree orig_reduc_id
, reduc_decl
;
22183 orig_reduc_id
= reduc_id
;
22184 reduc_id
= c_omp_reduction_id (reduc_code
, reduc_id
);
22185 reduc_decl
= c_omp_reduction_decl (reduc_id
);
22186 c_parser_consume_token (parser
);
22188 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>"))
22193 location_t loc
= c_parser_peek_token (parser
)->location
;
22194 struct c_type_name
*ctype
= c_parser_type_name (parser
);
22197 type
= groktypename (ctype
, NULL
, NULL
);
22198 if (type
== error_mark_node
)
22200 else if ((INTEGRAL_TYPE_P (type
)
22201 || TREE_CODE (type
) == REAL_TYPE
22202 || TREE_CODE (type
) == COMPLEX_TYPE
)
22203 && orig_reduc_id
== NULL_TREE
)
22204 error_at (loc
, "predeclared arithmetic type in "
22205 "%<#pragma omp declare reduction%>");
22206 else if (TREE_CODE (type
) == FUNCTION_TYPE
22207 || TREE_CODE (type
) == ARRAY_TYPE
)
22208 error_at (loc
, "function or array type in "
22209 "%<#pragma omp declare reduction%>");
22210 else if (TYPE_ATOMIC (type
))
22211 error_at (loc
, "%<_Atomic%> qualified type in "
22212 "%<#pragma omp declare reduction%>");
22213 else if (TYPE_QUALS_NO_ADDR_SPACE (type
))
22214 error_at (loc
, "const, volatile or restrict qualified type in "
22215 "%<#pragma omp declare reduction%>");
22219 for (t
= DECL_INITIAL (reduc_decl
); t
; t
= TREE_CHAIN (t
))
22220 if (comptypes (TREE_PURPOSE (t
), type
))
22222 error_at (loc
, "redeclaration of %qs "
22223 "%<#pragma omp declare reduction%> for "
22225 IDENTIFIER_POINTER (reduc_id
)
22226 + sizeof ("omp declare reduction ") - 1,
22229 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t
),
22231 error_at (ploc
, "previous %<#pragma omp declare "
22235 if (t
== NULL_TREE
)
22236 types
.safe_push (type
);
22238 if (c_parser_next_token_is (parser
, CPP_COMMA
))
22239 c_parser_consume_token (parser
);
22247 if (!c_parser_require (parser
, CPP_COLON
, "expected %<:%>")
22248 || types
.is_empty ())
22251 clauses
.release ();
22255 c_token
*token
= c_parser_peek_token (parser
);
22256 if (token
->type
== CPP_EOF
|| token
->type
== CPP_PRAGMA_EOL
)
22258 c_parser_consume_token (parser
);
22260 c_parser_skip_to_pragma_eol (parser
);
22264 if (types
.length () > 1)
22266 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
22268 c_token
*token
= c_parser_peek_token (parser
);
22269 if (token
->type
== CPP_EOF
)
22271 clauses
.safe_push (*token
);
22272 c_parser_consume_token (parser
);
22274 clauses
.safe_push (*c_parser_peek_token (parser
));
22275 c_parser_skip_to_pragma_eol (parser
);
22277 /* Make sure nothing tries to read past the end of the tokens. */
22279 memset (&eof_token
, 0, sizeof (eof_token
));
22280 eof_token
.type
= CPP_EOF
;
22281 clauses
.safe_push (eof_token
);
22282 clauses
.safe_push (eof_token
);
22285 int errs
= errorcount
;
22286 FOR_EACH_VEC_ELT (types
, i
, type
)
22288 tokens_avail
= parser
->tokens_avail
;
22289 gcc_assert (parser
->tokens
== &parser
->tokens_buf
[0]);
22290 if (!clauses
.is_empty ())
22292 parser
->tokens
= clauses
.address ();
22293 parser
->tokens_avail
= clauses
.length ();
22294 parser
->in_pragma
= true;
22297 bool nested
= current_function_decl
!= NULL_TREE
;
22299 c_push_function_context ();
22300 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
22301 reduc_id
, default_function_type
);
22302 current_function_decl
= fndecl
;
22303 allocate_struct_function (fndecl
, true);
22305 tree stmt
= push_stmt_list ();
22306 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
22307 warn about these. */
22308 tree omp_out
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22309 get_identifier ("omp_out"), type
);
22310 DECL_ARTIFICIAL (omp_out
) = 1;
22311 DECL_CONTEXT (omp_out
) = fndecl
;
22312 pushdecl (omp_out
);
22313 tree omp_in
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22314 get_identifier ("omp_in"), type
);
22315 DECL_ARTIFICIAL (omp_in
) = 1;
22316 DECL_CONTEXT (omp_in
) = fndecl
;
22318 struct c_expr combiner
= c_parser_expression (parser
);
22319 struct c_expr initializer
;
22320 tree omp_priv
= NULL_TREE
, omp_orig
= NULL_TREE
;
22322 initializer
.set_error ();
22323 if (!c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
22325 else if (c_parser_next_token_is (parser
, CPP_NAME
)
22326 && strcmp (IDENTIFIER_POINTER
22327 (c_parser_peek_token (parser
)->value
),
22328 "initializer") == 0)
22330 c_parser_consume_token (parser
);
22333 omp_priv
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22334 get_identifier ("omp_priv"), type
);
22335 DECL_ARTIFICIAL (omp_priv
) = 1;
22336 DECL_INITIAL (omp_priv
) = error_mark_node
;
22337 DECL_CONTEXT (omp_priv
) = fndecl
;
22338 pushdecl (omp_priv
);
22339 omp_orig
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
22340 get_identifier ("omp_orig"), type
);
22341 DECL_ARTIFICIAL (omp_orig
) = 1;
22342 DECL_CONTEXT (omp_orig
) = fndecl
;
22343 pushdecl (omp_orig
);
22344 if (!c_parser_require (parser
, CPP_OPEN_PAREN
, "expected %<(%>"))
22346 else if (!c_parser_next_token_is (parser
, CPP_NAME
))
22348 c_parser_error (parser
, "expected %<omp_priv%> or "
22352 else if (strcmp (IDENTIFIER_POINTER
22353 (c_parser_peek_token (parser
)->value
),
22356 if (c_parser_peek_2nd_token (parser
)->type
!= CPP_OPEN_PAREN
22357 || c_parser_peek_token (parser
)->id_kind
!= C_ID_ID
)
22359 c_parser_error (parser
, "expected function-name %<(%>");
22363 initializer
= c_parser_postfix_expression (parser
);
22364 if (initializer
.value
22365 && TREE_CODE (initializer
.value
) == CALL_EXPR
)
22368 tree c
= initializer
.value
;
22369 for (j
= 0; j
< call_expr_nargs (c
); j
++)
22371 tree a
= CALL_EXPR_ARG (c
, j
);
22373 if (TREE_CODE (a
) == ADDR_EXPR
22374 && TREE_OPERAND (a
, 0) == omp_priv
)
22377 if (j
== call_expr_nargs (c
))
22378 error ("one of the initializer call arguments should be "
22384 c_parser_consume_token (parser
);
22385 if (!c_parser_require (parser
, CPP_EQ
, "expected %<=%>"))
22389 tree st
= push_stmt_list ();
22390 location_t loc
= c_parser_peek_token (parser
)->location
;
22391 rich_location
richloc (line_table
, loc
);
22392 start_init (omp_priv
, NULL_TREE
, 0, &richloc
);
22393 struct c_expr init
= c_parser_initializer (parser
);
22395 finish_decl (omp_priv
, loc
, init
.value
,
22396 init
.original_type
, NULL_TREE
);
22397 pop_stmt_list (st
);
22401 && !c_parser_require (parser
, CPP_CLOSE_PAREN
, "expected %<)%>"))
22407 c_parser_skip_to_pragma_eol (parser
);
22409 tree t
= tree_cons (type
, make_tree_vec (omp_priv
? 6 : 3),
22410 DECL_INITIAL (reduc_decl
));
22411 DECL_INITIAL (reduc_decl
) = t
;
22412 DECL_SOURCE_LOCATION (omp_out
) = rloc
;
22413 TREE_VEC_ELT (TREE_VALUE (t
), 0) = omp_out
;
22414 TREE_VEC_ELT (TREE_VALUE (t
), 1) = omp_in
;
22415 TREE_VEC_ELT (TREE_VALUE (t
), 2) = combiner
.value
;
22416 walk_tree (&combiner
.value
, c_check_omp_declare_reduction_r
,
22417 &TREE_VEC_ELT (TREE_VALUE (t
), 0), NULL
);
22420 DECL_SOURCE_LOCATION (omp_priv
) = rloc
;
22421 TREE_VEC_ELT (TREE_VALUE (t
), 3) = omp_priv
;
22422 TREE_VEC_ELT (TREE_VALUE (t
), 4) = omp_orig
;
22423 TREE_VEC_ELT (TREE_VALUE (t
), 5) = initializer
.value
;
22424 walk_tree (&initializer
.value
, c_check_omp_declare_reduction_r
,
22425 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
22426 walk_tree (&DECL_INITIAL (omp_priv
),
22427 c_check_omp_declare_reduction_r
,
22428 &TREE_VEC_ELT (TREE_VALUE (t
), 3), NULL
);
22432 pop_stmt_list (stmt
);
22434 if (cfun
->language
!= NULL
)
22436 ggc_free (cfun
->language
);
22437 cfun
->language
= NULL
;
22440 current_function_decl
= NULL_TREE
;
22442 c_pop_function_context ();
22444 if (!clauses
.is_empty ())
22446 parser
->tokens
= &parser
->tokens_buf
[0];
22447 parser
->tokens_avail
= tokens_avail
;
22451 if (errs
!= errorcount
)
22455 clauses
.release ();
22461 #pragma omp declare simd declare-simd-clauses[optseq] new-line
22462 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22463 initializer-clause[opt] new-line
22464 #pragma omp declare target new-line
22467 #pragma omp declare variant (identifier) match (context-selector) */
22470 c_parser_omp_declare (c_parser
*parser
, enum pragma_context context
)
22472 c_parser_consume_pragma (parser
);
22473 if (c_parser_next_token_is (parser
, CPP_NAME
))
22475 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22476 if (strcmp (p
, "simd") == 0)
22478 /* c_parser_consume_token (parser); done in
22479 c_parser_omp_declare_simd. */
22480 c_parser_omp_declare_simd (parser
, context
);
22483 if (strcmp (p
, "reduction") == 0)
22485 c_parser_consume_token (parser
);
22486 c_parser_omp_declare_reduction (parser
, context
);
22489 if (!flag_openmp
) /* flag_openmp_simd */
22491 c_parser_skip_to_pragma_eol (parser
, false);
22494 if (strcmp (p
, "target") == 0)
22496 c_parser_consume_token (parser
);
22497 c_parser_omp_declare_target (parser
);
22500 if (strcmp (p
, "variant") == 0)
22502 /* c_parser_consume_token (parser); done in
22503 c_parser_omp_declare_simd. */
22504 c_parser_omp_declare_simd (parser
, context
);
22509 c_parser_error (parser
, "expected %<simd%>, %<reduction%>, "
22510 "%<target%> or %<variant%>");
22511 c_parser_skip_to_pragma_eol (parser
);
22516 #pragma omp requires clauses[optseq] new-line */
22519 c_parser_omp_requires (c_parser
*parser
)
22522 enum omp_requires new_req
= (enum omp_requires
) 0;
22524 c_parser_consume_pragma (parser
);
22526 location_t loc
= c_parser_peek_token (parser
)->location
;
22527 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
22530 && c_parser_next_token_is (parser
, CPP_COMMA
)
22531 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
22532 c_parser_consume_token (parser
);
22536 if (c_parser_next_token_is (parser
, CPP_NAME
))
22539 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22540 location_t cloc
= c_parser_peek_token (parser
)->location
;
22541 enum omp_requires this_req
= (enum omp_requires
) 0;
22543 if (!strcmp (p
, "unified_address"))
22544 this_req
= OMP_REQUIRES_UNIFIED_ADDRESS
;
22545 else if (!strcmp (p
, "unified_shared_memory"))
22546 this_req
= OMP_REQUIRES_UNIFIED_SHARED_MEMORY
;
22547 else if (!strcmp (p
, "dynamic_allocators"))
22548 this_req
= OMP_REQUIRES_DYNAMIC_ALLOCATORS
;
22549 else if (!strcmp (p
, "reverse_offload"))
22550 this_req
= OMP_REQUIRES_REVERSE_OFFLOAD
;
22551 else if (!strcmp (p
, "atomic_default_mem_order"))
22553 c_parser_consume_token (parser
);
22555 matching_parens parens
;
22556 if (parens
.require_open (parser
))
22558 if (c_parser_next_token_is (parser
, CPP_NAME
))
22560 tree v
= c_parser_peek_token (parser
)->value
;
22561 p
= IDENTIFIER_POINTER (v
);
22563 if (!strcmp (p
, "seq_cst"))
22565 = (enum omp_requires
) OMP_MEMORY_ORDER_SEQ_CST
;
22566 else if (!strcmp (p
, "relaxed"))
22568 = (enum omp_requires
) OMP_MEMORY_ORDER_RELAXED
;
22569 else if (!strcmp (p
, "acq_rel"))
22571 = (enum omp_requires
) OMP_MEMORY_ORDER_ACQ_REL
;
22575 error_at (c_parser_peek_token (parser
)->location
,
22576 "expected %<seq_cst%>, %<relaxed%> or "
22578 switch (c_parser_peek_token (parser
)->type
)
22581 case CPP_PRAGMA_EOL
:
22582 case CPP_CLOSE_PAREN
:
22585 if (c_parser_peek_2nd_token (parser
)->type
22586 == CPP_CLOSE_PAREN
)
22587 c_parser_consume_token (parser
);
22592 c_parser_consume_token (parser
);
22594 parens
.skip_until_found_close (parser
);
22597 c_parser_skip_to_pragma_eol (parser
, false);
22605 error_at (cloc
, "expected %<unified_address%>, "
22606 "%<unified_shared_memory%>, "
22607 "%<dynamic_allocators%>, "
22608 "%<reverse_offload%> "
22609 "or %<atomic_default_mem_order%> clause");
22610 c_parser_skip_to_pragma_eol (parser
, false);
22613 if (p
&& this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
)
22614 sorry_at (cloc
, "%qs clause on %<requires%> directive not "
22615 "supported yet", p
);
22617 c_parser_consume_token (parser
);
22620 if ((this_req
& ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
22622 if ((this_req
& new_req
) != 0)
22623 error_at (cloc
, "too many %qs clauses", p
);
22624 if (this_req
!= OMP_REQUIRES_DYNAMIC_ALLOCATORS
22625 && (omp_requires_mask
& OMP_REQUIRES_TARGET_USED
) != 0)
22626 error_at (cloc
, "%qs clause used lexically after first "
22627 "target construct or offloading API", p
);
22629 else if ((new_req
& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
22631 error_at (cloc
, "too many %qs clauses",
22632 "atomic_default_mem_order");
22633 this_req
= (enum omp_requires
) 0;
22635 else if ((omp_requires_mask
22636 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
) != 0)
22638 error_at (cloc
, "more than one %<atomic_default_mem_order%>"
22639 " clause in a single compilation unit");
22641 = (enum omp_requires
)
22643 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER
);
22645 else if ((omp_requires_mask
22646 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED
) != 0)
22647 error_at (cloc
, "%<atomic_default_mem_order%> clause used "
22648 "lexically after first %<atomic%> construct "
22649 "without memory order clause");
22650 new_req
= (enum omp_requires
) (new_req
| this_req
);
22652 = (enum omp_requires
) (omp_requires_mask
| this_req
);
22658 c_parser_skip_to_pragma_eol (parser
);
22661 error_at (loc
, "%<pragma omp requires%> requires at least one clause");
22664 /* Helper function for c_parser_omp_taskloop.
22665 Disallow zero sized or potentially zero sized task reductions. */
22668 c_finish_taskloop_clauses (tree clauses
)
22670 tree
*pc
= &clauses
;
22671 for (tree c
= clauses
; c
; c
= *pc
)
22673 bool remove
= false;
22674 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
22676 tree type
= strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
22677 if (integer_zerop (TYPE_SIZE_UNIT (type
)))
22679 error_at (OMP_CLAUSE_LOCATION (c
),
22680 "zero sized type %qT in %<reduction%> clause", type
);
22683 else if (TREE_CODE (TYPE_SIZE_UNIT (type
)) != INTEGER_CST
)
22685 error_at (OMP_CLAUSE_LOCATION (c
),
22686 "variable sized type %qT in %<reduction%> clause",
22692 *pc
= OMP_CLAUSE_CHAIN (c
);
22694 pc
= &OMP_CLAUSE_CHAIN (c
);
22700 #pragma omp taskloop taskloop-clause[optseq] new-line
22703 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
22706 #define OMP_TASKLOOP_CLAUSE_MASK \
22707 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
22708 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22709 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22710 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22711 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
22712 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
22713 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
22714 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22715 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
22716 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22717 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
22718 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
22719 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
22720 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
22721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
22726 c_parser_omp_taskloop (location_t loc
, c_parser
*parser
,
22727 char *p_name
, omp_clause_mask mask
, tree
*cclauses
,
22730 tree clauses
, block
, ret
;
22732 strcat (p_name
, " taskloop");
22733 mask
|= OMP_TASKLOOP_CLAUSE_MASK
;
22734 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
22736 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
)) != 0)
22737 mask
&= ~(OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_IN_REDUCTION
);
22739 if (c_parser_next_token_is (parser
, CPP_NAME
))
22741 const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22743 if (strcmp (p
, "simd") == 0)
22745 tree cclauses_buf
[C_OMP_CLAUSE_SPLIT_COUNT
];
22746 if (cclauses
== NULL
)
22747 cclauses
= cclauses_buf
;
22748 c_parser_consume_token (parser
);
22749 if (!flag_openmp
) /* flag_openmp_simd */
22750 return c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
,
22752 block
= c_begin_compound_stmt (true);
22753 ret
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, cclauses
, if_p
);
22754 block
= c_end_compound_stmt (loc
, block
, true);
22757 ret
= make_node (OMP_TASKLOOP
);
22758 TREE_TYPE (ret
) = void_type_node
;
22759 OMP_FOR_BODY (ret
) = block
;
22760 OMP_FOR_CLAUSES (ret
) = cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
22761 OMP_FOR_CLAUSES (ret
)
22762 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret
));
22763 SET_EXPR_LOCATION (ret
, loc
);
22768 if (!flag_openmp
) /* flag_openmp_simd */
22770 c_parser_skip_to_pragma_eol (parser
, false);
22774 clauses
= c_parser_omp_all_clauses (parser
, mask
, p_name
, cclauses
== NULL
);
22777 omp_split_clauses (loc
, OMP_TASKLOOP
, mask
, clauses
, cclauses
);
22778 clauses
= cclauses
[C_OMP_CLAUSE_SPLIT_TASKLOOP
];
22781 clauses
= c_finish_taskloop_clauses (clauses
);
22782 block
= c_begin_compound_stmt (true);
22783 ret
= c_parser_omp_for_loop (loc
, parser
, OMP_TASKLOOP
, clauses
, NULL
, if_p
);
22784 block
= c_end_compound_stmt (loc
, block
, true);
22791 #pragma omp nothing new-line */
22794 c_parser_omp_nothing (c_parser
*parser
)
22796 c_parser_consume_pragma (parser
);
22797 c_parser_skip_to_pragma_eol (parser
);
22801 #pragma omp error clauses[optseq] new-line */
22804 c_parser_omp_error (c_parser
*parser
, enum pragma_context context
)
22806 int at_compilation
= -1;
22807 int severity_fatal
= -1;
22808 tree message
= NULL_TREE
;
22811 location_t loc
= c_parser_peek_token (parser
)->location
;
22813 c_parser_consume_pragma (parser
);
22815 while (c_parser_next_token_is_not (parser
, CPP_PRAGMA_EOL
))
22818 && c_parser_next_token_is (parser
, CPP_COMMA
)
22819 && c_parser_peek_2nd_token (parser
)->type
== CPP_NAME
)
22820 c_parser_consume_token (parser
);
22824 if (!c_parser_next_token_is (parser
, CPP_NAME
))
22828 = IDENTIFIER_POINTER (c_parser_peek_token (parser
)->value
);
22829 location_t cloc
= c_parser_peek_token (parser
)->location
;
22830 static const char *args
[] = {
22831 "execution", "compilation", "warning", "fatal"
22834 int idx
= 0, n
= -1;
22835 tree m
= NULL_TREE
;
22837 if (!strcmp (p
, "at"))
22838 v
= &at_compilation
;
22839 else if (!strcmp (p
, "severity"))
22841 v
= &severity_fatal
;
22844 else if (strcmp (p
, "message"))
22847 "expected %<at%>, %<severity%> or %<message%> clause");
22848 c_parser_skip_to_pragma_eol (parser
, false);
22852 c_parser_consume_token (parser
);
22854 matching_parens parens
;
22855 if (parens
.require_open (parser
))
22859 location_t expr_loc
= c_parser_peek_token (parser
)->location
;
22860 c_expr expr
= c_parser_expr_no_commas (parser
, NULL
);
22861 expr
= convert_lvalue_to_rvalue (expr_loc
, expr
, true, true);
22862 m
= convert (const_string_type_node
, expr
.value
);
22863 m
= c_fully_fold (m
, false, NULL
);
22867 if (c_parser_next_token_is (parser
, CPP_NAME
))
22869 tree val
= c_parser_peek_token (parser
)->value
;
22870 const char *q
= IDENTIFIER_POINTER (val
);
22872 if (!strcmp (q
, args
[idx
]))
22874 else if (!strcmp (q
, args
[idx
+ 1]))
22879 error_at (c_parser_peek_token (parser
)->location
,
22880 "expected %qs or %qs", args
[idx
], args
[idx
+ 1]);
22882 switch (c_parser_peek_token (parser
)->type
)
22885 case CPP_PRAGMA_EOL
:
22886 case CPP_CLOSE_PAREN
:
22889 if (c_parser_peek_2nd_token (parser
)->type
22890 == CPP_CLOSE_PAREN
)
22891 c_parser_consume_token (parser
);
22896 c_parser_consume_token (parser
);
22899 parens
.skip_until_found_close (parser
);
22905 error_at (cloc
, "too many %qs clauses", p
);
22915 error_at (cloc
, "too many %qs clauses", p
);
22925 c_parser_skip_to_pragma_eol (parser
);
22929 if (at_compilation
== -1)
22930 at_compilation
= 1;
22931 if (severity_fatal
== -1)
22932 severity_fatal
= 1;
22933 if (!at_compilation
)
22935 if (context
!= pragma_compound
)
22937 error_at (loc
, "%<#pragma omp error%> with %<at(execution)%> clause "
22938 "may only be used in compound statements");
22942 = builtin_decl_explicit (severity_fatal
? BUILT_IN_GOMP_ERROR
22943 : BUILT_IN_GOMP_WARNING
);
22945 message
= build_zero_cst (const_string_type_node
);
22946 tree stmt
= build_call_expr_loc (loc
, fndecl
, 2, message
,
22947 build_all_ones_cst (size_type_node
));
22951 const char *msg
= NULL
;
22954 msg
= c_getstr (message
);
22956 msg
= _("<message unknown at compile time>");
22959 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
22960 "%<pragma omp error%> encountered: %s", msg
);
22962 emit_diagnostic (severity_fatal
? DK_ERROR
: DK_WARNING
, loc
, 0,
22963 "%<pragma omp error%> encountered");
22967 /* Main entry point to parsing most OpenMP pragmas. */
22970 c_parser_omp_construct (c_parser
*parser
, bool *if_p
)
22972 enum pragma_kind p_kind
;
22975 char p_name
[sizeof "#pragma omp teams distribute parallel for simd"];
22976 omp_clause_mask
mask (0);
22978 loc
= c_parser_peek_token (parser
)->location
;
22979 p_kind
= c_parser_peek_token (parser
)->pragma_kind
;
22980 c_parser_consume_pragma (parser
);
22984 case PRAGMA_OACC_ATOMIC
:
22985 c_parser_omp_atomic (loc
, parser
, true);
22987 case PRAGMA_OACC_CACHE
:
22988 strcpy (p_name
, "#pragma acc");
22989 stmt
= c_parser_oacc_cache (loc
, parser
);
22991 case PRAGMA_OACC_DATA
:
22992 stmt
= c_parser_oacc_data (loc
, parser
, if_p
);
22994 case PRAGMA_OACC_HOST_DATA
:
22995 stmt
= c_parser_oacc_host_data (loc
, parser
, if_p
);
22997 case PRAGMA_OACC_KERNELS
:
22998 case PRAGMA_OACC_PARALLEL
:
22999 case PRAGMA_OACC_SERIAL
:
23000 strcpy (p_name
, "#pragma acc");
23001 stmt
= c_parser_oacc_compute (loc
, parser
, p_kind
, p_name
, if_p
);
23003 case PRAGMA_OACC_LOOP
:
23004 strcpy (p_name
, "#pragma acc");
23005 stmt
= c_parser_oacc_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23007 case PRAGMA_OACC_WAIT
:
23008 strcpy (p_name
, "#pragma wait");
23009 stmt
= c_parser_oacc_wait (loc
, parser
, p_name
);
23011 case PRAGMA_OMP_ALLOCATE
:
23012 c_parser_omp_allocate (loc
, parser
);
23014 case PRAGMA_OMP_ATOMIC
:
23015 c_parser_omp_atomic (loc
, parser
, false);
23017 case PRAGMA_OMP_CRITICAL
:
23018 stmt
= c_parser_omp_critical (loc
, parser
, if_p
);
23020 case PRAGMA_OMP_DISTRIBUTE
:
23021 strcpy (p_name
, "#pragma omp");
23022 stmt
= c_parser_omp_distribute (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23024 case PRAGMA_OMP_FOR
:
23025 strcpy (p_name
, "#pragma omp");
23026 stmt
= c_parser_omp_for (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23028 case PRAGMA_OMP_LOOP
:
23029 strcpy (p_name
, "#pragma omp");
23030 stmt
= c_parser_omp_loop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23032 case PRAGMA_OMP_MASKED
:
23033 strcpy (p_name
, "#pragma omp");
23034 stmt
= c_parser_omp_masked (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23036 case PRAGMA_OMP_MASTER
:
23037 strcpy (p_name
, "#pragma omp");
23038 stmt
= c_parser_omp_master (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23040 case PRAGMA_OMP_PARALLEL
:
23041 strcpy (p_name
, "#pragma omp");
23042 stmt
= c_parser_omp_parallel (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23044 case PRAGMA_OMP_SCOPE
:
23045 stmt
= c_parser_omp_scope (loc
, parser
, if_p
);
23047 case PRAGMA_OMP_SECTIONS
:
23048 strcpy (p_name
, "#pragma omp");
23049 stmt
= c_parser_omp_sections (loc
, parser
, p_name
, mask
, NULL
);
23051 case PRAGMA_OMP_SIMD
:
23052 strcpy (p_name
, "#pragma omp");
23053 stmt
= c_parser_omp_simd (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23055 case PRAGMA_OMP_SINGLE
:
23056 stmt
= c_parser_omp_single (loc
, parser
, if_p
);
23058 case PRAGMA_OMP_TASK
:
23059 stmt
= c_parser_omp_task (loc
, parser
, if_p
);
23061 case PRAGMA_OMP_TASKGROUP
:
23062 stmt
= c_parser_omp_taskgroup (loc
, parser
, if_p
);
23064 case PRAGMA_OMP_TASKLOOP
:
23065 strcpy (p_name
, "#pragma omp");
23066 stmt
= c_parser_omp_taskloop (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23068 case PRAGMA_OMP_TEAMS
:
23069 strcpy (p_name
, "#pragma omp");
23070 stmt
= c_parser_omp_teams (loc
, parser
, p_name
, mask
, NULL
, if_p
);
23073 gcc_unreachable ();
23076 if (stmt
&& stmt
!= error_mark_node
)
23077 gcc_assert (EXPR_LOCATION (stmt
) != UNKNOWN_LOCATION
);
23082 # pragma omp threadprivate (variable-list) */
23085 c_parser_omp_threadprivate (c_parser
*parser
)
23090 c_parser_consume_pragma (parser
);
23091 loc
= c_parser_peek_token (parser
)->location
;
23092 vars
= c_parser_omp_var_list_parens (parser
, OMP_CLAUSE_ERROR
, NULL
);
23094 /* Mark every variable in VARS to be assigned thread local storage. */
23095 for (t
= vars
; t
; t
= TREE_CHAIN (t
))
23097 tree v
= TREE_PURPOSE (t
);
23099 /* FIXME diagnostics: Ideally we should keep individual
23100 locations for all the variables in the var list to make the
23101 following errors more precise. Perhaps
23102 c_parser_omp_var_list_parens() should construct a list of
23103 locations to go along with the var list. */
23105 /* If V had already been marked threadprivate, it doesn't matter
23106 whether it had been used prior to this point. */
23108 error_at (loc
, "%qD is not a variable", v
);
23109 else if (TREE_USED (v
) && !C_DECL_THREADPRIVATE_P (v
))
23110 error_at (loc
, "%qE declared %<threadprivate%> after first use", v
);
23111 else if (! is_global_var (v
))
23112 error_at (loc
, "automatic variable %qE cannot be %<threadprivate%>", v
);
23113 else if (TREE_TYPE (v
) == error_mark_node
)
23115 else if (! COMPLETE_TYPE_P (TREE_TYPE (v
)))
23116 error_at (loc
, "%<threadprivate%> %qE has incomplete type", v
);
23119 if (! DECL_THREAD_LOCAL_P (v
))
23121 set_decl_tls_model (v
, decl_default_tls_model (v
));
23122 /* If rtl has been already set for this var, call
23123 make_decl_rtl once again, so that encode_section_info
23124 has a chance to look at the new decl flags. */
23125 if (DECL_RTL_SET_P (v
))
23128 C_DECL_THREADPRIVATE_P (v
) = 1;
23132 c_parser_skip_to_pragma_eol (parser
);
23135 /* Parse a transaction attribute (GCC Extension).
23137 transaction-attribute:
23139 attribute-specifier
23143 c_parser_transaction_attributes (c_parser
*parser
)
23145 if (c_parser_next_token_is_keyword (parser
, RID_ATTRIBUTE
))
23146 return c_parser_gnu_attributes (parser
);
23148 if (!c_parser_next_token_is (parser
, CPP_OPEN_SQUARE
))
23150 return c_parser_std_attribute_specifier (parser
, true);
23153 /* Parse a __transaction_atomic or __transaction_relaxed statement
23156 transaction-statement:
23157 __transaction_atomic transaction-attribute[opt] compound-statement
23158 __transaction_relaxed compound-statement
23160 Note that the only valid attribute is: "outer".
23164 c_parser_transaction (c_parser
*parser
, enum rid keyword
)
23166 unsigned int old_in
= parser
->in_transaction
;
23167 unsigned int this_in
= 1, new_in
;
23168 location_t loc
= c_parser_peek_token (parser
)->location
;
23171 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
23172 || keyword
== RID_TRANSACTION_RELAXED
)
23173 && c_parser_next_token_is_keyword (parser
, keyword
));
23174 c_parser_consume_token (parser
);
23176 if (keyword
== RID_TRANSACTION_RELAXED
)
23177 this_in
|= TM_STMT_ATTR_RELAXED
;
23180 attrs
= c_parser_transaction_attributes (parser
);
23182 this_in
|= parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
);
23185 /* Keep track if we're in the lexical scope of an outer transaction. */
23186 new_in
= this_in
| (old_in
& TM_STMT_ATTR_OUTER
);
23188 parser
->in_transaction
= new_in
;
23189 stmt
= c_parser_compound_statement (parser
);
23190 parser
->in_transaction
= old_in
;
23193 stmt
= c_finish_transaction (loc
, stmt
, this_in
);
23195 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
23196 "%<__transaction_atomic%> without transactional memory support enabled"
23197 : "%<__transaction_relaxed %> "
23198 "without transactional memory support enabled"));
23203 /* Parse a __transaction_atomic or __transaction_relaxed expression
23206 transaction-expression:
23207 __transaction_atomic ( expression )
23208 __transaction_relaxed ( expression )
23211 static struct c_expr
23212 c_parser_transaction_expression (c_parser
*parser
, enum rid keyword
)
23215 unsigned int old_in
= parser
->in_transaction
;
23216 unsigned int this_in
= 1;
23217 location_t loc
= c_parser_peek_token (parser
)->location
;
23220 gcc_assert ((keyword
== RID_TRANSACTION_ATOMIC
23221 || keyword
== RID_TRANSACTION_RELAXED
)
23222 && c_parser_next_token_is_keyword (parser
, keyword
));
23223 c_parser_consume_token (parser
);
23225 if (keyword
== RID_TRANSACTION_RELAXED
)
23226 this_in
|= TM_STMT_ATTR_RELAXED
;
23229 attrs
= c_parser_transaction_attributes (parser
);
23231 this_in
|= parse_tm_stmt_attr (attrs
, 0);
23234 parser
->in_transaction
= this_in
;
23235 matching_parens parens
;
23236 if (parens
.require_open (parser
))
23238 tree expr
= c_parser_expression (parser
).value
;
23239 ret
.original_type
= TREE_TYPE (expr
);
23240 ret
.value
= build1 (TRANSACTION_EXPR
, ret
.original_type
, expr
);
23241 if (this_in
& TM_STMT_ATTR_RELAXED
)
23242 TRANSACTION_EXPR_RELAXED (ret
.value
) = 1;
23243 SET_EXPR_LOCATION (ret
.value
, loc
);
23244 ret
.original_code
= TRANSACTION_EXPR
;
23245 if (!parens
.require_close (parser
))
23247 c_parser_skip_until_found (parser
, CPP_CLOSE_PAREN
, NULL
);
23255 ret
.original_code
= ERROR_MARK
;
23256 ret
.original_type
= NULL
;
23258 parser
->in_transaction
= old_in
;
23261 error_at (loc
, (keyword
== RID_TRANSACTION_ATOMIC
?
23262 "%<__transaction_atomic%> without transactional memory support enabled"
23263 : "%<__transaction_relaxed %> "
23264 "without transactional memory support enabled"));
23266 set_c_expr_source_range (&ret
, loc
, loc
);
23271 /* Parse a __transaction_cancel statement (GCC Extension).
23273 transaction-cancel-statement:
23274 __transaction_cancel transaction-attribute[opt] ;
23276 Note that the only valid attribute is "outer".
23280 c_parser_transaction_cancel (c_parser
*parser
)
23282 location_t loc
= c_parser_peek_token (parser
)->location
;
23284 bool is_outer
= false;
23286 gcc_assert (c_parser_next_token_is_keyword (parser
, RID_TRANSACTION_CANCEL
));
23287 c_parser_consume_token (parser
);
23289 attrs
= c_parser_transaction_attributes (parser
);
23291 is_outer
= (parse_tm_stmt_attr (attrs
, TM_STMT_ATTR_OUTER
) != 0);
23295 error_at (loc
, "%<__transaction_cancel%> without "
23296 "transactional memory support enabled");
23299 else if (parser
->in_transaction
& TM_STMT_ATTR_RELAXED
)
23301 error_at (loc
, "%<__transaction_cancel%> within a "
23302 "%<__transaction_relaxed%>");
23307 if ((parser
->in_transaction
& TM_STMT_ATTR_OUTER
) == 0
23308 && !is_tm_may_cancel_outer (current_function_decl
))
23310 error_at (loc
, "outer %<__transaction_cancel%> not "
23311 "within outer %<__transaction_atomic%> or "
23312 "a %<transaction_may_cancel_outer%> function");
23316 else if (parser
->in_transaction
== 0)
23318 error_at (loc
, "%<__transaction_cancel%> not within "
23319 "%<__transaction_atomic%>");
23323 return add_stmt (build_tm_abort_call (loc
, is_outer
));
23326 return build1 (NOP_EXPR
, void_type_node
, error_mark_node
);
23329 /* Parse a single source file. */
23332 c_parse_file (void)
23334 /* Use local storage to begin. If the first token is a pragma, parse it.
23335 If it is #pragma GCC pch_preprocess, then this will load a PCH file
23336 which will cause garbage collection. */
23339 memset (&tparser
, 0, sizeof tparser
);
23340 tparser
.translate_strings_p
= true;
23341 tparser
.tokens
= &tparser
.tokens_buf
[0];
23342 the_parser
= &tparser
;
23344 if (c_parser_peek_token (&tparser
)->pragma_kind
== PRAGMA_GCC_PCH_PREPROCESS
)
23345 c_parser_pragma_pch_preprocess (&tparser
);
23347 c_common_no_more_pch ();
23349 the_parser
= ggc_alloc
<c_parser
> ();
23350 *the_parser
= tparser
;
23351 if (tparser
.tokens
== &tparser
.tokens_buf
[0])
23352 the_parser
->tokens
= &the_parser
->tokens_buf
[0];
23354 /* Initialize EH, if we've been told to do so. */
23355 if (flag_exceptions
)
23356 using_eh_for_cleanups ();
23358 c_parser_translation_unit (the_parser
);
23362 /* Parse the body of a function declaration marked with "__RTL".
23364 The RTL parser works on the level of characters read from a
23365 FILE *, whereas c_parser works at the level of tokens.
23366 Square this circle by consuming all of the tokens up to and
23367 including the closing brace, recording the start/end of the RTL
23368 fragment, and reopening the file and re-reading the relevant
23369 lines within the RTL parser.
23371 This requires the opening and closing braces of the C function
23372 to be on separate lines from the RTL they wrap.
23374 Take ownership of START_WITH_PASS, if non-NULL. */
23377 c_parser_parse_rtl_body (c_parser
*parser
, char *start_with_pass
)
23379 if (!c_parser_require (parser
, CPP_OPEN_BRACE
, "expected %<{%>"))
23381 free (start_with_pass
);
23382 return c_parser_peek_token (parser
)->location
;
23385 location_t start_loc
= c_parser_peek_token (parser
)->location
;
23387 /* Consume all tokens, up to the closing brace, handling
23388 matching pairs of braces in the rtl dump. */
23389 int num_open_braces
= 1;
23392 switch (c_parser_peek_token (parser
)->type
)
23394 case CPP_OPEN_BRACE
:
23397 case CPP_CLOSE_BRACE
:
23398 if (--num_open_braces
== 0)
23399 goto found_closing_brace
;
23402 error_at (start_loc
, "no closing brace");
23403 free (start_with_pass
);
23404 return c_parser_peek_token (parser
)->location
;
23408 c_parser_consume_token (parser
);
23411 found_closing_brace
:
23412 /* At the closing brace; record its location. */
23413 location_t end_loc
= c_parser_peek_token (parser
)->location
;
23415 /* Consume the closing brace. */
23416 c_parser_consume_token (parser
);
23418 /* Invoke the RTL parser. */
23419 if (!read_rtl_function_body_from_file_range (start_loc
, end_loc
))
23421 free (start_with_pass
);
23425 /* Run the backend on the cfun created above, transferring ownership of
23426 START_WITH_PASS. */
23427 run_rtl_passes (start_with_pass
);
23431 #include "gt-c-c-parser.h"